optimising and making it better

This commit is contained in:
sdarbinyan
2026-02-26 21:54:21 +04:00
parent 7a00a8f1e3
commit 10b4974719
58 changed files with 318 additions and 1804 deletions

View File

@@ -1,12 +1,14 @@
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 } from '../../services';
import { ApiService, CartService, TelegramService, SeoService } from '../../services';
import { Item } from '../../models';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Subscription } from 'rxjs';
import { environment } from '../../../environments/environment';
import { SecurityContext } from '@angular/core';
import { getDiscountedPrice } from '../../utils/item.utils';
@Component({
selector: 'app-item-detail',
@@ -31,6 +33,11 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
reviewSubmitStatus = signal<'idle' | 'loading' | 'success' | 'error'>('idle');
private routeSubscription?: Subscription;
private reviewResetTimeout?: ReturnType<typeof setTimeout>;
private reviewErrorTimeout?: ReturnType<typeof setTimeout>;
private reloadTimeout?: ReturnType<typeof setTimeout>;
private seoService = inject(SeoService);
constructor(
private route: ActivatedRoute,
@@ -49,6 +56,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 {
@@ -57,6 +68,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) => {
@@ -81,18 +93,18 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
getDiscountedPrice(): number {
const currentItem = this.item();
if (!currentItem) return 0;
return currentItem.price * (1 - currentItem.discount / 100);
return getDiscountedPrice(currentItem);
}
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;
}
@@ -102,10 +114,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 '<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>';
if (diffDays === 1) return '<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>';
if (diffDays < 7) return `${diffDays} <EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD>`;
if (diffDays < 30) return `${Math.floor(diffDays / 7)} <EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD>`;
if (diffDays === 0) return 'Сегодня';
if (diffDays === 1) return 'Вчера';
if (diffDays < 7) return `${diffDays} дн. назад`;
if (diffDays < 30) return `${Math.floor(diffDays / 7)} нед. назад`;
return date.toLocaleDateString('ru-RU', {
day: 'numeric',
@@ -120,7 +132,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
getUserDisplayName(): string | null {
if (!this.telegramService.isTelegramApp()) {
return '<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>';
return 'Пользователь';
}
return this.telegramService.getDisplayName();
}
@@ -149,13 +161,13 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
this.reviewSubmitStatus.set('success');
this.newReview = { rating: 0, comment: '', anonymous: false };
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> 3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
setTimeout(() => {
// Сброс состояния через 3 секунды
this.reviewResetTimeout = setTimeout(() => {
this.reviewSubmitStatus.set('idle');
}, 3000);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
setTimeout(() => {
// Перезагрузить данные товара после отправки отзыва
this.reloadTimeout = setTimeout(() => {
this.loadItem(currentItem.itemID);
}, 500);
},
@@ -163,8 +175,8 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
console.error('Error submitting review:', err);
this.reviewSubmitStatus.set('error');
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> 5 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
setTimeout(() => {
// Сброс состояния об ошибке через 5 секунд
this.reviewErrorTimeout = setTimeout(() => {
this.reviewSubmitStatus.set('idle');
}, 5000);
}