Skip to content

Commit

Permalink
docs: add translations to auth related components and core services
Browse files Browse the repository at this point in the history
  • Loading branch information
danieljancar committed Jun 5, 2024
1 parent 407e23c commit 313671d
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 109 deletions.
2 changes: 1 addition & 1 deletion apps/course/src/app/core/feedback/toast.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class ToastService {

this.toasts.push(toast);

setTimeout(() => this.removeToast(toast), 5000);
setTimeout(() => this.removeToast(toast), 4500);
return this.toasts;
}

Expand Down
4 changes: 2 additions & 2 deletions apps/course/src/app/core/util/language.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ export class LanguageService {
() => {
localStorage.setItem(this.LANG_KEY, lang);
this.toastService.showToast(
this.translate.instant('language-change-success'),
this.translate.instant('languageService.language-change-success'),
ToastType.Success,
);
},
() => {
this.toastService.showToast(
this.translate.instant('language-change-error'),
this.translate.instant('languageService.language-change-error'),
ToastType.Error,
);
},
Expand Down
17 changes: 9 additions & 8 deletions apps/course/src/app/features/auth/account/account.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
>
<div>
<label class="label">
<span class="label-text">Name</span>
<span class="label-text">{{ 'account.name' | translate }}</span>
</label>
<input
type="text"
placeholder="Please enter your name"
[placeholder]="'account.name-placeholder' | translate"
[value]="user.name"
class="input input-bordered w-full"
formControlName="name"
Expand All @@ -41,11 +41,11 @@
</div>
<div>
<label class="label">
<span class="label-text">Email</span>
<span class="label-text">{{ 'account.email' | translate }}</span>
</label>
<input
type="email"
placeholder="Please enter your email"
[placeholder]="'account.email-placeholder' | translate"
[value]="user.email"
class="input input-bordered w-full"
formControlName="email"
Expand All @@ -58,11 +58,11 @@
</div>
<div>
<label class="label">
<span class="label-text">Bio</span>
<span class="label-text">{{ 'account.bio' | translate }}</span>
</label>
<textarea
class="textarea textarea-bordered h-24 w-full"
placeholder="Please enter your bio"
[placeholder]="'account.bio-placeholder' | translate"
formControlName="bio"
>{{ user.bio }}</textarea
>
Expand All @@ -81,13 +81,14 @@
class="btn btn-primary mt-4 w-full"
type="submit"
>
Update
{{ 'account.update' | translate }}
</button>
</form>
}
@if (user.updatedAt) {
<p class="text-center text-xs mt-2">
Last updated: {{ user.updatedAt.toDate() | relativeTime: 'relative' }}
{{ 'account.last-updated' | translate }}:
{{ user.updatedAt.toDate() | relativeTime: 'relative' }}
</p>
}
}
Expand Down
45 changes: 31 additions & 14 deletions apps/course/src/app/features/auth/account/account.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { RelativeTimePipe } from '../../../pipes/relative-time.pipe';
import { interval, Observable, Subscription } from 'rxjs';
import { ToastType } from '../../../types/feedback/toast.types';
import { UserService } from '../../../core/data/user.service';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

@Component({
selector: 'app-account',
Expand All @@ -39,6 +40,7 @@ import { UserService } from '../../../core/data/user.service';
RouterLink,
AccountProfileBannerComponent,
RelativeTimePipe,
TranslateModule,
],
})
export class AccountComponent implements OnInit, OnDestroy {
Expand All @@ -54,6 +56,7 @@ export class AccountComponent implements OnInit, OnDestroy {
private toastService: ToastService,
private changeDetectorRef: ChangeDetectorRef,
private userService: UserService,
private t: TranslateService,
) {
this.setTitle();
this.userProfileForm = this.initUserProfileForm();
Expand Down Expand Up @@ -81,14 +84,14 @@ export class AccountComponent implements OnInit, OnDestroy {
.updateUserAvatar(file)
.then(() => {
this.toastService.showToast(
'Avatar updated successfully.',
this.t.instant('account.update-avatar-success'),
ToastType.Success,
);
this.avatarIsUploading = false;
})
.catch(() => {
this.toastService.showToast(
'Failed to update avatar, please try again.',
this.t.instant('account.update-avatar-error'),
ToastType.Error,
);
this.avatarIsUploading = false;
Expand All @@ -103,14 +106,14 @@ export class AccountComponent implements OnInit, OnDestroy {
.updateUser(updatedUserData)
.then(() => {
this.toastService.showToast(
'Your profile was updated successfully.',
this.t.instant('account.update-profile-success'),
ToastType.Success,
);
this.loadUser();
})
.catch(() => {
this.toastService.showToast(
'There was an error updating your profile.',
this.t.instant('account.update-profile-error'),
ToastType.Error,
);
});
Expand All @@ -129,7 +132,7 @@ export class AccountComponent implements OnInit, OnDestroy {
},
error: () => {
this.toastService.showToast(
'Error loading user data.',
this.t.instant('account.load-user-data-error'),
ToastType.Error,
);
this.isLoading = false;
Expand All @@ -141,7 +144,7 @@ export class AccountComponent implements OnInit, OnDestroy {
private setTitle(): void {
const titleService = inject(Title);
titleService.setTitle(
`Account - ${environment.metaConfig.title} - ${AppComponent.chorizo.title}`,
`${this.t.instant('account.account')} - ${environment.metaConfig.title} - ${AppComponent.chorizo.title}`,
);
}

Expand Down Expand Up @@ -177,14 +180,28 @@ export class AccountComponent implements OnInit, OnDestroy {

// eslint-disable-next-line @typescript-eslint/no-explicit-any
private parseErrors(errors: any): string {
if (errors['required']) return 'This field is required';
if (errors['username']) return 'Invalid username format';
if (errors['email']) return 'Invalid email format';
if (errors['bio']) return 'Bio should be between 3 and 800 characters';
if (errors['minlength'])
return `Minimum length should be ${errors['minlength']['requiredLength']}`;
if (errors['maxlength'])
return `Maximum length should be ${errors['maxlength']['requiredLength']}`;
if (errors['required']) {
return this.t.instant('account.parse-errors.required');
}
if (errors['username']) {
return this.t.instant('account.parse-errors.invalid-username');
}
if (errors['email']) {
return this.t.instant('account.parse-errors.invalid-email');
}
if (errors['bio']) {
return this.t.instant('account.parse-errors.bio-length');
}
if (errors['minlength']) {
return this.t.instant('account.parse-errors.min-length', {
min: errors['minlength']['requiredLength'],
});
}
if (errors['maxlength']) {
return this.t.instant('account.parse-errors.max-length', {
max: errors['maxlength']['requiredLength'],
});
}
return 'Unknown error';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
}
</div>
<p class="mt-2 text-blue-500 hover:text-blue-600 cursor-pointer text-xs">
<label class="cursor-pointer" for="avatarUpload"> Change avatar </label>
<label class="cursor-pointer" for="avatarUpload">{{
'accountProfileBanner.change-avatar' | translate
}}</label>
<input
(change)="onFileSelected($event)"
accept="image/*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import {
import { MatIcon } from '@angular/material/icon';
import { ImageLoaderService } from '../../../../core/util/image-loader.service';
import { NgOptimizedImage } from '@angular/common';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

@Component({
selector: 'app-account-profile-banner',
standalone: true,
imports: [MatIcon, NgOptimizedImage],
imports: [MatIcon, NgOptimizedImage, TranslateModule],
templateUrl: './account-profile-banner.component.html',
styleUrl: './account-profile-banner.component.scss',
})
Expand All @@ -25,7 +26,10 @@ export class AccountProfileBannerComponent implements OnChanges {

avatarUrl: string | undefined;

constructor(private imageLoaderService: ImageLoaderService) {}
constructor(
private imageLoaderService: ImageLoaderService,
private t: TranslateService,
) {}

ngOnChanges(changes: SimpleChanges): void {
if (changes['avatarPath']?.currentValue) {
Expand All @@ -43,7 +47,9 @@ export class AccountProfileBannerComponent implements OnChanges {
.then((url) => {
this.avatarUrl = url;
})
.catch((error) => console.error('Error loading avatar image:', error));
.catch((error) =>
console.error(this.t.instant('accountProfileBanner.load-avatar-error')),
);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
32 changes: 17 additions & 15 deletions apps/course/src/app/features/auth/login/login.component.html
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
<div class="flex justify-center items-center my-auto h-full">
<div class="card w-full max-w-lg">
<div class="card-body">
<h2 class="card-title">Login</h2>
<p>Enter your credentials to access your account.</p>
<h2 class="card-title">{{ 'login.title' | translate }}</h2>
<p>{{ 'login.credentials-description' | translate }}</p>
<form (ngSubmit)="submit()" [formGroup]="credentials">
<label class="label">
<span class="label-text">Email</span>
<span class="label-text">{{ 'login.email-label' | translate }}</span>
</label>
<input
[placeholder]="'login.email-placeholder' | translate"
class="input input-bordered w-full"
formControlName="email"
placeholder="Email"
type="email"
/>
@if (getErrorMessage('email')) {
@if (parseErrors('email')) {
<div class="text-error text-xs p-1">
{{ getErrorMessage('email') }}
{{ parseErrors('email') }}
</div>
}

<label class="label">
<span class="label-text">Password</span>
<span class="label-text">{{
'login.password-label' | translate
}}</span>
</label>
<input
[placeholder]="'login.password-placeholder' | translate"
class="input input-bordered w-full"
formControlName="password"
placeholder="Password"
type="password"
/>
@if (getErrorMessage('password')) {
@if (parseErrors('password')) {
<div class="text-error text-xs p-1">
{{ getErrorMessage('password') }}
{{ parseErrors('password') }}
</div>
}

<button
[disabled]="!credentials.valid || isLoggingIn"
class="btn btn-primary mt-4 w-full"
Expand All @@ -42,13 +42,15 @@ <h2 class="card-title">Login</h2>
@if (isLoggingIn) {
<span class="loading loading-spinner"></span>
}
Login
{{ 'login.credentials-submit' | translate }}
</button>
</form>
<div class="text-center mt-4">
<p class="mb-5">
Don't have an account?
<a class="link link-primary" routerLink="/a/register">Register</a>
{{ 'login.no-account-message' | translate }}
<a class="link link-primary" routerLink="/a/register">{{
'login.register-link' | translate
}}</a>
</p>
</div>
</div>
Expand Down
22 changes: 14 additions & 8 deletions apps/course/src/app/features/auth/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import { environment } from '../../../../environments/environment';
import { AppComponent } from '../../../app.component';
import { ToastType } from '../../../types/feedback/toast.types';
import { isReactive } from '@angular/core/primitives/signals';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
standalone: true,
imports: [ReactiveFormsModule, RouterLink],
imports: [ReactiveFormsModule, RouterLink, TranslateModule],
})
export class LoginComponent {
public credentials: FormGroup;
Expand All @@ -31,7 +32,8 @@ export class LoginComponent {
private authService: AuthService,
private router: Router,
private toastService: ToastService,
titleService: Title,
private t: TranslateService,
private titleService: Title,
) {
this.credentials = this.formBuilder.group({
email: [
Expand All @@ -54,7 +56,7 @@ export class LoginComponent {
});

titleService.setTitle(
`Login - ${environment.metaConfig.title} - ${AppComponent.chorizo.title}`,
`${this.t.instant('login.title')} - ${environment.metaConfig.title} - ${AppComponent.chorizo.title}`,
);
}

Expand All @@ -78,20 +80,24 @@ export class LoginComponent {
}
}

public getErrorMessage(controlName: string): string | null {
public parseErrors(controlName: string): string | null {
const control = this.credentials.get(controlName);
if (control && control.touched && control.errors) {
if (control.errors['required']) {
return 'This field is required';
return this.t.instant('login.parse-errors.required');
}
if (control.errors['email']) {
return 'Invalid email format, please try another.';
return this.t.instant('login.parse-errors.invalid-email');
}
if (control.errors['minlength']) {
return `Minimum length should be ${control.errors['minlength']['requiredLength']}`;
return this.t.instant('login.parse-errors.min-length', {
min: control.errors['minlength']['requiredLength'],
});
}
if (control.errors['maxlength']) {
return `Maximum length should be ${control.errors['maxlength']['requiredLength']}`;
return this.t.instant('login.parse-errors.max-length', {
max: control.errors['maxlength']['requiredLength'],
});
}
}
return null;
Expand Down
Loading

0 comments on commit 313671d

Please sign in to comment.