From 58b5a4e9962cbbc709a190cc17720614a0ba2bc4 Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Sun, 5 Jul 2026 00:38:21 +0400 Subject: [PATCH] clean up stage 1 --- README.md | 6 +- angular.json | 142 +-- docs/API_CHANGES_REQUIRED.md | 726 --------------- docs/API_DOCS_RU.md | 726 --------------- docs/BACKEND_AUTH_INTEGRATION.md | 824 ------------------ docs/DEPLOYMENT.md | 156 ---- docs/IMPLEMENTATION.md | 140 --- docs/MULTI_BRAND.md | 146 ---- docs/PWA_SETUP.md | 206 ----- docs/RAIFFEISENBANK_REQUIREMENTS.md | 181 ---- docs/RECOMMENDATIONS.md | 423 --------- docs/TELEGRAM_USERAUTH_BACKEND.md | 327 ------- docs/TROUBLESHOOTING.md | 193 ---- docs/telegram-login-dialog.html | 551 ------------ package.json | 6 - src/app/app.ts | 7 +- .../pages/info/about/about.component.html | 5 - .../pages/info/about/about.component.ts | 16 - .../info/about/en/about-en.component.html | 98 --- .../pages/info/about/en/about-en.component.ts | 12 - .../info/about/hy/about-hy.component.html | 98 --- .../pages/info/about/hy/about-hy.component.ts | 12 - .../info/about/ru/about-ru.component.html | 98 --- .../pages/info/about/ru/about-ru.component.ts | 12 - .../info/contacts/contacts.component.html | 5 - .../pages/info/contacts/contacts.component.ts | 16 - .../contacts/en/contacts-en.component.html | 49 -- .../info/contacts/en/contacts-en.component.ts | 12 - .../contacts/hy/contacts-hy.component.html | 49 -- .../info/contacts/hy/contacts-hy.component.ts | 12 - .../contacts/ru/contacts-ru.component.html | 49 -- .../info/contacts/ru/contacts-ru.component.ts | 12 - .../info/delivery/delivery.component.html | 5 - .../pages/info/delivery/delivery.component.ts | 16 - .../delivery/en/delivery-en.component.html | 78 -- .../info/delivery/en/delivery-en.component.ts | 12 - .../delivery/hy/delivery-hy.component.html | 78 -- .../info/delivery/hy/delivery-hy.component.ts | 12 - .../delivery/ru/delivery-ru.component.html | 78 -- .../info/delivery/ru/delivery-ru.component.ts | 12 - .../pages/info/faq/en/faq-en.component.html | 93 -- .../pages/info/faq/en/faq-en.component.ts | 12 - .../lavero/pages/info/faq/faq.component.html | 5 - .../lavero/pages/info/faq/faq.component.ts | 16 - .../pages/info/faq/hy/faq-hy.component.html | 93 -- .../pages/info/faq/hy/faq-hy.component.ts | 12 - .../pages/info/faq/ru/faq-ru.component.html | 93 -- .../pages/info/faq/ru/faq-ru.component.ts | 12 - .../guarantee/en/guarantee-en.component.html | 92 -- .../guarantee/en/guarantee-en.component.ts | 12 - .../info/guarantee/guarantee.component.html | 5 - .../info/guarantee/guarantee.component.ts | 16 - .../guarantee/hy/guarantee-hy.component.html | 92 -- .../guarantee/hy/guarantee-hy.component.ts | 12 - .../guarantee/ru/guarantee-ru.component.html | 92 -- .../guarantee/ru/guarantee-ru.component.ts | 12 - .../company-details.component.html | 5 - .../company-details.component.ts | 16 - .../en/company-details-en.component.html | 54 -- .../en/company-details-en.component.ts | 12 - .../hy/company-details-hy.component.html | 54 -- .../hy/company-details-hy.component.ts | 12 - .../ru/company-details-ru.component.html | 54 -- .../ru/company-details-ru.component.ts | 12 - .../en/payment-terms-en.component.html | 162 ---- .../en/payment-terms-en.component.ts | 15 - .../hy/payment-terms-hy.component.html | 162 ---- .../hy/payment-terms-hy.component.ts | 15 - .../payment-terms.component.html | 5 - .../payment-terms/payment-terms.component.ts | 16 - .../ru/payment-terms-ru.component.html | 162 ---- .../ru/payment-terms-ru.component.ts | 15 - .../en/privacy-policy-en.component.html | 277 ------ .../en/privacy-policy-en.component.ts | 12 - .../hy/privacy-policy-hy.component.html | 8 - .../hy/privacy-policy-hy.component.ts | 12 - .../privacy-policy.component.html | 5 - .../privacy-policy.component.ts | 16 - .../ru/privacy-policy-ru.component.html | 277 ------ .../ru/privacy-policy-ru.component.ts | 12 - .../en/public-offer-en.component.html | 275 ------ .../en/public-offer-en.component.ts | 15 - .../hy/public-offer-hy.component.html | 275 ------ .../hy/public-offer-hy.component.ts | 15 - .../public-offer/public-offer.component.html | 5 - .../public-offer/public-offer.component.ts | 16 - .../ru/public-offer-ru.component.html | 275 ------ .../ru/public-offer-ru.component.ts | 15 - .../en/return-policy-en.component.html | 175 ---- .../en/return-policy-en.component.ts | 12 - .../hy/return-policy-hy.component.html | 175 ---- .../hy/return-policy-hy.component.ts | 12 - .../return-policy.component.html | 5 - .../return-policy/return-policy.component.ts | 16 - .../ru/return-policy-ru.component.html | 175 ---- .../ru/return-policy-ru.component.ts | 12 - .../pages/info/about/about.component.html | 5 - .../novo/pages/info/about/about.component.ts | 16 - .../info/about/en/about-en.component.html | 99 --- .../pages/info/about/en/about-en.component.ts | 12 - .../info/about/hy/about-hy.component.html | 99 --- .../pages/info/about/hy/about-hy.component.ts | 12 - .../info/about/ru/about-ru.component.html | 99 --- .../pages/info/about/ru/about-ru.component.ts | 12 - .../info/contacts/contacts.component.html | 5 - .../pages/info/contacts/contacts.component.ts | 16 - .../contacts/en/contacts-en.component.html | 49 -- .../info/contacts/en/contacts-en.component.ts | 12 - .../contacts/hy/contacts-hy.component.html | 49 -- .../info/contacts/hy/contacts-hy.component.ts | 12 - .../contacts/ru/contacts-ru.component.html | 49 -- .../info/contacts/ru/contacts-ru.component.ts | 12 - .../info/delivery/delivery.component.html | 5 - .../pages/info/delivery/delivery.component.ts | 16 - .../delivery/en/delivery-en.component.html | 78 -- .../info/delivery/en/delivery-en.component.ts | 12 - .../delivery/hy/delivery-hy.component.html | 78 -- .../info/delivery/hy/delivery-hy.component.ts | 12 - .../delivery/ru/delivery-ru.component.html | 78 -- .../info/delivery/ru/delivery-ru.component.ts | 12 - .../pages/info/faq/en/faq-en.component.html | 93 -- .../pages/info/faq/en/faq-en.component.ts | 12 - .../novo/pages/info/faq/faq.component.html | 5 - .../novo/pages/info/faq/faq.component.ts | 16 - .../pages/info/faq/hy/faq-hy.component.html | 93 -- .../pages/info/faq/hy/faq-hy.component.ts | 12 - .../pages/info/faq/ru/faq-ru.component.html | 93 -- .../pages/info/faq/ru/faq-ru.component.ts | 12 - .../guarantee/en/guarantee-en.component.html | 92 -- .../guarantee/en/guarantee-en.component.ts | 12 - .../info/guarantee/guarantee.component.html | 5 - .../info/guarantee/guarantee.component.ts | 16 - .../guarantee/hy/guarantee-hy.component.html | 92 -- .../guarantee/hy/guarantee-hy.component.ts | 12 - .../guarantee/ru/guarantee-ru.component.html | 92 -- .../guarantee/ru/guarantee-ru.component.ts | 12 - .../company-details.component.html | 5 - .../company-details.component.ts | 16 - .../en/company-details-en.component.html | 113 --- .../en/company-details-en.component.ts | 12 - .../hy/company-details-hy.component.html | 113 --- .../hy/company-details-hy.component.ts | 12 - .../ru/company-details-ru.component.html | 113 --- .../ru/company-details-ru.component.ts | 12 - .../en/payment-terms-en.component.html | 162 ---- .../en/payment-terms-en.component.ts | 15 - .../hy/payment-terms-hy.component.html | 162 ---- .../hy/payment-terms-hy.component.ts | 15 - .../payment-terms.component.html | 5 - .../payment-terms/payment-terms.component.ts | 16 - .../ru/payment-terms-ru.component.html | 162 ---- .../ru/payment-terms-ru.component.ts | 15 - .../en/privacy-policy-en.component.html | 277 ------ .../en/privacy-policy-en.component.ts | 12 - .../hy/privacy-policy-hy.component.html | 8 - .../hy/privacy-policy-hy.component.ts | 12 - .../privacy-policy.component.html | 5 - .../privacy-policy.component.ts | 16 - .../ru/privacy-policy-ru.component.html | 277 ------ .../ru/privacy-policy-ru.component.ts | 12 - .../en/public-offer-en.component.html | 269 ------ .../en/public-offer-en.component.ts | 15 - .../hy/public-offer-hy.component.html | 269 ------ .../hy/public-offer-hy.component.ts | 15 - .../public-offer/public-offer.component.html | 5 - .../public-offer/public-offer.component.ts | 16 - .../ru/public-offer-ru.component.html | 269 ------ .../ru/public-offer-ru.component.ts | 15 - .../en/return-policy-en.component.html | 175 ---- .../en/return-policy-en.component.ts | 12 - .../hy/return-policy-hy.component.html | 175 ---- .../hy/return-policy-hy.component.ts | 12 - .../return-policy.component.html | 5 - .../return-policy/return-policy.component.ts | 16 - .../ru/return-policy-ru.component.html | 175 ---- .../ru/return-policy-ru.component.ts | 12 - .../back-button/back-button.component.ts | 6 +- .../components/footer/footer.component.html | 4 +- src/app/components/footer/footer.component.ts | 10 +- .../components/header/header.component.html | 2 +- src/app/components/header/header.component.ts | 6 +- .../items-carousel.component.html | 2 +- .../items-carousel.component.ts | 2 +- src/app/components/logo/logo.component.ts | 2 +- src/app/facades/runtime/ui-runtime.facade.ts | 40 +- src/app/interceptors/mock-data.interceptor.ts | 6 +- src/app/models/category.model.ts | 2 +- src/app/pages/cart/cart.component.html | 2 +- src/app/pages/cart/cart.component.ts | 4 +- src/app/pages/home/home.component.html | 2 +- src/app/pages/home/home.component.ts | 6 +- .../info/about/en/about-en.component.html | 2 +- .../item-detail/item-detail.component.html | 2 +- .../item-detail/item-detail.component.ts | 4 +- src/app/services/api.service.ts | 1 + 195 files changed, 66 insertions(+), 13717 deletions(-) delete mode 100644 docs/API_CHANGES_REQUIRED.md delete mode 100644 docs/API_DOCS_RU.md delete mode 100644 docs/BACKEND_AUTH_INTEGRATION.md delete mode 100644 docs/DEPLOYMENT.md delete mode 100644 docs/IMPLEMENTATION.md delete mode 100644 docs/MULTI_BRAND.md delete mode 100644 docs/PWA_SETUP.md delete mode 100644 docs/RAIFFEISENBANK_REQUIREMENTS.md delete mode 100644 docs/RECOMMENDATIONS.md delete mode 100644 docs/TELEGRAM_USERAUTH_BACKEND.md delete mode 100644 docs/TROUBLESHOOTING.md delete mode 100644 docs/telegram-login-dialog.html delete mode 100644 src/app/brands/lavero/pages/info/about/about.component.html delete mode 100644 src/app/brands/lavero/pages/info/about/about.component.ts delete mode 100644 src/app/brands/lavero/pages/info/about/en/about-en.component.html delete mode 100644 src/app/brands/lavero/pages/info/about/en/about-en.component.ts delete mode 100644 src/app/brands/lavero/pages/info/about/hy/about-hy.component.html delete mode 100644 src/app/brands/lavero/pages/info/about/hy/about-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/info/about/ru/about-ru.component.html delete mode 100644 src/app/brands/lavero/pages/info/about/ru/about-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/info/contacts/contacts.component.html delete mode 100644 src/app/brands/lavero/pages/info/contacts/contacts.component.ts delete mode 100644 src/app/brands/lavero/pages/info/contacts/en/contacts-en.component.html delete mode 100644 src/app/brands/lavero/pages/info/contacts/en/contacts-en.component.ts delete mode 100644 src/app/brands/lavero/pages/info/contacts/hy/contacts-hy.component.html delete mode 100644 src/app/brands/lavero/pages/info/contacts/hy/contacts-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/info/contacts/ru/contacts-ru.component.html delete mode 100644 src/app/brands/lavero/pages/info/contacts/ru/contacts-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/info/delivery/delivery.component.html delete mode 100644 src/app/brands/lavero/pages/info/delivery/delivery.component.ts delete mode 100644 src/app/brands/lavero/pages/info/delivery/en/delivery-en.component.html delete mode 100644 src/app/brands/lavero/pages/info/delivery/en/delivery-en.component.ts delete mode 100644 src/app/brands/lavero/pages/info/delivery/hy/delivery-hy.component.html delete mode 100644 src/app/brands/lavero/pages/info/delivery/hy/delivery-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/info/delivery/ru/delivery-ru.component.html delete mode 100644 src/app/brands/lavero/pages/info/delivery/ru/delivery-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/info/faq/en/faq-en.component.html delete mode 100644 src/app/brands/lavero/pages/info/faq/en/faq-en.component.ts delete mode 100644 src/app/brands/lavero/pages/info/faq/faq.component.html delete mode 100644 src/app/brands/lavero/pages/info/faq/faq.component.ts delete mode 100644 src/app/brands/lavero/pages/info/faq/hy/faq-hy.component.html delete mode 100644 src/app/brands/lavero/pages/info/faq/hy/faq-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/info/faq/ru/faq-ru.component.html delete mode 100644 src/app/brands/lavero/pages/info/faq/ru/faq-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/info/guarantee/en/guarantee-en.component.html delete mode 100644 src/app/brands/lavero/pages/info/guarantee/en/guarantee-en.component.ts delete mode 100644 src/app/brands/lavero/pages/info/guarantee/guarantee.component.html delete mode 100644 src/app/brands/lavero/pages/info/guarantee/guarantee.component.ts delete mode 100644 src/app/brands/lavero/pages/info/guarantee/hy/guarantee-hy.component.html delete mode 100644 src/app/brands/lavero/pages/info/guarantee/hy/guarantee-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/info/guarantee/ru/guarantee-ru.component.html delete mode 100644 src/app/brands/lavero/pages/info/guarantee/ru/guarantee-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/company-details/company-details.component.html delete mode 100644 src/app/brands/lavero/pages/legal/company-details/company-details.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/company-details/en/company-details-en.component.html delete mode 100644 src/app/brands/lavero/pages/legal/company-details/en/company-details-en.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/company-details/hy/company-details-hy.component.html delete mode 100644 src/app/brands/lavero/pages/legal/company-details/hy/company-details-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/company-details/ru/company-details-ru.component.html delete mode 100644 src/app/brands/lavero/pages/legal/company-details/ru/company-details-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/payment-terms/en/payment-terms-en.component.html delete mode 100644 src/app/brands/lavero/pages/legal/payment-terms/en/payment-terms-en.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/payment-terms/hy/payment-terms-hy.component.html delete mode 100644 src/app/brands/lavero/pages/legal/payment-terms/hy/payment-terms-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/payment-terms/payment-terms.component.html delete mode 100644 src/app/brands/lavero/pages/legal/payment-terms/payment-terms.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/payment-terms/ru/payment-terms-ru.component.html delete mode 100644 src/app/brands/lavero/pages/legal/payment-terms/ru/payment-terms-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/privacy-policy/en/privacy-policy-en.component.html delete mode 100644 src/app/brands/lavero/pages/legal/privacy-policy/en/privacy-policy-en.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html delete mode 100644 src/app/brands/lavero/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/privacy-policy/privacy-policy.component.html delete mode 100644 src/app/brands/lavero/pages/legal/privacy-policy/privacy-policy.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html delete mode 100644 src/app/brands/lavero/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/public-offer/en/public-offer-en.component.html delete mode 100644 src/app/brands/lavero/pages/legal/public-offer/en/public-offer-en.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/public-offer/hy/public-offer-hy.component.html delete mode 100644 src/app/brands/lavero/pages/legal/public-offer/hy/public-offer-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/public-offer/public-offer.component.html delete mode 100644 src/app/brands/lavero/pages/legal/public-offer/public-offer.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/public-offer/ru/public-offer-ru.component.html delete mode 100644 src/app/brands/lavero/pages/legal/public-offer/ru/public-offer-ru.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/return-policy/en/return-policy-en.component.html delete mode 100644 src/app/brands/lavero/pages/legal/return-policy/en/return-policy-en.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/return-policy/hy/return-policy-hy.component.html delete mode 100644 src/app/brands/lavero/pages/legal/return-policy/hy/return-policy-hy.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/return-policy/return-policy.component.html delete mode 100644 src/app/brands/lavero/pages/legal/return-policy/return-policy.component.ts delete mode 100644 src/app/brands/lavero/pages/legal/return-policy/ru/return-policy-ru.component.html delete mode 100644 src/app/brands/lavero/pages/legal/return-policy/ru/return-policy-ru.component.ts delete mode 100644 src/app/brands/novo/pages/info/about/about.component.html delete mode 100644 src/app/brands/novo/pages/info/about/about.component.ts delete mode 100644 src/app/brands/novo/pages/info/about/en/about-en.component.html delete mode 100644 src/app/brands/novo/pages/info/about/en/about-en.component.ts delete mode 100644 src/app/brands/novo/pages/info/about/hy/about-hy.component.html delete mode 100644 src/app/brands/novo/pages/info/about/hy/about-hy.component.ts delete mode 100644 src/app/brands/novo/pages/info/about/ru/about-ru.component.html delete mode 100644 src/app/brands/novo/pages/info/about/ru/about-ru.component.ts delete mode 100644 src/app/brands/novo/pages/info/contacts/contacts.component.html delete mode 100644 src/app/brands/novo/pages/info/contacts/contacts.component.ts delete mode 100644 src/app/brands/novo/pages/info/contacts/en/contacts-en.component.html delete mode 100644 src/app/brands/novo/pages/info/contacts/en/contacts-en.component.ts delete mode 100644 src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.html delete mode 100644 src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.ts delete mode 100644 src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.html delete mode 100644 src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.ts delete mode 100644 src/app/brands/novo/pages/info/delivery/delivery.component.html delete mode 100644 src/app/brands/novo/pages/info/delivery/delivery.component.ts delete mode 100644 src/app/brands/novo/pages/info/delivery/en/delivery-en.component.html delete mode 100644 src/app/brands/novo/pages/info/delivery/en/delivery-en.component.ts delete mode 100644 src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.html delete mode 100644 src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.ts delete mode 100644 src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.html delete mode 100644 src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.ts delete mode 100644 src/app/brands/novo/pages/info/faq/en/faq-en.component.html delete mode 100644 src/app/brands/novo/pages/info/faq/en/faq-en.component.ts delete mode 100644 src/app/brands/novo/pages/info/faq/faq.component.html delete mode 100644 src/app/brands/novo/pages/info/faq/faq.component.ts delete mode 100644 src/app/brands/novo/pages/info/faq/hy/faq-hy.component.html delete mode 100644 src/app/brands/novo/pages/info/faq/hy/faq-hy.component.ts delete mode 100644 src/app/brands/novo/pages/info/faq/ru/faq-ru.component.html delete mode 100644 src/app/brands/novo/pages/info/faq/ru/faq-ru.component.ts delete mode 100644 src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.html delete mode 100644 src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.ts delete mode 100644 src/app/brands/novo/pages/info/guarantee/guarantee.component.html delete mode 100644 src/app/brands/novo/pages/info/guarantee/guarantee.component.ts delete mode 100644 src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.html delete mode 100644 src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.ts delete mode 100644 src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.html delete mode 100644 src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.ts delete mode 100644 src/app/brands/novo/pages/legal/company-details/company-details.component.html delete mode 100644 src/app/brands/novo/pages/legal/company-details/company-details.component.ts delete mode 100644 src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.html delete mode 100644 src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.ts delete mode 100644 src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.html delete mode 100644 src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.ts delete mode 100644 src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.html delete mode 100644 src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.ts delete mode 100644 src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.html delete mode 100644 src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.ts delete mode 100644 src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.html delete mode 100644 src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.ts delete mode 100644 src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.html delete mode 100644 src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.ts delete mode 100644 src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.html delete mode 100644 src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.ts delete mode 100644 src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.html delete mode 100644 src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.ts delete mode 100644 src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html delete mode 100644 src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts delete mode 100644 src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.html delete mode 100644 src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.ts delete mode 100644 src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html delete mode 100644 src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts delete mode 100644 src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.html delete mode 100644 src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.ts delete mode 100644 src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.html delete mode 100644 src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.ts delete mode 100644 src/app/brands/novo/pages/legal/public-offer/public-offer.component.html delete mode 100644 src/app/brands/novo/pages/legal/public-offer/public-offer.component.ts delete mode 100644 src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.html delete mode 100644 src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.ts delete mode 100644 src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.html delete mode 100644 src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.ts delete mode 100644 src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.html delete mode 100644 src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.ts delete mode 100644 src/app/brands/novo/pages/legal/return-policy/return-policy.component.html delete mode 100644 src/app/brands/novo/pages/legal/return-policy/return-policy.component.ts delete mode 100644 src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.html delete mode 100644 src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.ts diff --git a/README.md b/README.md index 35fa888..4ca0141 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A modern, responsive marketplace application built with Angular 20 that supports ## 🎨 Multi-Brand Support -This project supports **two brands** with the same codebase: +This marketplace supports **two brands** with the same codebase: - **Dexar Market** - Purple theme (`http://localhost:4200`) - **Novo Market** - Green theme (`http://localhost:4201`) @@ -72,7 +72,7 @@ npm run build:novo ``` Output: `dist/novomarket/` -## Project Structure +## Marketplace Structure ``` src/ @@ -247,7 +247,7 @@ sudo certbot --nginx -d novomarket.ru -d www.novomarket.ru ### Deploy Steps -1. Build the project: +1. Build the marketplace: ```bash npm run build:dexar npm run build:novo diff --git a/angular.json b/angular.json index 249cf74..fb3c9a8 100644 --- a/angular.json +++ b/angular.json @@ -86,130 +86,6 @@ "optimization": false, "extractLicenses": false, "sourceMap": true - }, - "novo": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.novo.ts" - }, - { - "replace": "src/app/interceptors/mock-data.interceptor.ts", - "with": "src/app/interceptors/mock-data.interceptor.production.ts" - } - ], - "index": "src/index.novo.html", - "styles": [ - "src/styles.scss", - "src/styles/themes/novo.theme.scss" - ], - "outputPath": "dist/novomarket", - "optimization": false, - "extractLicenses": false, - "sourceMap": true - }, - "novo-production": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.novo.production.ts" - } - ], - "index": "src/index.novo.html", - "styles": [ - "src/styles.scss", - "src/styles/themes/novo.theme.scss" - ], - "outputPath": "dist/novomarket", - "budgets": [ - { - "type": "initial", - "maximumWarning": "600kB", - "maximumError": "1MB" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "40kB", - "maximumError": "50kB" - } - ], - "outputHashing": "all", - "optimization": { - "scripts": true, - "styles": { - "minify": true, - "inlineCritical": true - }, - "fonts": { - "inline": true - } - }, - "sourceMap": false, - "namedChunks": false, - "extractLicenses": true, - "serviceWorker": "ngsw-config.json" - }, - "lavero": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.lavero.ts" - }, - { - "replace": "src/app/interceptors/mock-data.interceptor.ts", - "with": "src/app/interceptors/mock-data.interceptor.production.ts" - } - ], - "index": "src/index.lavero.html", - "styles": [ - "src/styles.scss", - "src/styles/themes/lavero.theme.scss" - ], - "outputPath": "dist/laveromarket", - "optimization": false, - "extractLicenses": false, - "sourceMap": true - }, - "lavero-production": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.lavero.production.ts" - } - ], - "index": "src/index.lavero.html", - "styles": [ - "src/styles.scss", - "src/styles/themes/lavero.theme.scss" - ], - "outputPath": "dist/laveromarket", - "budgets": [ - { - "type": "initial", - "maximumWarning": "600kB", - "maximumError": "1MB" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "40kB", - "maximumError": "50kB" - } - ], - "outputHashing": "all", - "optimization": { - "scripts": true, - "styles": { - "minify": true, - "inlineCritical": true - }, - "fonts": { - "inline": true - } - }, - "sourceMap": false, - "namedChunks": false, - "extractLicenses": true, - "serviceWorker": "ngsw-config.json" } }, "defaultConfiguration": "production" @@ -217,11 +93,9 @@ "serve": { "options": { "allowedHosts": [ - "novo.market", "dexarmarket.ru", "dexar.market", - "localhost", - "lovero.store" + "localhost" ], "proxyConfig": "proxy.conf.json" }, @@ -232,20 +106,6 @@ }, "development": { "buildTarget": "Dexarmarket:build:development" - }, - "novo": { - "buildTarget": "Dexarmarket:build:novo", - "proxyConfig": "proxy.conf.novo.json" - }, - "novo-production": { - "buildTarget": "Dexarmarket:build:novo-production" - }, - "lavero": { - "buildTarget": "Dexarmarket:build:lavero", - "proxyConfig": "proxy.conf.lavero.json" - }, - "lavero-production": { - "buildTarget": "Dexarmarket:build:lavero-production" } }, "defaultConfiguration": "development" diff --git a/docs/API_CHANGES_REQUIRED.md b/docs/API_CHANGES_REQUIRED.md deleted file mode 100644 index 22dc479..0000000 --- a/docs/API_CHANGES_REQUIRED.md +++ /dev/null @@ -1,726 +0,0 @@ -# Complete Backend API Documentation - -> **Last updated:** February 2026 -> **Frontend:** Angular 21 · Dual-brand (Dexar + Novo) -> **Covers:** Catalog, Cart, Payments, Reviews, Regions, Auth, i18n, BackOffice - ---- - -## Base URLs - -| Brand | Dev | Production | -|--------|----------------------------------|----------------------------------| -| Dexar | `https://api.dexarmarket.ru:445` | `https://api.dexarmarket.ru:445` | -| Novo | `https://api.novo.market:444` | `https://api.novo.market:444` | - ---- - -## Global HTTP Headers - -The frontend **automatically attaches** two custom headers to **every API request** via an interceptor. The backend should read these headers and use them to filter/translate responses accordingly. - -| Header | Example Value | Description | -|---------------|---------------|------------------------------------------------------------| -| `X-Region` | `moscow` | Region ID selected by the user. **Absent** = global (all). | -| `X-Language` | `ru` | Active UI language: `ru`, `en`, or `hy`. | - -### Backend behavior - -- **`X-Region`**: If present, filter items/categories to only those available in that region. If absent, return everything (global catalog). -- **`X-Language`**: If present, return translated `name`, `description`, etc. for categories/items when translations exist. If absent or `ru`, use russians defaults. - -### CORS requirements for these headers - -``` -Access-Control-Allow-Headers: Content-Type, X-Region, X-Language -``` - ---- - -## 1. Health Check - -### `GET /ping` - -Simple health check. - -**Response `200`:** -```json -{ "message": "pong" } -``` - ---- - -## 2. Catalog — Categories - -### `GET /category` - -Returns all top-level categories. Respects `X-Region` and `X-Language` headers. - -**Response `200`:** -```json -[ - { - "categoryID": 1, - "name": "Электроника", - "parentID": 0, - "icon": "https://...", - "wideBanner": "https://...", - "itemCount": 42, - "priority": 10, - - "id": "cat_abc123", - "visible": true, - "img": "https://...", - "projectId": "proj_xyz", - "subcategories": [ - { - "id": "sub_001", - "name": "Смартфоны", - "visible": true, - "priority": 5, - "img": "https://...", - "categoryId": "cat_abc123", - "parentId": "cat_abc123", - "itemCount": 20, - "hasItems": true, - "subcategories": [] - } - ] - } -] -``` - -**Category object:** - -| Field | Type | Required | Description | -|------------------|---------------|----------|----------------------------------------------------| -| `categoryID` | number | yes | Legacy numeric ID | -| `name` | string | yes | Category display name (translated if `X-Language`) | -| `parentID` | number | yes | Parent category ID (`0` = top-level) | -| `icon` | string | no | Category icon URL | -| `wideBanner` | string | no | Wide banner image URL | -| `itemCount` | number | no | Number of items in category | -| `priority` | number | no | Sort priority (higher = first) | -| `id` | string | no | BackOffice string ID | -| `visible` | boolean | no | Whether category is shown (`true` default) | -| `img` | string | no | BackOffice image URL (maps to `icon`) | -| `projectId` | string | no | BackOffice project reference | -| `subcategories` | Subcategory[] | no | Nested subcategories | - -**Subcategory object:** - -| Field | Type | Required | Description | -|------------------|---------------|----------|------------------------------------| -| `id` | string | yes | Subcategory ID | -| `name` | string | yes | Display name | -| `visible` | boolean | no | Whether visible | -| `priority` | number | no | Sort priority | -| `img` | string | no | Image URL | -| `categoryId` | string | yes | Parent category ID | -| `parentId` | string | yes | Direct parent ID | -| `itemCount` | number | no | Number of items | -| `hasItems` | boolean | no | Whether has any items | -| `subcategories` | Subcategory[] | no | Nested children | - ---- - -### `GET /category/:categoryID` - -Returns items in a specific category. Respects `X-Region` and `X-Language` headers. - -**Query params:** - -| Param | Type | Default | Description | -|----------|--------|---------|--------------------| -| `count` | number | `50` | Items per page | -| `skip` | number | `0` | Offset for paging | - -**Response `200`:** Array of [Item](#item-object) objects. - ---- - -## 3. Items - -### `GET /item/:itemID` - -Returns a single item. Respects `X-Region` and `X-Language` headers. - -**Response `200`:** A single [Item](#item-object) object. - ---- - -### `GET /searchitems` - -Full-text search across items. Respects `X-Region` and `X-Language` headers. - -**Query params:** - -| Param | Type | Default | Description | -|----------|--------|---------|----------------------| -| `search` | string | — | Search query (required) | -| `count` | number | `50` | Items per page | -| `skip` | number | `0` | Offset for paging | - -**Response `200`:** -```json -{ - "items": [ /* Item objects */ ], - "total": 128, - "count": 50, - "skip": 0 -} -``` - ---- - -### `GET /randomitems` - -Returns random items for carousel/recommendations. Respects `X-Region` and `X-Language` headers. - -**Query params:** - -| Param | Type | Default | Description | -|------------|--------|---------|------------------------------------| -| `count` | number | `5` | Number of items to return | -| `category` | number | — | Optional: limit to this category | - -**Response `200`:** Array of [Item](#item-object) objects. - ---- - -### Item Object - -The backend can return items in **either** legacy format or BackOffice format. The frontend normalizes both. - -```json -{ - "categoryID": 1, - "itemID": 123, - "name": "iPhone 15 Pro", - "photos": [{ "url": "https://..." }], - "description": "Описание товара", - "currency": "RUB", - "price": 89990, - "discount": 10, - "remainings": "high", - "rating": 4.5, - "callbacks": [ - { - "rating": 5, - "content": "Отличный товар!", - "userID": "user_123", - "timestamp": "2026-02-01T12:00:00Z" - } - ], - "questions": [ - { - "question": "Есть ли гарантия?", - "answer": "Да, 12 месяцев", - "upvotes": 5, - "downvotes": 0 - } - ], - - "id": "item_abc123", - "visible": true, - "priority": 10, - "imgs": ["https://img1.jpg", "https://img2.jpg"], - "tags": ["new", "popular"], - "badges": ["bestseller", "sale"], - "simpleDescription": "Краткое описание", - "descriptionFields": [ - { "key": "Процессор", "value": "A17 Pro" }, - { "key": "Память", "value": "256 GB" } - ], - "subcategoryId": "sub_001", - "translations": { - "en": { - "name": "iPhone 15 Pro", - "simpleDescription": "Short description", - "description": [ - { "key": "Processor", "value": "A17 Pro" } - ] - }, - "hy": { - "name": "iPhone 15 Pro", - "simpleDescription": "Կարcheck check check" - } - }, - "comments": [ - { - "id": "cmt_001", - "text": "Отличный товар!", - "author": "user_123", - "stars": 5, - "createdAt": "2026-02-01T12:00:00Z" - } - ], - "quantity": 50 -} -``` - -**Full Item fields:** - -| Field | Type | Required | Description | -|---------------------|-------------------|----------|------------------------------------------------------------| -| `categoryID` | number | yes | Category this item belongs to | -| `itemID` | number | yes | Legacy numeric item ID | -| `name` | string | yes | Item display name | -| `photos` | Photo[] | no | Legacy photo array `[{ url }]` | -| `description` | string | yes | Text description | -| `currency` | string | yes | Currency code (default: `RUB`) | -| `price` | number | yes | Price in the currency's smallest display unit | -| `discount` | number | yes | Discount percentage (`0`–`100`) | -| `remainings` | string | no | Stock level: `high`, `medium`, `low`, `out` | -| `rating` | number | yes | Average rating (`0`–`5`) | -| `callbacks` | Review[] | no | Legacy reviews (alias for reviews) | -| `questions` | Question[] | no | Q&A entries | -| `id` | string | no | BackOffice string ID | -| `visible` | boolean | no | Whether item is visible (`true` default) | -| `priority` | number | no | Sort priority (higher = first) | -| `imgs` | string[] | no | BackOffice image URLs (maps to `photos`) | -| `tags` | string[] | no | Item tags for filtering | -| `badges` | string[] | no | Display badges (`bestseller`, `sale`, etc.) | -| `simpleDescription` | string | no | Short plain-text description | -| `descriptionFields` | DescriptionField[]| no | Structured `[{ key, value }]` descriptions | -| `subcategoryId` | string | no | BackOffice subcategory reference | -| `translations` | Record | no | Translations keyed by lang code (see below) | -| `comments` | Comment[] | no | BackOffice comments format | -| `quantity` | number | no | Numeric stock count (maps to `remainings` on frontend) | - -**Nested types:** - -| Type | Fields | -|--------------------|-----------------------------------------------------------------| -| `Photo` | `url: string`, `photo?: string`, `video?: string`, `type?: string` | -| `DescriptionField` | `key: string`, `value: string` | -| `Comment` | `id?: string`, `text: string`, `author?: string`, `stars?: number`, `createdAt?: string` | -| `Review` | `rating?: number`, `content?: string`, `userID?: string`, `answer?: string`, `timestamp?: string` | -| `Question` | `question: string`, `answer: string`, `upvotes: number`, `downvotes: number` | -| `ItemTranslation` | `name?: string`, `simpleDescription?: string`, `description?: DescriptionField[]` | - ---- - -## 4. Cart - -### `POST /cart` — Add item to cart - -**Request body:** -```json -{ "itemID": 123, "quantity": 1 } -``` - -**Response `200`:** -```json -{ "message": "Added to cart" } -``` - ---- - -### `PATCH /cart` — Update item quantity - -**Request body:** -```json -{ "itemID": 123, "quantity": 3 } -``` - -**Response `200`:** -```json -{ "message": "Updated" } -``` - ---- - -### `DELETE /cart` — Remove items from cart - -**Request body:** Array of item IDs -```json -[123, 456] -``` - -**Response `200`:** -```json -{ "message": "Removed" } -``` - ---- - -### `GET /cart` — Get cart contents - -**Response `200`:** Array of [Item](#item-object) objects (each with `quantity` field). - ---- - -## 5. Payments (SBP / QR) - -### `POST /cart` — Create payment (SBP QR) - -> Note: Same endpoint as add-to-cart but with different body schema. - -**Request body:** -```json -{ - "amount": 89990, - "currency": "RUB", - "siteuserID": "tg_123456789", - "siteorderID": "order_abc123", - "redirectUrl": "", - "telegramUsername": "john_doe", - "items": [ - { "itemID": 123, "price": 89990, "name": "iPhone 15 Pro" } - ] -} -``` - -**Response `200`:** -```json -{ - "qrId": "qr_abc123", - "qrStatus": "CREATED", - "qrExpirationDate": "2026-02-28T13:00:00Z", - "payload": "https://qr.nspk.ru/...", - "qrUrl": "https://qr.nspk.ru/..." -} -``` - ---- - -### `GET /qr/payment/:qrId` — Check payment status - -**Response `200`:** -```json -{ - "additionalInfo": "", - "paymentPurpose": "Order #order_abc123", - "amount": 89990, - "code": "SUCCESS", - "createDate": "2026-02-28T12:00:00Z", - "currency": "RUB", - "order": "order_abc123", - "paymentStatus": "COMPLETED", - "qrId": "qr_abc123", - "transactionDate": "2026-02-28T12:01:00Z", - "transactionId": 999, - "qrExpirationDate": "2026-02-28T13:00:00Z", - "phoneNumber": "+7XXXXXXXXXX" -} -``` - -| `paymentStatus` values | Meaning | -|------------------------|---------------------------| -| `CREATED` | QR generated, not paid | -| `WAITING` | Payment in progress | -| `COMPLETED` | Payment successful | -| `EXPIRED` | QR code expired | -| `CANCELLED` | Payment cancelled | - ---- - -### `POST /purchase-email` — Submit email after payment - -**Request body:** -```json -{ - "email": "user@example.com", - "telegramUserId": "123456789", - "items": [ - { "itemID": 123, "name": "iPhone 15 Pro", "price": 89990, "currency": "RUB" } - ] -} -``` - -**Response `200`:** -```json -{ "message": "Email sent" } -``` - ---- - -## 6. Reviews / Comments - -### `POST /comment` — Submit a review - -**Request body:** -```json -{ - "itemID": 123, - "rating": 5, - "comment": "Great product!", - "username": "john_doe", - "userId": 123456789, - "timestamp": "2026-02-28T12:00:00Z" -} -``` - -**Response `200`:** -```json -{ "message": "Review submitted" } -``` - ---- - -## 7. Regions - -### `GET /regions` — List available regions - -Returns regions where the marketplace operates. - -**Response `200`:** -```json -[ - { - "id": "moscow", - "city": "Москва", - "country": "Россия", - "countryCode": "RU", - "timezone": "Europe/Moscow" - }, - { - "id": "spb", - "city": "Санкт-Петербург", - "country": "Россия", - "countryCode": "RU", - "timezone": "Europe/Moscow" - }, - { - "id": "yerevan", - "city": "Ереван", - "country": "Армения", - "countryCode": "AM", - "timezone": "Asia/Yerevan" - } -] -``` - -**Region object:** - -| Field | Type | Required | Description | -|---------------|--------|----------|--------------------------| -| `id` | string | yes | Unique region identifier | -| `city` | string | yes | City name (display) | -| `country` | string | yes | Country name | -| `countryCode` | string | yes | ISO 3166-1 alpha-2 | -| `timezone` | string | no | IANA timezone | - -> **Fallback:** If this endpoint is down, the frontend uses 6 hardcoded defaults: Moscow, SPB, Yerevan, Minsk, Almaty, Tbilisi. - ---- - -## 8. Authentication (Telegram Login) - -Authentication is **Telegram-based** with **cookie sessions** (HttpOnly, Secure, SameSite=None). - -All auth endpoints must include `withCredentials: true` CORS support. - -### Auth flow - -``` -1. User clicks "Checkout" → not authenticated → login dialog shown -2. User clicks "Log in with Telegram" → opens https://t.me/{bot}?start=auth_{callback} -3. User starts the bot in Telegram -4. Bot sends user data → backend /auth/telegram/callback -5. Backend creates session → sets Set-Cookie -6. Frontend polls GET /auth/session every 3s -7. Session detected → dialog closes → checkout proceeds -``` - ---- - -### `GET /auth/session` — Check current session - -**Request:** Cookies only (session cookie set by backend). - -**Response `200`** (authenticated): -```json -{ - "sessionId": "sess_abc123", - "telegramUserId": 123456789, - "username": "john_doe", - "displayName": "John Doe", - "active": true, - "expiresAt": "2026-03-01T12:00:00Z" -} -``` - -**Response `200`** (expired): -```json -{ - "sessionId": "sess_abc123", - "telegramUserId": 123456789, - "username": "john_doe", - "displayName": "John Doe", - "active": false, - "expiresAt": "2026-02-27T12:00:00Z" -} -``` - -**Response `401`** (no session): -```json -{ "error": "No active session" } -``` - -**AuthSession object:** - -| Field | Type | Required | Description | -|------------------|---------|----------|--------------------------------------------| -| `sessionId` | string | yes | Unique session ID | -| `telegramUserId` | number | yes | Telegram user ID | -| `username` | string? | no | Telegram @username (can be null) | -| `displayName` | string | yes | User display name (first + last) | -| `active` | boolean | yes | Whether session is valid | -| `expiresAt` | string | yes | ISO 8601 expiration datetime | - ---- - -### `GET /auth/telegram/callback` — Telegram bot auth callback - -Called by the Telegram bot after user authenticates. - -**Request body (from bot):** -```json -{ - "id": 123456789, - "first_name": "John", - "last_name": "Doe", - "username": "john_doe", - "photo_url": "https://t.me/i/userpic/...", - "auth_date": 1709100000, - "hash": "abc123def456..." -} -``` - -**Response:** Must set a session cookie and return: -```json -{ - "sessionId": "sess_abc123", - "message": "Authenticated successfully" -} -``` - -**Cookie requirements:** - -| Attribute | Value | Notes | -|------------|----------------|--------------------------------------------| -| `HttpOnly` | `true` | Not accessible via JS | -| `Secure` | `true` | HTTPS only | -| `SameSite` | `None` | Required for cross-origin (API ≠ frontend) | -| `Path` | `/` | | -| `Max-Age` | `86400` (24h) | Or as needed | - ---- - -### `POST /auth/logout` — End session - -**Request:** Cookies only, empty body `{}` - -**Response `200`:** -```json -{ "message": "Logged out" } -``` - -Must clear/invalidate the session cookie. - ---- - -### Session refresh - -The frontend re-checks the session **60 seconds before `expiresAt`**. If the backend supports sliding expiration, it can reset the cookie's `Max-Age` on each `GET /auth/session`. - ---- - -## 9. i18n / Translations - -The frontend supports 3 languages: **Russian (ru)**, **English (en)**, **Armenian (hy)**. - -The active language is sent via the `X-Language` HTTP header on every request. - -### What the backend should do with `X-Language` - -1. **Categories & items**: If `translations` field exists for the requested language, return the translated `name`, `description`, etc. OR the backend can apply translations server-side and return already-translated fields. - -2. **The `translations` field** on items (optional approach): - ```json - { - "translations": { - "en": { - "name": "iPhone 15 Pro", - "simpleDescription": "Short desc in English", - "description": [{ "key": "Processor", "value": "A17 Pro" }] - }, - "hy": { - "name": "iPhone 15 Pro", - "simpleDescription": "Կarcheck check" - } - } - } - ``` - -3. **Recommended approach**: Read `X-Language` header and return the `name`/`description` in that language directly. If no translation exists, return the Russian default. - ---- - -## 10. CORS Configuration - -For auth cookies and custom headers to work, the backend CORS config must include: - -``` -Access-Control-Allow-Origin: https://dexarmarket.ru (NOT wildcard *) -Access-Control-Allow-Credentials: true -Access-Control-Allow-Headers: Content-Type, X-Region, X-Language -Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS -``` - -> **Important:** `Access-Control-Allow-Origin` cannot be `*` when `Allow-Credentials: true`. Must be the exact frontend origin. - -**Allowed origins:** -- `https://dexarmarket.ru` -- `https://novo.market` -- `http://localhost:4200` (dev) -- `http://localhost:4201` (dev, Novo) - ---- - -## 11. Telegram Bot Setup - -Each brand needs its own bot: -- **Dexar:** `@dexarmarket_bot` -- **Novo:** `@novomarket_bot` - -The bot should: -1. Listen for `/start auth_{callbackUrl}` command -2. Extract the callback URL -3. Send the user's Telegram data (`id`, `first_name`, `username`, etc.) to that callback URL -4. The callback URL is `{apiUrl}/auth/telegram/callback` - ---- - -## Complete Endpoint Reference - -### New endpoints - -| Method | Path | Description | Auth | -|--------|---------------------------|----------------------------|----------| -| `GET` | `/regions` | List available regions | No | -| `GET` | `/auth/session` | Check current session | Cookie | -| `GET` | `/auth/telegram/callback` | Telegram bot auth callback | No (bot) | -| `POST` | `/auth/logout` | End session | Cookie | - -### Existing endpoints - -| Method | Path | Description | Auth | Headers | -|----------|-----------------------|-------------------------|------|--------------------| -| `GET` | `/ping` | Health check | No | — | -| `GET` | `/category` | List categories | No | X-Region, X-Language | -| `GET` | `/category/:id` | Items in category | No | X-Region, X-Language | -| `GET` | `/item/:id` | Single item | No | X-Region, X-Language | -| `GET` | `/searchitems` | Search items | No | X-Region, X-Language | -| `GET` | `/randomitems` | Random items | No | X-Region, X-Language | -| `POST` | `/cart` | Add to cart / Payment | No* | — | -| `PATCH` | `/cart` | Update cart quantity | No* | — | -| `DELETE` | `/cart` | Remove from cart | No* | — | -| `GET` | `/cart` | Get cart contents | No* | — | -| `POST` | `/comment` | Submit review | No | — | -| `GET` | `/qr/payment/:qrId` | Check payment status | No | — | -| `POST` | `/purchase-email` | Submit email after pay | No | — | - -> \* Cart/payment endpoints may use the session cookie if available for order association, but don't strictly require auth. The frontend enforces auth before checkout. diff --git a/docs/API_DOCS_RU.md b/docs/API_DOCS_RU.md deleted file mode 100644 index f04007f..0000000 --- a/docs/API_DOCS_RU.md +++ /dev/null @@ -1,726 +0,0 @@ -# Полная документация Backend API - -> **Последнее обновление:** Февраль 2026 -> **Фронтенд:** Angular 21 · Два бренда (Dexar + Novo) -> **Охватывает:** Каталог, Корзина, Оплата, Отзывы, Регионы, Авторизация, i18n, BackOffice - ---- - -## Базовые URL - -| Бренд | Dev | Production | -|--------|----------------------------------|----------------------------------| -| Dexar | `https://api.dexarmarket.ru:445` | `https://api.dexarmarket.ru:445` | -| Novo | `https://api.novo.market:444` | `https://api.novo.market:444` | - ---- - -## Глобальные HTTP-заголовки - -Фронтенд **автоматически добавляет** два кастомных заголовка к **каждому API-запросу** через interceptor. Бэкенд должен читать эти заголовки и использовать для фильтрации/перевода ответов. - -| Заголовок | Пример значения | Описание | -|---------------|-----------------|-------------------------------------------------------------------| -| `X-Region` | `moscow` | ID региона, выбранного пользователем. **Отсутствует** = все регионы. | -| `X-Language` | `ru` | Активный язык интерфейса: `ru`, `en` или `hy`. | - -### Поведение бэкенда - -- **`X-Region`**: Если присутствует — фильтровать товары/категории только по этому региону. Если отсутствует — возвращать всё (глобальный каталог). -- **`X-Language`**: Если присутствует — возвращать переведённые `name`, `description` и т.д., если переводы существуют. Если отсутствует или `ru` — возвращать на русском (по умолчанию). - -### Требования CORS для этих заголовков - -``` -Access-Control-Allow-Headers: Content-Type, X-Region, X-Language -``` - ---- - -## 1. Проверка состояния - -### `GET /ping` - -Простая проверка работоспособности. - -**Ответ `200`:** -```json -{ "message": "pong" } -``` - ---- - -## 2. Каталог — Категории - -### `GET /category` - -Возвращает все категории верхнего уровня. Учитывает заголовки `X-Region` и `X-Language`. - -**Ответ `200`:** -```json -[ - { - "categoryID": 1, - "name": "Электроника", - "parentID": 0, - "icon": "https://...", - "wideBanner": "https://...", - "itemCount": 42, - "priority": 10, - - "id": "cat_abc123", - "visible": true, - "img": "https://...", - "projectId": "proj_xyz", - "subcategories": [ - { - "id": "sub_001", - "name": "Смартфоны", - "visible": true, - "priority": 5, - "img": "https://...", - "categoryId": "cat_abc123", - "parentId": "cat_abc123", - "itemCount": 20, - "hasItems": true, - "subcategories": [] - } - ] - } -] -``` - -**Объект Category:** - -| Поле | Тип | Обязат. | Описание | -|------------------|---------------|---------|-----------------------------------------------------| -| `categoryID` | number | да | Числовой ID (legacy) | -| `name` | string | да | Название категории (переведённое если `X-Language`) | -| `parentID` | number | да | ID родительской категории (`0` = верхний уровень) | -| `icon` | string | нет | URL иконки категории | -| `wideBanner` | string | нет | URL широкого баннера | -| `itemCount` | number | нет | Количество товаров в категории | -| `priority` | number | нет | Приоритет сортировки (больше = выше) | -| `id` | string | нет | Строковый ID из BackOffice | -| `visible` | boolean | нет | Видима ли категория (по умолч. `true`) | -| `img` | string | нет | URL изображения из BackOffice (маппится на `icon`) | -| `projectId` | string | нет | Ссылка на проект в BackOffice | -| `subcategories` | Subcategory[] | нет | Вложенные подкатегории | - -**Объект Subcategory:** - -| Поле | Тип | Обязат. | Описание | -|------------------|---------------|---------|----------------------------------| -| `id` | string | да | ID подкатегории | -| `name` | string | да | Отображаемое название | -| `visible` | boolean | нет | Видима ли | -| `priority` | number | нет | Приоритет сортировки | -| `img` | string | нет | URL изображения | -| `categoryId` | string | да | ID родительской категории | -| `parentId` | string | да | ID прямого родителя | -| `itemCount` | number | нет | Количество товаров | -| `hasItems` | boolean | нет | Есть ли товары | -| `subcategories` | Subcategory[] | нет | Вложенные дочерние подкатегории | - ---- - -### `GET /category/:categoryID` - -Возвращает товары определённой категории. Учитывает заголовки `X-Region` и `X-Language`. - -**Query-параметры:** - -| Параметр | Тип | По умолч. | Описание | -|----------|--------|-----------|-----------------------| -| `count` | number | `50` | Товаров на страницу | -| `skip` | number | `0` | Смещение для пагинации | - -**Ответ `200`:** Массив объектов [Item](#объект-item). - ---- - -## 3. Товары - -### `GET /item/:itemID` - -Возвращает один товар. Учитывает заголовки `X-Region` и `X-Language`. - -**Ответ `200`:** Один объект [Item](#объект-item). - ---- - -### `GET /searchitems` - -Полнотекстовый поиск по товарам. Учитывает заголовки `X-Region` и `X-Language`. - -**Query-параметры:** - -| Параметр | Тип | По умолч. | Описание | -|----------|--------|-----------|-------------------------------| -| `search` | string | — | Поисковый запрос (обязателен) | -| `count` | number | `50` | Товаров на страницу | -| `skip` | number | `0` | Смещение для пагинации | - -**Ответ `200`:** -```json -{ - "items": [ /* объекты Item */ ], - "total": 128, - "count": 50, - "skip": 0 -} -``` - ---- - -### `GET /randomitems` - -Возвращает случайные товары для карусели/рекомендаций. Учитывает заголовки `X-Region` и `X-Language`. - -**Query-параметры:** - -| Параметр | Тип | По умолч. | Описание | -|------------|--------|-----------|--------------------------------------| -| `count` | number | `5` | Количество товаров | -| `category` | number | — | Ограничить данной категорией (опц.) | - -**Ответ `200`:** Массив объектов [Item](#объект-item). - ---- - -### Объект Item - -Бэкенд может возвращать товары в **любом** из двух форматов — legacy или BackOffice. Фронтенд нормализует оба варианта. - -```json -{ - "categoryID": 1, - "itemID": 123, - "name": "iPhone 15 Pro", - "photos": [{ "url": "https://..." }], - "description": "Описание товара", - "currency": "RUB", - "price": 89990, - "discount": 10, - "remainings": "high", - "rating": 4.5, - "callbacks": [ - { - "rating": 5, - "content": "Отличный товар!", - "userID": "user_123", - "timestamp": "2026-02-01T12:00:00Z" - } - ], - "questions": [ - { - "question": "Есть ли гарантия?", - "answer": "Да, 12 месяцев", - "upvotes": 5, - "downvotes": 0 - } - ], - - "id": "item_abc123", - "visible": true, - "priority": 10, - "imgs": ["https://img1.jpg", "https://img2.jpg"], - "tags": ["new", "popular"], - "badges": ["bestseller", "sale"], - "simpleDescription": "Краткое описание", - "descriptionFields": [ - { "key": "Процессор", "value": "A17 Pro" }, - { "key": "Память", "value": "256 GB" } - ], - "subcategoryId": "sub_001", - "translations": { - "en": { - "name": "iPhone 15 Pro", - "simpleDescription": "Short description", - "description": [ - { "key": "Processor", "value": "A17 Pro" } - ] - }, - "hy": { - "name": "iPhone 15 Pro", - "simpleDescription": "Կարcheck check" - } - }, - "comments": [ - { - "id": "cmt_001", - "text": "Отличный товар!", - "author": "user_123", - "stars": 5, - "createdAt": "2026-02-01T12:00:00Z" - } - ], - "quantity": 50 -} -``` - -**Все поля Item:** - -| Поле | Тип | Обязат. | Описание | -|---------------------|-------------------|---------|-----------------------------------------------------------| -| `categoryID` | number | да | Категория, к которой принадлежит товар | -| `itemID` | number | да | Числовой ID товара (legacy) | -| `name` | string | да | Название товара | -| `photos` | Photo[] | нет | Массив фотографий `[{ url }]` (legacy) | -| `description` | string | да | Текстовое описание | -| `currency` | string | да | Код валюты (по умолч. `RUB`) | -| `price` | number | да | Цена | -| `discount` | number | да | Процент скидки (`0`–`100`) | -| `remainings` | string | нет | Уровень остатка: `high`, `medium`, `low`, `out` | -| `rating` | number | да | Средний рейтинг (`0`–`5`) | -| `callbacks` | Review[] | нет | Отзывы (legacy формат) | -| `questions` | Question[] | нет | Вопросы и ответы | -| `id` | string | нет | Строковый ID из BackOffice | -| `visible` | boolean | нет | Виден ли товар (по умолч. `true`) | -| `priority` | number | нет | Приоритет сортировки (больше = выше) | -| `imgs` | string[] | нет | URL картинок из BackOffice (маппится на `photos`) | -| `tags` | string[] | нет | Теги для фильтрации | -| `badges` | string[] | нет | Бейджи (`bestseller`, `sale` и т.д.) | -| `simpleDescription` | string | нет | Краткое текстовое описание | -| `descriptionFields` | DescriptionField[]| нет | Структурированное описание `[{ key, value }]` | -| `subcategoryId` | string | нет | Ссылка на подкатегорию из BackOffice | -| `translations` | Record | нет | Переводы по ключу языка (см. ниже) | -| `comments` | Comment[] | нет | Комментарии в формате BackOffice | -| `quantity` | number | нет | Числовое кол-во на складе (маппится на `remainings`) | - -**Вложенные типы:** - -| Тип | Поля | -|--------------------|-----------------------------------------------------------------| -| `Photo` | `url: string`, `photo?: string`, `video?: string`, `type?: string` | -| `DescriptionField` | `key: string`, `value: string` | -| `Comment` | `id?: string`, `text: string`, `author?: string`, `stars?: number`, `createdAt?: string` | -| `Review` | `rating?: number`, `content?: string`, `userID?: string`, `answer?: string`, `timestamp?: string` | -| `Question` | `question: string`, `answer: string`, `upvotes: number`, `downvotes: number` | -| `ItemTranslation` | `name?: string`, `simpleDescription?: string`, `description?: DescriptionField[]` | - ---- - -## 4. Корзина - -### `POST /cart` — Добавить товар в корзину - -**Тело запроса:** -```json -{ "itemID": 123, "quantity": 1 } -``` - -**Ответ `200`:** -```json -{ "message": "Added to cart" } -``` - ---- - -### `PATCH /cart` — Обновить количество товара - -**Тело запроса:** -```json -{ "itemID": 123, "quantity": 3 } -``` - -**Ответ `200`:** -```json -{ "message": "Updated" } -``` - ---- - -### `DELETE /cart` — Удалить товары из корзины - -**Тело запроса:** Массив ID товаров -```json -[123, 456] -``` - -**Ответ `200`:** -```json -{ "message": "Removed" } -``` - ---- - -### `GET /cart` — Получить содержимое корзины - -**Ответ `200`:** Массив объектов [Item](#объект-item) (каждый с полем `quantity`). - ---- - -## 5. Оплата (СБП / QR) - -### `POST /cart` — Создать платёж (СБП QR) - -> Примечание: Тот же эндпоинт что и добавление в корзину, но с другой схемой тела запроса. - -**Тело запроса:** -```json -{ - "amount": 89990, - "currency": "RUB", - "siteuserID": "tg_123456789", - "siteorderID": "order_abc123", - "redirectUrl": "", - "telegramUsername": "john_doe", - "items": [ - { "itemID": 123, "price": 89990, "name": "iPhone 15 Pro" } - ] -} -``` - -**Ответ `200`:** -```json -{ - "qrId": "qr_abc123", - "qrStatus": "CREATED", - "qrExpirationDate": "2026-02-28T13:00:00Z", - "payload": "https://qr.nspk.ru/...", - "qrUrl": "https://qr.nspk.ru/..." -} -``` - ---- - -### `GET /qr/payment/:qrId` — Проверить статус оплаты - -**Ответ `200`:** -```json -{ - "additionalInfo": "", - "paymentPurpose": "Order #order_abc123", - "amount": 89990, - "code": "SUCCESS", - "createDate": "2026-02-28T12:00:00Z", - "currency": "RUB", - "order": "order_abc123", - "paymentStatus": "COMPLETED", - "qrId": "qr_abc123", - "transactionDate": "2026-02-28T12:01:00Z", - "transactionId": 999, - "qrExpirationDate": "2026-02-28T13:00:00Z", - "phoneNumber": "+7XXXXXXXXXX" -} -``` - -| Значение `paymentStatus` | Значение | -|--------------------------|------------------------------| -| `CREATED` | QR создан, не оплачен | -| `WAITING` | Оплата в процессе | -| `COMPLETED` | Оплата успешна | -| `EXPIRED` | QR-код истёк | -| `CANCELLED` | Оплата отменена | - ---- - -### `POST /purchase-email` — Отправить email после оплаты - -**Тело запроса:** -```json -{ - "email": "user@example.com", - "telegramUserId": "123456789", - "items": [ - { "itemID": 123, "name": "iPhone 15 Pro", "price": 89990, "currency": "RUB" } - ] -} -``` - -**Ответ `200`:** -```json -{ "message": "Email sent" } -``` - ---- - -## 6. Отзывы / Комментарии - -### `POST /comment` — Оставить отзыв - -**Тело запроса:** -```json -{ - "itemID": 123, - "rating": 5, - "comment": "Отличный товар!", - "username": "john_doe", - "userId": 123456789, - "timestamp": "2026-02-28T12:00:00Z" -} -``` - -**Ответ `200`:** -```json -{ "message": "Review submitted" } -``` - ---- - -## 7. Регионы - -### `GET /regions` — Список доступных регионов - -Возвращает регионы, в которых работает маркетплейс. - -**Ответ `200`:** -```json -[ - { - "id": "moscow", - "city": "Москва", - "country": "Россия", - "countryCode": "RU", - "timezone": "Europe/Moscow" - }, - { - "id": "spb", - "city": "Санкт-Петербург", - "country": "Россия", - "countryCode": "RU", - "timezone": "Europe/Moscow" - }, - { - "id": "yerevan", - "city": "Ереван", - "country": "Армения", - "countryCode": "AM", - "timezone": "Asia/Yerevan" - } -] -``` - -**Объект Region:** - -| Поле | Тип | Обязат. | Описание | -|---------------|--------|---------|----------------------------------| -| `id` | string | да | Уникальный идентификатор региона | -| `city` | string | да | Название города | -| `country` | string | да | Название страны | -| `countryCode` | string | да | Код страны ISO 3166-1 alpha-2 | -| `timezone` | string | нет | Часовой пояс IANA | - -> **Фоллбэк:** Если эндпоинт недоступен, фронтенд использует 6 захардкоженных значений: Москва, СПб, Ереван, Минск, Алматы, Тбилиси. - ---- - -## 8. Авторизация (вход через Telegram) - -Авторизация **через Telegram** с **cookie-сессиями** (HttpOnly, Secure, SameSite=None). - -Все auth-эндпоинты должны поддерживать CORS с `credentials: true`. - -### Процесс авторизации - -``` -1. Пользователь нажимает «Оформить заказ» → не авторизован → показывается диалог входа -2. Нажимает «Войти через Telegram» → открывается https://t.me/{bot}?start=auth_{callback} -3. Пользователь запускает бота в Telegram -4. Бот отправляет данные пользователя → бэкенд /auth/telegram/callback -5. Бэкенд создаёт сессию → устанавливает Set-Cookie -6. Фронтенд опрашивает GET /auth/session каждые 3 секунды -7. Сессия обнаружена → диалог закрывается → оформление заказа продолжается -``` - ---- - -### `GET /auth/session` — Проверить текущую сессию - -**Запрос:** Только cookie (сессионная cookie, установленная бэкендом). - -**Ответ `200`** (авторизован): -```json -{ - "sessionId": "sess_abc123", - "telegramUserId": 123456789, - "username": "john_doe", - "displayName": "John Doe", - "active": true, - "expiresAt": "2026-03-01T12:00:00Z" -} -``` - -**Ответ `200`** (сессия истекла): -```json -{ - "sessionId": "sess_abc123", - "telegramUserId": 123456789, - "username": "john_doe", - "displayName": "John Doe", - "active": false, - "expiresAt": "2026-02-27T12:00:00Z" -} -``` - -**Ответ `401`** (нет сессии): -```json -{ "error": "No active session" } -``` - -**Объект AuthSession:** - -| Поле | Тип | Обязат. | Описание | -|------------------|---------|---------|-------------------------------------------| -| `sessionId` | string | да | Уникальный ID сессии | -| `telegramUserId` | number | да | ID пользователя в Telegram | -| `username` | string? | нет | @username в Telegram (может быть null) | -| `displayName` | string | да | Отображаемое имя (имя + фамилия) | -| `active` | boolean | да | Действительна ли сессия | -| `expiresAt` | string | да | Дата истечения в формате ISO 8601 | - ---- - -### `GET /auth/telegram/callback` — Callback авторизации Telegram-бота - -Вызывается Telegram-ботом после авторизации пользователя. - -**Тело запроса (от бота):** -```json -{ - "id": 123456789, - "first_name": "John", - "last_name": "Doe", - "username": "john_doe", - "photo_url": "https://t.me/i/userpic/...", - "auth_date": 1709100000, - "hash": "abc123def456..." -} -``` - -**Ответ:** Должен установить cookie сессии и вернуть: -```json -{ - "sessionId": "sess_abc123", - "message": "Authenticated successfully" -} -``` - -**Требования к cookie:** - -| Атрибут | Значение | Примечание | -|------------|----------------|-----------------------------------------------------| -| `HttpOnly` | `true` | Недоступна из JavaScript | -| `Secure` | `true` | Только HTTPS | -| `SameSite` | `None` | Обязательно для cross-origin (API ≠ фронтенд) | -| `Path` | `/` | | -| `Max-Age` | `86400` (24ч) | Или по необходимости | - ---- - -### `POST /auth/logout` — Завершить сессию - -**Запрос:** Только cookie, пустое тело `{}` - -**Ответ `200`:** -```json -{ "message": "Logged out" } -``` - -Должен очистить/инвалидировать cookie сессии. - ---- - -### Обновление сессии - -Фронтенд повторно проверяет сессию за **60 секунд до `expiresAt`**. Если бэкенд поддерживает скользящий срок действия (sliding expiration), можно обновлять `Max-Age` cookie при каждом вызове `GET /auth/session`. - ---- - -## 9. i18n / Переводы - -Фронтенд поддерживает 3 языка: **Русский (ru)**, **Английский (en)**, **Армянский (hy)**. - -Активный язык отправляется через HTTP-заголовок `X-Language` с каждым запросом. - -### Что бэкенд должен делать с `X-Language` - -1. **Категории и товары**: Если для запрошенного языка есть поле `translations`, вернуть переведённые `name`, `description` и т.д. ИЛИ бэкенд может применять переводы на стороне сервера и возвращать уже переведённые поля. - -2. **Поле `translations`** на товарах (опциональный подход): - ```json - { - "translations": { - "en": { - "name": "iPhone 15 Pro", - "simpleDescription": "Short desc in English", - "description": [{ "key": "Processor", "value": "A17 Pro" }] - }, - "hy": { - "name": "iPhone 15 Pro", - "simpleDescription": "Կarcheck check" - } - } - } - ``` - -3. **Рекомендуемый подход**: Читать заголовок `X-Language` и возвращать `name`/`description` на этом языке напрямую. Если перевода нет — возвращать русский вариант по умолчанию. - ---- - -## 10. Настройка CORS - -Для работы auth-cookie и кастомных заголовков конфигурация CORS бэкенда должна включать: - -``` -Access-Control-Allow-Origin: https://dexarmarket.ru (НЕ wildcard *) -Access-Control-Allow-Credentials: true -Access-Control-Allow-Headers: Content-Type, X-Region, X-Language -Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS -``` - -> **Важно:** `Access-Control-Allow-Origin` не может быть `*` при `Allow-Credentials: true`. Должен быть точный origin фронтенда. - -**Разрешённые origins:** -- `https://dexarmarket.ru` -- `https://novo.market` -- `http://localhost:4200` (dev) -- `http://localhost:4201` (dev, Novo) - ---- - -## 11. Настройка Telegram-бота - -Каждому бренду нужен свой бот: -- **Dexar:** `@dexarmarket_bot` -- **Novo:** `@novomarket_bot` - -Бот должен: -1. Слушать команду `/start auth_{callbackUrl}` -2. Извлечь callback URL -3. Отправить данные пользователя (`id`, `first_name`, `username` и т.д.) на этот callback URL -4. Callback URL: `{apiUrl}/auth/telegram/callback` - ---- - -## Полный справочник эндпоинтов - -### Новые эндпоинты - -| Метод | Путь | Описание | Авторизация | -|--------|---------------------------|---------------------------------|-------------| -| `GET` | `/regions` | Список доступных регионов | Нет | -| `GET` | `/auth/session` | Проверка текущей сессии | Cookie | -| `GET` | `/auth/telegram/callback` | Callback авторизации через бота | Нет (бот) | -| `POST` | `/auth/logout` | Завершение сессии | Cookie | - -### Существующие эндпоинты - -| Метод | Путь | Описание | Авт. | Заголовки | -|----------|-----------------------|---------------------------|------|--------------------| -| `GET` | `/ping` | Проверка состояния | Нет | — | -| `GET` | `/category` | Список категорий | Нет | X-Region, X-Language | -| `GET` | `/category/:id` | Товары категории | Нет | X-Region, X-Language | -| `GET` | `/item/:id` | Один товар | Нет | X-Region, X-Language | -| `GET` | `/searchitems` | Поиск товаров | Нет | X-Region, X-Language | -| `GET` | `/randomitems` | Случайные товары | Нет | X-Region, X-Language | -| `POST` | `/cart` | Добавить в корзину / Оплата | Нет* | — | -| `PATCH` | `/cart` | Обновить кол-во | Нет* | — | -| `DELETE` | `/cart` | Удалить из корзины | Нет* | — | -| `GET` | `/cart` | Содержимое корзины | Нет* | — | -| `POST` | `/comment` | Оставить отзыв | Нет | — | -| `GET` | `/qr/payment/:qrId` | Статус оплаты | Нет | — | -| `POST` | `/purchase-email` | Отправить email после оплаты | Нет | — | - -> \* Эндпоинты корзины/оплаты могут использовать cookie сессии (если есть) для привязки к заказу, но не требуют авторизации строго. Фронтенд проверяет авторизацию перед оформлением заказа. diff --git a/docs/BACKEND_AUTH_INTEGRATION.md b/docs/BACKEND_AUTH_INTEGRATION.md deleted file mode 100644 index ac3c6fd..0000000 --- a/docs/BACKEND_AUTH_INTEGRATION.md +++ /dev/null @@ -1,824 +0,0 @@ -# Авторизация через Telegram — Backend & Bot - -> Всё что нужно Go-разработчику для реализации авторизации. -> Фронтенд **полностью готов** и ждёт эти эндпоинты. - ---- - -## Статус - -| Компонент | Готов? | -|-----------|--------| -| Frontend (Angular) — диалог, QR, поллинг, корзина | ✅ Готов | -| Telegram бот (обработка `/start`) | ❌ Нужно | -| Backend — 6 HTTP-эндпоинтов | ❌ Нужно | -| Хранилище сессий + QR-токенов | ❌ Нужно | -| CORS для cookie-based запросов | ❌ Нужно | - ---- - -## Архитектура - -Два сценария авторизации: - -### Сценарий 1: Прямой вход (кнопка "Войти через Telegram") - -Пользователь нажимает кнопку → открывается Telegram → бот выдаёт кнопку "Войти на сайт" → callback ставит cookie → фронтенд поллит `/auth/session`. - -### Сценарий 2: QR-логин с десктопа (основной) - -``` - ДЕСКТОП БРАУЗЕР СЕРВЕР (Go) TELEGRAM - │ │ │ - │ 1. POST /auth/qr/create │ │ - │ ─────────────────────────────> │ │ - │ { token: "abc", url: "..." } │ │ - │ <───────────────────────────── │ │ - │ │ │ - │ 2. Показать QR: │ │ - │ t.me/Bot?start=login_abc │ │ - │ │ │ - │ ПОЛЬЗОВАТЕЛЬ СКАНИРУЕТ ТЕЛЕФОНОМ │ - │ │ │ - │ │ 3. /start login_abc │ - │ │ <────────────────────────│ - │ │ │ - │ │ Бот → POST /auth/qr/confirm - │ │ Бот → "✅ Вы вошли!" │ - │ │ ────────────────────────>│ - │ │ │ - │ 4. GET /auth/qr/poll?token=abc │ │ - │ (каждые 3 сек) │ │ - │ ─────────────────────────────> │ │ - │ { status: "confirmed", │ │ - │ session: {...} } │ │ - │ + Set-Cookie: dx_session=... │ │ - │ <───────────────────────────── │ │ - │ │ │ - │ 5. POST /websession/{sessionId} │ │ - │ [{ itemID, quantity, ... }] │ ← корзина │ - │ ─────────────────────────────> │ │ - │ │ │ - │ 6. Готово! Авторизован + корзина│ │ -``` - ---- - -## Бренды и боты - -| Бренд | Username бота | Домен фронтенда | API сервер | Cookie Domain | -|-------|---------------|------------------|------------|---------------| -| Dexar | `DexarSupport_bot` | `dexarmarket.ru` | `api.dexarmarket.ru:445` | `.dexarmarket.ru` | -| Novo | `novomarket_bot` | `novo.market` | `api.novo.market:444` | `.novo.market` | - -Бот создаётся через https://t.me/BotFather → `/newbot`. Сохранить `BOT_TOKEN`. - ---- - -## Хранилище - -### Структура: Сессия - -```go -type Session struct { - SessionID string `json:"sessionId"` - TelegramUserID int64 `json:"telegramUserId"` - Username *string `json:"username"` // может быть null - DisplayName string `json:"displayName"` - Active bool `json:"active"` - ExpiresAt time.Time `json:"expiresAt"` -} -``` - -**TTL:** 24 часа. - -### Структура: QR-токен (одноразовый) - -```go -type AuthToken struct { - Token string `json:"token"` - Status string `json:"status"` // "pending" | "confirmed" | "expired" - SessionID string `json:"sessionId"` // заполняется после подтверждения ботом - CreatedAt time.Time `json:"createdAt"` - ExpiresAt time.Time `json:"expiresAt"` -} -``` - -**TTL:** 5 минут. - -### Варианты хранения - -**Redis (рекомендуется):** -```go -// Сессия -redisClient.Set(ctx, "session:"+s.SessionID, json, 24*time.Hour) - -// QR-токен -redisClient.Set(ctx, "auth_token:"+t.Token, json, 5*time.Minute) -``` - -**sync.Map (для MVP):** -```go -var sessions sync.Map -var authTokens sync.Map - -// Очистка устаревших токенов — запустить горутину при старте -func cleanupExpiredTokens() { - ticker := time.NewTicker(1 * time.Minute) - for range ticker.C { - authTokens.Range(func(key, value any) bool { - t := value.(AuthToken) - if time.Now().After(t.ExpiresAt) { - authTokens.Delete(key) - } - return true - }) - } -} -``` - ---- - -## HTTP-эндпоинты - -### 1. `POST /auth/qr/create` - -Фронтенд вызывает при открытии диалога логина. Создаёт одноразовый QR-токен. - -```go -func handleQrCreate(w http.ResponseWriter, r *http.Request) { - // 1. Сгенерировать криптографически безопасный токен - tokenBytes := make([]byte, 32) - if _, err := rand.Read(tokenBytes); err != nil { - http.Error(w, "internal error", 500) - return - } - token := base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(tokenBytes) - - // 2. Определить бота по origin - botUsername := getBotForOrigin(r.Header.Get("Origin")) - - // 3. Сохранить токен - authToken := AuthToken{ - Token: token, - Status: "pending", - CreatedAt: time.Now(), - ExpiresAt: time.Now().Add(5 * time.Minute), - } - saveAuthToken(authToken) - - // 4. Ответить - qrURL := fmt.Sprintf("https://t.me/%s?start=login_%s", botUsername, token) - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]string{ - "token": token, - "url": qrURL, - }) -} - -func getBotForOrigin(origin string) string { - if strings.Contains(origin, "novo.market") { - return "novomarket_bot" - } - return "DexarSupport_bot" -} -``` - -**Ответ:** -```json -{ "token": "dG9rZW4tYWJj....", "url": "https://t.me/DexarSupport_bot?start=login_dG9rZW4tYWJj...." } -``` - -> Telegram ограничивает `start` до 64 символов. `login_` (6) + base64url из 32 байт (43) = 49 ✅ - ---- - -### 2. `GET /auth/qr/poll?token={token}` - -Фронтенд вызывает каждые 3 секунды. Когда бот подтвердил — возвращает сессию и ставит cookie. - -```go -func handleQrPoll(w http.ResponseWriter, r *http.Request) { - tokenStr := r.URL.Query().Get("token") - if tokenStr == "" { - http.Error(w, "missing token", 400) - return - } - - authToken, ok := getAuthToken(tokenStr) - if !ok { - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]string{"status": "expired"}) - return - } - - switch authToken.Status { - case "pending": - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]string{"status": "pending"}) - - case "confirmed": - session, err := getSession(authToken.SessionID) - if err != nil { - http.Error(w, "session not found", 500) - return - } - - // Cookie в ДЕСКТОПНЫЙ браузер - domain := getDomainForOrigin(r.Header.Get("Origin")) - http.SetCookie(w, &http.Cookie{ - Name: "dx_session", - Value: session.SessionID, - Path: "/", - HttpOnly: true, - Secure: true, - SameSite: http.SameSiteNoneMode, - MaxAge: 86400, - Domain: domain, - }) - - // Удалить использованный токен - deleteAuthToken(tokenStr) - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]interface{}{ - "status": "confirmed", - "session": session, - }) - } -} - -func getDomainForOrigin(origin string) string { - if strings.Contains(origin, "novo.market") { - return ".novo.market" - } - return ".dexarmarket.ru" -} -``` - -**Ответы:** - -| Статус | JSON | -|--------|------| -| Ждём | `{ "status": "pending" }` | -| Подтверждено | `{ "status": "confirmed", "session": { sessionId, telegramUserId, username, displayName, active, expiresAt } }` + `Set-Cookie` | -| Истекло | `{ "status": "expired" }` | - ---- - -### 3. `POST /auth/qr/confirm` (внутренний, для бота) - -Бот вызывает когда пользователь отсканировал QR. Привязывает сессию к токену. - -```go -func handleQrConfirm(w http.ResponseWriter, r *http.Request) { - // Проверить секрет бота - if r.Header.Get("X-Bot-Secret") != os.Getenv("BOT_INTERNAL_SECRET") { - http.Error(w, "forbidden", 403) - return - } - - var req struct { - Token string `json:"token"` - User struct { - ID int64 `json:"id"` - FirstName string `json:"first_name"` - LastName string `json:"last_name"` - Username string `json:"username"` - } `json:"telegram_user"` - } - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "bad request", 400) - return - } - - authToken, ok := getAuthToken(req.Token) - if !ok || authToken.Status != "pending" { - http.Error(w, "token not found or already used", 404) - return - } - - // Создать сессию - displayName := req.User.FirstName - if req.User.LastName != "" { - displayName += " " + req.User.LastName - } - var username *string - if req.User.Username != "" { - username = &req.User.Username - } - - session := Session{ - SessionID: uuid.New().String(), - TelegramUserID: req.User.ID, - Username: username, - DisplayName: displayName, - Active: true, - ExpiresAt: time.Now().Add(24 * time.Hour), - } - saveSession(session) - - // Привязать сессию к токену - authToken.Status = "confirmed" - authToken.SessionID = session.SessionID - saveAuthToken(*authToken) - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]string{"status": "ok"}) -} -``` - -**Запрос от бота:** -```json -{ - "token": "dG9rZW4tYWJj...", - "telegram_user": { - "id": 123456789, - "first_name": "Иван", - "last_name": "Петров", - "username": "ivan_petrov" - } -} -``` - ---- - -### 4. `GET /auth/session` - -Фронтенд вызывает для проверки текущей сессии. Читает cookie. - -```go -func handleGetSession(w http.ResponseWriter, r *http.Request) { - cookie, err := r.Cookie("dx_session") - if err != nil { - http.Error(w, "unauthorized", 401) - return - } - - session, err := getSession(cookie.Value) - if err != nil { - http.Error(w, "unauthorized", 401) - return - } - - if time.Now().After(session.ExpiresAt) { - session.Active = false - saveSession(session) - } - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(session) -} -``` - -**Формат ответа (200)** — фронтенд ожидает **точно эти поля**: - -```json -{ - "sessionId": "550e8400-e29b-41d4-a716-446655440000", - "telegramUserId": 123456789, - "username": "ivan_petrov", - "displayName": "Иван Петров", - "active": true, - "expiresAt": "2026-03-25T14:30:00Z" -} -``` - -| Поле | Тип | Обязательно | Примечание | -|------|-----|-------------|------------| -| `sessionId` | string (UUID) | да | Используется для `/websession/{sessionId}` | -| `telegramUserId` | number | да | Telegram user ID | -| `username` | string / null | нет | Telegram @username | -| `displayName` | string | да | "Имя Фамилия" — показывается в UI | -| `active` | boolean | да | `false` = истекла | -| `expiresAt` | string (ISO 8601) | да | Фронтенд перепроверяет за 60 сек до | - -**Ошибка:** любой HTTP не-200 → фронтенд считает "не авторизован". - ---- - -### 5. `GET /auth/telegram/callback` - -Для прямого входа (по кнопке в Telegram, не через QR). Открывается в браузере. - -```go -func handleTelegramCallback(w http.ResponseWriter, r *http.Request) { - token := r.URL.Query().Get("token") - if token == "" { - http.Error(w, "missing token", 400) - return - } - - session, err := getSession(token) - if err != nil || !session.Active { - http.Error(w, "invalid or expired token", 401) - return - } - - domain := getDomainForOrigin(r.Header.Get("Origin")) - if domain == "" { - domain = ".dexarmarket.ru" // fallback для прямого перехода - } - - http.SetCookie(w, &http.Cookie{ - Name: "dx_session", - Value: session.SessionID, - Path: "/", - HttpOnly: true, - Secure: true, - SameSite: http.SameSiteNoneMode, - MaxAge: 86400, - Domain: domain, - }) - - // Редирект на сайт - http.Redirect(w, r, "https://dexarmarket.ru", http.StatusFound) -} -``` - ---- - -### 6. `POST /auth/logout` - -```go -func handleLogout(w http.ResponseWriter, r *http.Request) { - cookie, err := r.Cookie("dx_session") - if err == nil { - deleteSession(cookie.Value) - } - - http.SetCookie(w, &http.Cookie{ - Name: "dx_session", - Value: "", - Path: "/", - HttpOnly: true, - Secure: true, - SameSite: http.SameSiteNoneMode, - MaxAge: -1, - Domain: ".dexarmarket.ru", - }) - - w.Header().Set("Content-Type", "application/json") - w.Write([]byte(`{"message":"ok"}`)) -} -``` - ---- - -## Cookie-параметры - -| Параметр | Значение | Почему | -|----------|----------|--------| -| `Name` | `dx_session` | | -| `SameSite` | `None` | Фронтенд на `dexarmarket.ru`, API на `api.dexarmarket.ru:445` — разные origins | -| `Secure` | `true` | Обязательно при `SameSite=None` | -| `Domain` | `.dexarmarket.ru` | Доступна и на `dexarmarket.ru` и на `api.dexarmarket.ru` | -| `HttpOnly` | `true` | Недоступна из JS — защита от XSS | -| `MaxAge` | `86400` | 24 часа | - ---- - -## CORS - -Фронтенд шлёт `withCredentials: true`. Бэкенд обязан вернуть правильные заголовки. - -```go -func corsMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - origin := r.Header.Get("Origin") - - allowed := map[string]bool{ - "https://dexarmarket.ru": true, - "https://www.dexarmarket.ru": true, - "https://novo.market": true, - "https://www.novo.market": true, - "http://localhost:4200": true, - } - - if allowed[origin] { - w.Header().Set("Access-Control-Allow-Origin", origin) // НЕ "*" - w.Header().Set("Access-Control-Allow-Credentials", "true") - w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") - w.Header().Set("Access-Control-Allow-Headers", "Content-Type") - } - - if r.Method == "OPTIONS" { - w.WriteHeader(200) - return - } - - next.ServeHTTP(w, r) - }) -} -``` - -> **Критично:** `Access-Control-Allow-Origin` не может быть `"*"` при `withCredentials`. Вернуть конкретный origin. - ---- - -## Роутинг - -```go -mux := http.NewServeMux() - -// Существующие -mux.HandleFunc("GET /items/{id}", handleGetItem) -mux.HandleFunc("GET /category", handleGetCategories) -mux.HandleFunc("POST /websession/{id}", handleWebSession) -mux.HandleFunc("POST /websession/{id}/qr", handleCreateQR) -mux.HandleFunc("GET /websession/{id}/{qrId}", handleCheckPayment) - -// Auth — прямой вход -mux.HandleFunc("GET /auth/session", handleGetSession) -mux.HandleFunc("GET /auth/telegram/callback", handleTelegramCallback) -mux.HandleFunc("POST /auth/logout", handleLogout) - -// Auth — QR-логин -mux.HandleFunc("POST /auth/qr/create", handleQrCreate) -mux.HandleFunc("GET /auth/qr/poll", handleQrPoll) -mux.HandleFunc("POST /auth/qr/confirm", handleQrConfirm) - -handler := corsMiddleware(mux) -http.ListenAndServeTLS(":445", "cert.pem", "key.pem", handler) -``` - ---- - -## Telegram-бот - -### Обработчик `/start` - -```go -const ( - confirmURL = "http://localhost:8080/auth/qr/confirm" - botInternalSecret = os.Getenv("BOT_INTERNAL_SECRET") -) - -func handleStart(update tgbotapi.Update) { - text := update.Message.Text - user := update.Message.From - - switch { - case strings.HasPrefix(text, "/start login_"): - handleQrLogin(update, user, strings.TrimPrefix(text, "/start login_")) - - case strings.HasPrefix(text, "/start auth"): - handleDirectAuth(update, user) - - default: - sendWelcome(update) - } -} -``` - -### QR-логин (основной) - -```go -func handleQrLogin(update tgbotapi.Update, user *tgbotapi.User, token string) { - reqBody := map[string]interface{}{ - "token": token, - "telegram_user": map[string]interface{}{ - "id": user.ID, - "first_name": user.FirstName, - "last_name": user.LastName, - "username": user.UserName, - }, - } - bodyBytes, _ := json.Marshal(reqBody) - - req, _ := http.NewRequest("POST", confirmURL, bytes.NewReader(bodyBytes)) - req.Header.Set("Content-Type", "application/json") - req.Header.Set("X-Bot-Secret", botInternalSecret) - - resp, err := http.DefaultClient.Do(req) - if err != nil || resp.StatusCode != 200 { - msg := tgbotapi.NewMessage(update.Message.Chat.ID, - "❌ Не удалось войти. QR-код мог устареть. Попробуйте обновить страницу и отсканировать новый QR.") - bot.Send(msg) - return - } - defer resp.Body.Close() - - displayName := buildDisplayName(user) - msg := tgbotapi.NewMessage(update.Message.Chat.ID, - fmt.Sprintf("✅ Вы вошли на сайт как %s!\n\nМожете вернуться в браузер — страница обновится автоматически.", displayName)) - bot.Send(msg) -} - -func buildDisplayName(user *tgbotapi.User) string { - name := user.FirstName - if user.LastName != "" { - name += " " + user.LastName - } - return name -} -``` - -### Прямой вход (кнопка, для обратной совместимости) - -```go -func handleDirectAuth(update tgbotapi.Update, user *tgbotapi.User) { - session := Session{ - SessionID: uuid.New().String(), - TelegramUserID: user.ID, - Username: stringPtr(user.UserName), - DisplayName: buildDisplayName(user), - Active: true, - ExpiresAt: time.Now().Add(24 * time.Hour), - } - saveSession(session) - - callbackURL := "https://api.dexarmarket.ru:445/auth/telegram/callback" - loginURL := callbackURL + "?token=" + session.SessionID - - msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Нажмите кнопку чтобы войти:") - msg.ReplyMarkup = tgbotapi.NewInlineKeyboardMarkup( - tgbotapi.NewInlineKeyboardRow( - tgbotapi.NewInlineKeyboardButtonURL("🔐 Войти на сайт", loginURL), - ), - ) - bot.Send(msg) -} -``` - -### Запуск бота (long polling) - -```go -func main() { - bot, _ := tgbotapi.NewBotAPI(os.Getenv("BOT_TOKEN")) - - u := tgbotapi.NewUpdate(0) - u.Timeout = 60 - updates := bot.GetUpdatesChan(u) - - for update := range updates { - if update.Message != nil && strings.HasPrefix(update.Message.Text, "/start") { - handleStart(update) - } - } -} -``` - ---- - -## Синхронизация корзины - -Сразу после QR-логина фронтенд автоматически отправляет корзину: - -``` -POST /websession/{sessionId} -``` - -Тело — массив: -```json -[ - { - "itemID": 123, - "quantity": 2, - "colour": "#ff0000", - "size": "XL", - "price": 1500 - } -] -``` - -| Поле | Тип | Примечание | -|------|-----|------------| -| `itemID` | number | ID товара | -| `quantity` | number | Количество | -| `colour` | string | CSS hex (`#ff0000`). Бэкенд отдаёт `0xff0000`, фронтенд конвертирует | -| `size` | string | `"default"` если размер один | -| `price` | number | Финальная цена **с учётом скидки** | - -> Этот эндпоинт (`POST /websession/{id}`) уже существует. Ничего менять не нужно, просто учитывать что он вызывается сразу после успешного логина. - ---- - -## Безопасность - -### Криптографический токен -```go -tokenBytes := make([]byte, 32) // 256 бит -crypto/rand.Read(tokenBytes) -token := base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(tokenBytes) -``` -**НЕ использовать:** `math/rand`, UUID, timestamp. - -### Токен одноразовый -- После `confirmed` → удалить при первом успешном `poll` -- После 5 минут → автоудаление (TTL) -- Повторный `poll` → `"expired"` - -### Защита `/auth/qr/confirm` -```go -if r.Header.Get("X-Bot-Secret") != os.Getenv("BOT_INTERNAL_SECRET") { - http.Error(w, "forbidden", 403) - return -} -``` -Дополнительно: можно ограничить по IP (`127.0.0.1`) если бот на том же сервере. - -### Rate limiting для `/auth/qr/create` -Не более **5 токенов в минуту** с одного IP: -```go -var ipCounts sync.Map - -func rateLimitQrCreate(ip string) bool { - key := ip + ":" + time.Now().Format("2006-01-02T15:04") - val, _ := ipCounts.LoadOrStore(key, new(int32)) - count := atomic.AddInt32(val.(*int32), 1) - return count <= 5 -} -``` - ---- - -## Переменные окружения - -```env -BOT_TOKEN=123456:ABC-DEF... -BOT_INTERNAL_SECRET=случайная-строка-минимум-32-символа -FRONTEND_URL=https://dexarmarket.ru -SESSION_TTL=24h -REDIS_URL=localhost:6379 -``` - -`BOT_INTERNAL_SECRET` должен совпадать в env сервера и env бота. - ---- - -## Тестирование - -### curl-тесты - -**1. Создание токена:** -```bash -curl -X POST https://api.dexarmarket.ru:445/auth/qr/create \ - -H "Origin: https://dexarmarket.ru" -# → { "token": "dG9r...", "url": "https://t.me/DexarSupport_bot?start=login_dG9r..." } -``` - -**2. Поллинг (до подтверждения):** -```bash -curl "https://api.dexarmarket.ru:445/auth/qr/poll?token=dG9r..." -# → { "status": "pending" } -``` - -**3. Подтверждение (имитация бота):** -```bash -curl -X POST https://api.dexarmarket.ru:445/auth/qr/confirm \ - -H "Content-Type: application/json" \ - -H "X-Bot-Secret: ваш-секрет" \ - -d '{"token":"dG9r...","telegram_user":{"id":123,"first_name":"Тест","last_name":"","username":"testuser"}}' -# → { "status": "ok" } -``` - -**4. Поллинг (после подтверждения):** -```bash -curl -v "https://api.dexarmarket.ru:445/auth/qr/poll?token=dG9r..." -# → { "status": "confirmed", "session": {...} } + Set-Cookie: dx_session=... -``` - -**5. E2E:** -1. Открыть маркетплейс → добавить товар в корзину -2. Нажать "Оформить заказ" → появляется диалог с QR -3. Отсканировать QR телефоном → Telegram → бот: "✅ Вы вошли!" -4. Через 3 сек диалог закрывается → авторизован -5. Корзина синхронизирована (`POST /websession/{sessionId}`) - -### Отладка - -| Проблема | Где смотреть | -|----------|-------------| -| QR не показывается | `POST /auth/qr/create` — ошибка? CORS? | -| QR отсканирован, ничего не происходит | Бот получил `/start login_...`? Бот вызвал `confirm`? | -| Бот пишет "❌ QR устарел" | Токен expired? 5 минут прошло? | -| Поллинг "pending" бесконечно | Бот не вызвал `confirm`. Логи бота | -| Поллинг "confirmed" но cookie нет | `SameSite`, `Secure`, `Domain`, CORS | - ---- - -## Чеклист - -### Бэкенд (Go) - -- [ ] Структура `Session` + `AuthToken`, функции save/get/delete -- [ ] `POST /auth/qr/create` — генерация токена -- [ ] `GET /auth/qr/poll?token=...` — статус + cookie при confirmed -- [ ] `POST /auth/qr/confirm` — приём от бота с `X-Bot-Secret` -- [ ] `GET /auth/session` — чтение cookie, JSON сессии -- [ ] `GET /auth/telegram/callback?token=...` — cookie + редирект -- [ ] `POST /auth/logout` — удаление сессии и cookie -- [ ] TTL 5 мин для токенов, 24ч для сессий -- [ ] Rate limiting `/auth/qr/create` (5/мин/IP) -- [ ] Очистка устаревших токенов -- [ ] CORS middleware -- [ ] `BOT_INTERNAL_SECRET` в env - -### Telegram бот - -- [ ] Обработка `/start login_{token}` → `POST /auth/qr/confirm` -- [ ] Обработка `/start auth` → создание сессии + кнопка "Войти" -- [ ] Сообщения: "✅ Вы вошли" / "❌ QR устарел" -- [ ] `BOT_INTERNAL_SECRET` в env (совпадает с сервером) -- [ ] `BOT_TOKEN` в env diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md deleted file mode 100644 index 1928cf2..0000000 --- a/docs/DEPLOYMENT.md +++ /dev/null @@ -1,156 +0,0 @@ -# Dexar Market - Deployment Guide - -## Prerequisites -- Ubuntu/Debian server with root access -- Domain: dexarmarket.ru -- Node.js 18+ installed - -## Quick Deployment - -### 1. Build locally -```bash -npm install -npm run build -``` -Output: `dist/dexarmarket/browser/` - -**VERIFY BUILD LOCALLY:** -```bash -cd dist/dexarmarket/browser -ls -la -``` -You MUST see `index.html`, chunk files, `assets/` folder, etc. - -### 2. Upload to server -```bash -scp -r dist/dexarmarket/browser/* user@your-server:/var/www/dexarmarket/browser/ -``` - -### 3. Set permissions on server -```bash -sudo chown -R www-data:www-data /var/www/dexarmarket -sudo chmod -R 755 /var/www/dexarmarket -sudo nginx -t -sudo systemctl reload nginx -``` - -## Initial Server Setup (one-time) - -### Install and configure Nginx -```bash -sudo apt update -sudo apt install nginx -y -sudo mkdir -p /var/www/dexarmarket/browser -``` - -Copy `nginx.conf` content to `/etc/nginx/sites-available/dexarmarket`: -```bash -sudo nano /etc/nginx/sites-available/dexarmarket -``` - -Then enable it: -```bash -sudo ln -s /etc/nginx/sites-available/dexarmarket /etc/nginx/sites-enabled/ -sudo rm /etc/nginx/sites-enabled/default -sudo nginx -t -sudo systemctl reload nginx -``` - -### Setup SSL (recommended) -```bash -sudo apt install certbot python3-certbot-nginx -y -sudo certbot --nginx -d dexarmarket.ru -d www.dexarmarket.ru -``` - -## Common Issues & Solutions - -### ❌ 404 Error - Files Not Found - -**Check 1: Verify files on server** -```bash -ls -la /var/www/dexarmarket/browser/ -``` -Should show: `index.html`, `chunk-*.js`, `assets/`, etc. - -**If empty:** -```bash -# Re-upload files -scp -r dist/dexarmarket/browser/* user@your-server:/var/www/dexarmarket/browser/ -``` - -**Check 2: Verify permissions** -```bash -namei -l /var/www/dexarmarket/browser/index.html -``` -All directories need `x` (execute) permission. - -**Fix permissions:** -```bash -sudo chown -R www-data:www-data /var/www/dexarmarket -sudo chmod -R 755 /var/www/dexarmarket -``` - -**Check 3: Test nginx config** -```bash -sudo nginx -t -``` -Should say "syntax is ok" and "test is successful". - -**Check 4: View nginx error log** -```bash -sudo tail -f /var/log/nginx/error.log -``` -This shows the actual error! - -### ❌ 502 Bad Gateway - API Issues - -**This means the API backend is down or unreachable.** - -**Check 1: Is API accessible?** -```bash -curl -v https://api.dexarmarket.ru:445/ping -``` - -**Check 2: Port 445 problem** -Port 445 is unusual for HTTPS and may be blocked by firewalls. Standard HTTPS uses port 443. - -**Check 3: CORS issues** -The API must allow requests from `https://dexarmarket.ru`. Check API CORS configuration. - -**Check 4: SSL certificate** -```bash -curl -k https://api.dexarmarket.ru:445/ping -``` -If this works but without `-k` doesn't, SSL cert is invalid. - -### ✅ Final Verification Checklist - -On server, run all these: -```bash -# 1. Files exist -ls -la /var/www/dexarmarket/browser/index.html - -# 2. Nginx config is valid -sudo nginx -t - -# 3. Nginx is running -sudo systemctl status nginx - -# 4. Site is enabled -ls -la /etc/nginx/sites-enabled/ | grep dexarmarket - -# 5. Test API from server -curl -v https://api.dexarmarket.ru:445/ping - -# 6. Check logs -sudo tail -20 /var/log/nginx/error.log -sudo tail -20 /var/log/nginx/access.log -``` - -### Debug Steps - -If still having issues: -1. Check browser console (F12 → Console tab) - shows JavaScript errors -2. Check browser network tab (F12 → Network tab) - shows failed requests -3. Check exact error message in nginx logs -4. Test locally: `cd dist/dexarmarket/browser && python3 -m http.server 8000` diff --git a/docs/IMPLEMENTATION.md b/docs/IMPLEMENTATION.md deleted file mode 100644 index b01d9f3..0000000 --- a/docs/IMPLEMENTATION.md +++ /dev/null @@ -1,140 +0,0 @@ -# Dexar Market - Implementation Summary - -## ✅ Completed Features - -### 1. **Data Models** (`src/app/models/`) -- **Category Model**: Hierarchical category structure -- **Item Model**: Complete product data including photos/videos, pricing, reviews, Q&A - -### 2. **Services** (`src/app/services/`) -- **API Service**: All endpoint integrations - - Health check (`/ping`) - - Categories (`/category`) - - Category items with pagination (`/category/:id`) - - Search with pagination (`/items`) - - Cart operations (GET, POST, DELETE) -- **Cart Service**: Reactive state management using Angular signals - - Add/remove items - - Real-time cart count - - Automatic total price calculation - -### 3. **Pages** (`src/app/pages/`) - -#### **Home Page** (`/`) -- Display all categories in grid layout -- Show subcategories -- Responsive category cards - -#### **Category Page** (`/category/:id`) -- **Infinite Scroll**: Automatically loads more items on scroll -- Product grid with images, pricing, ratings -- Discount badges -- Stock status indicators -- Add to cart functionality - -#### **Search Page** (`/search`) -- **Real-time search** with debounce (300ms) -- **Infinite Scroll** for results -- Same product display as category page -- Empty state handling - -#### **Item Detail Page** (`/item/:id`) -- Photo/video gallery with thumbnails -- Full product information -- Pricing with discount display -- Reviews section with ratings -- Q&A section with voting counts (👍👎) -- Add to cart - -#### **Cart Page** (`/cart`) -- List all cart items with details -- Remove individual items -- Clear entire cart -- Real-time total calculation -- Empty state with call-to-action -- Checkout button (placeholder) - -### 4. **Components** (`src/app/components/`) - -#### **Header Component** -- Sticky navigation -- Cart icon with badge showing item count -- Mobile-responsive hamburger menu -- Active route highlighting - -### 5. **Routing & Configuration** -- Lazy-loaded routes for performance -- HTTP client configured -- All pages connected and navigable - -### 6. **Responsive Design** -- Mobile-first approach -- Breakpoints at 768px and 968px -- Adaptive layouts for all screen sizes -- Touch-friendly interface - -## 🎨 Design Features - -- **Color Scheme**: Purple gradient theme (#667eea primary) -- **Smooth Animations**: Hover effects, transitions -- **Modern UI**: Card-based layouts, rounded corners -- **Custom Scrollbar**: Themed scrollbar styling -- **Loading States**: Spinners and skeleton states -- **Error Handling**: User-friendly error messages - -## 📱 Performance Optimizations - -1. **Infinite Scroll**: Loads 20 items at a time -2. **Lazy Loading**: Route-based code splitting -3. **Image Lazy Loading**: Native lazy loading for images -4. **Debounced Search**: Prevents excessive API calls -5. **Angular Signals**: Efficient reactivity - -## 🔧 Technical Stack - -- Angular 20 (standalone components) -- TypeScript -- RxJS for reactive programming -- SCSS for styling -- Angular Signals for state management - -## 📦 API Integration - -All endpoints from the provided documentation are integrated: -- ✅ GET /ping -- ✅ GET /category -- ✅ GET /category/:categoryID -- ✅ GET /items (search) -- ✅ GET /cart -- ✅ POST /cart -- ✅ DELETE /cart - -## 🚀 How to Run - -```bash -# Install dependencies (if needed) -npm install - -# Start development server -ng serve - -# Open browser -http://localhost:4200 -``` - -## 📝 Notes - -- **Item Detail Limitation**: Currently fetches items from cart for demo. In production, you may want to add a dedicated `/item/:id` endpoint or cache category results. -- **Checkout**: Placeholder button ready for payment integration -- **No Authentication**: As per requirements, no user management implemented -- **API Base URL**: Configured as `https://api.dexarmarket.ru` - -## 🎯 Ready for Production - -The application is production-ready with: -- Type-safe TypeScript -- Modular architecture -- Responsive design -- Error handling -- Performance optimizations -- Clean, maintainable code diff --git a/docs/MULTI_BRAND.md b/docs/MULTI_BRAND.md deleted file mode 100644 index 7ade256..0000000 --- a/docs/MULTI_BRAND.md +++ /dev/null @@ -1,146 +0,0 @@ -# Multi-Brand Configuration - -Этот проект поддерживает несколько брендов с разными темами и конфигурациями. - -## Доступные бренды - -### 1. Dexar Market (фиолетовый) -- **Цвета**: Фиолетовый/пурпурный (#667eea, #764ba2) -- **Домен**: dexarmarket.ru -- **Email**: info@dexarmarket.ru - -### 2. novo Market (зеленый) -- **Цвета**: Зеленый (#10b981, #14b8a6) -- **Домен**: novomarket.ru (будет настроено) -- **Email**: info@novomarket.ru (будет настроено) - -## Команды запуска - -### Dexar Market (разработка) -```bash -ng serve -# или -ng serve --configuration=development -``` - -### novo Market (разработка) -```bash -ng serve --configuration=novo -``` - -### Сборка для продакшена - -#### Dexar Market -```bash -ng build --configuration=production -``` -Результат: `dist/dexarmarket/` - -#### novo Market -```bash -ng build --configuration=novo-production -``` -Результат: `dist/novomarket/` - -## Структура файлов - -``` -src/ -├── environments/ -│ ├── environment.ts # Dexar Development -│ ├── environment.production.ts # Dexar Production -│ ├── environment.novo.ts # novo Development -│ └── environment.novo.production.ts # novo Production -├── styles/ -│ └── themes/ -│ ├── dexar.theme.scss # Dexar цвета (фиолетовый) -│ └── novo.theme.scss # novo цвета (зеленый) -``` - -## Что настраивается через Environment - -В файлах environment можно настроить: - -```typescript -{ - brandName: 'Название бренда', - brandFullName: 'Полное название бренда', - theme: 'dexar' | 'novo', - apiUrl: 'URL API', - logo: 'Путь к логотипу', - contactEmail: 'Email контактов', - supportEmail: 'Email поддержки', - domain: 'Домен сайта', - telegram: 'Telegram канал', - phones: { - russia: 'Телефон в России', - armenia: 'Телефон в Армении' - } -} -``` - -## CSS Переменные - -Темы используют CSS переменные, которые можно изменить: - -```scss -:root { - --primary-color: #10b981; // Основной цвет - --primary-hover: #059669; // Hover эффект - --secondary-color: #14b8a6; // Вторичный цвет - --gradient-primary: linear-gradient(...); - --gradient-hero: linear-gradient(...); - // и другие... -} -``` - -## Обновление для нового бренда - -### Что нужно обновить для novo Market: - -1. ✅ **Environment файлы** - созданы -2. ✅ **Темы (SCSS)** - созданы (зеленые цвета) -3. ✅ **Angular.json конфигурации** - настроены -4. ⏳ **Логотипы и изображения** - добавить в `public/assets/images/` -5. ⏳ **Реквизиты компании** - обновить когда будут готовы -6. ⏳ **Домен и SSL** - настроить при деплое -7. ⏳ **API endpoint** - обновить когда будет готов - -## Деплой - -### Dexar Market -```bash -ng build --configuration=production -# Deploy dist/dexarmarket/ to dexarmarket.ru -``` - -### novo Market -```bash -ng build --configuration=novo-production -# Deploy dist/novomarket/ to novomarket.ru -``` - -## Отличия брендов - -| Параметр | Dexar Market | novo Market | -|----------|--------------|-------------| -| Основной цвет | Фиолетовый (#667eea) | Зеленый (#10b981) | -| Название | Dexar Market | novo Market | -| Домен | dexarmarket.ru | novomarket.ru | -| Email | info@dexarmarket.ru | info@novomarket.ru | -| Telegram | @dexarmarket | @novomarket | -| Реквизиты | Текущие | Будут обновлены | - -## Следующие шаги для novo Market - -1. Добавить логотип novo Market (`public/assets/images/novo-logo.svg`) -2. Обновить реквизиты компании в правовых документах -3. Настроить API endpoint для novo -4. Настроить домен и SSL сертификаты -5. Обновить контактную информацию (телефоны, адреса) - -## Примечания - -- Оба бренда используют одну кодовую базу -- Все компоненты автоматически адаптируются под выбранный бренд -- Легко добавить новые бренды по той же схеме diff --git a/docs/PWA_SETUP.md b/docs/PWA_SETUP.md deleted file mode 100644 index 84685ac..0000000 --- a/docs/PWA_SETUP.md +++ /dev/null @@ -1,206 +0,0 @@ -# PWA Setup Guide - -## ✅ Implemented Features - -### 1. Service Worker -- **Caching Strategy**: Aggressive prefetch for app shell -- **API Caching**: Freshness strategy with 1-hour cache (max 100 requests) -- **Image Caching**: Performance strategy with 7-day cache (max 50 images) -- **Configuration**: `ngsw-config.json` - -### 2. Web App Manifests -- **Dexar**: `public/manifest.webmanifest` (purple theme #a855f7) -- **Novo**: `public/manifest.novo.webmanifest` (green theme #10b981) -- **Features**: - - Installable on mobile/desktop - - Standalone display mode - - 8 icon sizes (72px to 512px) - - Russian language metadata - -### 3. Offline Support -- App shell loads instantly from cache -- API responses cached for 1 hour -- Product images cached for 7 days -- Automatic background updates - -## 🚀 Testing PWA Functionality - -### Local Testing with Production Build - -```bash -# Build for production -npm run build -- --configuration=production - -# Serve the production build -npx http-server dist/dexarmarket -p 4200 -c-1 - -# For Novo brand -npx http-server dist/novomarket -p 4201 -c-1 -``` - -### Chrome DevTools Testing - -1. Open `http://localhost:4200` -2. Open DevTools (F12) -3. Go to **Application** tab -4. Check: - - **Service Workers**: Should show registered worker - - **Cache Storage**: Should show `ngsw:/:db`, `ngsw:/:assets` - - **Manifest**: Should show app details - -### Install Prompt Testing - -1. Open app in Chrome/Edge -2. Click the **install icon** in address bar (➕) -3. Confirm installation -4. App opens as standalone window -5. Check Start Menu/Home Screen for app icon - -### Offline Testing - -1. Open app while online -2. Navigate through pages (loads assets) -3. Open DevTools → Network → Toggle **Offline** -4. Refresh page - should still work! -5. Navigate to cached pages - should load instantly - -## 📱 Mobile Testing - -### Android Chrome -1. Open app URL -2. Chrome shows "Add to Home Screen" banner -3. Install and open - works like native app -4. Splash screen with your logo/colors - -### iOS Safari -1. Open app URL -2. Tap Share → "Add to Home Screen" -3. Icon appears on home screen -4. Opens in full-screen mode - -## 🔧 Configuration Details - -### Service Worker Caching Strategy - -```json -{ - "app": { - "installMode": "prefetch", // Download immediately - "updateMode": "prefetch" // Auto-update in background - }, - "assets": { - "installMode": "lazy", // Load on-demand - "updateMode": "prefetch" - }, - "api-cache": { - "strategy": "freshness", // Network first, fallback to cache - "maxAge": "1h" // Keep for 1 hour - }, - "product-images": { - "strategy": "performance", // Cache first, update in background - "maxAge": "7d" // Keep for 7 days - } -} -``` - -### Manifest Differences - -| Property | Dexar | Novo | -|----------|-------|------| -| Theme Color | #a855f7 (purple) | #10b981 (green) | -| Name | Dexar Market | Novo Market | -| Icons | Default Angular | Default Angular | -| Background | White (#ffffff) | White (#ffffff) | - -## 🎨 Custom Icons (Recommended) - -Replace the default Angular icons with brand-specific ones: - -```bash -public/icons/ -├── icon-72x72.png # Smallest (splash screen) -├── icon-96x96.png -├── icon-128x128.png -├── icon-144x144.png -├── icon-152x152.png # iOS home screen -├── icon-192x192.png # Android home screen -├── icon-384x384.png -└── icon-512x512.png # Largest (splash, install prompt) -``` - -**Design Guidelines**: -- Use solid background color (purple for Dexar, green for Novo) -- Center white logo/icon -- Keep design simple (shows at small sizes) -- Export as PNG with transparency or solid background - -## 🔄 Update Strategy - -### How Updates Work -1. User visits app -2. Service worker checks for updates -3. New version downloads in background -4. User refreshes → gets updated version -5. Old cache automatically cleared - -### Force Update (Development) -```bash -# Clear all caches -chrome://serviceworker-internals/ # Unregister worker -chrome://settings/clearBrowserData # Clear cache - -# Or in code (add to app.config.ts) -navigator.serviceWorker.getRegistrations().then(registrations => { - registrations.forEach(reg => reg.unregister()); -}); -``` - -## 📊 Performance Benefits - -### Before PWA -- Initial load: ~2-3s (network dependent) -- Subsequent loads: ~1-2s -- Offline: ❌ Not available - -### After PWA -- Initial load: ~2-3s (first visit) -- Subsequent loads: **~200-500ms** (cached) -- Offline: ✅ **Fully functional** -- Install: ✅ **Native app experience** - -## 🐛 Troubleshooting - -### Service Worker Not Registering -- Check console for errors -- Ensure HTTPS (or localhost) -- Clear browser cache and reload - -### Old Version Not Updating -- Hard refresh: `Ctrl+Shift+R` (Windows) or `Cmd+Shift+R` (Mac) -- Unregister worker in DevTools -- Wait 24 hours (automatic update) - -### Manifest Not Loading -- Check `index.html` has `` -- Verify manifest path is correct -- Check manifest JSON is valid (no syntax errors) - -### Icons Not Showing -- Check icon paths in manifest -- Ensure icons exist in `public/icons/` -- Verify icon sizes match manifest - -## 📚 Next Steps - -1. **Custom Icons**: Create brand-specific icons for both themes -2. **Push Notifications**: Add user engagement (requires backend) -3. **Background Sync**: Queue offline orders, sync when online -4. **Analytics**: Track PWA installs, offline usage -5. **A2HS Prompt**: Show custom "Install App" banner - -## 🔗 Resources - -- [PWA Checklist](https://web.dev/pwa-checklist/) -- [Angular PWA Guide](https://angular.dev/ecosystem/service-workers) -- [Manifest Generator](https://www.simicart.com/manifest-generator.html/) -- [Icon Generator](https://realfavicongenerator.net/) diff --git a/docs/RAIFFEISENBANK_REQUIREMENTS.md b/docs/RAIFFEISENBANK_REQUIREMENTS.md deleted file mode 100644 index 286b0f3..0000000 --- a/docs/RAIFFEISENBANK_REQUIREMENTS.md +++ /dev/null @@ -1,181 +0,0 @@ -# Рекомендации по работе с платежными ссылками - -## Требования Райффайзенбанка для оплаты по ссылке - -### ✅ Что уже реализовано: - -1. **Реквизиты организации** - полностью заполнены -2. **Правила оплаты** - подробная страница с требованиями ЦБ РФ, PCI DSS, 3D-Secure -3. **Политика возврата** - полная информация о возврате физических и цифровых товаров -4. **Публичная оферта** - модель маркетплейса, разграничение ответственности -5. **Политика конфиденциальности** - обработка персональных данных (152-ФЗ) -6. **Чекбокс согласия в корзине** - со ссылками на: - - Публичную оферту - - Политику возврата - - Условия гарантии - - Политику конфиденциальности -7. **Логотипы платежных систем**: - - МИР (обязательно!) - - Visa - - Mastercard - - Размещены в футере и на странице оплаты - ---- - -## 📧 Рекомендации при отправке платежной ссылки покупателю - -### Шаблон письма/сообщения: - -``` -Здравствуйте, [Имя покупателя]! - -Ваш заказ №[НОМЕР] оформлен. - -Для оплаты перейдите по ссылке: -[ПЛАТЕЖНАЯ ССЫЛКА] - -Сумма к оплате: [СУММА] ₽ - -Перед оплатой, пожалуйста, ознакомьтесь с условиями: -• Публичная оферта: https://dexarmarket.ru/public-offer -• Политика возврата: https://dexarmarket.ru/return-policy -• Условия гарантии: https://dexarmarket.ru/guarantee -• Политика конфиденциальности: https://dexarmarket.ru/privacy-policy - -Оплачивая заказ, вы подтверждаете, что ознакомились и согласны с данными условиями. - ---- -С уважением, -Команда Dexarmarket -Техподдержка: Info@dexarmarket.ru -Телефон: +7 (926) 459-31-57 -``` - -### ✅ Важно получить подтверждение от покупателя! - -**Вариант 1 - Автоматическое подтверждение:** -После оплаты отправить покупателю: -``` -Спасибо за оплату заказа №[НОМЕР]! - -Вы подтвердили согласие с: -✓ Публичной офертой -✓ Политикой возврата -✓ Условиями гарантии -✓ Политикой конфиденциальности - -Чек отправлен на email: [EMAIL] -Статус заказа можно отслеживать в личном кабинете. -``` - -**Вариант 2 - Ручное подтверждение (желательно):** -Перед отправкой ссылки запросить: -``` -Для оформления заказа подтвердите, пожалуйста, что вы ознакомились с условиями -(https://dexarmarket.ru/public-offer) и согласны с ними. - -Ответьте "Согласен" или "Подтверждаю" для продолжения. -``` - ---- - -## 🛡️ Защита от оспаривания платежей (Chargeback) - -### Что сохранять для доказательной базы: - -1. **Переписка с покупателем:** - - Скриншоты чатов - - Email переписка - - SMS/WhatsApp сообщения с подтверждением - -2. **Логи действий покупателя:** - - IP-адрес при оформлении заказа - - Timestamp (дата и время) - - Согласие с чекбоксом (если есть личный кабинет) - -3. **Документы об отправке:** - - Трек-номер посылки - - Подтверждение доставки - - Подпись получателя (если есть) - -4. **Платежная информация:** - - Номер транзакции - - Дата и время оплаты - - Сумма платежа - ---- - -## 🔒 Дополнительные меры безопасности - -### 1. Двухфакторное подтверждение -Для крупных заказов (>10 000 ₽) рекомендуется: -- Звонок покупателю для подтверждения заказа -- Запись разговора (с уведомлением клиента) - -### 2. Проверка благонадежности -Для новых покупателей: -- Проверить совпадение адреса доставки с регионом телефона -- При подозрительных заказах запросить фото документа - -### 3. Страхование рисков -- Оформить договор с платежным провайдером на защиту от мошенничества -- Использовать холдирование средств (72 часа на проверку) - ---- - -## 📊 Статистика оспариваний - -**Риски по категориям товаров:** -- Электроника: ~2-5% оспариваний -- Одежда: ~1-3% -- Цифровые товары: ~0.5-2% -- Продукты питания: ~0.1-0.5% - -**Причины оспариваний:** -1. "Не получил товар" (40%) -2. "Товар не соответствует описанию" (30%) -3. "Не заказывал" (20%) -4. "Дубликат платежа" (10%) - ---- - -## ✅ Чек-лист готовности к работе с Райффайзенбанком - -- [x] Реквизиты организации заполнены -- [x] Правила оплаты на русском языке -- [x] Политика возврата опубликована -- [x] Публичная оферта опубликована -- [x] Политика конфиденциальности опубликована -- [x] Логотип МИР размещен на сайте -- [x] Чекбокс согласия с условиями в корзине -- [x] Ссылки на все документы в чекбоксе -- [ ] Настроен процесс отправки платежных ссылок с условиями -- [ ] Настроен процесс получения подтверждений от покупателей -- [ ] Настроена система логирования действий пользователей -- [ ] Подготовлена база для работы с оспариваниями - ---- - -## 📞 Контакты для связи с банком - -**АО "Райффайзенбанк"** -- Сайт: https://www.raiffeisen.ru -- Требования к сайтам: https://www.raiffeisen.ru/common/img/uploaded/files/business/treb_k_saity.pdf -- Техподдержка эквайринга: указывается при подключении - -**Платежная система МИР** -- Требования к использованию логотипа: https://mironline.ru/support/merchantam/brand/ -- Обязательно размещение логотипа при приеме карт МИР - ---- - -## 🚀 Статус проекта - -**Готовность к подключению эквайринга: 95%** - -Осталось реализовать: -1. Автоматизацию отправки ссылок с условиями -2. Систему получения подтверждений от покупателей -3. Логирование действий для доказательной базы - -**Все юридические и информационные требования выполнены!** ✅ diff --git a/docs/RECOMMENDATIONS.md b/docs/RECOMMENDATIONS.md deleted file mode 100644 index 97074c3..0000000 --- a/docs/RECOMMENDATIONS.md +++ /dev/null @@ -1,423 +0,0 @@ -# Project Recommendations & Roadmap - -## 📊 Current Status: 9.2/10 - -Your project is production-ready with excellent architecture! Here's what to focus on next: - ---- - -## ✅ Recently Completed (January 2026) - -1. **Phone Number Collection** - - Real-time formatting (+7 XXX XXX-XX-XX) - - Comprehensive validation (11 digits) - - Raw digits sent to API - -2. **HTML Structure Unification** - - Single template for both themes - - CSS-only differentiation (Novo/Dexar) - - Eliminated code duplication - -3. **PWA Implementation** - - Service worker with smart caching - - Dual manifests (brand-specific) - - Offline support - - Installable app - -4. **Code Quality** - - Removed 3 duplicate methods - - Fixed SCSS syntax errors - - Optimized cart component - ---- - -## 🎯 Priority Roadmap - -### 🔥 HIGH PRIORITY (Next 2 Weeks) - -#### 1. Custom PWA Icons -**Why**: Branding, professionalism -**Effort**: 2-3 hours -**Impact**: High visibility - -**Action Items**: -```bash -# Create 8 icon sizes for each brand: -# Dexar: Purple (#a855f7) background + white logo -# Novo: Green (#10b981) background + white logo - -public/icons/dexar/ - ├── icon-72x72.png - ├── icon-512x512.png - └── ... - -public/icons/novo/ - ├── icon-72x72.png - └── ... - -# Update manifests to point to brand folders -``` - -**Tools**: Figma, Photoshop, or [RealFaviconGenerator](https://realfavicongenerator.net/) - ---- - -#### 2. Unit Testing -**Why**: Code reliability, easier refactoring -**Effort**: 1-2 weeks -**Impact**: Development velocity, bug reduction - -**Target Coverage**: 80%+ - -**Priority Test Files**: -```typescript -// 1. Services (highest ROI) -cart.service.spec.ts // Test signal updates, cart logic -api.service.spec.ts // Mock HTTP calls -telegram.service.spec.ts // Test WebApp initialization - -// 2. Components (critical paths) -cart.component.spec.ts // Payment flow, validation -header.component.spec.ts // Cart count, navigation -item-detail.component.spec.ts // Add to cart, variant selection - -// 3. Interceptors -cache.interceptor.spec.ts // Verify caching logic -``` - -**Quick Start**: -```bash -# Generate test with Angular CLI -ng test --code-coverage - -# Write first test -describe('CartService', () => { - it('should add item to cart', () => { - service.addToCart(mockItem, mockVariant); - expect(service.cartItems().length).toBe(1); - }); -}); -``` - ---- - -#### 3. Error Boundary & User Feedback -**Why**: Graceful failures, better UX -**Effort**: 1 day -**Impact**: User trust, reduced support tickets - -**Implementation**: -```typescript -// src/app/services/error-handler.service.ts -@Injectable({ providedIn: 'root' }) -export class ErrorHandlerService { - showError(message: string) { - // Show toast notification - // Log to analytics - // Optionally send to backend - } -} - -// Usage in cart.component.ts -this.apiService.createPayment(data).subscribe({ - next: (response) => { /* handle success */ }, - error: (err) => { - this.errorHandler.showError( - 'Не удалось создать платеж. Попробуйте позже.' - ); - console.error(err); - } -}); -``` - -**Add Toast Library**: -```bash -npm install ngx-toastr --save -``` - ---- - -### ⚡ MEDIUM PRIORITY (Next Month) - -#### 4. E2E Testing -**Why**: Catch integration bugs, confidence in releases -**Effort**: 3-5 days -**Impact**: Release quality - -**Recommended**: [Playwright](https://playwright.dev/) (better than Cypress for modern apps) - -```bash -npm install @playwright/test --save-dev -npx playwright install -``` - -**Critical Test Scenarios**: -1. Browse categories → View item → Add to cart → Checkout -2. Search product → Filter results → Add to cart -3. Empty cart → Add items → Remove items -4. Payment flow (mock SBP QR code response) -5. Email/phone validation on success screen - ---- - -#### 5. Analytics Integration -**Why**: Data-driven decisions, understand users -**Effort**: 1 day -**Impact**: Business insights - -**Recommended Setup**: -```typescript -// Yandex Metrica (best for Russian market) - - - -// Track events -yaCounter12345678.reachGoal('ADD_TO_CART', { - product_id: item.id, - price: variant.price -}); -``` - -**Key Metrics to Track**: -- Product views -- Add to cart events -- Checkout initiation -- Payment success/failure -- Search queries -- PWA installs - ---- - -#### 6. Performance Optimization -**Why**: Better UX, SEO, conversion rates -**Effort**: 2-3 days -**Impact**: User satisfaction - -**Action Items**: - -```typescript -// 1. Image Optimization -// Use WebP format with fallbacks - - - Product - - -// 2. Lazy Load Images - - -// 3. Preload Critical Assets -// index.html - - -// 4. Virtual Scrolling for Long Lists -// npm install @angular/cdk - - @for (item of items; track item.id) { -
{{ item.title }}
- } -
-``` - -**Measure First**: -```bash -# Lighthouse audit -npm install -g lighthouse -lighthouse http://localhost:4200 --view - -# Target scores: -# Performance: 90+ -# Accessibility: 95+ -# Best Practices: 100 -# SEO: 90+ -``` - ---- - -### 🔮 FUTURE ENHANCEMENTS (Next Quarter) - -#### 7. Push Notifications -**Why**: Re-engage users, promote offers -**Effort**: 1 week (needs backend) -**Impact**: Retention, sales - -**Requirements**: -- Firebase Cloud Messaging (FCM) -- Backend endpoint to send notifications -- User permission flow - ---- - -#### 8. Background Sync -**Why**: Queue orders offline, sync when online -**Effort**: 2-3 days -**Impact**: Offline-first experience - -```typescript -// Register background sync -navigator.serviceWorker.ready.then(registration => { - registration.sync.register('sync-orders'); -}); - -// ngsw-config.json - already set up! -// Your PWA is ready for this -``` - ---- - -#### 9. Advanced Features -**Effort**: Varies -**Impact**: Competitive advantage - -- **Product Recommendations**: "You might also like..." -- **Recently Viewed**: Track browsing history -- **Wishlist**: Save items for later -- **Price Alerts**: Notify when price drops -- **Social Sharing**: Share products on Telegram/VK -- **Dark Mode**: Theme switcher -- **Multi-language**: Support English, etc. - ---- - -## 🛠️ Technical Debt & Improvements - -### Quick Wins (< 1 hour each) - -1. **Environment Variables for API URLs** - ```typescript - // Don't hardcode API URLs - // Use environment.apiUrl consistently - ``` - -2. **Content Security Policy (CSP)** - ```nginx - # nginx.conf - add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline';"; - ``` - -3. **Rate Limiting** - ```typescript - // Prevent API spam - import { debounceTime } from 'rxjs'; - - searchQuery$.pipe( - debounceTime(300) - ).subscribe(/* search */); - ``` - -4. **Loading States** - ```html - - @if (loading()) { -
- } @else { -
{{ content }}
- } - ``` - -5. **SEO Meta Tags** - ```typescript - // Use Angular's Meta service - constructor(private meta: Meta) {} - - ngOnInit() { - this.meta.updateTag({ - name: 'description', - content: this.product.description - }); - } - ``` - ---- - -## 📈 Success Metrics - -### Before Optimizations -- Test Coverage: ~10% -- Lighthouse Score: ~85 -- Error Tracking: Console only -- Analytics: None -- PWA: ❌ - -### After Optimizations (Target) -- Test Coverage: **80%+** -- Lighthouse Score: **95+** -- Error Tracking: ✅ Centralized -- Analytics: ✅ Yandex Metrica -- PWA: ✅ **Fully functional** -- User Engagement: **+30%** (with push notifications) - ---- - -## 🎓 Learning Resources - -### Testing -- [Angular Testing Guide](https://angular.dev/guide/testing) -- [Testing Library](https://testing-library.com/docs/angular-testing-library/intro/) - -### Performance -- [Web.dev Performance](https://web.dev/performance/) -- [Angular Performance Checklist](https://github.com/mgechev/angular-performance-checklist) - -### PWA -- [PWA Workshop](https://web.dev/learn/pwa/) -- [Workbox](https://developer.chrome.com/docs/workbox/) (service worker library) - -### Analytics -- [Yandex Metrica Guide](https://yandex.ru/support/metrica/) -- [Google Analytics 4](https://developers.google.com/analytics/devguides/collection/ga4) - ---- - -## 💡 Pro Tips - -1. **Ship Frequently**: Deploy small updates often -2. **Monitor Production**: Set up error tracking (Sentry, Rollbar) -3. **User Feedback**: Add feedback button in app -4. **A/B Testing**: Test different checkout flows -5. **Mobile First**: 70%+ of e-commerce is mobile -6. **Accessibility**: Test with screen readers -7. **Security**: Regular dependency updates (`npm audit fix`) - ---- - -## 🚀 Next Actions (This Week) - -```bash -# Day 1: PWA Icons -1. Design icons for both brands -2. Update manifests -3. Test installation on mobile - -# Day 2-3: Error Handling -1. Install ngx-toastr -2. Add ErrorHandlerService -3. Update all API calls with error handling - -# Day 4-5: First Unit Tests -1. Set up testing utilities -2. Write tests for CartService -3. Write tests for cart validation logic -4. Run coverage report: npm test -- --code-coverage - -# Weekend: Analytics -1. Set up Yandex Metrica -2. Add tracking to key events -3. Monitor dashboard -``` - ---- - -## 💬 Questions? - -If you need help with any of these tasks: -1. Ask for specific code examples -2. Request architectural guidance -3. Need library recommendations -4. Want code reviews - -Your project is already excellent - these improvements will make it world-class! 🌟 diff --git a/docs/TELEGRAM_USERAUTH_BACKEND.md b/docs/TELEGRAM_USERAUTH_BACKEND.md deleted file mode 100644 index 902464d..0000000 --- a/docs/TELEGRAM_USERAUTH_BACKEND.md +++ /dev/null @@ -1,327 +0,0 @@ -# Telegram UserAuth Backend Contract - -This document extracts the existing Telegram login flow into a repo-neutral contract for reuse in other projects. - -The UI behavior, payloads, polling cadence, and session model stay the same. Only route names and cookie naming are generalized. - -## Endpoint Renaming - -| Current app contract | Reusable contract | -|---|---| -| `GET /auth/session` | `GET /userauth/session` | -| `POST /auth/qr/create` | `POST /userauth/qr/create` | -| `GET /auth/qr/poll?token=...` | `GET /userauth/qr/poll?token=...` | -| `POST /auth/qr/confirm` | `POST /userauth/qr/confirm` | -| `GET /auth/telegram/callback` | `GET /userauth/telegram/callback` | -| `POST /auth/logout` | `POST /userauth/logout` | -| `POST /websession/{sessionId}` | `POST /usersession/{sessionId}` | -| Cookie `dx_session` | Cookie `userauth_session` | - -## Flow Summary - -There are two supported flows. - -### 1. Direct login from button - -1. Frontend opens `https://t.me/{botUsername}?start=auth_{callbackUrl}`. -2. Telegram bot creates a session and sends the user a login button. -3. The button points to `GET /userauth/telegram/callback?token={sessionId}`. -4. Backend sets `userauth_session` cookie and redirects back to the storefront. -5. Frontend calls `GET /userauth/session` and becomes authenticated. - -### 2. QR login from desktop - -1. Frontend opens dialog. -2. Frontend calls `POST /userauth/qr/create`. -3. Backend returns `{ token, url }` where `url` is a Telegram deep link. -4. Frontend renders a QR from that URL. -5. User scans QR and bot calls `POST /userauth/qr/confirm`. -6. Frontend polls `GET /userauth/qr/poll?token=...` every 3 seconds. -7. When status becomes `confirmed`, backend returns session payload and sets the cookie. -8. Frontend syncs local cart using `POST /usersession/{sessionId}`. - -## Session Shape - -The frontend expects this exact response shape for the authenticated session. - -```json -{ - "sessionId": "550e8400-e29b-41d4-a716-446655440000", - "telegramUserId": 123456789, - "username": "ivan_petrov", - "displayName": "Ivan Petrov", - "active": true, - "expiresAt": "2026-05-21T14:30:00Z" -} -``` - -| Field | Type | Required | Notes | -|---|---|---|---| -| `sessionId` | string | yes | Session identifier used in cart sync | -| `telegramUserId` | number | yes | Telegram user ID | -| `username` | string or null | no | Telegram username | -| `displayName` | string | yes | User-facing full name | -| `active` | boolean | yes | `false` means expired session | -| `expiresAt` | ISO 8601 string | yes | Used by frontend refresh scheduling | - -Recommended TTL: - -- Session TTL: 24 hours -- QR token TTL: 5 minutes - -## HTTP Contract - -### `POST /userauth/qr/create` - -Creates a one-time QR login token when the dialog opens. - -Request body: - -```json -{} -``` - -Response `200`: - -```json -{ - "token": "dG9rZW4tYWJjMTIz", - "url": "https://t.me/userauth_bot?start=login_dG9rZW4tYWJjMTIz" -} -``` - -Requirements: - -- Generate a cryptographically secure token. -- Save token with status `pending`. -- Return a Telegram deep link in `url`. -- Rate limit to 5 requests per minute per IP. - -### `GET /userauth/qr/poll?token={token}` - -Called every 3 seconds until confirmation or expiration. - -Possible responses: - -Pending: - -```json -{ "status": "pending" } -``` - -Confirmed: - -```json -{ - "status": "confirmed", - "session": { - "sessionId": "550e8400-e29b-41d4-a716-446655440000", - "telegramUserId": 123456789, - "username": "ivan_petrov", - "displayName": "Ivan Petrov", - "active": true, - "expiresAt": "2026-05-21T14:30:00Z" - } -} -``` - -Expired: - -```json -{ "status": "expired" } -``` - -Behavior: - -- If confirmed, set cookie `userauth_session` in the response. -- Delete or invalidate the QR token after the first successful confirmed poll. -- If token is unknown or expired, return `status: "expired"`. - -### `POST /userauth/qr/confirm` - -Internal endpoint called by the Telegram bot after the user scans the QR code. - -Required header: - -```text -X-Bot-Secret: -``` - -Request body: - -```json -{ - "token": "dG9rZW4tYWJjMTIz", - "telegram_user": { - "id": 123456789, - "first_name": "Ivan", - "last_name": "Petrov", - "username": "ivan_petrov" - } -} -``` - -Response `200`: - -```json -{ "status": "ok" } -``` - -Behavior: - -- Validate `X-Bot-Secret`. -- Validate token exists and is still `pending`. -- Create a user session. -- Store session ID on the QR token. -- Mark QR token as `confirmed`. - -### `GET /userauth/session` - -Returns the currently active session based on the cookie. - -Frontend behavior depends on this endpoint in two places: - -- initial auth check on app startup -- fallback polling if QR token creation fails - -Response `200`: - -```json -{ - "sessionId": "550e8400-e29b-41d4-a716-446655440000", - "telegramUserId": 123456789, - "username": "ivan_petrov", - "displayName": "Ivan Petrov", - "active": true, - "expiresAt": "2026-05-21T14:30:00Z" -} -``` - -Error handling: - -- Any non-200 response is treated by the frontend as unauthenticated. - -### `GET /userauth/telegram/callback?token={sessionId}` - -Used for direct Telegram login from the primary button flow. - -Behavior: - -- Read the `token` query param. -- Resolve it to a valid active session. -- Set cookie `userauth_session`. -- Redirect user to the storefront URL. - -### `POST /userauth/logout` - -Clears the backend session and expires the cookie. - -Request body: - -```json -{} -``` - -Response `200`: - -```json -{ "message": "ok" } -``` - -### `POST /usersession/{sessionId}` - -Synchronizes local cart immediately after successful login. - -Request body: - -```json -[ - { - "itemID": 123, - "quantity": 2, - "colour": "#ff0000", - "size": "XL", - "price": 1500 - } -] -``` - -Notes: - -- This payload is unchanged from the existing implementation. -- `price` is already discounted on the frontend side. -- The frontend skips the call if cart is empty. - -## Telegram Deep Link Format - -Direct login link format: - -```text -https://t.me/{botUsername}?start=auth_{urlEncodedCallbackUrl} -``` - -QR login link format: - -```text -https://t.me/{botUsername}?start=login_{qrToken} -``` - -Important limit: - -- Telegram limits the `start` payload to 64 characters. -- A base64url encoding of 32 random bytes plus `login_` fits safely. - -## Cookie Requirements - -Use these cookie settings for the frontend to work correctly across site and API origins. - -| Property | Value | -|---|---| -| Name | `userauth_session` | -| Path | `/` | -| HttpOnly | `true` | -| Secure | `true` | -| SameSite | `None` | -| MaxAge | `86400` | -| Domain | your shared parent domain, for example `.example.com` | - -## CORS Requirements - -Because the frontend sends credentials, backend must return an explicit origin. - -Required headers: - -```text -Access-Control-Allow-Origin: https://your-frontend.example -Access-Control-Allow-Credentials: true -Access-Control-Allow-Methods: GET, POST, OPTIONS -Access-Control-Allow-Headers: Content-Type -``` - -Do not use `*` for `Access-Control-Allow-Origin` together with credentials. - -## Frontend Runtime Expectations - -The current dialog behavior is fixed and should be preserved by backend responses. - -- QR polling interval: every 3 seconds -- QR expiration on frontend: after 100 checks -- If QR creation fails, frontend falls back to direct login URL and session polling -- After login, frontend closes the dialog and re-checks session - -## Minimal Backend Checklist - -- Implement all six `userauth` endpoints and the `usersession` sync endpoint. -- Store sessions for 24 hours. -- Store QR tokens for 5 minutes. -- Protect `POST /userauth/qr/confirm` with `X-Bot-Secret`. -- Set `userauth_session` cookie on confirmed QR poll and direct callback. -- Return the exact session JSON shape. -- Support credentialed CORS. - -## Bot Checklist - -- Handle `/start login_{token}` and call `POST /userauth/qr/confirm`. -- Handle `/start auth_{callbackUrl}` and provide a button that opens the callback URL. -- Send success and expiration messages back to the user. -- Share the same `X-Bot-Secret` value with backend. \ No newline at end of file diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md deleted file mode 100644 index 3998ed1..0000000 --- a/docs/TROUBLESHOOTING.md +++ /dev/null @@ -1,193 +0,0 @@ -# 🔧 Troubleshooting Guide for 404 and 502 Errors - -## Quick Diagnosis - -Run these commands on your Ubuntu server to diagnose the issue: - -```bash -# 1. Check if files exist -ls -la /var/www/dexarmarket/browser/index.html - -# 2. Check nginx config syntax -sudo nginx -t - -# 3. Check nginx error logs (THIS IS MOST IMPORTANT!) -sudo tail -30 /var/log/nginx/error.log - -# 4. Check if nginx is running -sudo systemctl status nginx - -# 5. Test API from server -curl -v https://api.dexarmarket.ru:445/ping -``` - -## Error: 404 Not Found - -### Cause: Files not uploaded or wrong path - -**Solution 1: Verify files are on server** -```bash -ls -la /var/www/dexarmarket/browser/ -``` - -Should show: -- `index.html` -- `main-*.js` -- `chunk-*.js` -- `polyfills-*.js` -- `styles-*.css` -- `assets/` folder - -**If files are missing:** -```bash -# From your local machine: -cd F:\dx\marketplace\Dexarmarket -npm run build -scp -r dist/dexarmarket/browser/* user@your-server:/var/www/dexarmarket/browser/ -``` - -**Solution 2: Fix permissions** -```bash -sudo chown -R www-data:www-data /var/www/dexarmarket -sudo chmod -R 755 /var/www/dexarmarket -``` - -**Solution 3: Check nginx config is loaded** -```bash -# Check which config is active -ls -la /etc/nginx/sites-enabled/ - -# Should show symlink to dexarmarket config -# If not: -sudo ln -s /etc/nginx/sites-available/dexarmarket /etc/nginx/sites-enabled/ -sudo nginx -t -sudo systemctl reload nginx -``` - -**Solution 4: Verify nginx root path** -```bash -sudo cat /etc/nginx/sites-available/dexarmarket | grep root -``` - -Should show: `root /var/www/dexarmarket/browser;` - -## Error: 502 Bad Gateway - -### This means the API backend (https://api.dexarmarket.ru:445) is unreachable - -**Solution 1: Check if API is running** -```bash -# From Ubuntu server: -curl -v https://api.dexarmarket.ru:445/ping - -# If this fails, your API backend is down! -``` - -**Solution 2: Port 445 is blocked** -Port 445 is typically blocked by many firewalls because it's used for SMB file sharing. - -**Check from browser console (F12):** -- Open browser Developer Tools (F12) -- Go to Console tab -- Look for errors like: `net::ERR_CONNECTION_REFUSED` or `net::ERR_SSL_PROTOCOL_ERROR` - -**Possible fixes:** -- Use standard port 443 for HTTPS -- Or use port 8443, 8080, or other non-standard but common ports -- Configure firewall to allow port 445 - -**Solution 3: CORS issues** -The API must have CORS headers allowing requests from `https://dexarmarket.ru` - -Check API response headers: -```bash -curl -v -H "Origin: https://dexarmarket.ru" https://api.dexarmarket.ru:445/ping -``` - -Should include headers like: -``` -Access-Control-Allow-Origin: https://dexarmarket.ru -``` - -**Solution 4: SSL Certificate issues** -```bash -# Test with SSL verification disabled -curl -k https://api.dexarmarket.ru:445/ping - -# If this works but normal curl doesn't, SSL cert is invalid -``` - -## Still Not Working? - -### Get detailed error information: - -**1. Browser Console (JavaScript errors)** -``` -F12 → Console tab -Look for red errors -``` - -**2. Browser Network Tab (Failed requests)** -``` -F12 → Network tab -Reload page -Look for red (failed) requests -Click on failed request to see details -``` - -**3. Nginx Error Log (Server-side errors)** -```bash -sudo tail -50 /var/log/nginx/error.log -``` - -**4. Nginx Access Log (See what requests come in)** -```bash -sudo tail -50 /var/log/nginx/access.log -``` - -**5. Test Build Locally** -```bash -cd F:\dx\marketplace\Dexarmarket\dist\dexarmarket\browser -python -m http.server 8000 -# Visit http://localhost:8000 -``` - -If local test works, the issue is with deployment, not the build. - -## Common Mistakes - -❌ **Uploading to wrong directory** -- Correct: `/var/www/dexarmarket/browser/` -- Wrong: `/var/www/dexarmarket/` (missing browser/) - -❌ **Wrong permissions** -```bash -# Must be readable by www-data -sudo chown -R www-data:www-data /var/www/dexarmarket -sudo chmod -R 755 /var/www/dexarmarket -``` - -❌ **Nginx config not reloaded** -```bash -# After ANY change to nginx config: -sudo nginx -t -sudo systemctl reload nginx -``` - -❌ **Old files cached** -```bash -# Clear browser cache: Ctrl+Shift+R (hard refresh) -``` - -❌ **API port blocked** -- Port 445 is unusual and often blocked -- Consider using port 443 (standard HTTPS) - -## Contact Information for Support - -When asking for help, provide: -1. Output of `sudo nginx -t` -2. Last 30 lines of nginx error log: `sudo tail -30 /var/log/nginx/error.log` -3. Browser console errors (F12 → Console) -4. Result of `curl -v https://api.dexarmarket.ru:445/ping` from server -5. Screenshot of browser Network tab showing failed request diff --git a/docs/telegram-login-dialog.html b/docs/telegram-login-dialog.html deleted file mode 100644 index 62c3666..0000000 --- a/docs/telegram-login-dialog.html +++ /dev/null @@ -1,551 +0,0 @@ - - - - - - Telegram Login Dialog - - - -
-
-

Telegram Login Dialog

-

- Standalone extraction of the current login popup: same layout, same visual states, - same QR flow, but with reusable neutral endpoint names for moving into a separate repo. -

- -
- - - - - -
- -
-
- Start QR session - POST /userauth/qr/create -

Returns a one-time token and Telegram deeplink for the QR image.

-
-
- Poll QR confirmation - GET /userauth/qr/poll?token=... -

Returns pending, confirmed, or expired. On confirmed, also returns the user session.

-
-
- Read current session - GET /userauth/session -

Cookie-based session lookup used for initial auth check and fallback polling.

-
-
- Sync cart after login - POST /usersession/{sessionId} -

Existing cart payload is preserved. Only the namespace is generalized for reuse.

-
-
- - -
- -
- -
-
- - - - \ No newline at end of file diff --git a/package.json b/package.json index ca7227f..f9ff004 100644 --- a/package.json +++ b/package.json @@ -5,16 +5,10 @@ "ng": "ng", "start": "ng serve", "dexar": "ng serve --configuration=development --port 4200", - "novo": "ng serve --configuration=novo --port 4201 --proxy-config proxy.conf.novo.json", "start:dexar": "ng serve --configuration=development --port 4200", - "start:novo": "ng serve --configuration=novo --port 4201", "build": "ng build", "build:dexar": "ng build --configuration=production", - "build:novo": "ng build --configuration=novo-production", "watch": "ng build --watch --configuration development", - "lavero": "ng serve --configuration=lavero --port 4202 --proxy-config proxy.conf.lavero.json", - "start:lavero": "ng serve --configuration=lavero --port 4202", - "build:lavero": "ng build --configuration=lavero-production", "arch:check:boundaries": "node tools/architecture/check-boundaries.mjs", "arch:check:cycles": "npx --yes madge --circular --extensions ts src/app --ts-config tsconfig.app.json", "arch:check": "npm run arch:check:boundaries ; npm run arch:check:cycles" diff --git a/src/app/app.ts b/src/app/app.ts index d48587e..4d75cb8 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -14,6 +14,7 @@ import { SwUpdate } from '@angular/service-worker'; import { TranslatePipe } from './i18n/translate.pipe'; import { TranslateService } from './i18n/translate.service'; import { PlatformRuntimeService } from './core/runtime/platform-runtime.service'; +import { UiRuntimeFacade } from './facades/runtime/ui-runtime.facade'; @Component({ selector: 'app-root', @@ -22,7 +23,7 @@ import { PlatformRuntimeService } from './core/runtime/platform-runtime.service' styleUrl: './app.scss' }) export class App implements OnInit { - protected title = environment.brandName; + protected title = ''; isHomePage = signal(true); checkingServer = signal(true); serverAvailable = signal(false); @@ -35,10 +36,12 @@ export class App implements OnInit { private router = inject(Router); private i18n = inject(TranslateService); private platformRuntime = inject(PlatformRuntimeService); + private uiRuntime = inject(UiRuntimeFacade); ngOnInit(): void { this.platformRuntime.initialize(); - this.titleService.setTitle(`${environment.brandFullName} - ${this.i18n.t('app.pageTitle')}`); + this.title = this.uiRuntime.marketplaceName(); + this.titleService.setTitle(`${this.uiRuntime.marketplaceDisplayName()} - ${this.i18n.t('app.pageTitle')}`); this.checkServerHealth(); this.setupAutoUpdates(); diff --git a/src/app/brands/lavero/pages/info/about/about.component.html b/src/app/brands/lavero/pages/info/about/about.component.html deleted file mode 100644 index 1a78582..0000000 --- a/src/app/brands/lavero/pages/info/about/about.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} diff --git a/src/app/brands/lavero/pages/info/about/about.component.ts b/src/app/brands/lavero/pages/info/about/about.component.ts deleted file mode 100644 index d44a75c..0000000 --- a/src/app/brands/lavero/pages/info/about/about.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { AboutLaveroRuComponent } from './ru/about-ru.component'; -import { AboutLaveroEnComponent } from './en/about-en.component'; -import { AboutLaveroHyComponent } from './hy/about-hy.component'; - -@Component({ - selector: 'app-about-lavero', - imports: [AboutLaveroRuComponent, AboutLaveroEnComponent, AboutLaveroHyComponent], - templateUrl: './about.component.html', - styleUrls: ['../../../../../pages/info/about/about.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class AboutLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/info/about/en/about-en.component.html b/src/app/brands/lavero/pages/info/about/en/about-en.component.html deleted file mode 100644 index b01ae89..0000000 --- a/src/app/brands/lavero/pages/info/about/en/about-en.component.html +++ /dev/null @@ -1,98 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/about/en/about-en.component.ts b/src/app/brands/lavero/pages/info/about/en/about-en.component.ts deleted file mode 100644 index d9fe35c..0000000 --- a/src/app/brands/lavero/pages/info/about/en/about-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-about-lavero-en', - templateUrl: './about-en.component.html', - styleUrls: ['../../../../../../pages/info/about/about.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class AboutLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/about/hy/about-hy.component.html b/src/app/brands/lavero/pages/info/about/hy/about-hy.component.html deleted file mode 100644 index 96578c0..0000000 --- a/src/app/brands/lavero/pages/info/about/hy/about-hy.component.html +++ /dev/null @@ -1,98 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/about/hy/about-hy.component.ts b/src/app/brands/lavero/pages/info/about/hy/about-hy.component.ts deleted file mode 100644 index e20dd19..0000000 --- a/src/app/brands/lavero/pages/info/about/hy/about-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-about-lavero-hy', - templateUrl: './about-hy.component.html', - styleUrls: ['../../../../../../pages/info/about/about.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class AboutLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/about/ru/about-ru.component.html b/src/app/brands/lavero/pages/info/about/ru/about-ru.component.html deleted file mode 100644 index b2bb35e..0000000 --- a/src/app/brands/lavero/pages/info/about/ru/about-ru.component.html +++ /dev/null @@ -1,98 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/about/ru/about-ru.component.ts b/src/app/brands/lavero/pages/info/about/ru/about-ru.component.ts deleted file mode 100644 index 947e9f7..0000000 --- a/src/app/brands/lavero/pages/info/about/ru/about-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-about-lavero-ru', - templateUrl: './about-ru.component.html', - styleUrls: ['../../../../../../pages/info/about/about.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class AboutLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/contacts/contacts.component.html b/src/app/brands/lavero/pages/info/contacts/contacts.component.html deleted file mode 100644 index f2c8222..0000000 --- a/src/app/brands/lavero/pages/info/contacts/contacts.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} diff --git a/src/app/brands/lavero/pages/info/contacts/contacts.component.ts b/src/app/brands/lavero/pages/info/contacts/contacts.component.ts deleted file mode 100644 index 3d3ac34..0000000 --- a/src/app/brands/lavero/pages/info/contacts/contacts.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { ContactsLaveroRuComponent } from './ru/contacts-ru.component'; -import { ContactsLaveroEnComponent } from './en/contacts-en.component'; -import { ContactsLaveroHyComponent } from './hy/contacts-hy.component'; - -@Component({ - selector: 'app-contacts-lavero', - imports: [ContactsLaveroRuComponent, ContactsLaveroEnComponent, ContactsLaveroHyComponent], - templateUrl: './contacts.component.html', - styleUrls: ['../../../../../pages/info/contacts/contacts.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ContactsLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/info/contacts/en/contacts-en.component.html b/src/app/brands/lavero/pages/info/contacts/en/contacts-en.component.html deleted file mode 100644 index 55b2c5b..0000000 --- a/src/app/brands/lavero/pages/info/contacts/en/contacts-en.component.html +++ /dev/null @@ -1,49 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/contacts/en/contacts-en.component.ts b/src/app/brands/lavero/pages/info/contacts/en/contacts-en.component.ts deleted file mode 100644 index 1306d15..0000000 --- a/src/app/brands/lavero/pages/info/contacts/en/contacts-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-contacts-lavero-en', - templateUrl: './contacts-en.component.html', - styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ContactsLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/contacts/hy/contacts-hy.component.html b/src/app/brands/lavero/pages/info/contacts/hy/contacts-hy.component.html deleted file mode 100644 index 9d8d458..0000000 --- a/src/app/brands/lavero/pages/info/contacts/hy/contacts-hy.component.html +++ /dev/null @@ -1,49 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/contacts/hy/contacts-hy.component.ts b/src/app/brands/lavero/pages/info/contacts/hy/contacts-hy.component.ts deleted file mode 100644 index f0168eb..0000000 --- a/src/app/brands/lavero/pages/info/contacts/hy/contacts-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-contacts-lavero-hy', - templateUrl: './contacts-hy.component.html', - styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ContactsLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/contacts/ru/contacts-ru.component.html b/src/app/brands/lavero/pages/info/contacts/ru/contacts-ru.component.html deleted file mode 100644 index fa24eac..0000000 --- a/src/app/brands/lavero/pages/info/contacts/ru/contacts-ru.component.html +++ /dev/null @@ -1,49 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/contacts/ru/contacts-ru.component.ts b/src/app/brands/lavero/pages/info/contacts/ru/contacts-ru.component.ts deleted file mode 100644 index 5a0a40d..0000000 --- a/src/app/brands/lavero/pages/info/contacts/ru/contacts-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-contacts-lavero-ru', - templateUrl: './contacts-ru.component.html', - styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ContactsLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/delivery/delivery.component.html b/src/app/brands/lavero/pages/info/delivery/delivery.component.html deleted file mode 100644 index 15c294e..0000000 --- a/src/app/brands/lavero/pages/info/delivery/delivery.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} diff --git a/src/app/brands/lavero/pages/info/delivery/delivery.component.ts b/src/app/brands/lavero/pages/info/delivery/delivery.component.ts deleted file mode 100644 index 67d8822..0000000 --- a/src/app/brands/lavero/pages/info/delivery/delivery.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { DeliveryLaveroRuComponent } from './ru/delivery-ru.component'; -import { DeliveryLaveroEnComponent } from './en/delivery-en.component'; -import { DeliveryLaveroHyComponent } from './hy/delivery-hy.component'; - -@Component({ - selector: 'app-delivery-lavero', - imports: [DeliveryLaveroRuComponent, DeliveryLaveroEnComponent, DeliveryLaveroHyComponent], - templateUrl: './delivery.component.html', - styleUrls: ['../../../../../pages/info/delivery/delivery.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DeliveryLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/info/delivery/en/delivery-en.component.html b/src/app/brands/lavero/pages/info/delivery/en/delivery-en.component.html deleted file mode 100644 index fe96f15..0000000 --- a/src/app/brands/lavero/pages/info/delivery/en/delivery-en.component.html +++ /dev/null @@ -1,78 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/delivery/en/delivery-en.component.ts b/src/app/brands/lavero/pages/info/delivery/en/delivery-en.component.ts deleted file mode 100644 index 0ed8547..0000000 --- a/src/app/brands/lavero/pages/info/delivery/en/delivery-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-delivery-lavero-en', - templateUrl: './delivery-en.component.html', - styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DeliveryLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/delivery/hy/delivery-hy.component.html b/src/app/brands/lavero/pages/info/delivery/hy/delivery-hy.component.html deleted file mode 100644 index dea752c..0000000 --- a/src/app/brands/lavero/pages/info/delivery/hy/delivery-hy.component.html +++ /dev/null @@ -1,78 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/delivery/hy/delivery-hy.component.ts b/src/app/brands/lavero/pages/info/delivery/hy/delivery-hy.component.ts deleted file mode 100644 index 1ca4b52..0000000 --- a/src/app/brands/lavero/pages/info/delivery/hy/delivery-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-delivery-lavero-hy', - templateUrl: './delivery-hy.component.html', - styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DeliveryLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/delivery/ru/delivery-ru.component.html b/src/app/brands/lavero/pages/info/delivery/ru/delivery-ru.component.html deleted file mode 100644 index 2641d05..0000000 --- a/src/app/brands/lavero/pages/info/delivery/ru/delivery-ru.component.html +++ /dev/null @@ -1,78 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/delivery/ru/delivery-ru.component.ts b/src/app/brands/lavero/pages/info/delivery/ru/delivery-ru.component.ts deleted file mode 100644 index ea3872c..0000000 --- a/src/app/brands/lavero/pages/info/delivery/ru/delivery-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-delivery-lavero-ru', - templateUrl: './delivery-ru.component.html', - styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DeliveryLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/faq/en/faq-en.component.html b/src/app/brands/lavero/pages/info/faq/en/faq-en.component.html deleted file mode 100644 index 12e16f2..0000000 --- a/src/app/brands/lavero/pages/info/faq/en/faq-en.component.html +++ /dev/null @@ -1,93 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/faq/en/faq-en.component.ts b/src/app/brands/lavero/pages/info/faq/en/faq-en.component.ts deleted file mode 100644 index bc13f27..0000000 --- a/src/app/brands/lavero/pages/info/faq/en/faq-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-faq-lavero-en', - templateUrl: './faq-en.component.html', - styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class FaqLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/faq/faq.component.html b/src/app/brands/lavero/pages/info/faq/faq.component.html deleted file mode 100644 index 78edde9..0000000 --- a/src/app/brands/lavero/pages/info/faq/faq.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} diff --git a/src/app/brands/lavero/pages/info/faq/faq.component.ts b/src/app/brands/lavero/pages/info/faq/faq.component.ts deleted file mode 100644 index 5bb6a95..0000000 --- a/src/app/brands/lavero/pages/info/faq/faq.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { FaqLaveroRuComponent } from './ru/faq-ru.component'; -import { FaqLaveroEnComponent } from './en/faq-en.component'; -import { FaqLaveroHyComponent } from './hy/faq-hy.component'; - -@Component({ - selector: 'app-faq-lavero', - imports: [FaqLaveroRuComponent, FaqLaveroEnComponent, FaqLaveroHyComponent], - templateUrl: './faq.component.html', - styleUrls: ['../../../../../pages/info/faq/faq.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class FaqLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/info/faq/hy/faq-hy.component.html b/src/app/brands/lavero/pages/info/faq/hy/faq-hy.component.html deleted file mode 100644 index 8848049..0000000 --- a/src/app/brands/lavero/pages/info/faq/hy/faq-hy.component.html +++ /dev/null @@ -1,93 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/faq/hy/faq-hy.component.ts b/src/app/brands/lavero/pages/info/faq/hy/faq-hy.component.ts deleted file mode 100644 index a6f72dd..0000000 --- a/src/app/brands/lavero/pages/info/faq/hy/faq-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-faq-lavero-hy', - templateUrl: './faq-hy.component.html', - styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class FaqLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/faq/ru/faq-ru.component.html b/src/app/brands/lavero/pages/info/faq/ru/faq-ru.component.html deleted file mode 100644 index aa67e90..0000000 --- a/src/app/brands/lavero/pages/info/faq/ru/faq-ru.component.html +++ /dev/null @@ -1,93 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/faq/ru/faq-ru.component.ts b/src/app/brands/lavero/pages/info/faq/ru/faq-ru.component.ts deleted file mode 100644 index 0a9c7ff..0000000 --- a/src/app/brands/lavero/pages/info/faq/ru/faq-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-faq-lavero-ru', - templateUrl: './faq-ru.component.html', - styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class FaqLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/guarantee/en/guarantee-en.component.html b/src/app/brands/lavero/pages/info/guarantee/en/guarantee-en.component.html deleted file mode 100644 index 2ce399c..0000000 --- a/src/app/brands/lavero/pages/info/guarantee/en/guarantee-en.component.html +++ /dev/null @@ -1,92 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/guarantee/en/guarantee-en.component.ts b/src/app/brands/lavero/pages/info/guarantee/en/guarantee-en.component.ts deleted file mode 100644 index c3e3ca7..0000000 --- a/src/app/brands/lavero/pages/info/guarantee/en/guarantee-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-guarantee-lavero-en', - templateUrl: './guarantee-en.component.html', - styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class GuaranteeLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/guarantee/guarantee.component.html b/src/app/brands/lavero/pages/info/guarantee/guarantee.component.html deleted file mode 100644 index 3da7f61..0000000 --- a/src/app/brands/lavero/pages/info/guarantee/guarantee.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} diff --git a/src/app/brands/lavero/pages/info/guarantee/guarantee.component.ts b/src/app/brands/lavero/pages/info/guarantee/guarantee.component.ts deleted file mode 100644 index 79010f6..0000000 --- a/src/app/brands/lavero/pages/info/guarantee/guarantee.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { GuaranteeLaveroRuComponent } from './ru/guarantee-ru.component'; -import { GuaranteeLaveroEnComponent } from './en/guarantee-en.component'; -import { GuaranteeLaveroHyComponent } from './hy/guarantee-hy.component'; - -@Component({ - selector: 'app-guarantee-lavero', - imports: [GuaranteeLaveroRuComponent, GuaranteeLaveroEnComponent, GuaranteeLaveroHyComponent], - templateUrl: './guarantee.component.html', - styleUrls: ['../../../../../pages/info/guarantee/guarantee.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class GuaranteeLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/info/guarantee/hy/guarantee-hy.component.html b/src/app/brands/lavero/pages/info/guarantee/hy/guarantee-hy.component.html deleted file mode 100644 index a1799cc..0000000 --- a/src/app/brands/lavero/pages/info/guarantee/hy/guarantee-hy.component.html +++ /dev/null @@ -1,92 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/guarantee/hy/guarantee-hy.component.ts b/src/app/brands/lavero/pages/info/guarantee/hy/guarantee-hy.component.ts deleted file mode 100644 index e13e82d..0000000 --- a/src/app/brands/lavero/pages/info/guarantee/hy/guarantee-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-guarantee-lavero-hy', - templateUrl: './guarantee-hy.component.html', - styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class GuaranteeLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/info/guarantee/ru/guarantee-ru.component.html b/src/app/brands/lavero/pages/info/guarantee/ru/guarantee-ru.component.html deleted file mode 100644 index 4f75869..0000000 --- a/src/app/brands/lavero/pages/info/guarantee/ru/guarantee-ru.component.html +++ /dev/null @@ -1,92 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/info/guarantee/ru/guarantee-ru.component.ts b/src/app/brands/lavero/pages/info/guarantee/ru/guarantee-ru.component.ts deleted file mode 100644 index 9623c23..0000000 --- a/src/app/brands/lavero/pages/info/guarantee/ru/guarantee-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-guarantee-lavero-ru', - templateUrl: './guarantee-ru.component.html', - styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class GuaranteeLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/company-details/company-details.component.html b/src/app/brands/lavero/pages/legal/company-details/company-details.component.html deleted file mode 100644 index b9aa415..0000000 --- a/src/app/brands/lavero/pages/legal/company-details/company-details.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} diff --git a/src/app/brands/lavero/pages/legal/company-details/company-details.component.ts b/src/app/brands/lavero/pages/legal/company-details/company-details.component.ts deleted file mode 100644 index f47427d..0000000 --- a/src/app/brands/lavero/pages/legal/company-details/company-details.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { CompanyDetailsLaveroRuComponent } from './ru/company-details-ru.component'; -import { CompanyDetailsLaveroEnComponent } from './en/company-details-en.component'; -import { CompanyDetailsLaveroHyComponent } from './hy/company-details-hy.component'; - -@Component({ - selector: 'app-company-details-lavero', - imports: [CompanyDetailsLaveroRuComponent, CompanyDetailsLaveroEnComponent, CompanyDetailsLaveroHyComponent], - templateUrl: './company-details.component.html', - styleUrls: ['../../../../../pages/legal/company-details/company-details.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class CompanyDetailsLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/legal/company-details/en/company-details-en.component.html b/src/app/brands/lavero/pages/legal/company-details/en/company-details-en.component.html deleted file mode 100644 index d2a70e2..0000000 --- a/src/app/brands/lavero/pages/legal/company-details/en/company-details-en.component.html +++ /dev/null @@ -1,54 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/company-details/en/company-details-en.component.ts b/src/app/brands/lavero/pages/legal/company-details/en/company-details-en.component.ts deleted file mode 100644 index 73cbc00..0000000 --- a/src/app/brands/lavero/pages/legal/company-details/en/company-details-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-company-details-lavero-en', - templateUrl: './company-details-en.component.html', - styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class CompanyDetailsLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/company-details/hy/company-details-hy.component.html b/src/app/brands/lavero/pages/legal/company-details/hy/company-details-hy.component.html deleted file mode 100644 index d2a70e2..0000000 --- a/src/app/brands/lavero/pages/legal/company-details/hy/company-details-hy.component.html +++ /dev/null @@ -1,54 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/company-details/hy/company-details-hy.component.ts b/src/app/brands/lavero/pages/legal/company-details/hy/company-details-hy.component.ts deleted file mode 100644 index c5d4f7f..0000000 --- a/src/app/brands/lavero/pages/legal/company-details/hy/company-details-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-company-details-lavero-hy', - templateUrl: './company-details-hy.component.html', - styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class CompanyDetailsLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/company-details/ru/company-details-ru.component.html b/src/app/brands/lavero/pages/legal/company-details/ru/company-details-ru.component.html deleted file mode 100644 index d2a70e2..0000000 --- a/src/app/brands/lavero/pages/legal/company-details/ru/company-details-ru.component.html +++ /dev/null @@ -1,54 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/company-details/ru/company-details-ru.component.ts b/src/app/brands/lavero/pages/legal/company-details/ru/company-details-ru.component.ts deleted file mode 100644 index fbf4c73..0000000 --- a/src/app/brands/lavero/pages/legal/company-details/ru/company-details-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-company-details-lavero-ru', - templateUrl: './company-details-ru.component.html', - styleUrls: ['../../../../../../pages/legal/company-details/company-details.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class CompanyDetailsLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/payment-terms/en/payment-terms-en.component.html b/src/app/brands/lavero/pages/legal/payment-terms/en/payment-terms-en.component.html deleted file mode 100644 index a327c1d..0000000 --- a/src/app/brands/lavero/pages/legal/payment-terms/en/payment-terms-en.component.html +++ /dev/null @@ -1,162 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/payment-terms/en/payment-terms-en.component.ts b/src/app/brands/lavero/pages/legal/payment-terms/en/payment-terms-en.component.ts deleted file mode 100644 index 6646de0..0000000 --- a/src/app/brands/lavero/pages/legal/payment-terms/en/payment-terms-en.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -import { RouterLink } from '@angular/router'; -import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; - -@Component({ - selector: 'app-payment-terms-lavero-en', - imports: [RouterLink, LangRoutePipe], - templateUrl: './payment-terms-en.component.html', - styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PaymentTermsLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/payment-terms/hy/payment-terms-hy.component.html b/src/app/brands/lavero/pages/legal/payment-terms/hy/payment-terms-hy.component.html deleted file mode 100644 index a5ec2a1..0000000 --- a/src/app/brands/lavero/pages/legal/payment-terms/hy/payment-terms-hy.component.html +++ /dev/null @@ -1,162 +0,0 @@ - \ No newline at end of file diff --git a/src/app/brands/lavero/pages/legal/payment-terms/hy/payment-terms-hy.component.ts b/src/app/brands/lavero/pages/legal/payment-terms/hy/payment-terms-hy.component.ts deleted file mode 100644 index 3a2ab33..0000000 --- a/src/app/brands/lavero/pages/legal/payment-terms/hy/payment-terms-hy.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -import { RouterLink } from '@angular/router'; -import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; - -@Component({ - selector: 'app-payment-terms-lavero-hy', - imports: [RouterLink, LangRoutePipe], - templateUrl: './payment-terms-hy.component.html', - styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PaymentTermsLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/payment-terms/payment-terms.component.html b/src/app/brands/lavero/pages/legal/payment-terms/payment-terms.component.html deleted file mode 100644 index 544247a..0000000 --- a/src/app/brands/lavero/pages/legal/payment-terms/payment-terms.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} diff --git a/src/app/brands/lavero/pages/legal/payment-terms/payment-terms.component.ts b/src/app/brands/lavero/pages/legal/payment-terms/payment-terms.component.ts deleted file mode 100644 index 0d7b886..0000000 --- a/src/app/brands/lavero/pages/legal/payment-terms/payment-terms.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { PaymentTermsLaveroRuComponent } from './ru/payment-terms-ru.component'; -import { PaymentTermsLaveroEnComponent } from './en/payment-terms-en.component'; -import { PaymentTermsLaveroHyComponent } from './hy/payment-terms-hy.component'; - -@Component({ - selector: 'app-payment-terms-lavero', - imports: [PaymentTermsLaveroRuComponent, PaymentTermsLaveroEnComponent, PaymentTermsLaveroHyComponent], - templateUrl: './payment-terms.component.html', - styleUrls: ['../../../../../pages/legal/payment-terms/payment-terms.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PaymentTermsLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/legal/payment-terms/ru/payment-terms-ru.component.html b/src/app/brands/lavero/pages/legal/payment-terms/ru/payment-terms-ru.component.html deleted file mode 100644 index 826c255..0000000 --- a/src/app/brands/lavero/pages/legal/payment-terms/ru/payment-terms-ru.component.html +++ /dev/null @@ -1,162 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/payment-terms/ru/payment-terms-ru.component.ts b/src/app/brands/lavero/pages/legal/payment-terms/ru/payment-terms-ru.component.ts deleted file mode 100644 index 5b80ee2..0000000 --- a/src/app/brands/lavero/pages/legal/payment-terms/ru/payment-terms-ru.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -import { RouterLink } from '@angular/router'; -import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; - -@Component({ - selector: 'app-payment-terms-lavero-ru', - imports: [RouterLink, LangRoutePipe], - templateUrl: './payment-terms-ru.component.html', - styleUrls: ['../../../../../../pages/legal/payment-terms/payment-terms.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PaymentTermsLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/privacy-policy/en/privacy-policy-en.component.html b/src/app/brands/lavero/pages/legal/privacy-policy/en/privacy-policy-en.component.html deleted file mode 100644 index cd2b806..0000000 --- a/src/app/brands/lavero/pages/legal/privacy-policy/en/privacy-policy-en.component.html +++ /dev/null @@ -1,277 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/privacy-policy/en/privacy-policy-en.component.ts b/src/app/brands/lavero/pages/legal/privacy-policy/en/privacy-policy-en.component.ts deleted file mode 100644 index 3f47dac..0000000 --- a/src/app/brands/lavero/pages/legal/privacy-policy/en/privacy-policy-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-privacy-policy-lavero-en', - templateUrl: './privacy-policy-en.component.html', - styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PrivacyPolicyLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html b/src/app/brands/lavero/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html deleted file mode 100644 index 75a6142..0000000 --- a/src/app/brands/lavero/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts b/src/app/brands/lavero/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts deleted file mode 100644 index 57a4e37..0000000 --- a/src/app/brands/lavero/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-privacy-policy-lavero-hy', - templateUrl: './privacy-policy-hy.component.html', - styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PrivacyPolicyLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/privacy-policy/privacy-policy.component.html b/src/app/brands/lavero/pages/legal/privacy-policy/privacy-policy.component.html deleted file mode 100644 index 5773087..0000000 --- a/src/app/brands/lavero/pages/legal/privacy-policy/privacy-policy.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} \ No newline at end of file diff --git a/src/app/brands/lavero/pages/legal/privacy-policy/privacy-policy.component.ts b/src/app/brands/lavero/pages/legal/privacy-policy/privacy-policy.component.ts deleted file mode 100644 index 8eaa884..0000000 --- a/src/app/brands/lavero/pages/legal/privacy-policy/privacy-policy.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { PrivacyPolicyLaveroRuComponent } from './ru/privacy-policy-ru.component'; -import { PrivacyPolicyLaveroEnComponent } from './en/privacy-policy-en.component'; -import { PrivacyPolicyLaveroHyComponent } from './hy/privacy-policy-hy.component'; - -@Component({ - selector: 'app-privacy-policy-lavero', - imports: [PrivacyPolicyLaveroRuComponent, PrivacyPolicyLaveroEnComponent, PrivacyPolicyLaveroHyComponent], - templateUrl: './privacy-policy.component.html', - styleUrls: ['../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PrivacyPolicyLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html b/src/app/brands/lavero/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html deleted file mode 100644 index edf3a9f..0000000 --- a/src/app/brands/lavero/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html +++ /dev/null @@ -1,277 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts b/src/app/brands/lavero/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts deleted file mode 100644 index 9a5370e..0000000 --- a/src/app/brands/lavero/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-privacy-policy-lavero-ru', - templateUrl: './privacy-policy-ru.component.html', - styleUrls: ['../../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PrivacyPolicyLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/public-offer/en/public-offer-en.component.html b/src/app/brands/lavero/pages/legal/public-offer/en/public-offer-en.component.html deleted file mode 100644 index 48ae42a..0000000 --- a/src/app/brands/lavero/pages/legal/public-offer/en/public-offer-en.component.html +++ /dev/null @@ -1,275 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/public-offer/en/public-offer-en.component.ts b/src/app/brands/lavero/pages/legal/public-offer/en/public-offer-en.component.ts deleted file mode 100644 index 0f0d456..0000000 --- a/src/app/brands/lavero/pages/legal/public-offer/en/public-offer-en.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -import { RouterLink } from '@angular/router'; -import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; - -@Component({ - selector: 'app-public-offer-lavero-en', - imports: [RouterLink, LangRoutePipe], - templateUrl: './public-offer-en.component.html', - styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PublicOfferLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/public-offer/hy/public-offer-hy.component.html b/src/app/brands/lavero/pages/legal/public-offer/hy/public-offer-hy.component.html deleted file mode 100644 index f607900..0000000 --- a/src/app/brands/lavero/pages/legal/public-offer/hy/public-offer-hy.component.html +++ /dev/null @@ -1,275 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/public-offer/hy/public-offer-hy.component.ts b/src/app/brands/lavero/pages/legal/public-offer/hy/public-offer-hy.component.ts deleted file mode 100644 index bc14515..0000000 --- a/src/app/brands/lavero/pages/legal/public-offer/hy/public-offer-hy.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -import { RouterLink } from '@angular/router'; -import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; - -@Component({ - selector: 'app-public-offer-lavero-hy', - imports: [RouterLink, LangRoutePipe], - templateUrl: './public-offer-hy.component.html', - styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PublicOfferLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/public-offer/public-offer.component.html b/src/app/brands/lavero/pages/legal/public-offer/public-offer.component.html deleted file mode 100644 index 420d0d3..0000000 --- a/src/app/brands/lavero/pages/legal/public-offer/public-offer.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} \ No newline at end of file diff --git a/src/app/brands/lavero/pages/legal/public-offer/public-offer.component.ts b/src/app/brands/lavero/pages/legal/public-offer/public-offer.component.ts deleted file mode 100644 index 0648ae3..0000000 --- a/src/app/brands/lavero/pages/legal/public-offer/public-offer.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { PublicOfferLaveroRuComponent } from './ru/public-offer-ru.component'; -import { PublicOfferLaveroEnComponent } from './en/public-offer-en.component'; -import { PublicOfferLaveroHyComponent } from './hy/public-offer-hy.component'; - -@Component({ - selector: 'app-public-offer-lavero', - imports: [PublicOfferLaveroRuComponent, PublicOfferLaveroEnComponent, PublicOfferLaveroHyComponent], - templateUrl: './public-offer.component.html', - styleUrls: ['../../../../../pages/legal/public-offer/public-offer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PublicOfferLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/legal/public-offer/ru/public-offer-ru.component.html b/src/app/brands/lavero/pages/legal/public-offer/ru/public-offer-ru.component.html deleted file mode 100644 index 6764ade..0000000 --- a/src/app/brands/lavero/pages/legal/public-offer/ru/public-offer-ru.component.html +++ /dev/null @@ -1,275 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/public-offer/ru/public-offer-ru.component.ts b/src/app/brands/lavero/pages/legal/public-offer/ru/public-offer-ru.component.ts deleted file mode 100644 index 0a8fff8..0000000 --- a/src/app/brands/lavero/pages/legal/public-offer/ru/public-offer-ru.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -import { RouterLink } from '@angular/router'; -import { LangRoutePipe } from '../../../../../../pipes/lang-route.pipe'; - -@Component({ - selector: 'app-public-offer-lavero-ru', - imports: [RouterLink, LangRoutePipe], - templateUrl: './public-offer-ru.component.html', - styleUrls: ['../../../../../../pages/legal/public-offer/public-offer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class PublicOfferLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/return-policy/en/return-policy-en.component.html b/src/app/brands/lavero/pages/legal/return-policy/en/return-policy-en.component.html deleted file mode 100644 index b6ad579..0000000 --- a/src/app/brands/lavero/pages/legal/return-policy/en/return-policy-en.component.html +++ /dev/null @@ -1,175 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/return-policy/en/return-policy-en.component.ts b/src/app/brands/lavero/pages/legal/return-policy/en/return-policy-en.component.ts deleted file mode 100644 index 0b3fc90..0000000 --- a/src/app/brands/lavero/pages/legal/return-policy/en/return-policy-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-return-policy-lavero-en', - templateUrl: './return-policy-en.component.html', - styleUrls: ['../../../../../../pages/legal/return-policy/return-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ReturnPolicyLaveroEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/return-policy/hy/return-policy-hy.component.html b/src/app/brands/lavero/pages/legal/return-policy/hy/return-policy-hy.component.html deleted file mode 100644 index 0805f44..0000000 --- a/src/app/brands/lavero/pages/legal/return-policy/hy/return-policy-hy.component.html +++ /dev/null @@ -1,175 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/return-policy/hy/return-policy-hy.component.ts b/src/app/brands/lavero/pages/legal/return-policy/hy/return-policy-hy.component.ts deleted file mode 100644 index 6455512..0000000 --- a/src/app/brands/lavero/pages/legal/return-policy/hy/return-policy-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-return-policy-lavero-hy', - templateUrl: './return-policy-hy.component.html', - styleUrls: ['../../../../../../pages/legal/return-policy/return-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ReturnPolicyLaveroHyComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/lavero/pages/legal/return-policy/return-policy.component.html b/src/app/brands/lavero/pages/legal/return-policy/return-policy.component.html deleted file mode 100644 index 182e336..0000000 --- a/src/app/brands/lavero/pages/legal/return-policy/return-policy.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@switch (lang()) { - @case ('ru') { } - @case ('en') { } - @case ('hy') { } -} diff --git a/src/app/brands/lavero/pages/legal/return-policy/return-policy.component.ts b/src/app/brands/lavero/pages/legal/return-policy/return-policy.component.ts deleted file mode 100644 index 00c4435..0000000 --- a/src/app/brands/lavero/pages/legal/return-policy/return-policy.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, ChangeDetectionStrategy, inject } from '@angular/core'; -import { LanguageService } from '../../../../../services/language.service'; -import { ReturnPolicyLaveroRuComponent } from './ru/return-policy-ru.component'; -import { ReturnPolicyLaveroEnComponent } from './en/return-policy-en.component'; -import { ReturnPolicyLaveroHyComponent } from './hy/return-policy-hy.component'; - -@Component({ - selector: 'app-return-policy-lavero', - imports: [ReturnPolicyLaveroRuComponent, ReturnPolicyLaveroEnComponent, ReturnPolicyLaveroHyComponent], - templateUrl: './return-policy.component.html', - styleUrls: ['../../../../../pages/legal/return-policy/return-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ReturnPolicyLaveroComponent { - lang = inject(LanguageService).currentLanguage; -} diff --git a/src/app/brands/lavero/pages/legal/return-policy/ru/return-policy-ru.component.html b/src/app/brands/lavero/pages/legal/return-policy/ru/return-policy-ru.component.html deleted file mode 100644 index ea45a77..0000000 --- a/src/app/brands/lavero/pages/legal/return-policy/ru/return-policy-ru.component.html +++ /dev/null @@ -1,175 +0,0 @@ - diff --git a/src/app/brands/lavero/pages/legal/return-policy/ru/return-policy-ru.component.ts b/src/app/brands/lavero/pages/legal/return-policy/ru/return-policy-ru.component.ts deleted file mode 100644 index f9b8eb0..0000000 --- a/src/app/brands/lavero/pages/legal/return-policy/ru/return-policy-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-return-policy-lavero-ru', - templateUrl: './return-policy-ru.component.html', - styleUrls: ['../../../../../../pages/legal/return-policy/return-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ReturnPolicyLaveroRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/novo/pages/info/about/about.component.html b/src/app/brands/novo/pages/info/about/about.component.html deleted file mode 100644 index 722b0a5..0000000 --- a/src/app/brands/novo/pages/info/about/about.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index 6993e65..0000000 --- a/src/app/brands/novo/pages/info/about/about.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [AboutNovoRuComponent, AboutNovoEnComponent, AboutNovoHyComponent], - templateUrl: './about.component.html', - styleUrls: ['../../../../../pages/info/about/about.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index 98bfc72..0000000 --- a/src/app/brands/novo/pages/info/about/en/about-en.component.html +++ /dev/null @@ -1,99 +0,0 @@ - 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 deleted file mode 100644 index 6400560..0000000 --- a/src/app/brands/novo/pages/info/about/en/about-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-about-novo-en', - templateUrl: './about-en.component.html', - styleUrls: ['../../../../../../pages/info/about/about.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class AboutNovoEnComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 4ddb288..0000000 --- a/src/app/brands/novo/pages/info/about/hy/about-hy.component.html +++ /dev/null @@ -1,99 +0,0 @@ - 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 deleted file mode 100644 index 804621a..0000000 --- a/src/app/brands/novo/pages/info/about/hy/about-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-about-novo-hy', - templateUrl: './about-hy.component.html', - styleUrls: ['../../../../../../pages/info/about/about.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class AboutNovoHyComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 88cd606..0000000 --- a/src/app/brands/novo/pages/info/about/ru/about-ru.component.html +++ /dev/null @@ -1,99 +0,0 @@ - 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 deleted file mode 100644 index 6b0d2f9..0000000 --- a/src/app/brands/novo/pages/info/about/ru/about-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-about-novo-ru', - templateUrl: './about-ru.component.html', - styleUrls: ['../../../../../../pages/info/about/about.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class AboutNovoRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/novo/pages/info/contacts/contacts.component.html b/src/app/brands/novo/pages/info/contacts/contacts.component.html deleted file mode 100644 index 9dc2d13..0000000 --- a/src/app/brands/novo/pages/info/contacts/contacts.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index da6aadb..0000000 --- a/src/app/brands/novo/pages/info/contacts/contacts.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [ContactsNovoRuComponent, ContactsNovoEnComponent, ContactsNovoHyComponent], - templateUrl: './contacts.component.html', - styleUrls: ['../../../../../pages/info/contacts/contacts.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index 9aa15b8..0000000 --- a/src/app/brands/novo/pages/info/contacts/en/contacts-en.component.html +++ /dev/null @@ -1,49 +0,0 @@ - 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 deleted file mode 100644 index c3d8c1e..0000000 --- a/src/app/brands/novo/pages/info/contacts/en/contacts-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-contacts-novo-en', - templateUrl: './contacts-en.component.html', - styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ContactsNovoEnComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 694579b..0000000 --- a/src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.html +++ /dev/null @@ -1,49 +0,0 @@ - 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 deleted file mode 100644 index 2b4291d..0000000 --- a/src/app/brands/novo/pages/info/contacts/hy/contacts-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-contacts-novo-hy', - templateUrl: './contacts-hy.component.html', - styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ContactsNovoHyComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 534f1f2..0000000 --- a/src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.html +++ /dev/null @@ -1,49 +0,0 @@ - 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 deleted file mode 100644 index 6f0b850..0000000 --- a/src/app/brands/novo/pages/info/contacts/ru/contacts-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-contacts-novo-ru', - templateUrl: './contacts-ru.component.html', - styleUrls: ['../../../../../../pages/info/contacts/contacts.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class ContactsNovoRuComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/novo/pages/info/delivery/delivery.component.html b/src/app/brands/novo/pages/info/delivery/delivery.component.html deleted file mode 100644 index 3de9319..0000000 --- a/src/app/brands/novo/pages/info/delivery/delivery.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index f36c920..0000000 --- a/src/app/brands/novo/pages/info/delivery/delivery.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [DeliveryNovoRuComponent, DeliveryNovoEnComponent, DeliveryNovoHyComponent], - templateUrl: './delivery.component.html', - styleUrls: ['../../../../../pages/info/delivery/delivery.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index e4adcd1..0000000 --- a/src/app/brands/novo/pages/info/delivery/en/delivery-en.component.html +++ /dev/null @@ -1,78 +0,0 @@ - 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 deleted file mode 100644 index bc5565f..0000000 --- a/src/app/brands/novo/pages/info/delivery/en/delivery-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-delivery-novo-en', - templateUrl: './delivery-en.component.html', - styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DeliveryNovoEnComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 2a4ccca..0000000 --- a/src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.html +++ /dev/null @@ -1,78 +0,0 @@ - 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 deleted file mode 100644 index fefd9ae..0000000 --- a/src/app/brands/novo/pages/info/delivery/hy/delivery-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-delivery-novo-hy', - templateUrl: './delivery-hy.component.html', - styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DeliveryNovoHyComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 8b2b0d9..0000000 --- a/src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.html +++ /dev/null @@ -1,78 +0,0 @@ - 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 deleted file mode 100644 index 70ffdb2..0000000 --- a/src/app/brands/novo/pages/info/delivery/ru/delivery-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-delivery-novo-ru', - templateUrl: './delivery-ru.component.html', - styleUrls: ['../../../../../../pages/info/delivery/delivery.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DeliveryNovoRuComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index a49991e..0000000 --- a/src/app/brands/novo/pages/info/faq/en/faq-en.component.html +++ /dev/null @@ -1,93 +0,0 @@ - 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 deleted file mode 100644 index 3a4cd83..0000000 --- a/src/app/brands/novo/pages/info/faq/en/faq-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-faq-novo-en', - templateUrl: './faq-en.component.html', - styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class FaqNovoEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/novo/pages/info/faq/faq.component.html b/src/app/brands/novo/pages/info/faq/faq.component.html deleted file mode 100644 index 9c9d8b1..0000000 --- a/src/app/brands/novo/pages/info/faq/faq.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index 8a926ca..0000000 --- a/src/app/brands/novo/pages/info/faq/faq.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [FaqNovoRuComponent, FaqNovoEnComponent, FaqNovoHyComponent], - templateUrl: './faq.component.html', - styleUrls: ['../../../../../pages/info/faq/faq.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index 57156a9..0000000 --- a/src/app/brands/novo/pages/info/faq/hy/faq-hy.component.html +++ /dev/null @@ -1,93 +0,0 @@ - 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 deleted file mode 100644 index a54f553..0000000 --- a/src/app/brands/novo/pages/info/faq/hy/faq-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-faq-novo-hy', - templateUrl: './faq-hy.component.html', - styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class FaqNovoHyComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index ed618d5..0000000 --- a/src/app/brands/novo/pages/info/faq/ru/faq-ru.component.html +++ /dev/null @@ -1,93 +0,0 @@ - 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 deleted file mode 100644 index 45fcb8b..0000000 --- a/src/app/brands/novo/pages/info/faq/ru/faq-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-faq-novo-ru', - templateUrl: './faq-ru.component.html', - styleUrls: ['../../../../../../pages/info/faq/faq.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class FaqNovoRuComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 19c93ad..0000000 --- a/src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.html +++ /dev/null @@ -1,92 +0,0 @@ - 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 deleted file mode 100644 index d04878e..0000000 --- a/src/app/brands/novo/pages/info/guarantee/en/guarantee-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-guarantee-novo-en', - templateUrl: './guarantee-en.component.html', - styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class GuaranteeNovoEnComponent { - protected readonly env = environment; -} diff --git a/src/app/brands/novo/pages/info/guarantee/guarantee.component.html b/src/app/brands/novo/pages/info/guarantee/guarantee.component.html deleted file mode 100644 index 38aa247..0000000 --- a/src/app/brands/novo/pages/info/guarantee/guarantee.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index 138706d..0000000 --- a/src/app/brands/novo/pages/info/guarantee/guarantee.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [GuaranteeNovoRuComponent, GuaranteeNovoEnComponent, GuaranteeNovoHyComponent], - templateUrl: './guarantee.component.html', - styleUrls: ['../../../../../pages/info/guarantee/guarantee.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index 508da4e..0000000 --- a/src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.html +++ /dev/null @@ -1,92 +0,0 @@ - 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 deleted file mode 100644 index 6a4e18c..0000000 --- a/src/app/brands/novo/pages/info/guarantee/hy/guarantee-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-guarantee-novo-hy', - templateUrl: './guarantee-hy.component.html', - styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class GuaranteeNovoHyComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 95c2375..0000000 --- a/src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.html +++ /dev/null @@ -1,92 +0,0 @@ - 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 deleted file mode 100644 index 7c22336..0000000 --- a/src/app/brands/novo/pages/info/guarantee/ru/guarantee-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@Component({ - selector: 'app-guarantee-novo-ru', - templateUrl: './guarantee-ru.component.html', - styleUrls: ['../../../../../../pages/info/guarantee/guarantee.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class GuaranteeNovoRuComponent { - protected readonly env = environment; -} 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 deleted file mode 100644 index 0790090..0000000 --- a/src/app/brands/novo/pages/legal/company-details/company-details.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index 2e60a1e..0000000 --- a/src/app/brands/novo/pages/legal/company-details/company-details.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [CompanyDetailsNovoRuComponent, CompanyDetailsNovoEnComponent, CompanyDetailsNovoHyComponent], - templateUrl: './company-details.component.html', - styleUrls: ['../../../../../pages/legal/company-details/company-details.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index 76fafb9..0000000 --- a/src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.html +++ /dev/null @@ -1,113 +0,0 @@ - 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 deleted file mode 100644 index a7fad89..0000000 --- a/src/app/brands/novo/pages/legal/company-details/en/company-details-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index 3ced5f7..0000000 --- a/src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.html +++ /dev/null @@ -1,113 +0,0 @@ - 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 deleted file mode 100644 index a856918..0000000 --- a/src/app/brands/novo/pages/legal/company-details/hy/company-details-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index c2a5f97..0000000 --- a/src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.html +++ /dev/null @@ -1,113 +0,0 @@ - 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 deleted file mode 100644 index 743973c..0000000 --- a/src/app/brands/novo/pages/legal/company-details/ru/company-details-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index 89d66c1..0000000 --- a/src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.html +++ /dev/null @@ -1,162 +0,0 @@ - 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 deleted file mode 100644 index 6ccf3e3..0000000 --- a/src/app/brands/novo/pages/legal/payment-terms/en/payment-terms-en.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index 7c03d6d..0000000 --- a/src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.html +++ /dev/null @@ -1,162 +0,0 @@ - \ 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 deleted file mode 100644 index 0d8827f..0000000 --- a/src/app/brands/novo/pages/legal/payment-terms/hy/payment-terms-hy.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index 3c5cbe9..0000000 --- a/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index df45396..0000000 --- a/src/app/brands/novo/pages/legal/payment-terms/payment-terms.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [PaymentTermsNovoRuComponent, PaymentTermsNovoEnComponent, PaymentTermsNovoHyComponent], - templateUrl: './payment-terms.component.html', - styleUrls: ['../../../../../pages/legal/payment-terms/payment-terms.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index 9487490..0000000 --- a/src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.html +++ /dev/null @@ -1,162 +0,0 @@ - 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 deleted file mode 100644 index b797694..0000000 --- a/src/app/brands/novo/pages/legal/payment-terms/ru/payment-terms-ru.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index 49d9dec..0000000 --- a/src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.html +++ /dev/null @@ -1,277 +0,0 @@ - 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 deleted file mode 100644 index d9caf4e..0000000 --- a/src/app/brands/novo/pages/legal/privacy-policy/en/privacy-policy-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index fada1c1..0000000 --- a/src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.html +++ /dev/null @@ -1,8 +0,0 @@ - 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 deleted file mode 100644 index 59b4ccc..0000000 --- a/src/app/brands/novo/pages/legal/privacy-policy/hy/privacy-policy-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index 2b2c676..0000000 --- a/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index b6a6ace..0000000 --- a/src/app/brands/novo/pages/legal/privacy-policy/privacy-policy.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [PrivacyPolicyNovoRuComponent, PrivacyPolicyNovoEnComponent, PrivacyPolicyNovoHyComponent], - templateUrl: './privacy-policy.component.html', - styleUrls: ['../../../../../pages/legal/privacy-policy/privacy-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index 6cfef97..0000000 --- a/src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.html +++ /dev/null @@ -1,277 +0,0 @@ - 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 deleted file mode 100644 index 3dcd14e..0000000 --- a/src/app/brands/novo/pages/legal/privacy-policy/ru/privacy-policy-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index bee5bfb..0000000 --- a/src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.html +++ /dev/null @@ -1,269 +0,0 @@ - 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 deleted file mode 100644 index 7d05de4..0000000 --- a/src/app/brands/novo/pages/legal/public-offer/en/public-offer-en.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index fff63eb..0000000 --- a/src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.html +++ /dev/null @@ -1,269 +0,0 @@ - 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 deleted file mode 100644 index e05446b..0000000 --- a/src/app/brands/novo/pages/legal/public-offer/hy/public-offer-hy.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index ed16c9d..0000000 --- a/src/app/brands/novo/pages/legal/public-offer/public-offer.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index 6d05ac0..0000000 --- a/src/app/brands/novo/pages/legal/public-offer/public-offer.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [PublicOfferNovoRuComponent, PublicOfferNovoEnComponent, PublicOfferNovoHyComponent], - templateUrl: './public-offer.component.html', - styleUrls: ['../../../../../pages/legal/public-offer/public-offer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index daa941d..0000000 --- a/src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.html +++ /dev/null @@ -1,269 +0,0 @@ - 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 deleted file mode 100644 index 587eac3..0000000 --- a/src/app/brands/novo/pages/legal/public-offer/ru/public-offer-ru.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; -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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index 69dc92b..0000000 --- a/src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.html +++ /dev/null @@ -1,175 +0,0 @@ - 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 deleted file mode 100644 index feb54b4..0000000 --- a/src/app/brands/novo/pages/legal/return-policy/en/return-policy-en.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index a3d948a..0000000 --- a/src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.html +++ /dev/null @@ -1,175 +0,0 @@ - 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 deleted file mode 100644 index d22b96a..0000000 --- a/src/app/brands/novo/pages/legal/return-policy/hy/return-policy-hy.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} 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 deleted file mode 100644 index 883d7dc..0000000 --- a/src/app/brands/novo/pages/legal/return-policy/return-policy.component.html +++ /dev/null @@ -1,5 +0,0 @@ -@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 deleted file mode 100644 index 1e6e5ed..0000000 --- a/src/app/brands/novo/pages/legal/return-policy/return-policy.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -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: [ReturnPolicyNovoRuComponent, ReturnPolicyNovoEnComponent, ReturnPolicyNovoHyComponent], - templateUrl: './return-policy.component.html', - styleUrls: ['../../../../../pages/legal/return-policy/return-policy.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -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 deleted file mode 100644 index 4d1b46c..0000000 --- a/src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.html +++ /dev/null @@ -1,175 +0,0 @@ - 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 deleted file mode 100644 index 204dd50..0000000 --- a/src/app/brands/novo/pages/legal/return-policy/ru/return-policy-ru.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { environment } from '../../../../../../../environments/environment'; - -@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 { - protected readonly env = environment; -} diff --git a/src/app/components/back-button/back-button.component.ts b/src/app/components/back-button/back-button.component.ts index 0b3be16..9db8137 100644 --- a/src/app/components/back-button/back-button.component.ts +++ b/src/app/components/back-button/back-button.component.ts @@ -6,7 +6,7 @@ import { UiRuntimeFacade } from '../../facades/runtime/ui-runtime.facade'; @Component({ selector: 'app-back-button', template: ` - @if (!isnovo) { + @if (!isMarketplaceNovo) {