Skip to content

Commit f0b896f

Browse files
committed
feat(app): add language change logic
1 parent bc370db commit f0b896f

7 files changed

Lines changed: 88 additions & 56 deletions

File tree

src/app/core/components/language-selector/language-selector.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<sl-dropdown>
22
<sl-button class="dropdown-button--primary" slot="trigger" caret>{{
3-
locale | uppercase
3+
localeId | uppercase
44
}}</sl-button>
55
<sl-menu class="menu--primary">
66
<sl-menu-item class="menu-item--primary" value="cut"

src/app/core/components/language-selector/language-selector.component.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import '@shoelace-style/shoelace/dist/components/menu/menu.js';
1313
import '@shoelace-style/shoelace/dist/components/menu-item/menu-item.js';
1414

1515
@Component({
16-
selector: 'app-language-selector',
17-
templateUrl: './language-selector.component.html',
18-
changeDetection: ChangeDetectionStrategy.OnPush,
19-
imports: [UpperCasePipe],
20-
schemas: [CUSTOM_ELEMENTS_SCHEMA]
16+
selector: 'app-language-selector',
17+
templateUrl: './language-selector.component.html',
18+
changeDetection: ChangeDetectionStrategy.OnPush,
19+
imports: [UpperCasePipe],
20+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
2121
})
2222
export class LanguageSelectorComponent {
2323
readonly router = inject(Router);
24-
readonly locale = inject(LOCALE_ID);
24+
readonly localeId = inject(LOCALE_ID);
2525
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Language } from '~core/enums/language.enum';
2+
3+
export const DEFAULT_LANGUAGE = Language.EN_US;

src/app/core/services/language.service.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { inject, Injectable, LOCALE_ID } from '@angular/core';
2+
import { DEFAULT_LANGUAGE } from '~core/constants/language.constants';
3+
import { Router } from '@angular/router';
24
import { Language } from '~core/enums/language.enum';
35
import { Locale } from '~core/enums/locale.enum';
46

@@ -7,11 +9,20 @@ import { Locale } from '~core/enums/locale.enum';
79
})
810
export class LanguageService {
911
private readonly localeId = inject(LOCALE_ID);
12+
private readonly router = inject(Router);
1013

1114
convertLocaleToAcceptLanguage(): Language {
1215
if (this.localeId === (Locale.ES as string)) {
1316
return Language.ES_ES;
1417
}
1518
return Language.EN_US;
1619
}
20+
21+
navigateWithUserLanguage(userLanguage: string, path: string) {
22+
if (userLanguage === this.localeId || userLanguage === (DEFAULT_LANGUAGE as string)) {
23+
void this.router.navigate([path]);
24+
} else {
25+
void this.router.navigate([`${userLanguage}${path}`]);
26+
}
27+
}
1728
}

src/app/features/authentication/pages/log-in/log-in.component.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
inject,
88
} from '@angular/core';
99
import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
10-
import { Router, RouterModule } from '@angular/router';
10+
import { RouterModule } from '@angular/router';
1111
import { emailValidator } from '~core/validators/email.validator';
1212
import { AUTH_URLS, ROOT_URLS } from '~core/constants/urls.constants';
1313
import { passwordValidator } from '~core/validators/password.validator';
@@ -21,21 +21,24 @@ import '@shoelace-style/shoelace/dist/components/input/input.js';
2121
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
2222
import { AlertService } from '~core/services/alert.service';
2323
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
24+
import type { User } from '~features/authentication/types/user.type';
25+
import { LanguageService } from '~core/services/language.service';
2426

2527
@Component({
26-
selector: 'app-log-in',
27-
templateUrl: './log-in.component.html',
28-
styleUrl: './log-in.component.scss',
29-
changeDetection: ChangeDetectionStrategy.OnPush,
30-
imports: [ReactiveFormsModule, RouterModule, SlInputIconFocusDirective, NgOptimizedImage],
31-
schemas: [CUSTOM_ELEMENTS_SCHEMA]
28+
selector: 'app-log-in',
29+
templateUrl: './log-in.component.html',
30+
styleUrl: './log-in.component.scss',
31+
changeDetection: ChangeDetectionStrategy.OnPush,
32+
imports: [ReactiveFormsModule, RouterModule, SlInputIconFocusDirective, NgOptimizedImage],
33+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
3234
})
3335
export class LogInComponent {
3436
private readonly changeDetectorRef = inject(ChangeDetectorRef);
3537
private readonly alertService = inject(AlertService);
36-
private readonly router = inject(Router);
38+
3739
private readonly formBuilder = inject(FormBuilder);
3840
private readonly authService = inject(AuthenticationService);
41+
private readonly languageService = inject(LanguageService);
3942
private readonly destroyRef = inject(DestroyRef);
4043

4144
translations = translations;
@@ -65,10 +68,13 @@ export class LogInComponent {
6568
.logIn({ email: formValue.email!, password: formValue.password! })
6669
.pipe(takeUntilDestroyed(this.destroyRef))
6770
.subscribe({
68-
next: () => {
71+
next: (user: User) => {
6972
this.isButtonLogInLoading = false;
7073
this.changeDetectorRef.markForCheck();
71-
void this.router.navigate([ROOT_URLS.myPokedex]);
74+
this.languageService.navigateWithUserLanguage(
75+
user.language as string,
76+
ROOT_URLS.myPokedex,
77+
);
7278
},
7379
error: (response) => {
7480
this.isButtonLogInLoading = false;

src/app/features/authentication/pages/my-account/my-account.component.ts

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,24 @@ import '@shoelace-style/shoelace/dist/components/icon/icon.js';
2828
import '@shoelace-style/shoelace/dist/components/select/select.js';
2929
import '@shoelace-style/shoelace/dist/components/option/option.js';
3030
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
31+
import { LanguageService } from '~core/services/language.service';
32+
import { AUTH_URLS } from '~core/constants/urls.constants';
3133

3234
@Component({
33-
selector: 'app-my-account',
34-
templateUrl: './my-account.component.html',
35-
styleUrl: './my-account.component.scss',
36-
changeDetection: ChangeDetectionStrategy.OnPush,
37-
imports: [
38-
RouterModule,
39-
ReactiveFormsModule,
40-
SlInputIconFocusDirective,
41-
PokemonImageComponent,
42-
AppSlSelectControlDirective,
43-
ThemeButtonComponent,
44-
NgOptimizedImage,
45-
],
46-
schemas: [CUSTOM_ELEMENTS_SCHEMA]
35+
selector: 'app-my-account',
36+
templateUrl: './my-account.component.html',
37+
styleUrl: './my-account.component.scss',
38+
changeDetection: ChangeDetectionStrategy.OnPush,
39+
imports: [
40+
RouterModule,
41+
ReactiveFormsModule,
42+
SlInputIconFocusDirective,
43+
PokemonImageComponent,
44+
AppSlSelectControlDirective,
45+
ThemeButtonComponent,
46+
NgOptimizedImage,
47+
],
48+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
4749
})
4850
export class MyAccountComponent implements OnInit {
4951
private readonly changeDetectorRef = inject(ChangeDetectorRef);
@@ -52,6 +54,7 @@ export class MyAccountComponent implements OnInit {
5254
private readonly pokemonService = inject(PokemonService);
5355
private readonly alertService = inject(AlertService);
5456
private readonly destroyRef = inject(DestroyRef);
57+
private readonly languageService = inject(LanguageService);
5558

5659
translations = translations;
5760
user: User | undefined;
@@ -110,25 +113,36 @@ export class MyAccountComponent implements OnInit {
110113
this.updateUserForm.markAllAsTouched();
111114
if (this.updateUserForm.valid) {
112115
this.isButtonUpdateUserFormLoading = true;
113-
const formValue = this.updateUserForm.getRawValue();
114-
this.userService
115-
.updateUser({
116-
name: formValue.name!,
117-
language: formValue.language!,
118-
})
119-
.pipe(takeUntilDestroyed(this.destroyRef))
120-
.subscribe({
121-
next: () => {
122-
this.isButtonUpdateUserFormLoading = false;
123-
this.alertService.createSuccessAlert(translations.myAccountSuccessAlert);
124-
this.changeDetectorRef.markForCheck();
125-
},
126-
error: () => {
127-
this.isButtonUpdateUserFormLoading = false;
128-
this.alertService.createErrorAlert(translations.genericErrorAlert);
129-
this.changeDetectorRef.markForCheck();
130-
},
131-
});
116+
this.updateUser();
132117
}
133118
}
119+
120+
updateUser() {
121+
const formValue = this.updateUserForm.getRawValue();
122+
this.userService
123+
.updateUser({
124+
name: formValue.name!,
125+
language: formValue.language!,
126+
})
127+
.pipe(takeUntilDestroyed(this.destroyRef))
128+
.subscribe({
129+
next: () => {
130+
this.isButtonUpdateUserFormLoading = false;
131+
this.alertService.createSuccessAlert(translations.myAccountSuccessAlert);
132+
this.changeDetectorRef.markForCheck();
133+
134+
if (this.user?.language !== formValue.language) {
135+
this.languageService.navigateWithUserLanguage(
136+
formValue.language as string,
137+
AUTH_URLS.myAccount,
138+
);
139+
}
140+
},
141+
error: () => {
142+
this.isButtonUpdateUserFormLoading = false;
143+
this.alertService.createErrorAlert(translations.genericErrorAlert);
144+
this.changeDetectorRef.markForCheck();
145+
},
146+
});
147+
}
134148
}

src/app/features/authentication/services/authentication.service.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ import type { Observable } from 'rxjs';
55
import { map } from 'rxjs';
66
import type { LoginRequest } from '~features/authentication/types/login-request.type';
77
import { environment } from '~environments/environment';
8-
import type {
9-
LoginResponse,
10-
LoginResponseData,
11-
} from '~features/authentication/types/login-response.type';
8+
import type { LoginResponse } from '~features/authentication/types/login-response.type';
129
import type {
1310
RefreshTokenResponse,
1411
RefreshTokenResponseData,
@@ -19,6 +16,7 @@ import type {
1916
RegisterResponseData,
2017
} from '~features/authentication/types/register-response.type';
2118
import { LanguageService } from '~core/services/language.service';
19+
import type { User } from '~features/authentication/types/user.type';
2220

2321
const IS_SESSION_ALIVE_KEY = 'isSessionAlive';
2422

@@ -64,7 +62,7 @@ export class AuthenticationService {
6462
);
6563
}
6664

67-
logIn(loginRequest: LoginRequest): Observable<LoginResponseData> {
65+
logIn(loginRequest: LoginRequest): Observable<User> {
6866
const loginEndpoint = `${this.apiUrl}/v1/authentication/login`;
6967
return this.httpClient
7068
.post<LoginResponse>(
@@ -80,7 +78,7 @@ export class AuthenticationService {
8078
const { data } = response;
8179
this.storageService?.setItem(IS_SESSION_ALIVE_KEY, 'true');
8280
this.isUserLoggedInSignal.set(true);
83-
return data;
81+
return data.user;
8482
}),
8583
);
8684
}

0 commit comments

Comments
 (0)