home page
This commit is contained in:
BIN
files/Obuv.webp
BIN
files/Obuv.webp
Binary file not shown.
|
Before Width: | Height: | Size: 8.3 KiB |
BIN
public/assets/images/footer_bg.webp
Normal file
BIN
public/assets/images/footer_bg.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
@@ -16,6 +16,9 @@
|
|||||||
</div>
|
</div>
|
||||||
} @else {
|
} @else {
|
||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
|
@if (!isHomePage()) {
|
||||||
|
<app-back-button />
|
||||||
|
}
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
|
|
||||||
import { Component, OnInit, OnDestroy, signal, ApplicationRef } from '@angular/core';
|
import { Component, OnInit, OnDestroy, signal, ApplicationRef } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { Router, RouterOutlet, NavigationEnd } from '@angular/router';
|
||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { HeaderComponent } from './components/header/header.component';
|
import { HeaderComponent } from './components/header/header.component';
|
||||||
import { FooterComponent } from './components/footer/footer.component';
|
import { FooterComponent } from './components/footer/footer.component';
|
||||||
|
import { BackButtonComponent } from './components/back-button/back-button.component';
|
||||||
import { ApiService } from './services';
|
import { ApiService } from './services';
|
||||||
import { Subscription, interval, concat } from 'rxjs';
|
import { Subscription, interval, concat } from 'rxjs';
|
||||||
import { first } from 'rxjs/operators';
|
import { filter, first } from 'rxjs/operators';
|
||||||
import { environment } from '../environments/environment';
|
import { environment } from '../environments/environment';
|
||||||
import { SwUpdate } from '@angular/service-worker';
|
import { SwUpdate } from '@angular/service-worker';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [RouterOutlet, HeaderComponent, FooterComponent, CommonModule],
|
imports: [RouterOutlet, HeaderComponent, FooterComponent, BackButtonComponent, CommonModule],
|
||||||
templateUrl: './app.html',
|
templateUrl: './app.html',
|
||||||
styleUrl: './app.scss'
|
styleUrl: './app.scss'
|
||||||
})
|
})
|
||||||
@@ -21,14 +22,17 @@ export class App implements OnInit, OnDestroy {
|
|||||||
protected title = environment.brandName;
|
protected title = environment.brandName;
|
||||||
serverAvailable = signal(true);
|
serverAvailable = signal(true);
|
||||||
checkingServer = signal(true);
|
checkingServer = signal(true);
|
||||||
|
isHomePage = signal(true);
|
||||||
private pingSubscription?: Subscription;
|
private pingSubscription?: Subscription;
|
||||||
private updateSubscription?: Subscription;
|
private updateSubscription?: Subscription;
|
||||||
|
private routerSubscription?: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private titleService: Title,
|
private titleService: Title,
|
||||||
private swUpdate: SwUpdate,
|
private swUpdate: SwUpdate,
|
||||||
private appRef: ApplicationRef
|
private appRef: ApplicationRef,
|
||||||
|
private router: Router
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@@ -36,6 +40,14 @@ export class App implements OnInit, OnDestroy {
|
|||||||
this.titleService.setTitle(`${environment.brandFullName} - Маркетплейс товаров и услуг`);
|
this.titleService.setTitle(`${environment.brandFullName} - Маркетплейс товаров и услуг`);
|
||||||
this.checkServerHealth();
|
this.checkServerHealth();
|
||||||
this.setupAutoUpdates();
|
this.setupAutoUpdates();
|
||||||
|
|
||||||
|
// Track route changes to show/hide back button
|
||||||
|
this.routerSubscription = this.router.events
|
||||||
|
.pipe(filter(event => event instanceof NavigationEnd))
|
||||||
|
.subscribe((event) => {
|
||||||
|
const url = (event as NavigationEnd).urlAfterRedirects || (event as NavigationEnd).url;
|
||||||
|
this.isHomePage.set(url === '/' || url === '/home' || url === '');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
checkServerHealth(): void {
|
checkServerHealth(): void {
|
||||||
@@ -84,6 +96,7 @@ export class App implements OnInit, OnDestroy {
|
|||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.pingSubscription?.unsubscribe();
|
this.pingSubscription?.unsubscribe();
|
||||||
this.updateSubscription?.unsubscribe();
|
this.updateSubscription?.unsubscribe();
|
||||||
|
this.routerSubscription?.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
retryConnection(): void {
|
retryConnection(): void {
|
||||||
|
|||||||
69
src/app/components/back-button/back-button.component.ts
Normal file
69
src/app/components/back-button/back-button.component.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { environment } from '../../../environments/environment';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-back-button',
|
||||||
|
standalone: true,
|
||||||
|
template: `
|
||||||
|
@if (!isnovo) {
|
||||||
|
<button class="dexar-back-btn" (click)="goBack()" aria-label="Назад">
|
||||||
|
<svg width="37" height="24" viewBox="0 0 37 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.73 11.46c-.97-.52-.97-1.4 0-1.92L20.39 1.21c1.48-.79 3.89-.19 3.89.95v3.74h6.94c1.28 0 2.31.59 2.31 1.31v6.56c0 .73-1.03 1.31-2.31 1.31h-6.94v3.74c0 1.15-2.42 1.74-3.89.96L4.73 11.46Z"
|
||||||
|
fill="#497671" fill-opacity="0.75" stroke="white" stroke-opacity="0.6" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
styles: [`
|
||||||
|
.dexar-back-btn {
|
||||||
|
position: fixed;
|
||||||
|
top: 76px;
|
||||||
|
left: 20px;
|
||||||
|
z-index: 100;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
|
||||||
|
svg path {
|
||||||
|
transition: fill 0.2s ease, fill-opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.08);
|
||||||
|
|
||||||
|
svg path {
|
||||||
|
fill: #A1B4B5;
|
||||||
|
fill-opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.dexar-back-btn {
|
||||||
|
top: 68px;
|
||||||
|
left: 12px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 30px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`]
|
||||||
|
})
|
||||||
|
export class BackButtonComponent {
|
||||||
|
isnovo = environment.theme === 'novo';
|
||||||
|
|
||||||
|
constructor(private location: Location) {}
|
||||||
|
|
||||||
|
goBack(): void {
|
||||||
|
this.location.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,49 +49,60 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
} @else {
|
} @else {
|
||||||
<!-- DEXAR VERSION - Original -->
|
<!-- DEXAR VERSION - Redesigned -->
|
||||||
<footer class="footer">
|
<footer class="dexar-footer">
|
||||||
<div class="footer-container">
|
<div class="dexar-footer-bg">
|
||||||
<div class="footer-section">
|
<div class="dexar-footer-container">
|
||||||
<h3>Информация</h3>
|
<div class="dexar-footer-top">
|
||||||
<ul>
|
<div class="dexar-footer-logo">
|
||||||
<li><a routerLink="/about">О компании</a></li>
|
<img src="/assets/images/dexar-logo.svg" alt="Dexar" class="dexar-footer-logo-desktop" loading="lazy" />
|
||||||
<li><a routerLink="/contacts">Контакты</a></li>
|
<img src="/assets/images/dexar-logo-small.svg" alt="Dexar" class="dexar-footer-logo-mobile" loading="lazy" />
|
||||||
<li><a routerLink="/company-details">Реквизиты организации</a></li>
|
</div>
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="footer-section">
|
<div class="dexar-footer-columns">
|
||||||
<h3>Документы</h3>
|
<div class="dexar-footer-col">
|
||||||
<ul>
|
<h4>Информация</h4>
|
||||||
<li><a routerLink="/payment-terms">Правила оплаты</a></li>
|
<ul>
|
||||||
<li><a routerLink="/return-policy">Политика возврата</a></li>
|
<li><a routerLink="/about">О компании</a></li>
|
||||||
<li><a routerLink="/public-offer">Публичная оферта</a></li>
|
<li><a routerLink="/contacts">Контакты</a></li>
|
||||||
<li><a routerLink="/privacy-policy">Политика конфиденциальности</a></li>
|
<li><a routerLink="/company-details">Реквизиты</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer-section">
|
<div class="dexar-footer-col">
|
||||||
<h3>Помощь</h3>
|
<h4>Документы</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a routerLink="/faq">Часто задаваемые вопросы</a></li>
|
<li><a routerLink="/payment-terms">Правила оплаты</a></li>
|
||||||
<li><a routerLink="/delivery">Доставка</a></li>
|
<li><a routerLink="/return-policy">Политика возврата</a></li>
|
||||||
<li><a routerLink="/guarantee">Гарантия</a></li>
|
<li><a routerLink="/public-offer">Публичная оферта</a></li>
|
||||||
</ul>
|
<li><a routerLink="/privacy-policy">Конфиденциальность</a></li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="footer-section payment-systems">
|
<div class="dexar-footer-col">
|
||||||
<h3>Способы оплаты</h3>
|
<h4>Помощь</h4>
|
||||||
<div class="payment-logos">
|
<ul>
|
||||||
<img src="/assets/images/mir-logo.svg" alt="МИР" class="payment-logo" loading="lazy" decoding="async" width="60" height="40" />
|
<li><a routerLink="/faq">FAQ</a></li>
|
||||||
<img src="/assets/images/visa-logo.svg" alt="Visa" class="payment-logo" loading="lazy" decoding="async" width="60" height="40" />
|
<li><a routerLink="/delivery">Доставка</a></li>
|
||||||
<img src="/assets/images/mastercard-logo.svg" alt="Mastercard" class="payment-logo" loading="lazy" decoding="async" width="60" height="40" />
|
<li><a routerLink="/guarantee">Гарантия</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dexar-footer-col">
|
||||||
|
<h4>Оплата</h4>
|
||||||
|
<div class="dexar-payment-logos">
|
||||||
|
<img src="/assets/images/mir-logo.svg" alt="МИР" loading="lazy" width="48" height="32" />
|
||||||
|
<img src="/assets/images/visa-logo.svg" alt="Visa" loading="lazy" width="48" height="32" />
|
||||||
|
<img src="/assets/images/mastercard-logo.svg" alt="Mastercard" loading="lazy" width="48" height="32" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dexar-footer-bottom">
|
||||||
|
<p>© {{ currentYear }} {{ brandName }}. Все права защищены.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer-bottom">
|
|
||||||
<p>© {{ currentYear }} {{ brandName }}. Все права защищены.</p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
</footer>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
.footer {
|
:host {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
background-color: #1a1a1a;
|
background-color: #1a1a1a;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
@@ -217,3 +222,192 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== DEXAR FOOTER STYLES ==========
|
||||||
|
.dexar-footer {
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-bg {
|
||||||
|
background-image: url('/assets/images/footer_bg.webp');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(30, 60, 56, 0.85);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
max-width: 1440px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 48px 40px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-top {
|
||||||
|
display: flex;
|
||||||
|
gap: 48px;
|
||||||
|
padding-bottom: 32px;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-logo {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding-top: 4px;
|
||||||
|
|
||||||
|
.dexar-footer-logo-desktop {
|
||||||
|
display: block;
|
||||||
|
height: 40px;
|
||||||
|
width: auto;
|
||||||
|
filter: brightness(0) invert(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-logo-mobile {
|
||||||
|
display: none;
|
||||||
|
height: 32px;
|
||||||
|
width: auto;
|
||||||
|
filter: brightness(0) invert(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-columns {
|
||||||
|
flex: 1;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-col {
|
||||||
|
h4 {
|
||||||
|
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #ffffff;
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-payment-logos {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 28px;
|
||||||
|
max-height: 28px;
|
||||||
|
width: auto;
|
||||||
|
max-width: 60px;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
object-fit: contain;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-bottom {
|
||||||
|
padding: 20px 0 0;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Responsive
|
||||||
|
@media (max-width: 992px) {
|
||||||
|
.dexar-footer-container {
|
||||||
|
padding: 40px 32px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-top {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-columns {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.dexar-footer-container {
|
||||||
|
padding: 32px 20px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-logo {
|
||||||
|
.dexar-footer-logo-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-logo-mobile {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-columns {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-col h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-col ul li a {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.dexar-footer-container {
|
||||||
|
padding: 24px 16px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-footer-columns {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,8 +88,8 @@
|
|||||||
<div class="dexar-actions">
|
<div class="dexar-actions">
|
||||||
<!-- Cart Button -->
|
<!-- Cart Button -->
|
||||||
<a routerLink="/cart" routerLinkActive="dexar-cart-active" class="dexar-cart-btn" (click)="closeMenu()">
|
<a routerLink="/cart" routerLinkActive="dexar-cart-active" class="dexar-cart-btn" (click)="closeMenu()">
|
||||||
<svg width="48" height="32" viewBox="0 0 48 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="32" height="24" viewBox="0 0 48 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M12 0.5H36C42.3513 0.5 47.5 5.64873 47.5 12V20C47.5 26.3513 42.3513 31.5 36 31.5H12C5.64873 31.5 0.5 26.3513 0.5 20V12C0.5 5.64873 5.64873 0.5 12 0.5Z" fill="#497671" fill-opacity="0.3" />
|
<path d="M12 0.5H36C42.3513 0.5 47.5 5.64873 47.5 12V20C47.5 26.3513 42.3513 31.5 36 31.5H12C5.64873 31.5 0.5 26.3513 0.5 20V12C0.5 5.64873 5.64873 0.5 12 0.5Z" fill="transparent" />
|
||||||
<path d="M12 0.5H36C42.3513 0.5 47.5 5.64873 47.5 12V20C47.5 26.3513 42.3513 31.5 36 31.5H12C5.64873 31.5 0.5 26.3513 0.5 20V12C0.5 5.64873 5.64873 0.5 12 0.5Z" stroke="#677B78" />
|
<path d="M12 0.5H36C42.3513 0.5 47.5 5.64873 47.5 12V20C47.5 26.3513 42.3513 31.5 36 31.5H12C5.64873 31.5 0.5 26.3513 0.5 20V12C0.5 5.64873 5.64873 0.5 12 0.5Z" stroke="#677B78" />
|
||||||
<path d="M10 3.9C10 3.40294 10.4029 3 10.9 3H13.6C14.013 3 14.373 3.28107 14.4731 3.68172L15.2027 6.6H36.1C36.3677 6.6 36.6216 6.7192 36.7925 6.92523C36.9635 7.13125 37.0339 7.40271 36.9846 7.66586L34.2846 22.0659C34.2048 22.4915 33.8331 22.8 33.4 22.8H31.6H19H17.2C16.7669 22.8 16.3952 22.4915 16.3154 22.0659L13.6204 7.69224L12.8973 4.8H10.9C10.4029 4.8 10 4.39706 10 3.9ZM15.5844 8.4L17.9469 21H32.6531L35.0156 8.4H15.5844ZM19 22.8C17.0118 22.8 15.4 24.4118 15.4 26.4C15.4 28.3882 17.0118 30 19 30C20.9882 30 22.6 28.3882 22.6 26.4C22.6 24.4118 20.9882 22.8 19 22.8ZM31.6 22.8C29.6118 22.8 28 24.4118 28 26.4C28 28.3882 29.6118 30 31.6 30C33.5882 30 35.2 28.3882 35.2 26.4C35.2 24.4118 33.5882 22.8 31.6 22.8ZM19 24.6C19.9941 24.6 20.8 25.4059 20.8 26.4C20.8 27.3941 19.9941 28.2 19 28.2C18.0059 28.2 17.2 27.3941 17.2 26.4C17.2 25.4059 18.0059 24.6 19 24.6ZM31.6 24.6C32.5941 24.6 33.4 25.4059 33.4 26.4C33.4 27.3941 32.5941 28.2 31.6 28.2C30.6059 28.2 29.8 27.3941 29.8 26.4C29.8 25.4059 30.6059 24.6 31.6 24.6Z" fill="#1E3C38" />
|
<path d="M10 3.9C10 3.40294 10.4029 3 10.9 3H13.6C14.013 3 14.373 3.28107 14.4731 3.68172L15.2027 6.6H36.1C36.3677 6.6 36.6216 6.7192 36.7925 6.92523C36.9635 7.13125 37.0339 7.40271 36.9846 7.66586L34.2846 22.0659C34.2048 22.4915 33.8331 22.8 33.4 22.8H31.6H19H17.2C16.7669 22.8 16.3952 22.4915 16.3154 22.0659L13.6204 7.69224L12.8973 4.8H10.9C10.4029 4.8 10 4.39706 10 3.9ZM15.5844 8.4L17.9469 21H32.6531L35.0156 8.4H15.5844ZM19 22.8C17.0118 22.8 15.4 24.4118 15.4 26.4C15.4 28.3882 17.0118 30 19 30C20.9882 30 22.6 28.3882 22.6 26.4C22.6 24.4118 20.9882 22.8 19 22.8ZM31.6 22.8C29.6118 22.8 28 24.4118 28 26.4C28 28.3882 29.6118 30 31.6 30C33.5882 30 35.2 28.3882 35.2 26.4C35.2 24.4118 33.5882 22.8 31.6 22.8ZM19 24.6C19.9941 24.6 20.8 25.4059 20.8 26.4C20.8 27.3941 19.9941 28.2 19 28.2C18.0059 28.2 17.2 27.3941 17.2 26.4C17.2 25.4059 18.0059 24.6 19 24.6ZM31.6 24.6C32.5941 24.6 33.4 25.4059 33.4 26.4C33.4 27.3941 32.5941 28.2 31.6 28.2C30.6059 28.2 29.8 27.3941 29.8 26.4C29.8 25.4059 30.6059 24.6 31.6 24.6Z" fill="#1E3C38" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
@@ -453,7 +453,7 @@
|
|||||||
// ========== DEXAR REDESIGN 2026 STYLES ==========
|
// ========== DEXAR REDESIGN 2026 STYLES ==========
|
||||||
.dexar-header {
|
.dexar-header {
|
||||||
background: rgba(117, 121, 124, 0.1);
|
background: rgba(117, 121, 124, 0.1);
|
||||||
padding: 14px 0;
|
padding: 8px 0;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
@@ -463,11 +463,11 @@
|
|||||||
.dexar-header-container {
|
.dexar-header-container {
|
||||||
max-width: 1440px;
|
max-width: 1440px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 56px;
|
padding: 0 40px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 57px;
|
gap: 32px;
|
||||||
height: 56px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-logo {
|
.dexar-logo {
|
||||||
@@ -477,8 +477,8 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
::ng-deep .logo-img {
|
::ng-deep .logo-img {
|
||||||
width: 148px;
|
width: 120px;
|
||||||
height: 48px;
|
height: 38px;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,13 +498,13 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 10px 48px;
|
padding: 6px 32px;
|
||||||
height: 49px;
|
height: 38px;
|
||||||
border: 1px solid #d3dad9;
|
border: 1px solid #d3dad9;
|
||||||
background: rgba(255, 255, 255, 0.74);
|
background: rgba(255, 255, 255, 0.74);
|
||||||
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 22px;
|
font-size: 15px;
|
||||||
color: #1e3c38;
|
color: #1e3c38;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -523,45 +523,45 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dexar-nav-btn-left {
|
.dexar-nav-btn-left {
|
||||||
border-radius: 13px 0 0 13px;
|
border-radius: 10px 0 0 10px;
|
||||||
padding: 10px 48px;
|
padding: 6px 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-nav-btn-middle {
|
.dexar-nav-btn-middle {
|
||||||
padding: 10px 63px;
|
padding: 6px 40px;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-nav-btn-right {
|
.dexar-nav-btn-right {
|
||||||
border-radius: 0 13px 13px 0;
|
border-radius: 0 10px 10px 0;
|
||||||
padding: 10px 42px;
|
padding: 6px 28px;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search Box
|
// Search Box
|
||||||
.dexar-search-wrapper {
|
.dexar-search-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
max-width: 234px;
|
max-width: 200px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-search-box {
|
.dexar-search-box {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 49px;
|
height: 38px;
|
||||||
background: rgba(255, 255, 255, 0.74);
|
background: rgba(255, 255, 255, 0.74);
|
||||||
border: 1px solid #d2dad9;
|
border: 1px solid #d2dad9;
|
||||||
border-radius: 22px;
|
border-radius: 19px;
|
||||||
box-shadow: 0 3px 4px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.12);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 20px;
|
padding: 0 14px;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-search-icon {
|
.dexar-search-icon {
|
||||||
width: 28px;
|
width: 20px;
|
||||||
height: 28px;
|
height: 20px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,7 +572,7 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 22px;
|
font-size: 15px;
|
||||||
color: #828e8d;
|
color: #828e8d;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@@ -591,8 +591,8 @@
|
|||||||
|
|
||||||
.dexar-cart-btn {
|
.dexar-cart-btn {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 48px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -601,8 +601,8 @@
|
|||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
width: 48px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
@@ -155,18 +155,18 @@
|
|||||||
// Dexar header specific styles
|
// Dexar header specific styles
|
||||||
:host-context(.dexar-header) {
|
:host-context(.dexar-header) {
|
||||||
.language-selector {
|
.language-selector {
|
||||||
width: 67px;
|
width: 52px;
|
||||||
height: 32px;
|
height: 26px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-button {
|
.language-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 6px;
|
padding: 4px;
|
||||||
gap: 8px;
|
gap: 4px;
|
||||||
background: rgba(255, 255, 255, 0.3);
|
background: rgba(255, 255, 255, 0.3);
|
||||||
border: 1px solid #677b78;
|
border: 1px solid #677b78;
|
||||||
border-radius: 12px;
|
border-radius: 8px;
|
||||||
color: #1e3c38;
|
color: #1e3c38;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@
|
|||||||
.language-code {
|
.language-code {
|
||||||
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 24px;
|
font-size: 15px;
|
||||||
color: #1e3c38;
|
color: #1e3c38;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
@@ -190,8 +190,8 @@
|
|||||||
|
|
||||||
.dropdown-arrow {
|
.dropdown-arrow {
|
||||||
display: block;
|
display: block;
|
||||||
width: 9px;
|
width: 7px;
|
||||||
height: 14px;
|
height: 10px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
||||||
path {
|
path {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
<p class="dexar-hero-tagline">просто и удобно</p>
|
<p class="dexar-hero-tagline">просто и удобно</p>
|
||||||
|
|
||||||
<div class="dexar-hero-actions">
|
<div class="dexar-hero-actions">
|
||||||
<a routerLink="/search" class="dexar-btn-primary">
|
<a (click)="scrollToCatalog()" class="dexar-btn-primary">
|
||||||
Перейти в каталог
|
Перейти в каталог
|
||||||
</a>
|
</a>
|
||||||
<button (click)="navigateToSearch()" class="dexar-btn-secondary">
|
<button (click)="navigateToSearch()" class="dexar-btn-secondary">
|
||||||
@@ -115,8 +115,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@if (!loading() && !error()) {
|
@if (!loading() && !error()) {
|
||||||
<section class="dexar-categories">
|
<section class="dexar-categories" id="catalog">
|
||||||
<h2 class="dexar-categories-title">Категории</h2>
|
<h2 class="dexar-categories-title">Каталог товаров</h2>
|
||||||
@if (getTopLevelCategories().length === 0) {
|
@if (getTopLevelCategories().length === 0) {
|
||||||
<div class="dexar-empty-categories">
|
<div class="dexar-empty-categories">
|
||||||
<div class="dexar-empty-icon">📦</div>
|
<div class="dexar-empty-icon">📦</div>
|
||||||
@@ -126,18 +126,19 @@
|
|||||||
} @else {
|
} @else {
|
||||||
<div class="dexar-categories-grid">
|
<div class="dexar-categories-grid">
|
||||||
@for (category of getTopLevelCategories(); track category.categoryID) {
|
@for (category of getTopLevelCategories(); track category.categoryID) {
|
||||||
<div class="dexar-category-card">
|
<a [routerLink]="['/category', category.categoryID]" class="dexar-category-card">
|
||||||
<a [routerLink]="['/category', category.categoryID]" class="dexar-category-link">
|
<div class="dexar-category-image">
|
||||||
<div class="dexar-category-media">
|
@if (category.icon) {
|
||||||
@if (category.icon) {
|
<img [src]="category.icon" [alt]="category.name" loading="lazy" decoding="async" />
|
||||||
<img [src]="category.icon" [alt]="category.name" loading="lazy" decoding="async" />
|
} @else {
|
||||||
} @else {
|
<div class="dexar-category-fallback">{{ category.name.charAt(0) }}</div>
|
||||||
<div class="dexar-category-fallback">{{ category.name }}</div>
|
}
|
||||||
}
|
</div>
|
||||||
</div>
|
<div class="dexar-category-info">
|
||||||
<h3>{{ category.name }}</h3>
|
<h3 class="dexar-category-name">{{ category.name }}</h3>
|
||||||
</a>
|
<p class="dexar-category-count">{{ getItemCount(category.categoryID) }} товаров</p>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -705,6 +705,7 @@
|
|||||||
// ========== DEXAR REDESIGN 2026 STYLES ==========
|
// ========== DEXAR REDESIGN 2026 STYLES ==========
|
||||||
.dexar-home {
|
.dexar-home {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hero Section
|
// Hero Section
|
||||||
@@ -908,7 +909,7 @@
|
|||||||
|
|
||||||
// Categories Section
|
// Categories Section
|
||||||
.dexar-categories {
|
.dexar-categories {
|
||||||
max-width: 1200px;
|
max-width: 1440px;
|
||||||
margin: 50px auto;
|
margin: 50px auto;
|
||||||
padding: 0 56px;
|
padding: 0 56px;
|
||||||
}
|
}
|
||||||
@@ -950,74 +951,44 @@
|
|||||||
|
|
||||||
.dexar-categories-grid {
|
.dexar-categories-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
grid-template-columns: repeat(4, 1fr);
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
animation: fadeIn 0.6s ease-in 0.3s both;
|
animation: fadeIn 0.6s ease-in 0.3s both;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-category-card {
|
.dexar-category-card {
|
||||||
background: white;
|
width: 100%;
|
||||||
border-radius: 16px;
|
|
||||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
|
||||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
text-decoration: none;
|
||||||
position: relative;
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 4px;
|
|
||||||
background: linear-gradient(90deg, #497671 0%, #a7ceca 100%);
|
|
||||||
transform: scaleX(0);
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateY(-8px);
|
transform: translateY(-4px);
|
||||||
box-shadow: 0 12px 32px rgba(73, 118, 113, 0.2);
|
|
||||||
|
|
||||||
&::before {
|
.dexar-category-image {
|
||||||
transform: scaleX(1);
|
box-shadow: 0 6px 8px 0 rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-category-info {
|
||||||
|
box-shadow: 0 6px 8px 0 rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-category-link {
|
.dexar-category-image {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
|
||||||
padding: 20px;
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.3rem;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #1e3c38;
|
|
||||||
margin: 16px 0 0 0;
|
|
||||||
transition: color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover h3 {
|
|
||||||
color: #497671;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dexar-category-media {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 200px;
|
aspect-ratio: 4 / 3;
|
||||||
background: #f5f5f5;
|
border: 1px solid #d3dad9;
|
||||||
border-radius: 12px;
|
border-radius: 13px 13px 0 0;
|
||||||
|
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.15);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
background: #f5f5f5;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -1037,12 +1008,51 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 3rem;
|
font-size: 5rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #497671;
|
color: #497671;
|
||||||
background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%);
|
background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dexar-category-info {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #d3dad9;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 0 0 13px 13px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
background: #f5f3f9;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 2px;
|
||||||
|
transition: background 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-category-name {
|
||||||
|
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: clamp(14px, 1.4vw, 18px);
|
||||||
|
color: #1e3c38;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.3;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
min-height: calc(2 * 1.3em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-category-count {
|
||||||
|
font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: clamp(11px, 1vw, 13px);
|
||||||
|
color: #697777;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
// Responsive Design
|
// Responsive Design
|
||||||
@media (max-width: 1200px) {
|
@media (max-width: 1200px) {
|
||||||
.dexar-hero {
|
.dexar-hero {
|
||||||
@@ -1065,6 +1075,11 @@
|
|||||||
.dexar-categories {
|
.dexar-categories {
|
||||||
padding: 0 40px;
|
padding: 0 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dexar-categories-grid {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 992px) {
|
@media (max-width: 992px) {
|
||||||
@@ -1102,8 +1117,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dexar-categories-grid {
|
.dexar-categories-grid {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 24px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1156,12 +1171,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dexar-categories-grid {
|
.dexar-categories-grid {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
grid-template-columns: repeat(2, 1fr);
|
||||||
gap: 20px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-category-media {
|
.dexar-category-info {
|
||||||
height: 160px;
|
padding: 10px 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1189,12 +1204,20 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dexar-categories {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.dexar-categories-grid {
|
.dexar-categories-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: repeat(2, 1fr);
|
||||||
gap: 16px;
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dexar-category-info {
|
||||||
|
padding: 8px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dexar-category-card:hover {
|
.dexar-category-card:hover {
|
||||||
transform: translateY(-4px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Component, OnInit, signal, computed, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, OnInit, signal, computed, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { Router, RouterLink } from '@angular/router';
|
import { Router, RouterLink } from '@angular/router';
|
||||||
|
import { forkJoin } from 'rxjs';
|
||||||
import { ApiService } from '../../services';
|
import { ApiService } from '../../services';
|
||||||
import { Category } from '../../models';
|
import { Category } from '../../models';
|
||||||
import { environment } from '../../../environments/environment';
|
import { environment } from '../../../environments/environment';
|
||||||
@@ -18,6 +19,7 @@ export class HomeComponent implements OnInit {
|
|||||||
brandName = environment.brandFullName;
|
brandName = environment.brandFullName;
|
||||||
isnovo = environment.theme === 'novo';
|
isnovo = environment.theme === 'novo';
|
||||||
categories = signal<Category[]>([]);
|
categories = signal<Category[]>([]);
|
||||||
|
itemCounts = signal<Map<number, number>>(new Map());
|
||||||
loading = signal(true);
|
loading = signal(true);
|
||||||
error = signal<string | null>(null);
|
error = signal<string | null>(null);
|
||||||
|
|
||||||
@@ -52,6 +54,7 @@ export class HomeComponent implements OnInit {
|
|||||||
next: (categories) => {
|
next: (categories) => {
|
||||||
this.categories.set(categories);
|
this.categories.set(categories);
|
||||||
this.loading.set(false);
|
this.loading.set(false);
|
||||||
|
this.loadItemCounts();
|
||||||
},
|
},
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
this.error.set('Failed to load categories');
|
this.error.set('Failed to load categories');
|
||||||
@@ -61,6 +64,31 @@ export class HomeComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadItemCounts(): void {
|
||||||
|
const topLevel = this.topLevelCategories();
|
||||||
|
if (topLevel.length === 0) return;
|
||||||
|
|
||||||
|
const requests: Record<string, ReturnType<ApiService['getCategoryItems']>> = {};
|
||||||
|
topLevel.forEach(cat => {
|
||||||
|
requests[cat.categoryID.toString()] = this.apiService.getCategoryItems(cat.categoryID, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
forkJoin(requests).subscribe({
|
||||||
|
next: (results) => {
|
||||||
|
const counts = new Map<number, number>();
|
||||||
|
Object.entries(results).forEach(([id, items]) => {
|
||||||
|
counts.set(Number(id), items.length);
|
||||||
|
});
|
||||||
|
this.itemCounts.set(counts);
|
||||||
|
},
|
||||||
|
error: (err) => console.error('Error loading item counts:', err)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getItemCount(categoryID: number): number {
|
||||||
|
return this.itemCounts().get(categoryID) || 0;
|
||||||
|
}
|
||||||
|
|
||||||
getTopLevelCategories(): Category[] {
|
getTopLevelCategories(): Category[] {
|
||||||
return this.topLevelCategories();
|
return this.topLevelCategories();
|
||||||
}
|
}
|
||||||
@@ -72,4 +100,28 @@ export class HomeComponent implements OnInit {
|
|||||||
navigateToSearch(): void {
|
navigateToSearch(): void {
|
||||||
this.router.navigate(['/search']);
|
this.router.navigate(['/search']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrollToCatalog(): void {
|
||||||
|
const target = document.getElementById('catalog');
|
||||||
|
if (!target) return;
|
||||||
|
|
||||||
|
const targetY = target.getBoundingClientRect().top + window.scrollY;
|
||||||
|
const startY = window.scrollY;
|
||||||
|
const distance = targetY - startY;
|
||||||
|
const duration = 1200;
|
||||||
|
let start: number | null = null;
|
||||||
|
|
||||||
|
const easeInOutCubic = (t: number) =>
|
||||||
|
t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
||||||
|
|
||||||
|
const step = (timestamp: number) => {
|
||||||
|
if (!start) start = timestamp;
|
||||||
|
const elapsed = timestamp - start;
|
||||||
|
const progress = Math.min(elapsed / duration, 1);
|
||||||
|
window.scrollTo(0, startY + distance * easeInOutCubic(progress));
|
||||||
|
if (progress < 1) requestAnimationFrame(step);
|
||||||
|
};
|
||||||
|
|
||||||
|
requestAnimationFrame(step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ body {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
background: linear-gradient(to bottom, #f8f9fa 0%, #e9ecef 100%);
|
background: linear-gradient(to bottom, #f8f9fa 0%, #e9ecef 100%);
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smooth Transitions */
|
/* Smooth Transitions */
|
||||||
|
|||||||
Reference in New Issue
Block a user