style changes

This commit is contained in:
sdarbinyan
2026-02-14 02:34:11 +04:00
parent 751ad48489
commit 4238d59fc6
20 changed files with 1448 additions and 1032 deletions

View File

@@ -192,201 +192,240 @@
}
</div>
} @else {
<!-- DEXAR VERSION - Original -->
<div class="item-detail-container">
<!-- DEXAR VERSION - Redesigned 2026 -->
<div class="dx-item-container">
@if (loading()) {
<div class="loading">
<div class="spinner"></div>
<div class="dx-loading">
<div class="dx-spinner"></div>
<p>Загрузка товара...</p>
</div>
}
@if (error()) {
<div class="error">
<div class="dx-error">
<p>{{ error() }}</p>
<a routerLink="/" class="back-link">Вернуться на главную</a>
<a routerLink="/" class="dx-back-link">Вернуться на главную</a>
</div>
}
@if (item() && !loading()) {
<div class="item-content">
<div class="item-gallery">
<div class="dx-item-content">
<!-- Gallery: thumbnails left + main photo -->
<div class="dx-gallery">
@if (item()?.photos && item()!.photos!.length > 0) {
<div class="main-photo">
@if (item()!.photos![selectedPhotoIndex()]?.video) {
<video [src]="item()!.photos![selectedPhotoIndex()].url" controls></video>
} @else {
<img [src]="item()!.photos![selectedPhotoIndex()].url" [alt]="item()!.name" fetchpriority="high" decoding="async" width="600" height="600" />
}
</div>
<div class="photo-thumbnails">
<div class="dx-thumbnails">
@for (photo of item()!.photos!; track $index) {
<div
class="thumbnail"
class="dx-thumb"
[class.active]="selectedPhotoIndex() === $index"
(click)="selectPhoto($index)">
@if (photo.video) {
<div class="video-indicator"></div>
<div class="dx-video-badge"></div>
}
<img [src]="photo.url" [alt]="'Photo ' + ($index + 1)" loading="lazy" decoding="async" />
<img [src]="photo.url" [alt]="'Фото ' + ($index + 1)" loading="lazy" decoding="async" />
</div>
}
</div>
} @else {
<div class="main-photo">
<div class="no-image">📦 Нет изображения</div>
</div>
}
</div>
<div class="item-info">
<h1>{{ item()!.name }}</h1>
<div class="rating-section">
<span class="rating">{{ getRatingStars(item()!.rating) }} {{ item()!.rating }}</span>
<span class="reviews-count">({{ item()!.callbacks?.length || 0 }} отзывов)</span>
</div>
<div class="price-section">
@if (item()!.discount > 0) {
<div class="discount-info">
<span class="original-price">{{ item()!.price }} {{ item()!.currency }}</span>
<span class="discount-badge">-{{ item()!.discount }}%</span>
</div>
<div class="current-price">{{ getDiscountedPrice() | number:'1.2-2' }} {{ item()!.currency }}</div>
<div class="dx-main-photo">
@if (item()?.photos && item()!.photos!.length > 0) {
@if (item()!.photos![selectedPhotoIndex()]?.video) {
<video [src]="item()!.photos![selectedPhotoIndex()].url" controls></video>
} @else {
<img [src]="item()!.photos![selectedPhotoIndex()].url" [alt]="item()!.name" fetchpriority="high" decoding="async" />
}
} @else {
<div class="current-price">{{ item()!.price }} {{ item()!.currency }}</div>
<div class="dx-no-image">
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#a1b4b5" stroke-width="1.5">
<rect x="3" y="3" width="18" height="18" rx="2"></rect>
<circle cx="8.5" cy="8.5" r="1.5"></circle>
<path d="M21 15l-5-5L5 21"></path>
</svg>
<span>Нет изображения</span>
</div>
}
</div>
</div>
<div class="stock-info">
<div class="stock-bar">
<span class="bar-segment" [class.filled]="item()!.remainings === 'high' || item()!.remainings === 'medium' || item()!.remainings === 'low'" [class.high]="item()!.remainings === 'high'" [class.medium]="item()!.remainings === 'medium'" [class.low]="item()!.remainings === 'low'"></span>
<span class="bar-segment" [class.filled]="item()!.remainings === 'high' || item()!.remainings === 'medium'" [class.high]="item()!.remainings === 'high'" [class.medium]="item()!.remainings === 'medium'"></span>
<span class="bar-segment" [class.filled]="item()!.remainings === 'high'" [class.high]="item()!.remainings === 'high'"></span>
<!-- Item Info -->
<div class="dx-info">
<h1 class="dx-title">{{ item()!.name }}</h1>
<div class="dx-rating">
<div class="dx-stars">
@for (star of [1, 2, 3, 4, 5]; track star) {
<svg width="18" height="18" viewBox="0 0 24 24" [attr.fill]="star <= item()!.rating ? '#497671' : 'none'" [attr.stroke]="star <= item()!.rating ? '#497671' : '#a1b4b5'" stroke-width="2">
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>
</svg>
}
</div>
<span class="dx-rating-value">{{ item()!.rating }}</span>
<span class="dx-rating-count">({{ item()!.callbacks?.length || 0 }} отзывов)</span>
</div>
<div class="dx-price-block">
@if (item()!.discount > 0) {
<div class="dx-price-row">
<span class="dx-old-price">{{ item()!.price }} {{ item()!.currency }}</span>
<span class="dx-discount-tag">-{{ item()!.discount }}%</span>
</div>
}
<div class="dx-current-price">
{{ item()!.discount > 0 ? (getDiscountedPrice() | number:'1.2-2') : item()!.price }} {{ item()!.currency }}
</div>
</div>
<button class="add-to-cart-btn" (click)="addToCart()">
<div class="dx-stock">
<span class="dx-stock-label">Наличие:</span>
<span class="dx-stock-status"
[class.high]="item()!.remainings === 'high'"
[class.medium]="item()!.remainings === 'medium'"
[class.low]="item()!.remainings === 'low'">
<span class="dx-stock-dot"></span>
{{ item()!.remainings === 'high' ? 'В наличии' : item()!.remainings === 'medium' ? 'Заканчивается' : 'Последние штуки' }}
</span>
</div>
<button class="dx-add-cart" (click)="addToCart()">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="9" cy="21" r="1"></circle>
<circle cx="20" cy="21" r="1"></circle>
<path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
</svg>
Добавить в корзину
</button>
<div class="description-section">
<div class="dx-description">
<h2>Описание</h2>
<div class="description" [innerHTML]="getSafeHtml(item()!.description)"></div>
<div class="dx-description-text" [innerHTML]="getSafeHtml(item()!.description)"></div>
</div>
</div>
</div>
<div class="reviews-section">
<!-- Reviews Section -->
<div class="dx-reviews-section">
<h2>Отзывы ({{ item()!.callbacks?.length || 0 }})</h2>
<!-- Review Submission Form -->
<div class="review-form">
<div class="dx-review-form">
<h3>Оставить отзыв</h3>
<div class="rating-input">
<div class="dx-rating-input">
<label>Оценка:</label>
<div class="star-selector">
<div class="dx-star-selector">
@for (star of [1, 2, 3, 4, 5]; track star) {
<span
class="star"
class="dx-star-pick"
[class.selected]="newReview.rating >= star"
(click)="setRating(star)">
</span>
}
</div>
</div>
<textarea
[(ngModel)]="newReview.comment"
placeholder="Напишите свой отзыв..."
rows="4">
placeholder="Поделитесь впечатлениями о товаре..."
rows="4"
class="dx-textarea">
</textarea>
<div class="form-actions">
<label class="anonymous-toggle">
<div class="dx-form-actions">
<label class="dx-anon-toggle">
<input type="checkbox" [(ngModel)]="newReview.anonymous">
Анонимно
<span>Анонимно</span>
</label>
@if (!newReview.anonymous && getUserDisplayName()) {
<span class="username-preview">Опубликуется как: {{ getUserDisplayName() }}</span>
<span class="dx-user-preview">{{ getUserDisplayName() }}</span>
}
<button
class="submit-review-btn"
class="dx-submit-btn"
(click)="submitReview()"
[disabled]="!newReview.rating || !newReview.comment.trim() || reviewSubmitStatus() === 'loading'"
[class.submitting]="reviewSubmitStatus() === 'loading'">
@if (reviewSubmitStatus() === 'loading') {
<span class="spinner-small"></span>
<span class="dx-spinner-sm"></span>
Отправка...
} @else {
Отправить отзыв
Отправить
}
</button>
</div>
@if (reviewSubmitStatus() === 'success') {
<div class="status-message success">
<span class="icon"></span>
<div class="dx-status success">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6L9 17l-5-5"/></svg>
Спасибо за ваш отзыв!
</div>
}
@if (reviewSubmitStatus() === 'error') {
<div class="status-message error">
<span class="icon"></span>
<div class="dx-status error">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M18 6L6 18M6 6l12 12"/></svg>
Ошибка отправки. Попробуйте позже.
</div>
}
</div>
<div class="reviews-list">
<div class="dx-reviews-list">
@if (item()?.callbacks && item()!.callbacks!.length > 0) {
@for (callback of item()!.callbacks; track $index) {
<div class="review-card">
<div class="review-header">
<span class="review-author">{{ callback.userID || 'Аноним' }}</span>
<div class="dx-review-card">
<div class="dx-review-header">
<div class="dx-reviewer">
<span class="dx-reviewer-name">{{ callback.userID || 'Аноним' }}</span>
@if (callback.timestamp) {
<span class="dx-review-date">{{ formatDate(callback.timestamp) }}</span>
}
</div>
@if (callback.rating) {
<div class="review-rating">{{ getRatingStars(callback.rating) }}</div>
}
@if (callback.timestamp) {
<span class="review-date">{{ formatDate(callback.timestamp) }}</span>
<div class="dx-review-stars">
@for (star of [1, 2, 3, 4, 5]; track star) {
<svg width="14" height="14" viewBox="0 0 24 24" [attr.fill]="star <= callback.rating ? '#497671' : 'none'" [attr.stroke]="star <= callback.rating ? '#497671' : '#d3dad9'" stroke-width="2">
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>
</svg>
}
</div>
}
</div>
@if (callback.content) {
<p class="review-text">{{ callback.content }}</p>
<p class="dx-review-text">{{ callback.content }}</p>
}
</div>
}
} @else {
<p class="no-reviews">Пока нет отзывов</p>
<p class="dx-no-reviews">Пока нет отзывов. Станьте первым!</p>
}
</div>
</div>
<div class="questions-section">
<h2>Вопросы и ответы ({{ item()!.questions?.length || 0 }})</h2>
<div class="questions-list">
@if (item()?.questions && item()!.questions!.length > 0) {
@for (question of item()!.questions; track $index) {
<div class="question-card">
<div class="question-text">
<strong>В:</strong> {{ question.question }}
<!-- Q&A Section -->
@if (item()!.questions && item()!.questions!.length > 0) {
<div class="dx-qa-section">
<h2>Вопросы и ответы ({{ item()!.questions!.length }})</h2>
<div class="dx-qa-list">
@for (question of item()!.questions!; track $index) {
<div class="dx-qa-card">
<div class="dx-question">
<span class="dx-qa-label q">В</span>
<span>{{ question.question }}</span>
</div>
<div class="answer-text">
<strong>О:</strong> {{ question.answer }}
<div class="dx-answer">
<span class="dx-qa-label a">О</span>
<span>{{ question.answer }}</span>
</div>
<div class="question-votes">
<span class="vote-up">👍 {{ question.upvotes }}</span>
<span class="vote-down">👎 {{ question.downvotes }}</span>
<div class="dx-qa-votes">
<button class="dx-vote up">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3H14z"/><path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/></svg>
{{ question.upvotes }}
</button>
<button class="dx-vote down">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3H10z"/><path d="M17 2h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"/></svg>
{{ question.downvotes }}
</button>
</div>
</div>
}
} @else {
<p class="no-questions">Пока нет вопросов</p>
}
</div>
</div>
</div>
}
}
</div>
}

File diff suppressed because it is too large Load Diff