diff --git a/.gitignore b/.gitignore index 0139063..3888800 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /out-tsc /bazel-out /files +changes.txt # Node /node_modules diff --git a/angular.json b/angular.json index 0698c77..edace0f 100644 --- a/angular.json +++ b/angular.json @@ -146,7 +146,8 @@ }, "sourceMap": false, "namedChunks": false, - "extractLicenses": true + "extractLicenses": true, + "serviceWorker": "ngsw-config.json" } }, "defaultConfiguration": "production" diff --git a/ngsw-config.json b/ngsw-config.json index 14e0154..a949b9a 100644 --- a/ngsw-config.json +++ b/ngsw-config.json @@ -8,7 +8,6 @@ "resources": { "files": [ "/favicon.ico", - "/index.csr.html", "/index.html", "/manifest.webmanifest", "/*.css", @@ -48,7 +47,7 @@ "https://**/*.webp" ], "cacheConfig": { - "maxSize": 50, + "maxSize": 200, "maxAge": "7d", "strategy": "performance" } diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 21b372d..773a15b 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -3,7 +3,6 @@ import { provideRouter, withInMemoryScrolling } from '@angular/router'; import { provideHttpClient, withInterceptors } from '@angular/common/http'; import { routes } from './app.routes'; -import { mockDataInterceptor } from './interceptors/mock-data.interceptor'; import { cacheInterceptor } from './interceptors/cache.interceptor'; import { provideServiceWorker } from '@angular/service-worker'; @@ -16,10 +15,11 @@ export const appConfig: ApplicationConfig = { withInMemoryScrolling({ scrollPositionRestoration: 'top' }) ), provideHttpClient( - withInterceptors([mockDataInterceptor, cacheInterceptor]) - ), provideServiceWorker('ngsw-worker.js', { - enabled: !isDevMode(), - registrationStrategy: 'registerWhenStable:30000' - }) + withInterceptors([cacheInterceptor]) + ), + provideServiceWorker('ngsw-worker.js', { + enabled: !isDevMode(), + registrationStrategy: 'registerWhenStable:30000' + }) ] -} +}; diff --git a/src/app/app.html b/src/app/app.html index ee0a585..775fccf 100644 --- a/src/app/app.html +++ b/src/app/app.html @@ -1,14 +1,14 @@ @if (checkingServer()) {
-

Подключение к серверу...

+

{{ 'app.connecting' | translate }}

} @else if (!serverAvailable()) {
⚠️
-

Сервер недоступен

-

Не удалось подключиться к серверу. Проверьте подключение к интернету.

- +

{{ 'app.serverUnavailable' | translate }}

+

{{ 'app.serverError' | translate }}

+
} @else { diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 2d3417d..76c8414 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,5 +1,6 @@ import { Routes } from '@angular/router'; import { brandInfoRoutes, brandLegalRoutes } from './brands/brand-routes'; +import { languageGuard } from './guards/language.guard'; // Core routes (same across all brands) const coreRoutes: Routes = [ @@ -29,13 +30,18 @@ const coreRoutes: Routes = [ } ]; -// Combine core routes with brand-specific routes +// All routes sit under a :lang prefix (e.g. /ru/cart, /en/item/5) export const routes: Routes = [ - ...coreRoutes, - ...brandInfoRoutes, - ...brandLegalRoutes, { - path: '**', - redirectTo: '' - } + path: ':lang', + canActivate: [languageGuard], + children: [ + ...coreRoutes, + ...brandInfoRoutes, + ...brandLegalRoutes, + { path: '**', redirectTo: '' } + ] + }, + // URLs without a language prefix → redirect to default language + { path: '**', redirectTo: 'ru' } ]; \ No newline at end of file diff --git a/src/app/app.ts b/src/app/app.ts index 9563e2f..ccaab04 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -11,10 +11,12 @@ import { filter, first } from 'rxjs/operators'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { environment } from '../environments/environment'; import { SwUpdate } from '@angular/service-worker'; +import { TranslatePipe } from './i18n/translate.pipe'; +import { TranslateService } from './i18n/translate.service'; @Component({ selector: 'app-root', - imports: [RouterOutlet, HeaderComponent, FooterComponent, BackButtonComponent], + imports: [RouterOutlet, HeaderComponent, FooterComponent, BackButtonComponent, TranslatePipe], templateUrl: './app.html', styleUrl: './app.scss' }) @@ -30,9 +32,10 @@ export class App implements OnInit { private swUpdate = inject(SwUpdate); private appRef = inject(ApplicationRef); private router = inject(Router); + private i18n = inject(TranslateService); ngOnInit(): void { - this.titleService.setTitle(`${environment.brandFullName} - Маркетплейс товаров и услуг`); + this.titleService.setTitle(`${environment.brandFullName} - ${this.i18n.t('app.pageTitle')}`); this.checkServerHealth(); this.setupAutoUpdates(); @@ -43,8 +46,10 @@ export class App implements OnInit { takeUntilDestroyed(this.destroyRef) ) .subscribe((event) => { - const url = (event as NavigationEnd).urlAfterRedirects || (event as NavigationEnd).url; - this.isHomePage.set(url === '/' || url === '/home' || url === ''); + const navEnd = event as NavigationEnd; + const url = navEnd.urlAfterRedirects || navEnd.url; + // Home pages: /ru, /en, /hy (with or without trailing slash) + this.isHomePage.set(/^\/[a-z]{2}\/?$/.test(url) || url === '/' || url === ''); }); } diff --git a/src/app/brands/dexar/pages/info/faq/faq.component.html b/src/app/brands/dexar/pages/info/faq/faq.component.html deleted file mode 100644 index 9dac502..0000000 --- a/src/app/brands/dexar/pages/info/faq/faq.component.html +++ /dev/null @@ -1,244 +0,0 @@ - diff --git a/src/app/brands/dexar/pages/legal/company-details/company-details.component.html b/src/app/brands/dexar/pages/legal/company-details/company-details.component.html deleted file mode 100644 index 7ae6a29..0000000 --- a/src/app/brands/dexar/pages/legal/company-details/company-details.component.html +++ /dev/null @@ -1,102 +0,0 @@ - diff --git a/src/app/brands/dexar/pages/legal/payment-terms/payment-terms.component.html b/src/app/brands/dexar/pages/legal/payment-terms/payment-terms.component.html deleted file mode 100644 index a65e258..0000000 --- a/src/app/brands/dexar/pages/legal/payment-terms/payment-terms.component.html +++ /dev/null @@ -1,119 +0,0 @@ - diff --git a/src/app/brands/dexar/pages/legal/privacy-policy/privacy-policy.component.html b/src/app/brands/dexar/pages/legal/privacy-policy/privacy-policy.component.html deleted file mode 100644 index cd47b3f..0000000 --- a/src/app/brands/dexar/pages/legal/privacy-policy/privacy-policy.component.html +++ /dev/null @@ -1,258 +0,0 @@ - diff --git a/src/app/brands/novo/pages/info/about/about.component.html b/src/app/brands/novo/pages/info/about/about.component.html index ea57919..722b0a5 100644 --- a/src/app/brands/novo/pages/info/about/about.component.html +++ b/src/app/brands/novo/pages/info/about/about.component.html @@ -1,99 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/brands/novo/pages/info/about/about.component.ts b/src/app/brands/novo/pages/info/about/about.component.ts index 858280e..6993e65 100644 --- a/src/app/brands/novo/pages/info/about/about.component.ts +++ b/src/app/brands/novo/pages/info/about/about.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { AboutNovoRuComponent } from './ru/about-ru.component'; +import { AboutNovoEnComponent } from './en/about-en.component'; +import { AboutNovoHyComponent } from './hy/about-hy.component'; @Component({ selector: 'app-about-novo', - imports: [], + imports: [AboutNovoRuComponent, AboutNovoEnComponent, AboutNovoHyComponent], templateUrl: './about.component.html', - styleUrls: ['../../../../../pages/info/about/about.component.scss'] + styleUrls: ['../../../../../pages/info/about/about.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class AboutNovoComponent {} +export class AboutNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/info/about/en/about-en.component.html b/src/app/brands/novo/pages/info/about/en/about-en.component.html new file mode 100644 index 0000000..e5b7520 --- /dev/null +++ b/src/app/brands/novo/pages/info/about/en/about-en.component.html @@ -0,0 +1,99 @@ + diff --git a/src/app/brands/novo/pages/info/about/en/about-en.component.ts b/src/app/brands/novo/pages/info/about/en/about-en.component.ts new file mode 100644 index 0000000..f3d7e12 --- /dev/null +++ b/src/app/brands/novo/pages/info/about/en/about-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-about-novo-en', + templateUrl: './about-en.component.html', + styleUrls: ['../../../../../../pages/info/about/about.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AboutNovoEnComponent {} diff --git a/src/app/brands/novo/pages/info/about/hy/about-hy.component.html b/src/app/brands/novo/pages/info/about/hy/about-hy.component.html new file mode 100644 index 0000000..5a1db55 --- /dev/null +++ b/src/app/brands/novo/pages/info/about/hy/about-hy.component.html @@ -0,0 +1,99 @@ + diff --git a/src/app/brands/novo/pages/info/about/hy/about-hy.component.ts b/src/app/brands/novo/pages/info/about/hy/about-hy.component.ts new file mode 100644 index 0000000..416ac17 --- /dev/null +++ b/src/app/brands/novo/pages/info/about/hy/about-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-about-novo-hy', + templateUrl: './about-hy.component.html', + styleUrls: ['../../../../../../pages/info/about/about.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AboutNovoHyComponent {} diff --git a/src/app/brands/novo/pages/info/about/ru/about-ru.component.html b/src/app/brands/novo/pages/info/about/ru/about-ru.component.html new file mode 100644 index 0000000..ea57919 --- /dev/null +++ b/src/app/brands/novo/pages/info/about/ru/about-ru.component.html @@ -0,0 +1,99 @@ + diff --git a/src/app/brands/novo/pages/info/about/ru/about-ru.component.ts b/src/app/brands/novo/pages/info/about/ru/about-ru.component.ts new file mode 100644 index 0000000..d007b19 --- /dev/null +++ b/src/app/brands/novo/pages/info/about/ru/about-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-about-novo-ru', + templateUrl: './about-ru.component.html', + styleUrls: ['../../../../../../pages/info/about/about.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AboutNovoRuComponent {} diff --git a/src/app/brands/novo/pages/info/contacts/contacts.component.html b/src/app/brands/novo/pages/info/contacts/contacts.component.html index a6f6c98..9dc2d13 100644 --- a/src/app/brands/novo/pages/info/contacts/contacts.component.html +++ b/src/app/brands/novo/pages/info/contacts/contacts.component.html @@ -1,49 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/brands/novo/pages/info/contacts/contacts.component.ts b/src/app/brands/novo/pages/info/contacts/contacts.component.ts index c87b3ef..da6aadb 100644 --- a/src/app/brands/novo/pages/info/contacts/contacts.component.ts +++ b/src/app/brands/novo/pages/info/contacts/contacts.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { ContactsNovoRuComponent } from './ru/contacts-ru.component'; +import { ContactsNovoEnComponent } from './en/contacts-en.component'; +import { ContactsNovoHyComponent } from './hy/contacts-hy.component'; @Component({ selector: 'app-contacts-novo', - imports: [], + imports: [ContactsNovoRuComponent, ContactsNovoEnComponent, ContactsNovoHyComponent], templateUrl: './contacts.component.html', - styleUrls: ['../../../../../pages/info/contacts/contacts.component.scss'] + styleUrls: ['../../../../../pages/info/contacts/contacts.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class ContactsNovoComponent {} +export class ContactsNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/info/contacts/en/contacts-en.component.html b/src/app/brands/novo/pages/info/contacts/en/contacts-en.component.html new file mode 100644 index 0000000..15fade9 --- /dev/null +++ b/src/app/brands/novo/pages/info/contacts/en/contacts-en.component.html @@ -0,0 +1,49 @@ + diff --git a/src/app/brands/novo/pages/info/contacts/en/contacts-en.component.ts b/src/app/brands/novo/pages/info/contacts/en/contacts-en.component.ts new file mode 100644 index 0000000..63a374b --- /dev/null +++ b/src/app/brands/novo/pages/info/contacts/en/contacts-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-contacts-novo-en', + templateUrl: './contacts-en.component.html', + styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ContactsNovoEnComponent {} diff --git a/src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.html b/src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.html new file mode 100644 index 0000000..2827b75 --- /dev/null +++ b/src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.html @@ -0,0 +1,49 @@ + diff --git a/src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.ts b/src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.ts new file mode 100644 index 0000000..90ccc8d --- /dev/null +++ b/src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-contacts-novo-hy', + templateUrl: './contacts-hy.component.html', + styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ContactsNovoHyComponent {} diff --git a/src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.html b/src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.html new file mode 100644 index 0000000..a6f6c98 --- /dev/null +++ b/src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.html @@ -0,0 +1,49 @@ + diff --git a/src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.ts b/src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.ts new file mode 100644 index 0000000..ead69b2 --- /dev/null +++ b/src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-contacts-novo-ru', + templateUrl: './contacts-ru.component.html', + styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ContactsNovoRuComponent {} diff --git a/src/app/brands/novo/pages/info/delivery/delivery.component.html b/src/app/brands/novo/pages/info/delivery/delivery.component.html index 4b86702..3de9319 100644 --- a/src/app/brands/novo/pages/info/delivery/delivery.component.html +++ b/src/app/brands/novo/pages/info/delivery/delivery.component.html @@ -1,78 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/brands/novo/pages/info/delivery/delivery.component.ts b/src/app/brands/novo/pages/info/delivery/delivery.component.ts index 971a09e..f36c920 100644 --- a/src/app/brands/novo/pages/info/delivery/delivery.component.ts +++ b/src/app/brands/novo/pages/info/delivery/delivery.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { DeliveryNovoRuComponent } from './ru/delivery-ru.component'; +import { DeliveryNovoEnComponent } from './en/delivery-en.component'; +import { DeliveryNovoHyComponent } from './hy/delivery-hy.component'; @Component({ selector: 'app-delivery-novo', - imports: [], + imports: [DeliveryNovoRuComponent, DeliveryNovoEnComponent, DeliveryNovoHyComponent], templateUrl: './delivery.component.html', - styleUrls: ['../../../../../pages/info/delivery/delivery.component.scss'] + styleUrls: ['../../../../../pages/info/delivery/delivery.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class DeliveryNovoComponent {} +export class DeliveryNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/info/delivery/en/delivery-en.component.html b/src/app/brands/novo/pages/info/delivery/en/delivery-en.component.html new file mode 100644 index 0000000..c23cbbc --- /dev/null +++ b/src/app/brands/novo/pages/info/delivery/en/delivery-en.component.html @@ -0,0 +1,78 @@ + diff --git a/src/app/brands/novo/pages/info/delivery/en/delivery-en.component.ts b/src/app/brands/novo/pages/info/delivery/en/delivery-en.component.ts new file mode 100644 index 0000000..a682efa --- /dev/null +++ b/src/app/brands/novo/pages/info/delivery/en/delivery-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-delivery-novo-en', + templateUrl: './delivery-en.component.html', + styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class DeliveryNovoEnComponent {} diff --git a/src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.html b/src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.html new file mode 100644 index 0000000..2b583fd --- /dev/null +++ b/src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.html @@ -0,0 +1,78 @@ + diff --git a/src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.ts b/src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.ts new file mode 100644 index 0000000..e54d462 --- /dev/null +++ b/src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-delivery-novo-hy', + templateUrl: './delivery-hy.component.html', + styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class DeliveryNovoHyComponent {} diff --git a/src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.html b/src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.html new file mode 100644 index 0000000..4b86702 --- /dev/null +++ b/src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.html @@ -0,0 +1,78 @@ + diff --git a/src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.ts b/src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.ts new file mode 100644 index 0000000..2165dae --- /dev/null +++ b/src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-delivery-novo-ru', + templateUrl: './delivery-ru.component.html', + styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class DeliveryNovoRuComponent {} diff --git a/src/app/brands/novo/pages/info/faq/en/faq-en.component.html b/src/app/brands/novo/pages/info/faq/en/faq-en.component.html new file mode 100644 index 0000000..b506318 --- /dev/null +++ b/src/app/brands/novo/pages/info/faq/en/faq-en.component.html @@ -0,0 +1,93 @@ + diff --git a/src/app/brands/novo/pages/info/faq/en/faq-en.component.ts b/src/app/brands/novo/pages/info/faq/en/faq-en.component.ts new file mode 100644 index 0000000..b239745 --- /dev/null +++ b/src/app/brands/novo/pages/info/faq/en/faq-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-faq-novo-en', + templateUrl: './faq-en.component.html', + styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class FaqNovoEnComponent {} diff --git a/src/app/brands/novo/pages/info/faq/faq.component.html b/src/app/brands/novo/pages/info/faq/faq.component.html index e8d3588..9c9d8b1 100644 --- a/src/app/brands/novo/pages/info/faq/faq.component.html +++ b/src/app/brands/novo/pages/info/faq/faq.component.html @@ -1,93 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/brands/novo/pages/info/faq/faq.component.ts b/src/app/brands/novo/pages/info/faq/faq.component.ts index 9294424..8a926ca 100644 --- a/src/app/brands/novo/pages/info/faq/faq.component.ts +++ b/src/app/brands/novo/pages/info/faq/faq.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { FaqNovoRuComponent } from './ru/faq-ru.component'; +import { FaqNovoEnComponent } from './en/faq-en.component'; +import { FaqNovoHyComponent } from './hy/faq-hy.component'; @Component({ selector: 'app-faq-novo', - imports: [], + imports: [FaqNovoRuComponent, FaqNovoEnComponent, FaqNovoHyComponent], templateUrl: './faq.component.html', - styleUrls: ['../../../../../pages/info/faq/faq.component.scss'] + styleUrls: ['../../../../../pages/info/faq/faq.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class FaqNovoComponent {} +export class FaqNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/info/faq/hy/faq-hy.component.html b/src/app/brands/novo/pages/info/faq/hy/faq-hy.component.html new file mode 100644 index 0000000..c9c7515 --- /dev/null +++ b/src/app/brands/novo/pages/info/faq/hy/faq-hy.component.html @@ -0,0 +1,93 @@ + diff --git a/src/app/brands/novo/pages/info/faq/hy/faq-hy.component.ts b/src/app/brands/novo/pages/info/faq/hy/faq-hy.component.ts new file mode 100644 index 0000000..e7ac448 --- /dev/null +++ b/src/app/brands/novo/pages/info/faq/hy/faq-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-faq-novo-hy', + templateUrl: './faq-hy.component.html', + styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class FaqNovoHyComponent {} diff --git a/src/app/brands/novo/pages/info/faq/ru/faq-ru.component.html b/src/app/brands/novo/pages/info/faq/ru/faq-ru.component.html new file mode 100644 index 0000000..e8d3588 --- /dev/null +++ b/src/app/brands/novo/pages/info/faq/ru/faq-ru.component.html @@ -0,0 +1,93 @@ + diff --git a/src/app/brands/novo/pages/info/faq/ru/faq-ru.component.ts b/src/app/brands/novo/pages/info/faq/ru/faq-ru.component.ts new file mode 100644 index 0000000..5649871 --- /dev/null +++ b/src/app/brands/novo/pages/info/faq/ru/faq-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-faq-novo-ru', + templateUrl: './faq-ru.component.html', + styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class FaqNovoRuComponent {} diff --git a/src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.html b/src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.html new file mode 100644 index 0000000..302eece --- /dev/null +++ b/src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.html @@ -0,0 +1,92 @@ + diff --git a/src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.ts b/src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.ts new file mode 100644 index 0000000..83193ad --- /dev/null +++ b/src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-guarantee-novo-en', + templateUrl: './guarantee-en.component.html', + styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class GuaranteeNovoEnComponent {} diff --git a/src/app/brands/novo/pages/info/guarantee/guarantee.component.html b/src/app/brands/novo/pages/info/guarantee/guarantee.component.html index 8649d45..38aa247 100644 --- a/src/app/brands/novo/pages/info/guarantee/guarantee.component.html +++ b/src/app/brands/novo/pages/info/guarantee/guarantee.component.html @@ -1,92 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/brands/novo/pages/info/guarantee/guarantee.component.ts b/src/app/brands/novo/pages/info/guarantee/guarantee.component.ts index 08877bb..138706d 100644 --- a/src/app/brands/novo/pages/info/guarantee/guarantee.component.ts +++ b/src/app/brands/novo/pages/info/guarantee/guarantee.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { GuaranteeNovoRuComponent } from './ru/guarantee-ru.component'; +import { GuaranteeNovoEnComponent } from './en/guarantee-en.component'; +import { GuaranteeNovoHyComponent } from './hy/guarantee-hy.component'; @Component({ selector: 'app-guarantee-novo', - imports: [], + imports: [GuaranteeNovoRuComponent, GuaranteeNovoEnComponent, GuaranteeNovoHyComponent], templateUrl: './guarantee.component.html', - styleUrls: ['../../../../../pages/info/guarantee/guarantee.component.scss'] + styleUrls: ['../../../../../pages/info/guarantee/guarantee.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class GuaranteeNovoComponent {} +export class GuaranteeNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.html b/src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.html new file mode 100644 index 0000000..adfb2c4 --- /dev/null +++ b/src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.html @@ -0,0 +1,92 @@ + diff --git a/src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.ts b/src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.ts new file mode 100644 index 0000000..4c05836 --- /dev/null +++ b/src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-guarantee-novo-hy', + templateUrl: './guarantee-hy.component.html', + styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class GuaranteeNovoHyComponent {} diff --git a/src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.html b/src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.html new file mode 100644 index 0000000..ee0c1ef --- /dev/null +++ b/src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.html @@ -0,0 +1,92 @@ + diff --git a/src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.ts b/src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.ts new file mode 100644 index 0000000..5d35dba --- /dev/null +++ b/src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-guarantee-novo-ru', + templateUrl: './guarantee-ru.component.html', + styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class GuaranteeNovoRuComponent {} diff --git a/src/app/brands/novo/pages/legal/company-details/company-details.component.html b/src/app/brands/novo/pages/legal/company-details/company-details.component.html index 8613e72..0790090 100644 --- a/src/app/brands/novo/pages/legal/company-details/company-details.component.html +++ b/src/app/brands/novo/pages/legal/company-details/company-details.component.html @@ -1,113 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/brands/novo/pages/legal/company-details/company-details.component.ts b/src/app/brands/novo/pages/legal/company-details/company-details.component.ts index 79b17e9..2e60a1e 100644 --- a/src/app/brands/novo/pages/legal/company-details/company-details.component.ts +++ b/src/app/brands/novo/pages/legal/company-details/company-details.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { CompanyDetailsNovoRuComponent } from './ru/company-details-ru.component'; +import { CompanyDetailsNovoEnComponent } from './en/company-details-en.component'; +import { CompanyDetailsNovoHyComponent } from './hy/company-details-hy.component'; @Component({ selector: 'app-company-details-novo', - imports: [], + imports: [CompanyDetailsNovoRuComponent, CompanyDetailsNovoEnComponent, CompanyDetailsNovoHyComponent], templateUrl: './company-details.component.html', - styleUrls: ['../../../../../pages/legal/company-details/company-details.component.scss'] + styleUrls: ['../../../../../pages/legal/company-details/company-details.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class CompanyDetailsNovoComponent {} +export class CompanyDetailsNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.html b/src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.html new file mode 100644 index 0000000..980cbb1 --- /dev/null +++ b/src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.html @@ -0,0 +1,113 @@ + diff --git a/src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.ts b/src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.ts new file mode 100644 index 0000000..6ba1df6 --- /dev/null +++ b/src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-company-details-novo-en', + templateUrl: './company-details-en.component.html', + styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CompanyDetailsNovoEnComponent {} diff --git a/src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.html b/src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.html new file mode 100644 index 0000000..6814b5d --- /dev/null +++ b/src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.html @@ -0,0 +1,113 @@ + diff --git a/src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.ts b/src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.ts new file mode 100644 index 0000000..893d7f4 --- /dev/null +++ b/src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-company-details-novo-hy', + templateUrl: './company-details-hy.component.html', + styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CompanyDetailsNovoHyComponent {} diff --git a/src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.html b/src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.html new file mode 100644 index 0000000..8613e72 --- /dev/null +++ b/src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.html @@ -0,0 +1,113 @@ + diff --git a/src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.ts b/src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.ts new file mode 100644 index 0000000..06dea49 --- /dev/null +++ b/src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-company-details-novo-ru', + templateUrl: './company-details-ru.component.html', + styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CompanyDetailsNovoRuComponent {} diff --git a/src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.html b/src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.html new file mode 100644 index 0000000..82ee7bb --- /dev/null +++ b/src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.html @@ -0,0 +1,162 @@ + diff --git a/src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.ts b/src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.ts new file mode 100644 index 0000000..2c83ecb --- /dev/null +++ b/src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-payment-terms-novo-en', + imports: [RouterLink, LangRoutePipe], + templateUrl: './payment-terms-en.component.html', + styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PaymentTermsNovoEnComponent {} diff --git a/src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.html b/src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.html new file mode 100644 index 0000000..bfe6170 --- /dev/null +++ b/src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.html @@ -0,0 +1,162 @@ + \ No newline at end of file diff --git a/src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.ts b/src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.ts new file mode 100644 index 0000000..6031c31 --- /dev/null +++ b/src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-payment-terms-novo-hy', + imports: [RouterLink, LangRoutePipe], + templateUrl: './payment-terms-hy.component.html', + styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PaymentTermsNovoHyComponent {} diff --git a/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.html b/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.html index f8b68eb..3c5cbe9 100644 --- a/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.html +++ b/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.html @@ -1,162 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.ts b/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.ts index 995ccb0..df45396 100644 --- a/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.ts +++ b/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { PaymentTermsNovoRuComponent } from './ru/payment-terms-ru.component'; +import { PaymentTermsNovoEnComponent } from './en/payment-terms-en.component'; +import { PaymentTermsNovoHyComponent } from './hy/payment-terms-hy.component'; @Component({ selector: 'app-payment-terms-novo', - imports: [], + imports: [PaymentTermsNovoRuComponent, PaymentTermsNovoEnComponent, PaymentTermsNovoHyComponent], templateUrl: './payment-terms.component.html', - styleUrls: ['../../../../../pages/legal/payment-terms/payment-terms.component.scss'] + styleUrls: ['../../../../../pages/legal/payment-terms/payment-terms.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class PaymentTermsNovoComponent {} +export class PaymentTermsNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.html b/src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.html new file mode 100644 index 0000000..3630e87 --- /dev/null +++ b/src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.html @@ -0,0 +1,162 @@ + diff --git a/src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.ts b/src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.ts new file mode 100644 index 0000000..cb53340 --- /dev/null +++ b/src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-payment-terms-novo-ru', + imports: [RouterLink, LangRoutePipe], + templateUrl: './payment-terms-ru.component.html', + styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PaymentTermsNovoRuComponent {} diff --git a/src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.html b/src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.html new file mode 100644 index 0000000..f3a5d34 --- /dev/null +++ b/src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.html @@ -0,0 +1,277 @@ + diff --git a/src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.ts b/src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.ts new file mode 100644 index 0000000..0f6ebb0 --- /dev/null +++ b/src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-privacy-policy-novo-en', + templateUrl: './privacy-policy-en.component.html', + styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PrivacyPolicyNovoEnComponent {} diff --git a/src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html b/src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html new file mode 100644 index 0000000..fada1c1 --- /dev/null +++ b/src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html @@ -0,0 +1,8 @@ + diff --git a/src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts b/src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts new file mode 100644 index 0000000..ba5c4ca --- /dev/null +++ b/src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-privacy-policy-novo-hy', + templateUrl: './privacy-policy-hy.component.html', + styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PrivacyPolicyNovoHyComponent {} diff --git a/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.html b/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.html index c94d62a..2b2c676 100644 --- a/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.html +++ b/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.html @@ -1,277 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} \ No newline at end of file diff --git a/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.ts b/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.ts index de07fe2..b6a6ace 100644 --- a/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.ts +++ b/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { PrivacyPolicyNovoRuComponent } from './ru/privacy-policy-ru.component'; +import { PrivacyPolicyNovoEnComponent } from './en/privacy-policy-en.component'; +import { PrivacyPolicyNovoHyComponent } from './hy/privacy-policy-hy.component'; @Component({ selector: 'app-privacy-policy-novo', - imports: [], + imports: [PrivacyPolicyNovoRuComponent, PrivacyPolicyNovoEnComponent, PrivacyPolicyNovoHyComponent], templateUrl: './privacy-policy.component.html', - styleUrls: ['../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'] + styleUrls: ['../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class PrivacyPolicyNovoComponent {} +export class PrivacyPolicyNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html b/src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html new file mode 100644 index 0000000..c94d62a --- /dev/null +++ b/src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html @@ -0,0 +1,277 @@ + diff --git a/src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts b/src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts new file mode 100644 index 0000000..9239910 --- /dev/null +++ b/src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-privacy-policy-novo-ru', + templateUrl: './privacy-policy-ru.component.html', + styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PrivacyPolicyNovoRuComponent {} diff --git a/src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.html b/src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.html new file mode 100644 index 0000000..8224136 --- /dev/null +++ b/src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.html @@ -0,0 +1,265 @@ + diff --git a/src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.ts b/src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.ts new file mode 100644 index 0000000..6163fbc --- /dev/null +++ b/src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-public-offer-novo-en', + imports: [RouterLink, LangRoutePipe], + templateUrl: './public-offer-en.component.html', + styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PublicOfferNovoEnComponent {} diff --git a/src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.html b/src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.html new file mode 100644 index 0000000..7a9fb84 --- /dev/null +++ b/src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.html @@ -0,0 +1,265 @@ + diff --git a/src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.ts b/src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.ts new file mode 100644 index 0000000..c54ac19 --- /dev/null +++ b/src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-public-offer-novo-hy', + imports: [RouterLink, LangRoutePipe], + templateUrl: './public-offer-hy.component.html', + styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PublicOfferNovoHyComponent {} diff --git a/src/app/brands/novo/pages/legal/public-offer/public-offer.component.html b/src/app/brands/novo/pages/legal/public-offer/public-offer.component.html index 99e2721..ed16c9d 100644 --- a/src/app/brands/novo/pages/legal/public-offer/public-offer.component.html +++ b/src/app/brands/novo/pages/legal/public-offer/public-offer.component.html @@ -1,267 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} \ No newline at end of file diff --git a/src/app/brands/novo/pages/legal/public-offer/public-offer.component.ts b/src/app/brands/novo/pages/legal/public-offer/public-offer.component.ts index 853e80a..6d05ac0 100644 --- a/src/app/brands/novo/pages/legal/public-offer/public-offer.component.ts +++ b/src/app/brands/novo/pages/legal/public-offer/public-offer.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { PublicOfferNovoRuComponent } from './ru/public-offer-ru.component'; +import { PublicOfferNovoEnComponent } from './en/public-offer-en.component'; +import { PublicOfferNovoHyComponent } from './hy/public-offer-hy.component'; @Component({ selector: 'app-public-offer-novo', - imports: [], + imports: [PublicOfferNovoRuComponent, PublicOfferNovoEnComponent, PublicOfferNovoHyComponent], templateUrl: './public-offer.component.html', - styleUrls: ['../../../../../pages/legal/public-offer/public-offer.component.scss'] + styleUrls: ['../../../../../pages/legal/public-offer/public-offer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class PublicOfferNovoComponent {} +export class PublicOfferNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.html b/src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.html new file mode 100644 index 0000000..a26bb86 --- /dev/null +++ b/src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.html @@ -0,0 +1,265 @@ + diff --git a/src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.ts b/src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.ts new file mode 100644 index 0000000..755f91b --- /dev/null +++ b/src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-public-offer-novo-ru', + imports: [RouterLink, LangRoutePipe], + templateUrl: './public-offer-ru.component.html', + styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PublicOfferNovoRuComponent {} diff --git a/src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.html b/src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.html new file mode 100644 index 0000000..ab15c38 --- /dev/null +++ b/src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.html @@ -0,0 +1,175 @@ + diff --git a/src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.ts b/src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.ts new file mode 100644 index 0000000..d4ba49a --- /dev/null +++ b/src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-return-policy-novo-en', + templateUrl: './return-policy-en.component.html', + styleUrls: ['../../../../../../pages/legal/return-policy/return-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ReturnPolicyNovoEnComponent {} diff --git a/src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.html b/src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.html new file mode 100644 index 0000000..59f4000 --- /dev/null +++ b/src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.html @@ -0,0 +1,175 @@ + diff --git a/src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.ts b/src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.ts new file mode 100644 index 0000000..5705f59 --- /dev/null +++ b/src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-return-policy-novo-hy', + templateUrl: './return-policy-hy.component.html', + styleUrls: ['../../../../../../pages/legal/return-policy/return-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ReturnPolicyNovoHyComponent {} diff --git a/src/app/brands/novo/pages/legal/return-policy/return-policy.component.html b/src/app/brands/novo/pages/legal/return-policy/return-policy.component.html index 3b809ed..883d7dc 100644 --- a/src/app/brands/novo/pages/legal/return-policy/return-policy.component.html +++ b/src/app/brands/novo/pages/legal/return-policy/return-policy.component.html @@ -1,175 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/brands/novo/pages/legal/return-policy/return-policy.component.ts b/src/app/brands/novo/pages/legal/return-policy/return-policy.component.ts index a9b3213..1e6e5ed 100644 --- a/src/app/brands/novo/pages/legal/return-policy/return-policy.component.ts +++ b/src/app/brands/novo/pages/legal/return-policy/return-policy.component.ts @@ -1,9 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../../../services/language.service'; +import { ReturnPolicyNovoRuComponent } from './ru/return-policy-ru.component'; +import { ReturnPolicyNovoEnComponent } from './en/return-policy-en.component'; +import { ReturnPolicyNovoHyComponent } from './hy/return-policy-hy.component'; @Component({ selector: 'app-return-policy-novo', - imports: [], + imports: [ReturnPolicyNovoRuComponent, ReturnPolicyNovoEnComponent, ReturnPolicyNovoHyComponent], templateUrl: './return-policy.component.html', - styleUrls: ['../../../../../pages/legal/return-policy/return-policy.component.scss'] + styleUrls: ['../../../../../pages/legal/return-policy/return-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class ReturnPolicyNovoComponent {} +export class ReturnPolicyNovoComponent { + lang = inject(LanguageService).currentLanguage; +} diff --git a/src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.html b/src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.html new file mode 100644 index 0000000..3b809ed --- /dev/null +++ b/src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.html @@ -0,0 +1,175 @@ + diff --git a/src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.ts b/src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.ts new file mode 100644 index 0000000..3fed8ea --- /dev/null +++ b/src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-return-policy-novo-ru', + templateUrl: './return-policy-ru.component.html', + styleUrls: ['../../../../../../pages/legal/return-policy/return-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ReturnPolicyNovoRuComponent {} diff --git a/src/app/components/back-button/back-button.component.ts b/src/app/components/back-button/back-button.component.ts index 217a8df..48de323 100644 --- a/src/app/components/back-button/back-button.component.ts +++ b/src/app/components/back-button/back-button.component.ts @@ -1,12 +1,13 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; import { Location } from '@angular/common'; import { environment } from '../../../environments/environment'; +import { TranslateService } from '../../i18n/translate.service'; @Component({ selector: 'app-back-button', template: ` @if (!isnovo) { - } @@ -16,9 +16,9 @@
-

Корзина пуста

-

Добавьте товары, чтобы начать покупки

-
Перейти к покупкам +

{{ 'cart.empty' | translate }}

+

{{ 'cart.emptyDesc' | translate }}

+ {{ 'cart.goShopping' | translate }} } @@ -30,13 +30,13 @@ [class.swiped]="swipedItemId() === item.itemID" (touchstart)="onSwipeStart(item.itemID, $event)">
- +
- {{ item.name }} + {{ item.name }}
@@ -147,7 +147,7 @@ @if (showPaymentPopup()) {
- - Открыть в новой вкладке + {{ 'cart.openNewTab' | translate }}
@@ -197,8 +197,8 @@ @if (paymentStatus() === 'success') {
-

Поздравляем! Оплата прошла успешно!

-

Введите ваши контактные данные, и мы отправим вам покупку в течение нескольких минут

+

{{ 'cart.paymentSuccess' | translate }}

+

{{ 'cart.paymentSuccessDesc' | translate }}

diff --git a/src/app/pages/cart/cart.component.ts b/src/app/pages/cart/cart.component.ts index 67906c4..58b4c90 100644 --- a/src/app/pages/cart/cart.component.ts +++ b/src/app/pages/cart/cart.component.ts @@ -1,29 +1,34 @@ -import { Component, computed, ChangeDetectionStrategy, signal, OnDestroy, OnInit } from '@angular/core'; +import { Component, computed, ChangeDetectionStrategy, signal, OnDestroy, inject } from '@angular/core'; import { DecimalPipe } from '@angular/common'; import { Router, RouterLink } from '@angular/router'; import { FormsModule } from '@angular/forms'; -import { CartService, ApiService } from '../../services'; +import { CartService, ApiService, LanguageService } from '../../services'; import { Item, CartItem } from '../../models'; import { interval, Subscription } from 'rxjs'; import { switchMap, take } from 'rxjs/operators'; import { EmptyCartIconComponent } from '../../components/empty-cart-icon/empty-cart-icon.component'; import { environment } from '../../../environments/environment'; import { getDiscountedPrice, getMainImage, trackByItemId, getBadgeClass } from '../../utils/item.utils'; +import { LangRoutePipe } from '../../pipes/lang-route.pipe'; +import { TranslatePipe } from '../../i18n/translate.pipe'; +import { TranslateService } from '../../i18n/translate.service'; @Component({ selector: 'app-cart', - imports: [DecimalPipe, RouterLink, FormsModule, EmptyCartIconComponent], + imports: [DecimalPipe, RouterLink, FormsModule, EmptyCartIconComponent, LangRoutePipe, TranslatePipe], templateUrl: './cart.component.html', styleUrls: ['./cart.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class CartComponent implements OnInit, OnDestroy { +export class CartComponent implements OnDestroy { items; itemCount; totalPrice; termsAccepted = false; isnovo = environment.theme === 'novo'; + private i18n = inject(TranslateService); + // Swipe state swipedItemId = signal(null); @@ -52,17 +57,14 @@ export class CartComponent implements OnInit, OnDestroy { constructor( private cartService: CartService, private apiService: ApiService, - private router: Router + private router: Router, + private langService: LanguageService ) { this.items = this.cartService.items; this.itemCount = this.cartService.itemCount; this.totalPrice = this.cartService.totalPrice; } - ngOnInit(): void { - // Component initialized - } - ngOnDestroy(): void { this.stopPolling(); if (this.closeTimeout) { @@ -109,16 +111,16 @@ export class CartComponent implements OnInit, OnDestroy { }; const cleanup = () => { - document.removeEventListener('touchmove', onMove as any); + document.removeEventListener('touchmove', onMove); document.removeEventListener('touchend', cleanup); }; - document.addEventListener('touchmove', onMove as any); + document.addEventListener('touchmove', onMove); document.addEventListener('touchend', cleanup); } clearCart(): void { - if (confirm('�� �������, ��� ������ �������� �������?')) { + if (confirm(this.i18n.t('cart.confirmClear'))) { this.cartService.clearCart(); } } @@ -130,7 +132,7 @@ export class CartComponent implements OnInit, OnDestroy { checkout(): void { if (!this.termsAccepted) { - alert('����������, ������� ������� ��������, �������� �������� � �������� ��� ����������� ���������� ������.'); + alert(this.i18n.t('cart.acceptTerms')); return; } this.openPaymentPopup(); @@ -252,7 +254,7 @@ export class CartComponent implements OnInit, OnDestroy { this.linkCopied.set(true); setTimeout(() => this.linkCopied.set(false), 2000); }).catch(err => { - console.error('������ �����������:', err); + console.error(this.i18n.t('cart.copyError'), err); }); } } @@ -317,17 +319,18 @@ export class CartComponent implements OnInit, OnDestroy { next: () => { this.emailSubmitting.set(false); // Show success message - alert('Email ������� ���������! ��������� ���� �����.'); + alert(this.i18n.t('cart.emailSuccess')); // Close popup and redirect to home page setTimeout(() => { this.closePaymentPopup(); - this.router.navigate(['/']); + const lang = this.langService.currentLanguage(); + this.router.navigate([`/${lang}`]); }, 500); }, error: (err) => { console.error('Error submitting email:', err); this.emailSubmitting.set(false); - alert('��������� ������ ��� �������� email. ����������, ���������� �����.'); + alert(this.i18n.t('cart.emailError')); } }); } @@ -388,11 +391,11 @@ export class CartComponent implements OnInit, OnDestroy { } if (digitsOnly.length === 0) { - this.phoneError.set('����� �������� ����������'); + this.phoneError.set(this.i18n.t('cart.phoneRequired')); } else if (digitsOnly.length < 11) { - this.phoneError.set(`������� ��� ${11 - digitsOnly.length} ����`); + this.phoneError.set(this.i18n.t('cart.phoneMoreDigits', { count: 11 - digitsOnly.length })); } else if (digitsOnly.length > 11) { - this.phoneError.set('������� ����� ����'); + this.phoneError.set(this.i18n.t('cart.phoneTooMany')); } else { this.phoneError.set(''); } @@ -420,19 +423,19 @@ export class CartComponent implements OnInit, OnDestroy { } if (email.length === 0) { - this.emailError.set('Email ����������'); + this.emailError.set(this.i18n.t('cart.emailRequired')); } else if (email.length < 5) { - this.emailError.set('Email ������� �������� (������� 5 ��������)'); + this.emailError.set(this.i18n.t('cart.emailTooShort')); } else if (email.length > 100) { - this.emailError.set('Email ������� ������� (�������� 100 ��������)'); + this.emailError.set(this.i18n.t('cart.emailTooLong')); } else if (!email.includes('@')) { - this.emailError.set('Email ������ ��������� @'); + this.emailError.set(this.i18n.t('cart.emailNeedsAt')); } else if (!email.includes('.')) { - this.emailError.set('Email ������ ��������� ����� (.com, .ru � �.�.)'); + this.emailError.set(this.i18n.t('cart.emailNeedsDomain')); } else { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { - this.emailError.set('������������ ������ email'); + this.emailError.set(this.i18n.t('cart.emailInvalid')); } else { this.emailError.set(''); } diff --git a/src/app/pages/category/category.component.html b/src/app/pages/category/category.component.html index 8d137b3..4c1e677 100644 --- a/src/app/pages/category/category.component.html +++ b/src/app/pages/category/category.component.html @@ -2,7 +2,7 @@ @if (error()) {

{{ error() }}

- +
} @@ -10,7 +10,7 @@
@for (item of items(); track trackByItemId($index, item)) {
- +
@if (item.discount > 0) { @@ -53,7 +53,7 @@
} @@ -62,13 +62,13 @@ @if (loading() && items().length > 0) {
-

Загрузка...

+

{{ 'category.loadingMore' | translate }}

} @if (!hasMore() && items().length > 0) {
-

Все товары загружены

+

{{ 'category.allLoaded' | translate }}

} @@ -82,16 +82,16 @@
-

Упс! Здесь пока пусто

-

В этой категории ещё нет товаров, но скоро они появятся

- На главную +

{{ 'category.emptyTitle' | translate }}

+

{{ 'category.emptyDesc' | translate }}

+ {{ 'category.goHome' | translate }}
} @if (loading() && items().length === 0) {
-

Загрузка товаров...

+

{{ 'category.loading' | translate }}

} } diff --git a/src/app/pages/category/category.component.ts b/src/app/pages/category/category.component.ts index dea52eb..ec9a18c 100644 --- a/src/app/pages/category/category.component.ts +++ b/src/app/pages/category/category.component.ts @@ -5,10 +5,12 @@ import { ApiService, CartService } from '../../services'; import { Item } from '../../models'; import { Subscription } from 'rxjs'; import { getDiscountedPrice, getMainImage, trackByItemId, getBadgeClass } from '../../utils/item.utils'; +import { LangRoutePipe } from '../../pipes/lang-route.pipe'; +import { TranslatePipe } from '../../i18n/translate.pipe'; @Component({ selector: 'app-category', - imports: [DecimalPipe, RouterLink], + imports: [DecimalPipe, RouterLink, LangRoutePipe, TranslatePipe], templateUrl: './category.component.html', styleUrls: ['./category.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush @@ -24,6 +26,7 @@ export class CategoryComponent implements OnInit, OnDestroy { private readonly count = 20; private isLoadingMore = false; private routeSubscription?: Subscription; + private scrollTimeout?: ReturnType; constructor( private route: ActivatedRoute, @@ -41,6 +44,7 @@ export class CategoryComponent implements OnInit, OnDestroy { ngOnDestroy(): void { this.routeSubscription?.unsubscribe(); + if (this.scrollTimeout) clearTimeout(this.scrollTimeout); } resetAndLoad(): void { @@ -80,8 +84,6 @@ export class CategoryComponent implements OnInit, OnDestroy { }); } - private scrollTimeout: any; - @HostListener('window:scroll') onScroll(): void { if (this.scrollTimeout) clearTimeout(this.scrollTimeout); diff --git a/src/app/pages/category/subcategories.component.html b/src/app/pages/category/subcategories.component.html index 30513ad..c117e1f 100644 --- a/src/app/pages/category/subcategories.component.html +++ b/src/app/pages/category/subcategories.component.html @@ -2,14 +2,14 @@ @if (loading()) {
-

Загрузка подкатегорий...

+

{{ 'subcategories.loading' | translate }}

} @if (error()) {

{{ error() }}

- +
} @@ -21,7 +21,7 @@ @if (subcategories().length > 0) { } } diff --git a/src/app/pages/category/subcategories.component.ts b/src/app/pages/category/subcategories.component.ts index dc3161a..310ee91 100644 --- a/src/app/pages/category/subcategories.component.ts +++ b/src/app/pages/category/subcategories.component.ts @@ -1,35 +1,48 @@ -import { Component, OnInit, signal, ChangeDetectionStrategy } from '@angular/core'; +import { Component, OnInit, OnDestroy, signal, ChangeDetectionStrategy, inject } from '@angular/core'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; -import { ApiService } from '../../services'; +import { ApiService, LanguageService } from '../../services'; import { Category } from '../../models'; +import { Subscription } from 'rxjs'; +import { LangRoutePipe } from '../../pipes/lang-route.pipe'; +import { TranslatePipe } from '../../i18n/translate.pipe'; +import { TranslateService } from '../../i18n/translate.service'; @Component({ selector: 'app-subcategories', - imports: [RouterLink], + imports: [RouterLink, LangRoutePipe, TranslatePipe], templateUrl: './subcategories.component.html', styleUrls: ['./subcategories.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class SubcategoriesComponent implements OnInit { +export class SubcategoriesComponent implements OnInit, OnDestroy { categories = signal([]); subcategories = signal([]); loading = signal(true); error = signal(null); + + private i18n = inject(TranslateService); parentName = signal(''); + private routeSubscription?: Subscription; + constructor( private route: ActivatedRoute, private router: Router, - private apiService: ApiService + private apiService: ApiService, + private langService: LanguageService ) {} ngOnInit(): void { - this.route.params.subscribe(params => { + this.routeSubscription = this.route.params.subscribe(params => { const id = parseInt(params['id'], 10); this.loadForParent(id); }); } + ngOnDestroy(): void { + this.routeSubscription?.unsubscribe(); + } + private loadForParent(parentID: number): void { this.loading.set(true); this.apiService.getCategories().subscribe({ @@ -37,11 +50,12 @@ export class SubcategoriesComponent implements OnInit { this.categories.set(cats); const subs = cats.filter(c => c.parentID === parentID); const parent = cats.find(c => c.categoryID === parentID); - this.parentName.set(parent ? parent.name : 'Категория'); + this.parentName.set(parent ? parent.name : this.i18n.t('home.categoriesTitle')); if (!subs || subs.length === 0) { // No subcategories: redirect to items list for this category - this.router.navigate(['/category', parentID, 'items'], { replaceUrl: true }); + const lang = this.langService.currentLanguage(); + this.router.navigate([`/${lang}/category`, parentID, 'items'], { replaceUrl: true }); } else { this.subcategories.set(subs); } diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html index 071f4c8..c6c0806 100644 --- a/src/app/pages/home/home.component.html +++ b/src/app/pages/home/home.component.html @@ -3,10 +3,10 @@
-

Добро пожаловать в {{ brandName }}

-

Найдите всё, что нужно, в одном месте

- - Начать поиск +

{{ 'home.welcomeTo' | translate:{ brand: brandName } }}

+

{{ 'home.subtitle' | translate }}

+
+ {{ 'home.startSearch' | translate }} @@ -21,36 +21,36 @@ @if (loading()) {
-

Загружаем категории...

+

​{{ 'home.loading' | translate }}

} @if (error()) {
⚠️
-

Что-то пошло не так

+

{{ 'home.errorTitle' | translate }}

{{ error() }}

- +
} @if (!loading() && !error()) {
-

Категории товаров

-

Выберите интересующую категорию

+

{{ 'home.categoriesTitle' | translate }}

+

{{ 'home.categoriesSubtitle' | translate }}

@if (topLevelCategories().length === 0) {
📦
-

Категории скоро появятся

-

Мы работаем над наполнением каталога

+

{{ 'home.categoriesEmpty' | translate }}

+

{{ 'home.categoriesEmptyDesc' | translate }}

} @else {
@for (category of topLevelCategories(); track category.categoryID) { - +
@if (category.icon) { @@ -78,16 +78,16 @@
-

Здесь ты найдёшь всё

-

Тысячи товаров в одном месте

-

просто и удобно

+

{{ 'home.dexarHeroTitle' | translate }}

+

{{ 'home.dexarHeroSubtitle' | translate }}

+

{{ 'home.dexarHeroTagline' | translate }}

- Перейти в каталог + {{ 'home.goToCatalog' | translate }} +
} @if (!loading() && !error()) {
-

Каталог товаров

+

{{ 'home.catalogTitle' | translate }}

@if (topLevelCategories().length === 0) {
📦
-

Категории пока отсутствуют

-

Скоро здесь появятся категории товаров

+

{{ 'home.emptyCategoriesDexar' | translate }}

+

{{ 'home.categoriesSoonDexar' | translate }}

} @else {
@for (category of topLevelCategories(); track category.categoryID) { -
- @if (isWideCategory(category.categoryID) && category.wideBanner && category.wideBanner !== true) { + @if (isWideCategory(category.categoryID) && category.wideBanner) { } @else if (category.icon) { @@ -140,7 +140,7 @@

{{ category.name }}

-

{{ getItemCount(category.categoryID) }} товаров

+

{{ 'home.itemsCount' | translate:{ count: getItemCount(category.categoryID) } }}

} diff --git a/src/app/pages/home/home.component.ts b/src/app/pages/home/home.component.ts index 61b83a6..c931d09 100644 --- a/src/app/pages/home/home.component.ts +++ b/src/app/pages/home/home.component.ts @@ -1,13 +1,15 @@ import { Component, OnInit, signal, computed, ChangeDetectionStrategy } from '@angular/core'; import { Router, RouterLink } from '@angular/router'; -import { ApiService } from '../../services'; +import { ApiService, LanguageService } from '../../services'; import { Category } from '../../models'; import { environment } from '../../../environments/environment'; import { ItemsCarouselComponent } from '../../components/items-carousel/items-carousel.component'; +import { LangRoutePipe } from '../../pipes/lang-route.pipe'; +import { TranslatePipe } from '../../i18n/translate.pipe'; @Component({ selector: 'app-home', - imports: [RouterLink, ItemsCarouselComponent], + imports: [RouterLink, ItemsCarouselComponent, LangRoutePipe, TranslatePipe], templateUrl: './home.component.html', styleUrls: ['./home.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush @@ -48,7 +50,7 @@ export class HomeComponent implements OnInit { return cache; }); - constructor(private apiService: ApiService, private router: Router) {} + constructor(private apiService: ApiService, private router: Router, private langService: LanguageService) {} ngOnInit(): void { this.loadCategories(); @@ -87,12 +89,6 @@ export class HomeComponent implements OnInit { topLevel.forEach(cat => { if (!cat.wideBanner) return; - // API may send wideBanner as a boolean flag instead of a URL - if (cat.wideBanner === true) { - this.wideCategories.update(set => { const next = new Set(set); next.add(cat.categoryID); return next; }); - return; - } - const img = new Image(); img.onload = () => { const ratio = img.naturalWidth / img.naturalHeight; @@ -104,12 +100,13 @@ export class HomeComponent implements OnInit { }); } }; - img.src = cat.wideBanner as string; + img.src = cat.wideBanner; }); } navigateToSearch(): void { - this.router.navigate(['/search']); + const lang = this.langService.currentLanguage(); + this.router.navigate([`/${lang}/search`]); } scrollToCatalog(): void { diff --git a/src/app/pages/info/about/about.component.html b/src/app/pages/info/about/about.component.html index 7ec0d9f..3e696b8 100644 --- a/src/app/pages/info/about/about.component.html +++ b/src/app/pages/info/about/about.component.html @@ -1,172 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/pages/info/about/about.component.ts b/src/app/pages/info/about/about.component.ts index b0af9aa..5e07e30 100644 --- a/src/app/pages/info/about/about.component.ts +++ b/src/app/pages/info/about/about.component.ts @@ -1,15 +1,16 @@ -import { Component } from '@angular/core'; -import { environment } from '../../../../environments/environment'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../services/language.service'; +import { AboutRuComponent } from './ru/about-ru.component'; +import { AboutEnComponent } from './en/about-en.component'; +import { AboutHyComponent } from './hy/about-hy.component'; @Component({ selector: 'app-about', - imports: [], + imports: [AboutRuComponent, AboutEnComponent, AboutHyComponent], templateUrl: './about.component.html', - styleUrls: ['./about.component.scss'] + styleUrls: ['./about.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class AboutComponent { - brandName = environment.brandName; - brandFullName = environment.brandFullName; - contactEmail = environment.contactEmail; - isnovo = environment.theme === 'novo'; + lang = inject(LanguageService).currentLanguage; } diff --git a/src/app/pages/info/about/en/about-en.component.html b/src/app/pages/info/about/en/about-en.component.html new file mode 100644 index 0000000..95eac43 --- /dev/null +++ b/src/app/pages/info/about/en/about-en.component.html @@ -0,0 +1,74 @@ + diff --git a/src/app/pages/info/about/en/about-en.component.ts b/src/app/pages/info/about/en/about-en.component.ts new file mode 100644 index 0000000..d0ce0d7 --- /dev/null +++ b/src/app/pages/info/about/en/about-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-about-en', + templateUrl: './about-en.component.html', + styleUrls: ['../about.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AboutEnComponent {} diff --git a/src/app/pages/info/about/hy/about-hy.component.html b/src/app/pages/info/about/hy/about-hy.component.html new file mode 100644 index 0000000..3f865be --- /dev/null +++ b/src/app/pages/info/about/hy/about-hy.component.html @@ -0,0 +1,74 @@ + diff --git a/src/app/pages/info/about/hy/about-hy.component.ts b/src/app/pages/info/about/hy/about-hy.component.ts new file mode 100644 index 0000000..da9c290 --- /dev/null +++ b/src/app/pages/info/about/hy/about-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-about-hy', + templateUrl: './about-hy.component.html', + styleUrls: ['../about.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AboutHyComponent {} diff --git a/src/app/brands/dexar/pages/info/about/about.component.html b/src/app/pages/info/about/ru/about-ru.component.html similarity index 98% rename from src/app/brands/dexar/pages/info/about/about.component.html rename to src/app/pages/info/about/ru/about-ru.component.html index 5a7d436..7f9fd0f 100644 --- a/src/app/brands/dexar/pages/info/about/about.component.html +++ b/src/app/pages/info/about/ru/about-ru.component.html @@ -55,7 +55,7 @@

Контактная информация

Телефон (Россия): +7 (926) 459-31-57

Телефон (Армения): +374 94 86 18 16

-

Email: info@dexarmarket.ru

+

Email: info@dexarmarket.ru

Часы работы:
Техподдержка: 24/7
Ответы на вопросы: 10:00 - 19:00 (МСК)

@@ -68,7 +68,7 @@

Офис в России:
121059, Москва, наб. Тараса Шевченко, 3к2

Основные реквизиты:
ИНН (РФ): 9909697628
ИНН (Армения): 03033502
КПП: 770287001
ОГРН: 85.110.1408711

Банковские реквизиты:
Банк: АО "Райффайзенбанк"
Расчетный счет: 40807810500000002376
Корр. счет: 30101810200000000700
БИК: 044525700

-

Контактная информация:
Телефон (Россия): +7 (926) 459-31-57
Телефон (Армения): +374 94 86 18 16
Email: info@dexarmarket.ru
Сайт: www.dexarmarket.ru

+

Контактная информация:
Телефон (Россия): +7 (926) 459-31-57
Телефон (Армения): +374 94 86 18 16
Email: info@dexarmarket.ru
Сайт: www.dexarmarket.ru

diff --git a/src/app/pages/info/about/ru/about-ru.component.ts b/src/app/pages/info/about/ru/about-ru.component.ts new file mode 100644 index 0000000..cebaf7c --- /dev/null +++ b/src/app/pages/info/about/ru/about-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-about-ru', + templateUrl: './about-ru.component.html', + styleUrls: ['../about.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AboutRuComponent {} diff --git a/src/app/pages/info/contacts/contacts.component.html b/src/app/pages/info/contacts/contacts.component.html index eb8dcec..0a22c36 100644 --- a/src/app/pages/info/contacts/contacts.component.html +++ b/src/app/pages/info/contacts/contacts.component.html @@ -1,94 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/pages/info/contacts/contacts.component.ts b/src/app/pages/info/contacts/contacts.component.ts index 54013e7..368ff61 100644 --- a/src/app/pages/info/contacts/contacts.component.ts +++ b/src/app/pages/info/contacts/contacts.component.ts @@ -1,17 +1,16 @@ -import { Component } from '@angular/core'; -import { environment } from '../../../../environments/environment'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../services/language.service'; +import { ContactsRuComponent } from './ru/contacts-ru.component'; +import { ContactsEnComponent } from './en/contacts-en.component'; +import { ContactsHyComponent } from './hy/contacts-hy.component'; @Component({ selector: 'app-contacts', - imports: [], + imports: [ContactsRuComponent, ContactsEnComponent, ContactsHyComponent], templateUrl: './contacts.component.html', - styleUrls: ['./contacts.component.scss'] + styleUrls: ['./contacts.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class ContactsComponent { - brandName = environment.brandName; - contactEmail = environment.contactEmail; - supportEmail = environment.supportEmail; - phones = environment.phones; - domain = environment.domain; - isnovo = environment.theme === 'novo'; + lang = inject(LanguageService).currentLanguage; } diff --git a/src/app/pages/info/contacts/en/contacts-en.component.html b/src/app/pages/info/contacts/en/contacts-en.component.html new file mode 100644 index 0000000..d58eaac --- /dev/null +++ b/src/app/pages/info/contacts/en/contacts-en.component.html @@ -0,0 +1,46 @@ + diff --git a/src/app/pages/info/contacts/en/contacts-en.component.ts b/src/app/pages/info/contacts/en/contacts-en.component.ts new file mode 100644 index 0000000..f259a6b --- /dev/null +++ b/src/app/pages/info/contacts/en/contacts-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-contacts-en', + templateUrl: './contacts-en.component.html', + styleUrls: ['../contacts.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ContactsEnComponent {} diff --git a/src/app/pages/info/contacts/hy/contacts-hy.component.html b/src/app/pages/info/contacts/hy/contacts-hy.component.html new file mode 100644 index 0000000..03896e8 --- /dev/null +++ b/src/app/pages/info/contacts/hy/contacts-hy.component.html @@ -0,0 +1,46 @@ + diff --git a/src/app/pages/info/contacts/hy/contacts-hy.component.ts b/src/app/pages/info/contacts/hy/contacts-hy.component.ts new file mode 100644 index 0000000..d6af768 --- /dev/null +++ b/src/app/pages/info/contacts/hy/contacts-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-contacts-hy', + templateUrl: './contacts-hy.component.html', + styleUrls: ['../contacts.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ContactsHyComponent {} diff --git a/src/app/brands/dexar/pages/info/contacts/contacts.component.html b/src/app/pages/info/contacts/ru/contacts-ru.component.html similarity index 99% rename from src/app/brands/dexar/pages/info/contacts/contacts.component.html rename to src/app/pages/info/contacts/ru/contacts-ru.component.html index 4933fc4..58ca87d 100644 --- a/src/app/brands/dexar/pages/info/contacts/contacts.component.html +++ b/src/app/pages/info/contacts/ru/contacts-ru.component.html @@ -1,7 +1,7 @@
- Наличие: + {{ 'itemDetail.stock' | translate }}
{{ getStockLabel() }} @@ -108,7 +108,7 @@ - Добавить в корзину + {{ 'itemDetail.addToCart' | translate }}
@@ -117,7 +117,7 @@ } @if (hasDescriptionFields()) { -

Характеристики

+

{{ 'itemDetail.specifications' | translate }}

@for (field of getTranslatedDescriptionFields(); track field.key) { @@ -129,7 +129,7 @@
} @else { -

Описание

+

{{ 'itemDetail.description' | translate }}

}
@@ -137,13 +137,13 @@
-

Отзывы ({{ item()!.callbacks?.length || 0 }})

+

{{ 'itemDetail.reviews' | translate }} ({{ item()!.callbacks?.length || 0 }})

-

Ваш отзыв

+

{{ 'itemDetail.yourReview' | translate }}

- +
@for (star of [1, 2, 3, 4, 5]; track star) {
@if (!newReview.anonymous && getUserDisplayName()) { {{ getUserDisplayName() }} @@ -176,12 +176,12 @@ [class.submitting]="reviewSubmitStatus() === 'loading'"> @if (reviewSubmitStatus() === 'loading') { - Отправка... + {{ 'itemDetail.submitting' | translate }} } @else { - Отправить + {{ 'itemDetail.submit' | translate }} }
@@ -191,7 +191,7 @@ - Спасибо за ваш отзыв! + {{ 'itemDetail.reviewSuccess' | translate }}
} @@ -200,7 +200,7 @@ - Ошибка отправки. Попробуйте позже. + {{ 'itemDetail.reviewError' | translate }}
}
@@ -211,7 +211,7 @@
- {{ review.userID || 'Пользователь' }} + {{ review.userID ? review.userID : ('itemDetail.defaultUser' | translate) }} @if (review.timestamp) { {{ formatDate(review.timestamp) }} } @@ -222,7 +222,7 @@
} } @else { -

Пока нет отзывов. Станьте первым!

+

{{ 'itemDetail.noReviews' | translate }}

}
@@ -234,14 +234,14 @@ @if (loading()) {
-

Загрузка товара...

+

{{ 'itemDetail.loadingDexar' | translate }}

} @if (error()) { } @@ -259,7 +259,7 @@ @if (photo.video) {
} - +
}
@@ -278,7 +278,7 @@ - Нет изображения + {{ 'itemDetail.noImage' | translate }}
}
@@ -313,7 +313,7 @@ }
{{ item()!.rating }} - ({{ item()!.callbacks?.length || 0 }} отзывов) + ({{ item()!.callbacks?.length || 0 }} {{ 'itemDetail.reviewsCount' | translate }})
@@ -329,7 +329,7 @@
- Наличие: + {{ 'itemDetail.stock' | translate }} {{ getStockLabel() }} @@ -345,7 +345,7 @@ - Добавить в корзину + {{ 'itemDetail.addToCart' | translate }}
@@ -354,7 +354,7 @@ } @if (hasDescriptionFields()) { -

Характеристики

+

{{ 'itemDetail.specifications' | translate }}

@for (field of getTranslatedDescriptionFields(); track field.key) { @@ -366,7 +366,7 @@
} @else { -

Описание

+

{{ 'itemDetail.description' | translate }}

}
@@ -375,12 +375,12 @@
-

Отзывы ({{ item()!.callbacks?.length || 0 }})

+

{{ 'itemDetail.reviews' | translate }} ({{ item()!.callbacks?.length || 0 }})

-

Оставить отзыв

+

{{ 'itemDetail.leaveReview' | translate }}

- +
@for (star of [1, 2, 3, 4, 5]; track star) {
@if (!newReview.anonymous && getUserDisplayName()) { {{ getUserDisplayName() }} @@ -413,9 +413,9 @@ [class.submitting]="reviewSubmitStatus() === 'loading'"> @if (reviewSubmitStatus() === 'loading') { - Отправка... + {{ 'itemDetail.submitting' | translate }} } @else { - Отправить + {{ 'itemDetail.submit' | translate }} }
@@ -423,14 +423,14 @@ @if (reviewSubmitStatus() === 'success') {
- Спасибо за ваш отзыв! + {{ 'itemDetail.reviewSuccess' | translate }}
} @if (reviewSubmitStatus() === 'error') {
- Ошибка отправки. Попробуйте позже. + {{ 'itemDetail.reviewError' | translate }}
}
@@ -441,7 +441,7 @@
- {{ callback.userID || 'Аноним' }} + {{ callback.userID ? callback.userID : ('itemDetail.defaultUser' | translate) }} @if (callback.timestamp) { {{ formatDate(callback.timestamp) }} } @@ -462,7 +462,7 @@
} } @else { -

Пока нет отзывов. Станьте первым!

+

{{ 'itemDetail.noReviews' | translate }}

}
@@ -470,7 +470,7 @@ @if (item()!.questions && item()!.questions!.length > 0) {
-

Вопросы и ответы ({{ item()!.questions!.length }})

+

{{ 'itemDetail.qna' | translate }} ({{ item()!.questions!.length }})

@for (question of item()!.questions!; track $index) {
diff --git a/src/app/pages/item-detail/item-detail.component.ts b/src/app/pages/item-detail/item-detail.component.ts index 6b03106..7c6a251 100644 --- a/src/app/pages/item-detail/item-detail.component.ts +++ b/src/app/pages/item-detail/item-detail.component.ts @@ -1,17 +1,21 @@ -import { Component, OnInit, OnDestroy, signal, ChangeDetectionStrategy } from '@angular/core'; +import { Component, OnInit, OnDestroy, signal, ChangeDetectionStrategy, inject } from '@angular/core'; import { DecimalPipe } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { ActivatedRoute, RouterLink } from '@angular/router'; -import { ApiService, CartService, TelegramService, LanguageService } from '../../services'; +import { ApiService, CartService, TelegramService, LanguageService, SeoService } from '../../services'; import { Item, DescriptionField } from '../../models'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { Subscription } from 'rxjs'; import { environment } from '../../../environments/environment'; -import { getAllImages, getStockStatus, getBadgeClass, getTranslatedField } from '../../utils/item.utils'; +import { SecurityContext } from '@angular/core'; +import { getDiscountedPrice, getAllImages, getStockStatus, getBadgeClass, getTranslatedField } from '../../utils/item.utils'; +import { LangRoutePipe } from '../../pipes/lang-route.pipe'; +import { TranslatePipe } from '../../i18n/translate.pipe'; +import { TranslateService } from '../../i18n/translate.service'; @Component({ selector: 'app-item-detail', - imports: [DecimalPipe, RouterLink, FormsModule], + imports: [DecimalPipe, RouterLink, FormsModule, LangRoutePipe, TranslatePipe], templateUrl: './item-detail.component.html', styleUrls: ['./item-detail.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush @@ -32,6 +36,12 @@ export class ItemDetailComponent implements OnInit, OnDestroy { reviewSubmitStatus = signal<'idle' | 'loading' | 'success' | 'error'>('idle'); private routeSubscription?: Subscription; + private reviewResetTimeout?: ReturnType; + private reviewErrorTimeout?: ReturnType; + private reloadTimeout?: ReturnType; + + private seoService = inject(SeoService); + private i18n = inject(TranslateService); constructor( private route: ActivatedRoute, @@ -51,6 +61,10 @@ export class ItemDetailComponent implements OnInit, OnDestroy { ngOnDestroy(): void { this.routeSubscription?.unsubscribe(); + if (this.reviewResetTimeout) clearTimeout(this.reviewResetTimeout); + if (this.reviewErrorTimeout) clearTimeout(this.reviewErrorTimeout); + if (this.reloadTimeout) clearTimeout(this.reloadTimeout); + this.seoService.resetToDefaults(); } loadItem(itemID: number): void { @@ -59,6 +73,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy { this.apiService.getItem(itemID).subscribe({ next: (item) => { this.item.set(item); + this.seoService.setItemMeta(item); this.loading.set(false); }, error: (err) => { @@ -83,7 +98,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy { getDiscountedPrice(): number { const currentItem = this.item(); if (!currentItem) return 0; - return currentItem.price * (1 - (currentItem.discount || 0) / 100); + return getDiscountedPrice(currentItem); } // BackOffice integration helpers @@ -138,14 +153,14 @@ export class ItemDetailComponent implements OnInit, OnDestroy { readonly getBadgeClass = getBadgeClass; getSafeHtml(html: string): SafeHtml { - return this.sanitizer.sanitize(1, html) || ''; + return this.sanitizer.sanitize(SecurityContext.HTML, html) || ''; } getRatingStars(rating: number): string { const fullStars = Math.floor(rating); const hasHalfStar = rating % 1 >= 0.5; - let stars = '?'.repeat(fullStars); - if (hasHalfStar) stars += '?'; + let stars = '★'.repeat(fullStars); + if (hasHalfStar) stars += '☆'; return stars; } @@ -155,10 +170,10 @@ export class ItemDetailComponent implements OnInit, OnDestroy { const diffMs = now.getTime() - date.getTime(); const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); - if (diffDays === 0) return '�������'; - if (diffDays === 1) return '�����'; - if (diffDays < 7) return `${diffDays} ��. �����`; - if (diffDays < 30) return `${Math.floor(diffDays / 7)} ���. �����`; + if (diffDays === 0) return this.i18n.t('itemDetail.today'); + if (diffDays === 1) return this.i18n.t('itemDetail.yesterday'); + if (diffDays < 7) return `${diffDays} ${this.i18n.t('itemDetail.daysAgo')}`; + if (diffDays < 30) return `${Math.floor(diffDays / 7)} ${this.i18n.t('itemDetail.weeksAgo')}`; return date.toLocaleDateString('ru-RU', { day: 'numeric', @@ -173,7 +188,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy { getUserDisplayName(): string | null { if (!this.telegramService.isTelegramApp()) { - return 'Пользователь'; + return this.i18n.t('itemDetail.defaultUser'); } return this.telegramService.getDisplayName(); } @@ -202,13 +217,13 @@ export class ItemDetailComponent implements OnInit, OnDestroy { this.reviewSubmitStatus.set('success'); this.newReview = { rating: 0, comment: '', anonymous: false }; - // ������ ��������� ����� 3 ������� - setTimeout(() => { + // Сброс состояния через 3 секунды + this.reviewResetTimeout = setTimeout(() => { this.reviewSubmitStatus.set('idle'); }, 3000); - // ������������� ������ ������ ����� ��������� �������� - setTimeout(() => { + // Перезагрузить данные товара после отправки отзыва + this.reloadTimeout = setTimeout(() => { this.loadItem(currentItem.itemID); }, 500); }, @@ -216,8 +231,8 @@ export class ItemDetailComponent implements OnInit, OnDestroy { console.error('Error submitting review:', err); this.reviewSubmitStatus.set('error'); - // ������ ��������� �� ������ ����� 5 ������ - setTimeout(() => { + // Сброс состояния об ошибке через 5 секунд + this.reviewErrorTimeout = setTimeout(() => { this.reviewSubmitStatus.set('idle'); }, 5000); } diff --git a/src/app/pages/legal/company-details/company-details.component.html b/src/app/pages/legal/company-details/company-details.component.html index b4ab45c..da787de 100644 --- a/src/app/pages/legal/company-details/company-details.component.html +++ b/src/app/pages/legal/company-details/company-details.component.html @@ -1,214 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/pages/legal/company-details/company-details.component.ts b/src/app/pages/legal/company-details/company-details.component.ts index ce23538..ecdd2d5 100644 --- a/src/app/pages/legal/company-details/company-details.component.ts +++ b/src/app/pages/legal/company-details/company-details.component.ts @@ -1,18 +1,16 @@ -import { Component } from '@angular/core'; -import { environment } from '../../../../environments/environment'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../services/language.service'; +import { CompanyDetailsRuComponent } from './ru/company-details-ru.component'; +import { CompanyDetailsEnComponent } from './en/company-details-en.component'; +import { CompanyDetailsHyComponent } from './hy/company-details-hy.component'; @Component({ selector: 'app-company-details', - imports: [], + imports: [CompanyDetailsRuComponent, CompanyDetailsEnComponent, CompanyDetailsHyComponent], templateUrl: './company-details.component.html', - styleUrls: ['./company-details.component.scss'] + styleUrls: ['./company-details.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class CompanyDetailsComponent { - brandName = environment.brandName; - brandFullName = environment.brandFullName; - contactEmail = environment.contactEmail; - supportEmail = environment.supportEmail; - domain = environment.domain; - phones = environment.phones; - isnovo = environment.theme === 'novo'; + lang = inject(LanguageService).currentLanguage; } diff --git a/src/app/pages/legal/company-details/en/company-details-en.component.html b/src/app/pages/legal/company-details/en/company-details-en.component.html new file mode 100644 index 0000000..ca1d633 --- /dev/null +++ b/src/app/pages/legal/company-details/en/company-details-en.component.html @@ -0,0 +1,98 @@ +

Company Details

+ + + + + + + + + + + + + + diff --git a/src/app/pages/legal/company-details/en/company-details-en.component.ts b/src/app/pages/legal/company-details/en/company-details-en.component.ts new file mode 100644 index 0000000..67d3bf3 --- /dev/null +++ b/src/app/pages/legal/company-details/en/company-details-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-company-details-en', + templateUrl: './company-details-en.component.html', + styleUrls: ['../company-details.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CompanyDetailsEnComponent {} diff --git a/src/app/pages/legal/company-details/hy/company-details-hy.component.html b/src/app/pages/legal/company-details/hy/company-details-hy.component.html new file mode 100644 index 0000000..418a376 --- /dev/null +++ b/src/app/pages/legal/company-details/hy/company-details-hy.component.html @@ -0,0 +1,98 @@ +

Կազմակերպության տվյալներ

+ + + + + + + + + + + + + + diff --git a/src/app/pages/legal/company-details/hy/company-details-hy.component.ts b/src/app/pages/legal/company-details/hy/company-details-hy.component.ts new file mode 100644 index 0000000..f894dcd --- /dev/null +++ b/src/app/pages/legal/company-details/hy/company-details-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-company-details-hy', + templateUrl: './company-details-hy.component.html', + styleUrls: ['../company-details.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CompanyDetailsHyComponent {} diff --git a/src/app/pages/legal/company-details/ru/company-details-ru.component.html b/src/app/pages/legal/company-details/ru/company-details-ru.component.html new file mode 100644 index 0000000..ab010c2 --- /dev/null +++ b/src/app/pages/legal/company-details/ru/company-details-ru.component.html @@ -0,0 +1,98 @@ +

Реквизиты организации

+ + + + + + + + + + + + + + diff --git a/src/app/pages/legal/company-details/ru/company-details-ru.component.ts b/src/app/pages/legal/company-details/ru/company-details-ru.component.ts new file mode 100644 index 0000000..e7c8eed --- /dev/null +++ b/src/app/pages/legal/company-details/ru/company-details-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-company-details-ru', + templateUrl: './company-details-ru.component.html', + styleUrls: ['../company-details.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CompanyDetailsRuComponent {} diff --git a/src/app/pages/legal/payment-terms/en/payment-terms-en.component.html b/src/app/pages/legal/payment-terms/en/payment-terms-en.component.html new file mode 100644 index 0000000..9208c0d --- /dev/null +++ b/src/app/pages/legal/payment-terms/en/payment-terms-en.component.html @@ -0,0 +1,113 @@ +

Payment Terms

+ + + + + + + + + + + + + + + + diff --git a/src/app/pages/legal/payment-terms/en/payment-terms-en.component.ts b/src/app/pages/legal/payment-terms/en/payment-terms-en.component.ts new file mode 100644 index 0000000..3457de6 --- /dev/null +++ b/src/app/pages/legal/payment-terms/en/payment-terms-en.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-payment-terms-en', + imports: [RouterLink, LangRoutePipe], + templateUrl: './payment-terms-en.component.html', + styleUrls: ['../payment-terms.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PaymentTermsEnComponent {} diff --git a/src/app/pages/legal/payment-terms/hy/payment-terms-hy.component.html b/src/app/pages/legal/payment-terms/hy/payment-terms-hy.component.html new file mode 100644 index 0000000..a463978 --- /dev/null +++ b/src/app/pages/legal/payment-terms/hy/payment-terms-hy.component.html @@ -0,0 +1,113 @@ +

Վճարման կանոններ

+ + + + + + + + + + + + + + + + diff --git a/src/app/pages/legal/payment-terms/hy/payment-terms-hy.component.ts b/src/app/pages/legal/payment-terms/hy/payment-terms-hy.component.ts new file mode 100644 index 0000000..9cccefc --- /dev/null +++ b/src/app/pages/legal/payment-terms/hy/payment-terms-hy.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-payment-terms-hy', + imports: [RouterLink, LangRoutePipe], + templateUrl: './payment-terms-hy.component.html', + styleUrls: ['../payment-terms.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PaymentTermsHyComponent {} diff --git a/src/app/pages/legal/payment-terms/payment-terms.component.html b/src/app/pages/legal/payment-terms/payment-terms.component.html index b0d6716..3761048 100644 --- a/src/app/pages/legal/payment-terms/payment-terms.component.html +++ b/src/app/pages/legal/payment-terms/payment-terms.component.html @@ -1,278 +1,6 @@ - diff --git a/src/app/pages/legal/payment-terms/payment-terms.component.ts b/src/app/pages/legal/payment-terms/payment-terms.component.ts index aa841e5..e7c7da5 100644 --- a/src/app/pages/legal/payment-terms/payment-terms.component.ts +++ b/src/app/pages/legal/payment-terms/payment-terms.component.ts @@ -1,15 +1,16 @@ -import { Component } from '@angular/core'; -import { RouterLink } from '@angular/router'; -import { environment } from '../../../../environments/environment'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../services/language.service'; +import { PaymentTermsRuComponent } from './ru/payment-terms-ru.component'; +import { PaymentTermsEnComponent } from './en/payment-terms-en.component'; +import { PaymentTermsHyComponent } from './hy/payment-terms-hy.component'; @Component({ selector: 'app-payment-terms', - imports: [RouterLink], + imports: [PaymentTermsRuComponent, PaymentTermsEnComponent, PaymentTermsHyComponent], templateUrl: './payment-terms.component.html', - styleUrls: ['./payment-terms.component.scss'] + styleUrls: ['./payment-terms.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class PaymentTermsComponent { - brandName = environment.brandName; - contactEmail = environment.contactEmail; - isnovo = environment.theme === 'novo'; + lang = inject(LanguageService).currentLanguage; } diff --git a/src/app/pages/legal/payment-terms/ru/payment-terms-ru.component.html b/src/app/pages/legal/payment-terms/ru/payment-terms-ru.component.html new file mode 100644 index 0000000..4a3f548 --- /dev/null +++ b/src/app/pages/legal/payment-terms/ru/payment-terms-ru.component.html @@ -0,0 +1,113 @@ +

Правила оплаты

+ + + + + + + + + + + + + + + + diff --git a/src/app/pages/legal/payment-terms/ru/payment-terms-ru.component.ts b/src/app/pages/legal/payment-terms/ru/payment-terms-ru.component.ts new file mode 100644 index 0000000..4a2d31c --- /dev/null +++ b/src/app/pages/legal/payment-terms/ru/payment-terms-ru.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-payment-terms-ru', + imports: [RouterLink, LangRoutePipe], + templateUrl: './payment-terms-ru.component.html', + styleUrls: ['../payment-terms.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PaymentTermsRuComponent {} diff --git a/src/app/pages/legal/privacy-policy/en/privacy-policy-en.component.html b/src/app/pages/legal/privacy-policy/en/privacy-policy-en.component.html new file mode 100644 index 0000000..06c6c81 --- /dev/null +++ b/src/app/pages/legal/privacy-policy/en/privacy-policy-en.component.html @@ -0,0 +1,363 @@ +

PERSONAL DATA PROCESSING POLICY

+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/pages/legal/privacy-policy/en/privacy-policy-en.component.ts b/src/app/pages/legal/privacy-policy/en/privacy-policy-en.component.ts new file mode 100644 index 0000000..2e5766f --- /dev/null +++ b/src/app/pages/legal/privacy-policy/en/privacy-policy-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-privacy-policy-en', + templateUrl: './privacy-policy-en.component.html', + styleUrls: ['../privacy-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PrivacyPolicyEnComponent {} diff --git a/src/app/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html b/src/app/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html new file mode 100644 index 0000000..06c6c81 --- /dev/null +++ b/src/app/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html @@ -0,0 +1,363 @@ +

PERSONAL DATA PROCESSING POLICY

+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts b/src/app/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts new file mode 100644 index 0000000..e6bc01d --- /dev/null +++ b/src/app/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-privacy-policy-hy', + templateUrl: './privacy-policy-hy.component.html', + styleUrls: ['../privacy-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PrivacyPolicyHyComponent {} diff --git a/src/app/pages/legal/privacy-policy/privacy-policy.component.html b/src/app/pages/legal/privacy-policy/privacy-policy.component.html index bb412e5..a419fa0 100644 --- a/src/app/pages/legal/privacy-policy/privacy-policy.component.html +++ b/src/app/pages/legal/privacy-policy/privacy-policy.component.html @@ -1,643 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} \ No newline at end of file diff --git a/src/app/pages/legal/privacy-policy/privacy-policy.component.ts b/src/app/pages/legal/privacy-policy/privacy-policy.component.ts index f0841ac..46cec9b 100644 --- a/src/app/pages/legal/privacy-policy/privacy-policy.component.ts +++ b/src/app/pages/legal/privacy-policy/privacy-policy.component.ts @@ -1,15 +1,16 @@ -import { Component } from '@angular/core'; -import { environment } from '../../../../environments/environment'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../services/language.service'; +import { PrivacyPolicyRuComponent } from './ru/privacy-policy-ru.component'; +import { PrivacyPolicyEnComponent } from './en/privacy-policy-en.component'; +import { PrivacyPolicyHyComponent } from './hy/privacy-policy-hy.component'; @Component({ selector: 'app-privacy-policy', - imports: [], + imports: [PrivacyPolicyRuComponent, PrivacyPolicyEnComponent, PrivacyPolicyHyComponent], templateUrl: './privacy-policy.component.html', - styleUrls: ['./privacy-policy.component.scss'] + styleUrls: ['./privacy-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class PrivacyPolicyComponent { - brandName = environment.brandName; - domain = environment.domain; - contactEmail = environment.contactEmail; - isnovo = environment.theme === 'novo'; + lang = inject(LanguageService).currentLanguage; } diff --git a/src/app/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html b/src/app/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html new file mode 100644 index 0000000..5edbdd1 --- /dev/null +++ b/src/app/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html @@ -0,0 +1,363 @@ +

ПОЛИТИКА В ОТНОШЕНИИ ОБРАБОТКИ ПЕРСОНАЛЬНЫХ ДАННЫХ

+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts b/src/app/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts new file mode 100644 index 0000000..b46f24b --- /dev/null +++ b/src/app/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-privacy-policy-ru', + templateUrl: './privacy-policy-ru.component.html', + styleUrls: ['../privacy-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PrivacyPolicyRuComponent {} diff --git a/src/app/pages/legal/public-offer/en/public-offer-en.component.html b/src/app/pages/legal/public-offer/en/public-offer-en.component.html new file mode 100644 index 0000000..d9d79fc --- /dev/null +++ b/src/app/pages/legal/public-offer/en/public-offer-en.component.html @@ -0,0 +1,461 @@ +

PUBLIC OFFER AGREEMENT

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/pages/legal/public-offer/en/public-offer-en.component.ts b/src/app/pages/legal/public-offer/en/public-offer-en.component.ts new file mode 100644 index 0000000..2473fc1 --- /dev/null +++ b/src/app/pages/legal/public-offer/en/public-offer-en.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-public-offer-en', + imports: [RouterLink, LangRoutePipe], + templateUrl: './public-offer-en.component.html', + styleUrls: ['../public-offer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PublicOfferEnComponent {} diff --git a/src/app/pages/legal/public-offer/hy/public-offer-hy.component.html b/src/app/pages/legal/public-offer/hy/public-offer-hy.component.html new file mode 100644 index 0000000..28d90c0 --- /dev/null +++ b/src/app/pages/legal/public-offer/hy/public-offer-hy.component.html @@ -0,0 +1 @@ +

Հdelays DELAYS ՀԱՄDELAYS

diff --git a/src/app/pages/legal/public-offer/hy/public-offer-hy.component.ts b/src/app/pages/legal/public-offer/hy/public-offer-hy.component.ts new file mode 100644 index 0000000..244fe84 --- /dev/null +++ b/src/app/pages/legal/public-offer/hy/public-offer-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-public-offer-hy', + templateUrl: './public-offer-hy.component.html', + styleUrls: ['../public-offer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PublicOfferHyComponent {} diff --git a/src/app/pages/legal/public-offer/public-offer.component.html b/src/app/pages/legal/public-offer/public-offer.component.html index c0cbc9c..45b4990 100644 --- a/src/app/pages/legal/public-offer/public-offer.component.html +++ b/src/app/pages/legal/public-offer/public-offer.component.html @@ -1,733 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} \ No newline at end of file diff --git a/src/app/pages/legal/public-offer/public-offer.component.ts b/src/app/pages/legal/public-offer/public-offer.component.ts index 71cb01c..d1f8525 100644 --- a/src/app/pages/legal/public-offer/public-offer.component.ts +++ b/src/app/pages/legal/public-offer/public-offer.component.ts @@ -1,16 +1,16 @@ -import { Component } from '@angular/core'; -import { RouterLink } from '@angular/router'; -import { environment } from '../../../../environments/environment'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../services/language.service'; +import { PublicOfferRuComponent } from './ru/public-offer-ru.component'; +import { PublicOfferEnComponent } from './en/public-offer-en.component'; +import { PublicOfferHyComponent } from './hy/public-offer-hy.component'; @Component({ selector: 'app-public-offer', - imports: [RouterLink], + imports: [PublicOfferRuComponent, PublicOfferEnComponent, PublicOfferHyComponent], templateUrl: './public-offer.component.html', - styleUrls: ['./public-offer.component.scss'] + styleUrls: ['./public-offer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class PublicOfferComponent { - brandName = environment.brandName; - domain = environment.domain; - contactEmail = environment.contactEmail; - isnovo = environment.theme === 'novo'; + lang = inject(LanguageService).currentLanguage; } diff --git a/src/app/brands/dexar/pages/legal/public-offer/public-offer.component.html b/src/app/pages/legal/public-offer/ru/public-offer-ru.component.html similarity index 94% rename from src/app/brands/dexar/pages/legal/public-offer/public-offer.component.html rename to src/app/pages/legal/public-offer/ru/public-offer-ru.component.html index a5a61ee..7292a54 100644 --- a/src/app/brands/dexar/pages/legal/public-offer/public-offer.component.html +++ b/src/app/pages/legal/public-offer/ru/public-offer-ru.component.html @@ -1,5 +1,3 @@ - diff --git a/src/app/pages/legal/public-offer/ru/public-offer-ru.component.ts b/src/app/pages/legal/public-offer/ru/public-offer-ru.component.ts new file mode 100644 index 0000000..8ed99c1 --- /dev/null +++ b/src/app/pages/legal/public-offer/ru/public-offer-ru.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { LangRoutePipe } from '../../../../pipes/lang-route.pipe'; + +@Component({ + selector: 'app-public-offer-ru', + imports: [RouterLink, LangRoutePipe], + templateUrl: './public-offer-ru.component.html', + styleUrls: ['../public-offer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PublicOfferRuComponent {} diff --git a/src/app/pages/legal/return-policy/en/return-policy-en.component.html b/src/app/pages/legal/return-policy/en/return-policy-en.component.html new file mode 100644 index 0000000..6943f39 --- /dev/null +++ b/src/app/pages/legal/return-policy/en/return-policy-en.component.html @@ -0,0 +1,130 @@ +

Return Policy

+ + + + + + + + + + + + + + + + + + + + diff --git a/src/app/pages/legal/return-policy/en/return-policy-en.component.ts b/src/app/pages/legal/return-policy/en/return-policy-en.component.ts new file mode 100644 index 0000000..ae630be --- /dev/null +++ b/src/app/pages/legal/return-policy/en/return-policy-en.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-return-policy-en', + templateUrl: './return-policy-en.component.html', + styleUrls: ['../return-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ReturnPolicyEnComponent {} diff --git a/src/app/pages/legal/return-policy/hy/return-policy-hy.component.html b/src/app/pages/legal/return-policy/hy/return-policy-hy.component.html new file mode 100644 index 0000000..b0125cd --- /dev/null +++ b/src/app/pages/legal/return-policy/hy/return-policy-hy.component.html @@ -0,0 +1,130 @@ +

Ապրանքների վերադարձի քաղաքականություն

+ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/pages/legal/return-policy/hy/return-policy-hy.component.ts b/src/app/pages/legal/return-policy/hy/return-policy-hy.component.ts new file mode 100644 index 0000000..8ae6e14 --- /dev/null +++ b/src/app/pages/legal/return-policy/hy/return-policy-hy.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-return-policy-hy', + templateUrl: './return-policy-hy.component.html', + styleUrls: ['../return-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ReturnPolicyHyComponent {} diff --git a/src/app/pages/legal/return-policy/return-policy.component.html b/src/app/pages/legal/return-policy/return-policy.component.html index d0d0163..c42d8e5 100644 --- a/src/app/pages/legal/return-policy/return-policy.component.html +++ b/src/app/pages/legal/return-policy/return-policy.component.html @@ -1,308 +1,5 @@ - +@switch (lang()) { + @case ('ru') { } + @case ('en') { } + @case ('hy') { } +} diff --git a/src/app/pages/legal/return-policy/return-policy.component.ts b/src/app/pages/legal/return-policy/return-policy.component.ts index a8faa7e..1d3b95a 100644 --- a/src/app/pages/legal/return-policy/return-policy.component.ts +++ b/src/app/pages/legal/return-policy/return-policy.component.ts @@ -1,15 +1,16 @@ -import { Component } from '@angular/core'; -import { RouterLink } from '@angular/router'; -import { environment } from '../../../../environments/environment'; +import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; +import { LanguageService } from '../../../services/language.service'; +import { ReturnPolicyRuComponent } from './ru/return-policy-ru.component'; +import { ReturnPolicyEnComponent } from './en/return-policy-en.component'; +import { ReturnPolicyHyComponent } from './hy/return-policy-hy.component'; @Component({ selector: 'app-return-policy', - imports: [], + imports: [ReturnPolicyRuComponent, ReturnPolicyEnComponent, ReturnPolicyHyComponent], templateUrl: './return-policy.component.html', - styleUrls: ['./return-policy.component.scss'] + styleUrls: ['./return-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class ReturnPolicyComponent { - brandName = environment.brandName; - contactEmail = environment.contactEmail; - isnovo = environment.theme === 'novo'; + lang = inject(LanguageService).currentLanguage; } diff --git a/src/app/brands/dexar/pages/legal/return-policy/return-policy.component.html b/src/app/pages/legal/return-policy/ru/return-policy-ru.component.html similarity index 99% rename from src/app/brands/dexar/pages/legal/return-policy/return-policy.component.html rename to src/app/pages/legal/return-policy/ru/return-policy-ru.component.html index 7863b7c..be676f1 100644 --- a/src/app/brands/dexar/pages/legal/return-policy/return-policy.component.html +++ b/src/app/pages/legal/return-policy/ru/return-policy-ru.component.html @@ -1,5 +1,3 @@ - diff --git a/src/app/pages/legal/return-policy/ru/return-policy-ru.component.ts b/src/app/pages/legal/return-policy/ru/return-policy-ru.component.ts new file mode 100644 index 0000000..d942e59 --- /dev/null +++ b/src/app/pages/legal/return-policy/ru/return-policy-ru.component.ts @@ -0,0 +1,9 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'app-return-policy-ru', + templateUrl: './return-policy-ru.component.html', + styleUrls: ['../return-policy.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ReturnPolicyRuComponent {} diff --git a/src/app/pages/search/search.component.html b/src/app/pages/search/search.component.html index 6a0c0c3..a1de3fa 100644 --- a/src/app/pages/search/search.component.html +++ b/src/app/pages/search/search.component.html @@ -1,12 +1,12 @@
-

Поиск товаров

+

{{ 'search.title' | translate }}

-

Ничего не найдено

-

По запросу "{{ searchQuery }}" товары не найдены

-

Попробуйте изменить запрос или используйте другие ключевые слова

+

{{ 'search.noResults' | translate }}

+

{{ 'search.noResultsFor' | translate:{ query: searchQuery } }}

+

{{ 'search.noResultsHint' | translate }}

} @@ -57,7 +57,7 @@
@for (item of items(); track trackByItemId($index, item)) {
- +
@if (item.discount > 0) { @@ -106,7 +106,7 @@
} @@ -115,13 +115,13 @@ @if (loading() && items().length > 0) {
-

Загрузка...

+

{{ 'search.loadingMore' | translate }}

} @if (!hasMore() && items().length > 0) {
-

Все результаты загружены

+

{{ 'search.allLoaded' | translate }}

} } @@ -134,7 +134,7 @@
-

Введите запрос для поиска товаров

+

{{ 'search.emptyState' | translate }}

}
diff --git a/src/app/pages/search/search.component.ts b/src/app/pages/search/search.component.ts index 3e53bce..c7af37e 100644 --- a/src/app/pages/search/search.component.ts +++ b/src/app/pages/search/search.component.ts @@ -1,4 +1,4 @@ -import { Component, signal, HostListener, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; +import { Component, signal, HostListener, OnDestroy, ChangeDetectionStrategy, inject } from '@angular/core'; import { DecimalPipe } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { RouterLink } from '@angular/router'; @@ -7,10 +7,13 @@ import { Item } from '../../models'; import { Subject, Subscription } from 'rxjs'; import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; import { getDiscountedPrice, getMainImage, trackByItemId, getBadgeClass } from '../../utils/item.utils'; +import { LangRoutePipe } from '../../pipes/lang-route.pipe'; +import { TranslatePipe } from '../../i18n/translate.pipe'; +import { TranslateService } from '../../i18n/translate.service'; @Component({ selector: 'app-search', - imports: [DecimalPipe, FormsModule, RouterLink], + imports: [DecimalPipe, FormsModule, RouterLink, LangRoutePipe, TranslatePipe], templateUrl: './search.component.html', styleUrls: ['./search.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush @@ -28,6 +31,7 @@ export class SearchComponent implements OnDestroy { private isLoadingMore = false; private searchSubject = new Subject(); private searchSubscription: Subscription; + private i18n = inject(TranslateService); constructor( private apiService: ApiService, @@ -48,6 +52,7 @@ export class SearchComponent implements OnDestroy { ngOnDestroy(): void { this.searchSubscription.unsubscribe(); this.searchSubject.complete(); + if (this.scrollTimeout) clearTimeout(this.scrollTimeout); } onSearchInput(query: string): void { @@ -98,7 +103,7 @@ export class SearchComponent implements OnDestroy { this.isLoadingMore = false; }, error: (err) => { - this.error.set('Ошибка при поиске товаров'); + this.error.set(this.i18n.t('home.errorTitle')); this.loading.set(false); this.isLoadingMore = false; console.error('Error searching items:', err); @@ -106,7 +111,7 @@ export class SearchComponent implements OnDestroy { }); } - private scrollTimeout: any; + private scrollTimeout?: ReturnType; @HostListener('window:scroll') onScroll(): void { diff --git a/src/app/pipes/lang-route.pipe.ts b/src/app/pipes/lang-route.pipe.ts new file mode 100644 index 0000000..38b4a99 --- /dev/null +++ b/src/app/pipes/lang-route.pipe.ts @@ -0,0 +1,25 @@ +import { Pipe, PipeTransform, inject } from '@angular/core'; +import { LanguageService } from '../services/language.service'; + +@Pipe({ + name: 'langRoute', + pure: false +}) +export class LangRoutePipe implements PipeTransform { + private langService = inject(LanguageService); + + transform(value: string | (string | number)[]): string | (string | number)[] { + const lang = this.langService.currentLanguage(); + + if (typeof value === 'string') { + return value === '/' ? `/${lang}` : `/${lang}${value}`; + } + + if (Array.isArray(value) && value.length > 0) { + const [first, ...rest] = value; + return [`/${lang}${first}`, ...rest]; + } + + return value; + } +} diff --git a/src/app/services/cart.service.ts b/src/app/services/cart.service.ts index 65ea3ed..ce8de1f 100644 --- a/src/app/services/cart.service.ts +++ b/src/app/services/cart.service.ts @@ -1,6 +1,7 @@ import { Injectable, signal, computed, effect } from '@angular/core'; import { ApiService } from './api.service'; import { Item, CartItem } from '../models'; +import { getDiscountedPrice } from '../utils/item.utils'; import { environment } from '../../environments/environment'; import type { } from '../types/telegram.types'; @@ -11,6 +12,7 @@ export class CartService { private readonly STORAGE_KEY = `${environment.brandName.toLowerCase().replace(/\s+/g, '_')}_cart`; private cartItems = signal([]); private isTelegram = typeof window !== 'undefined' && !!window.Telegram?.WebApp; + private addingItems = new Set(); items = this.cartItems.asReadonly(); itemCount = computed(() => { @@ -22,8 +24,7 @@ export class CartService { const items = this.cartItems(); if (!Array.isArray(items)) return 0; return items.reduce((total, item) => { - const price = item.price * (1 - (item.discount || 0) / 100); - return total + (price * item.quantity); + return total + (getDiscountedPrice(item) * item.quantity); }, 0); }); @@ -40,8 +41,8 @@ export class CartService { private saveToStorage(items: CartItem[]): void { const data = JSON.stringify(items); - // Always save to sessionStorage - sessionStorage.setItem(this.STORAGE_KEY, data); + // Always save to localStorage + localStorage.setItem(this.STORAGE_KEY, data); // Also save to Telegram CloudStorage if available if (this.isTelegram) { @@ -59,21 +60,21 @@ export class CartService { window.Telegram!.WebApp.CloudStorage.getItem(this.STORAGE_KEY, (err, value) => { if (err) { console.error('Error loading from Telegram CloudStorage:', err); - this.loadFromSessionStorage(); + this.loadFromLocalStorage(); } else if (value) { - this.parseAndSetCart(value) || this.loadFromSessionStorage(); + this.parseAndSetCart(value) || this.loadFromLocalStorage(); } else { - // No data in CloudStorage, try sessionStorage - this.loadFromSessionStorage(); + // No data in CloudStorage, try localStorage + this.loadFromLocalStorage(); } }); } else { - this.loadFromSessionStorage(); + this.loadFromLocalStorage(); } } - private loadFromSessionStorage(): void { - const stored = sessionStorage.getItem(this.STORAGE_KEY); + private loadFromLocalStorage(): void { + const stored = localStorage.getItem(this.STORAGE_KEY); if (stored) { this.parseAndSetCart(stored); } @@ -98,6 +99,9 @@ export class CartService { } addItem(itemID: number, quantity: number = 1): void { + // Prevent duplicate API calls for same item + if (this.addingItems.has(itemID)) return; + const currentItems = this.cartItems(); const existingItem = currentItems.find(i => i.itemID === itemID); @@ -106,14 +110,16 @@ export class CartService { this.updateQuantity(itemID, existingItem.quantity + quantity); } else { // Get item details from API and add to cart + this.addingItems.add(itemID); this.apiService.getItem(itemID).subscribe({ next: (item) => { const cartItem: CartItem = { ...item, quantity }; this.cartItems.set([...this.cartItems(), cartItem]); + this.addingItems.delete(itemID); }, error: (err) => { console.error('Error adding to cart:', err); - alert('Ошибка добавления в корзину: ' + (err.error?.message || err.message)); + this.addingItems.delete(itemID); } }); } diff --git a/src/app/services/index.ts b/src/app/services/index.ts index 4247c75..4f32ba6 100644 --- a/src/app/services/index.ts +++ b/src/app/services/index.ts @@ -2,3 +2,4 @@ export * from './api.service'; export * from './cart.service'; export * from './telegram.service'; export * from './language.service'; +export * from './seo.service'; diff --git a/src/app/services/language.service.ts b/src/app/services/language.service.ts index 05efd02..12232db 100644 --- a/src/app/services/language.service.ts +++ b/src/app/services/language.service.ts @@ -1,4 +1,5 @@ import { Injectable, signal } from '@angular/core'; +import { Router } from '@angular/router'; export interface Language { code: string; @@ -16,13 +17,13 @@ export class LanguageService { languages: Language[] = [ { code: 'ru', name: 'Русский', flag: '🇷🇺', flagSvg: '/flags/ru.svg', enabled: true }, - { code: 'en', name: 'English', flag: '🇬🇧', flagSvg: '/flags/en.svg', enabled: false }, - { code: 'hy', name: 'Հայերեն', flag: '🇦🇲', flagSvg: '/flags/arm.svg', enabled: false } + { code: 'en', name: 'English', flag: '🇬🇧', flagSvg: '/flags/en.svg', enabled: true }, + { code: 'hy', name: 'Հայերեն', flag: '🇦🇲', flagSvg: '/flags/arm.svg', enabled: true } ]; currentLanguage = this.currentLanguageSignal.asReadonly(); - constructor() { + constructor(private router: Router) { // Load saved language from localStorage const savedLang = localStorage.getItem('selectedLanguage'); if (savedLang && this.languages.find(l => l.code === savedLang && l.enabled)) { @@ -38,6 +39,19 @@ export class LanguageService { } } + /** Change language and navigate to the same page with the new prefix */ + switchLanguage(langCode: string): void { + const lang = this.languages.find(l => l.code === langCode); + if (!lang?.enabled) return; + + const currentUrl = this.router.url; + const currentLang = this.currentLanguageSignal(); + const newUrl = currentUrl.replace(new RegExp(`^/${currentLang}`), `/${langCode}`); + + this.setLanguage(langCode); + this.router.navigateByUrl(newUrl); + } + getCurrentLanguage(): Language | undefined { return this.languages.find(l => l.code === this.currentLanguageSignal()); } diff --git a/src/app/services/seo.service.ts b/src/app/services/seo.service.ts new file mode 100644 index 0000000..46597d1 --- /dev/null +++ b/src/app/services/seo.service.ts @@ -0,0 +1,117 @@ +import { Injectable, inject } from '@angular/core'; +import { Meta, Title } from '@angular/platform-browser'; +import { environment } from '../../environments/environment'; +import { Item } from '../models'; +import { getDiscountedPrice, getMainImage } from '../utils/item.utils'; + +@Injectable({ + providedIn: 'root' +}) +export class SeoService { + private meta = inject(Meta); + private title = inject(Title); + + private readonly siteUrl = `https://${environment.domain}`; + private readonly siteName = environment.brandFullName; + + /** + * Set Open Graph & Twitter Card meta tags for a product/item page. + */ + setItemMeta(item: Item): void { + const price = item.discount > 0 ? getDiscountedPrice(item) : item.price; + const imageUrl = this.resolveUrl(getMainImage(item)); + const itemUrl = `${this.siteUrl}/item/${item.itemID}`; + const description = this.truncate(this.stripHtml(item.description), 160); + const titleText = `${item.name} — ${this.siteName}`; + + this.title.setTitle(titleText); + + this.setOrUpdate([ + // Open Graph + { property: 'og:type', content: 'product' }, + { property: 'og:title', content: item.name }, + { property: 'og:description', content: description }, + { property: 'og:image', content: imageUrl }, + { property: 'og:url', content: itemUrl }, + { property: 'og:site_name', content: this.siteName }, + { property: 'og:locale', content: 'ru_RU' }, + + // Product-specific OG tags + { property: 'product:price:amount', content: price.toFixed(2) }, + { property: 'product:price:currency', content: item.currency || 'RUB' }, + + // Twitter Card + { name: 'twitter:card', content: 'summary_large_image' }, + { name: 'twitter:title', content: item.name }, + { name: 'twitter:description', content: description }, + { name: 'twitter:image', content: imageUrl }, + + // Standard meta + { name: 'description', content: description }, + ]); + } + + /** + * Reset meta tags back to defaults (call on navigation away from item page). + */ + resetToDefaults(): void { + const defaultTitle = `${this.siteName} — Marketplace`; + const defaultDescription = 'Modern marketplace for buying digital goods. Wide selection, convenient search, fast delivery.'; + const defaultImage = `${this.siteUrl}/og-image.jpg`; + + this.title.setTitle(defaultTitle); + + this.setOrUpdate([ + { property: 'og:type', content: 'website' }, + { property: 'og:title', content: defaultTitle }, + { property: 'og:description', content: defaultDescription }, + { property: 'og:image', content: defaultImage }, + { property: 'og:url', content: this.siteUrl }, + { property: 'og:site_name', content: this.siteName }, + { property: 'og:locale', content: 'ru_RU' }, + + { name: 'twitter:card', content: 'summary_large_image' }, + { name: 'twitter:title', content: defaultTitle }, + { name: 'twitter:description', content: defaultDescription }, + { name: 'twitter:image', content: defaultImage }, + + { name: 'description', content: defaultDescription }, + ]); + + // Remove product-specific tags + this.meta.removeTag("property='product:price:amount'"); + this.meta.removeTag("property='product:price:currency'"); + } + + private setOrUpdate(tags: Array<{ property?: string; name?: string; content: string }>): void { + for (const tag of tags) { + const selector = tag.property + ? `property='${tag.property}'` + : `name='${tag.name}'`; + + const existing = this.meta.getTag(selector); + if (existing) { + this.meta.updateTag(tag as any, selector); + } else { + this.meta.addTag(tag as any); + } + } + } + + /** Convert relative URLs to absolute */ + private resolveUrl(url: string): string { + if (!url || url.startsWith('http')) return url; + return `${this.siteUrl}${url.startsWith('/') ? '' : '/'}${url}`; + } + + /** Strip HTML tags from a string */ + private stripHtml(html: string): string { + return html?.replace(/<[^>]*>/g, '') || ''; + } + + /** Truncate text to maxLength, adding ellipsis */ + private truncate(text: string, maxLength: number): string { + if (!text || text.length <= maxLength) return text || ''; + return text.substring(0, maxLength - 1) + '…'; + } +} diff --git a/src/app/services/telegram.service.ts b/src/app/services/telegram.service.ts index 7943e83..5bb1c77 100644 --- a/src/app/services/telegram.service.ts +++ b/src/app/services/telegram.service.ts @@ -34,6 +34,6 @@ export class TelegramService { } getDisplayName(): string { - return this.getUsername() || this.getFullName() || 'Пользователь'; + return this.getUsername() || this.getFullName() || 'User'; } } diff --git a/src/app/utils/item.utils.ts b/src/app/utils/item.utils.ts index 0b278d8..13b2ebe 100644 --- a/src/app/utils/item.utils.ts +++ b/src/app/utils/item.utils.ts @@ -9,7 +9,7 @@ export function getMainImage(item: Item): string { if (item.imgs && item.imgs.length > 0) { return item.imgs[0]; } - return item.photos?.[0]?.url || ''; + return item.photos?.[0]?.url || '/assets/images/placeholder.svg'; } export function getAllImages(item: Item): string[] { diff --git a/src/index.html b/src/index.html index bdf99dc..b8204c5 100644 --- a/src/index.html +++ b/src/index.html @@ -49,8 +49,11 @@ - - + + + + +