From f62b2345f463695ef0f8f79830cd76b6e0332821 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Sat, 13 Jan 2024 10:35:22 +0700 Subject: Refactor src migrate folder --- src-migrate/common/components/elements/Modal.tsx | 90 --- .../common/components/elements/ReCaptcha.tsx | 17 - src-migrate/common/components/elements/Seo.tsx | 34 -- .../components/skeleton/PageContentSkeleton.tsx | 19 - src-migrate/common/constants/menu.ts | 20 - src-migrate/common/libs/auth.ts | 26 - src-migrate/common/libs/clsxm.ts | 6 - src-migrate/common/libs/formatCurrency.ts | 5 - src-migrate/common/libs/odooApi.ts | 81 --- src-migrate/common/libs/parse | 0 src-migrate/common/stores/useRegisterStore.ts | 60 -- .../common/styles/fonts/Inter/Inter-Black.woff | Bin 138764 -> 0 bytes .../common/styles/fonts/Inter/Inter-Black.woff2 | Bin 102868 -> 0 bytes .../styles/fonts/Inter/Inter-BlackItalic.woff | Bin 146824 -> 0 bytes .../styles/fonts/Inter/Inter-BlackItalic.woff2 | Bin 108752 -> 0 bytes .../common/styles/fonts/Inter/Inter-Bold.woff | Bin 143208 -> 0 bytes .../common/styles/fonts/Inter/Inter-Bold.woff2 | Bin 106140 -> 0 bytes .../styles/fonts/Inter/Inter-BoldItalic.woff | Bin 151052 -> 0 bytes .../styles/fonts/Inter/Inter-BoldItalic.woff2 | Bin 111808 -> 0 bytes .../common/styles/fonts/Inter/Inter-ExtraBold.woff | Bin 142920 -> 0 bytes .../styles/fonts/Inter/Inter-ExtraBold.woff2 | Bin 106108 -> 0 bytes .../styles/fonts/Inter/Inter-ExtraBoldItalic.woff | Bin 150628 -> 0 bytes .../styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 | Bin 111708 -> 0 bytes .../styles/fonts/Inter/Inter-ExtraLight.woff | Bin 140724 -> 0 bytes .../styles/fonts/Inter/Inter-ExtraLight.woff2 | Bin 104232 -> 0 bytes .../styles/fonts/Inter/Inter-ExtraLightItalic.woff | Bin 149996 -> 0 bytes .../fonts/Inter/Inter-ExtraLightItalic.woff2 | Bin 111392 -> 0 bytes .../common/styles/fonts/Inter/Inter-Italic.woff | Bin 144372 -> 0 bytes .../common/styles/fonts/Inter/Inter-Italic.woff2 | Bin 106876 -> 0 bytes .../common/styles/fonts/Inter/Inter-Light.woff | Bin 140632 -> 0 bytes .../common/styles/fonts/Inter/Inter-Light.woff2 | Bin 104332 -> 0 bytes .../styles/fonts/Inter/Inter-LightItalic.woff | Bin 150092 -> 0 bytes .../styles/fonts/Inter/Inter-LightItalic.woff2 | Bin 111332 -> 0 bytes .../common/styles/fonts/Inter/Inter-Medium.woff | Bin 142552 -> 0 bytes .../common/styles/fonts/Inter/Inter-Medium.woff2 | Bin 105924 -> 0 bytes .../styles/fonts/Inter/Inter-MediumItalic.woff | Bin 150988 -> 0 bytes .../styles/fonts/Inter/Inter-MediumItalic.woff2 | Bin 112184 -> 0 bytes .../common/styles/fonts/Inter/Inter-Regular.woff | Bin 133844 -> 0 bytes .../common/styles/fonts/Inter/Inter-Regular.woff2 | Bin 98868 -> 0 bytes .../common/styles/fonts/Inter/Inter-SemiBold.woff | Bin 142932 -> 0 bytes .../common/styles/fonts/Inter/Inter-SemiBold.woff2 | Bin 105804 -> 0 bytes .../styles/fonts/Inter/Inter-SemiBoldItalic.woff | Bin 151180 -> 0 bytes .../styles/fonts/Inter/Inter-SemiBoldItalic.woff2 | Bin 112048 -> 0 bytes .../common/styles/fonts/Inter/Inter-Thin.woff | Bin 135920 -> 0 bytes .../common/styles/fonts/Inter/Inter-Thin.woff2 | Bin 99632 -> 0 bytes .../styles/fonts/Inter/Inter-ThinItalic.woff | Bin 145480 -> 0 bytes .../styles/fonts/Inter/Inter-ThinItalic.woff2 | Bin 106496 -> 0 bytes .../styles/fonts/Inter/Inter-italic.var.woff2 | Bin 245036 -> 0 bytes .../styles/fonts/Inter/Inter-roman.var.woff2 | Bin 227180 -> 0 bytes .../common/styles/fonts/Inter/Inter.var.woff2 | Bin 324864 -> 0 bytes src-migrate/common/styles/fonts/Inter/inter.css | 199 ------ src-migrate/common/styles/globals.css | 674 --------------------- src-migrate/common/types/auth.ts | 58 -- src-migrate/common/types/cart.ts | 72 --- src-migrate/common/types/checkout.ts | 16 - src-migrate/common/types/nav.ts | 4 - src-migrate/common/types/odoo.ts | 6 - src-migrate/common/types/pageContent.ts | 5 - src-migrate/common/types/productVariant.ts | 13 - src-migrate/common/types/promotion.ts | 35 -- src-migrate/common/types/promotionProgram.ts | 8 - src-migrate/common/types/solr.ts | 7 - src-migrate/common/validations/auth.ts | 17 - src-migrate/components/seo.tsx | 32 + src-migrate/components/ui/image.tsx | 46 ++ src-migrate/components/ui/modal.tsx | 87 +++ src-migrate/components/ui/re-captcha.tsx | 15 + src-migrate/constants/menu.ts | 20 + src-migrate/libs/auth.ts | 26 + src-migrate/libs/clsxm.ts | 6 + src-migrate/libs/formatCurrency.ts | 5 + src-migrate/libs/formatNumber.ts | 8 + src-migrate/libs/odooApi.ts | 81 +++ src-migrate/libs/slug.ts | 34 ++ src-migrate/libs/toTitleCase.ts | 5 + .../account-activation/components/FormEmail.tsx | 6 +- .../account-activation/components/FormOTP.tsx | 6 +- .../account-activation/components/FormToken.tsx | 6 +- src-migrate/modules/cart/components/Item.tsx | 4 +- src-migrate/modules/cart/components/ItemAction.tsx | 4 +- src-migrate/modules/cart/components/ItemPromo.tsx | 2 +- src-migrate/modules/cart/components/ItemSelect.tsx | 4 +- src-migrate/modules/cart/components/Summary.tsx | 4 +- src-migrate/modules/cart/stores/useCartStore.ts | 2 +- .../modules/header/components/HeaderDesktop.tsx | 2 +- src-migrate/modules/page-content/index.tsx | 19 +- src-migrate/modules/popup-information/index.tsx | 4 +- .../product-card/components/ProductCard.tsx | 104 ++++ src-migrate/modules/product-card/index.tsx | 3 + .../product-card/styles/product-card.module.css | 50 ++ .../product-detail/components/AddToCart.tsx | 79 +++ .../product-detail/components/AddToWishlist.tsx | 17 + .../modules/product-detail/components/Image.tsx | 37 ++ .../product-detail/components/Information.tsx | 84 +++ .../product-detail/components/PriceAction.tsx | 53 ++ .../product-detail/components/ProductDetail.tsx | 126 ++++ .../product-detail/components/SimilarBottom.tsx | 21 + .../product-detail/components/SimilarSide.tsx | 34 ++ .../product-detail/components/VariantList.tsx | 85 +++ src-migrate/modules/product-detail/index.ts | 3 + .../product-detail/stores/useProductDetail.ts | 25 + .../product-detail/styles/information.module.css | 19 + .../product-detail/styles/price-action.module.css | 12 + .../styles/product-detail.module.css | 15 + .../product-detail/styles/side-similar.module.css | 3 + .../product-detail/styles/variant-list.module.css | 19 + .../modules/product-promo/components/AddToCart.tsx | 4 +- .../modules/product-promo/components/Card.tsx | 8 +- .../product-promo/components/CardCountdown.tsx | 4 +- .../product-promo/components/CategoryTab.tsx | 4 +- .../modules/product-promo/components/Item.tsx | 2 +- .../modules/product-promo/components/Modal.tsx | 2 +- .../product-promo/components/ModalContent.tsx | 2 +- .../modules/product-promo/components/Section.tsx | 2 +- .../modules/product-promo/stores/useModalStore.ts | 2 +- .../product-similar/hooks/useProductSimilar.tsx | 15 + .../product-slider/components/ProductSlider.tsx | 42 ++ src-migrate/modules/product-slider/index.ts | 3 + src-migrate/modules/register/components/Form.tsx | 4 +- .../modules/register/components/FormCaptcha.tsx | 4 +- .../modules/register/components/TermCondition.tsx | 4 +- .../modules/register/stores/useRegisterStore.ts | 60 ++ src-migrate/pages/_app.tsx | 4 +- src-migrate/pages/api/product-variant/[id].tsx | 2 +- .../product-variant/[id]/promotion/[category].tsx | 2 +- .../product-variant/[id]/promotion/highlight.tsx | 2 +- src-migrate/pages/api/promotion-program/[id].tsx | 3 +- src-migrate/pages/register.tsx | 2 +- src-migrate/pages/shop/cart.module.css | 31 - src-migrate/pages/shop/cart.tsx | 91 --- src-migrate/pages/shop/cart/cart.module.css | 31 + src-migrate/pages/shop/cart/index.tsx | 93 +++ src-migrate/pages/shop/product/[slug].tsx | 73 +++ src-migrate/pages/shop/product/product.module.css | 0 src-migrate/services/auth.ts | 4 +- src-migrate/services/cart.ts | 2 +- src-migrate/services/checkout.ts | 2 +- src-migrate/services/pageContent.ts | 2 +- src-migrate/services/product.ts | 59 ++ src-migrate/services/productVariant.ts | 23 + src-migrate/services/promotionProgram.ts | 2 +- src-migrate/services/variant.ts | 14 - src-migrate/styles/fonts/Inter/Inter-Black.woff | Bin 0 -> 138764 bytes src-migrate/styles/fonts/Inter/Inter-Black.woff2 | Bin 0 -> 102868 bytes .../styles/fonts/Inter/Inter-BlackItalic.woff | Bin 0 -> 146824 bytes .../styles/fonts/Inter/Inter-BlackItalic.woff2 | Bin 0 -> 108752 bytes src-migrate/styles/fonts/Inter/Inter-Bold.woff | Bin 0 -> 143208 bytes src-migrate/styles/fonts/Inter/Inter-Bold.woff2 | Bin 0 -> 106140 bytes .../styles/fonts/Inter/Inter-BoldItalic.woff | Bin 0 -> 151052 bytes .../styles/fonts/Inter/Inter-BoldItalic.woff2 | Bin 0 -> 111808 bytes .../styles/fonts/Inter/Inter-ExtraBold.woff | Bin 0 -> 142920 bytes .../styles/fonts/Inter/Inter-ExtraBold.woff2 | Bin 0 -> 106108 bytes .../styles/fonts/Inter/Inter-ExtraBoldItalic.woff | Bin 0 -> 150628 bytes .../styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 | Bin 0 -> 111708 bytes .../styles/fonts/Inter/Inter-ExtraLight.woff | Bin 0 -> 140724 bytes .../styles/fonts/Inter/Inter-ExtraLight.woff2 | Bin 0 -> 104232 bytes .../styles/fonts/Inter/Inter-ExtraLightItalic.woff | Bin 0 -> 149996 bytes .../fonts/Inter/Inter-ExtraLightItalic.woff2 | Bin 0 -> 111392 bytes src-migrate/styles/fonts/Inter/Inter-Italic.woff | Bin 0 -> 144372 bytes src-migrate/styles/fonts/Inter/Inter-Italic.woff2 | Bin 0 -> 106876 bytes src-migrate/styles/fonts/Inter/Inter-Light.woff | Bin 0 -> 140632 bytes src-migrate/styles/fonts/Inter/Inter-Light.woff2 | Bin 0 -> 104332 bytes .../styles/fonts/Inter/Inter-LightItalic.woff | Bin 0 -> 150092 bytes .../styles/fonts/Inter/Inter-LightItalic.woff2 | Bin 0 -> 111332 bytes src-migrate/styles/fonts/Inter/Inter-Medium.woff | Bin 0 -> 142552 bytes src-migrate/styles/fonts/Inter/Inter-Medium.woff2 | Bin 0 -> 105924 bytes .../styles/fonts/Inter/Inter-MediumItalic.woff | Bin 0 -> 150988 bytes .../styles/fonts/Inter/Inter-MediumItalic.woff2 | Bin 0 -> 112184 bytes src-migrate/styles/fonts/Inter/Inter-Regular.woff | Bin 0 -> 133844 bytes src-migrate/styles/fonts/Inter/Inter-Regular.woff2 | Bin 0 -> 98868 bytes src-migrate/styles/fonts/Inter/Inter-SemiBold.woff | Bin 0 -> 142932 bytes .../styles/fonts/Inter/Inter-SemiBold.woff2 | Bin 0 -> 105804 bytes .../styles/fonts/Inter/Inter-SemiBoldItalic.woff | Bin 0 -> 151180 bytes .../styles/fonts/Inter/Inter-SemiBoldItalic.woff2 | Bin 0 -> 112048 bytes src-migrate/styles/fonts/Inter/Inter-Thin.woff | Bin 0 -> 135920 bytes src-migrate/styles/fonts/Inter/Inter-Thin.woff2 | Bin 0 -> 99632 bytes .../styles/fonts/Inter/Inter-ThinItalic.woff | Bin 0 -> 145480 bytes .../styles/fonts/Inter/Inter-ThinItalic.woff2 | Bin 0 -> 106496 bytes .../styles/fonts/Inter/Inter-italic.var.woff2 | Bin 0 -> 245036 bytes .../styles/fonts/Inter/Inter-roman.var.woff2 | Bin 0 -> 227180 bytes src-migrate/styles/fonts/Inter/Inter.var.woff2 | Bin 0 -> 324864 bytes src-migrate/styles/fonts/Inter/inter.css | 199 ++++++ src-migrate/styles/globals.css | 674 +++++++++++++++++++++ src-migrate/types/auth.ts | 58 ++ src-migrate/types/cart.ts | 72 +++ src-migrate/types/checkout.ts | 16 + src-migrate/types/nav.ts | 4 + src-migrate/types/odoo.ts | 6 + src-migrate/types/pageContent.ts | 5 + src-migrate/types/product.ts | 39 ++ src-migrate/types/productVariant.ts | 33 + src-migrate/types/promotion.ts | 44 ++ src-migrate/types/promotionProgram.ts | 8 + src-migrate/types/solr.ts | 7 + src-migrate/validations/auth.ts | 17 + 195 files changed, 2808 insertions(+), 1667 deletions(-) delete mode 100644 src-migrate/common/components/elements/Modal.tsx delete mode 100644 src-migrate/common/components/elements/ReCaptcha.tsx delete mode 100644 src-migrate/common/components/elements/Seo.tsx delete mode 100644 src-migrate/common/components/skeleton/PageContentSkeleton.tsx delete mode 100644 src-migrate/common/constants/menu.ts delete mode 100644 src-migrate/common/libs/auth.ts delete mode 100644 src-migrate/common/libs/clsxm.ts delete mode 100644 src-migrate/common/libs/formatCurrency.ts delete mode 100644 src-migrate/common/libs/odooApi.ts delete mode 100644 src-migrate/common/libs/parse delete mode 100644 src-migrate/common/stores/useRegisterStore.ts delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Black.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Black.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Bold.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Bold.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Italic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Italic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Light.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Light.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Medium.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Medium.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Regular.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Regular.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Thin.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-Thin.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-italic.var.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter-roman.var.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/Inter.var.woff2 delete mode 100644 src-migrate/common/styles/fonts/Inter/inter.css delete mode 100644 src-migrate/common/styles/globals.css delete mode 100644 src-migrate/common/types/auth.ts delete mode 100644 src-migrate/common/types/cart.ts delete mode 100644 src-migrate/common/types/checkout.ts delete mode 100644 src-migrate/common/types/nav.ts delete mode 100644 src-migrate/common/types/odoo.ts delete mode 100644 src-migrate/common/types/pageContent.ts delete mode 100644 src-migrate/common/types/productVariant.ts delete mode 100644 src-migrate/common/types/promotion.ts delete mode 100644 src-migrate/common/types/promotionProgram.ts delete mode 100644 src-migrate/common/types/solr.ts delete mode 100644 src-migrate/common/validations/auth.ts create mode 100644 src-migrate/components/seo.tsx create mode 100644 src-migrate/components/ui/image.tsx create mode 100644 src-migrate/components/ui/modal.tsx create mode 100644 src-migrate/components/ui/re-captcha.tsx create mode 100644 src-migrate/constants/menu.ts create mode 100644 src-migrate/libs/auth.ts create mode 100644 src-migrate/libs/clsxm.ts create mode 100644 src-migrate/libs/formatCurrency.ts create mode 100644 src-migrate/libs/formatNumber.ts create mode 100644 src-migrate/libs/odooApi.ts create mode 100644 src-migrate/libs/slug.ts create mode 100644 src-migrate/libs/toTitleCase.ts create mode 100644 src-migrate/modules/product-card/components/ProductCard.tsx create mode 100644 src-migrate/modules/product-card/index.tsx create mode 100644 src-migrate/modules/product-card/styles/product-card.module.css create mode 100644 src-migrate/modules/product-detail/components/AddToCart.tsx create mode 100644 src-migrate/modules/product-detail/components/AddToWishlist.tsx create mode 100644 src-migrate/modules/product-detail/components/Image.tsx create mode 100644 src-migrate/modules/product-detail/components/Information.tsx create mode 100644 src-migrate/modules/product-detail/components/PriceAction.tsx create mode 100644 src-migrate/modules/product-detail/components/ProductDetail.tsx create mode 100644 src-migrate/modules/product-detail/components/SimilarBottom.tsx create mode 100644 src-migrate/modules/product-detail/components/SimilarSide.tsx create mode 100644 src-migrate/modules/product-detail/components/VariantList.tsx create mode 100644 src-migrate/modules/product-detail/index.ts create mode 100644 src-migrate/modules/product-detail/stores/useProductDetail.ts create mode 100644 src-migrate/modules/product-detail/styles/information.module.css create mode 100644 src-migrate/modules/product-detail/styles/price-action.module.css create mode 100644 src-migrate/modules/product-detail/styles/product-detail.module.css create mode 100644 src-migrate/modules/product-detail/styles/side-similar.module.css create mode 100644 src-migrate/modules/product-detail/styles/variant-list.module.css create mode 100644 src-migrate/modules/product-similar/hooks/useProductSimilar.tsx create mode 100644 src-migrate/modules/product-slider/components/ProductSlider.tsx create mode 100644 src-migrate/modules/product-slider/index.ts create mode 100644 src-migrate/modules/register/stores/useRegisterStore.ts delete mode 100644 src-migrate/pages/shop/cart.module.css delete mode 100644 src-migrate/pages/shop/cart.tsx create mode 100644 src-migrate/pages/shop/cart/cart.module.css create mode 100644 src-migrate/pages/shop/cart/index.tsx create mode 100644 src-migrate/pages/shop/product/[slug].tsx create mode 100644 src-migrate/pages/shop/product/product.module.css create mode 100644 src-migrate/services/product.ts create mode 100644 src-migrate/services/productVariant.ts delete mode 100644 src-migrate/services/variant.ts create mode 100644 src-migrate/styles/fonts/Inter/Inter-Black.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-Black.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-Bold.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-Bold.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-Italic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-Italic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-Light.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-Light.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-LightItalic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-LightItalic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-Medium.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-Medium.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-Regular.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-Regular.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-SemiBold.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-SemiBold.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-Thin.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-Thin.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff create mode 100644 src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-italic.var.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter-roman.var.woff2 create mode 100644 src-migrate/styles/fonts/Inter/Inter.var.woff2 create mode 100644 src-migrate/styles/fonts/Inter/inter.css create mode 100644 src-migrate/styles/globals.css create mode 100644 src-migrate/types/auth.ts create mode 100644 src-migrate/types/cart.ts create mode 100644 src-migrate/types/checkout.ts create mode 100644 src-migrate/types/nav.ts create mode 100644 src-migrate/types/odoo.ts create mode 100644 src-migrate/types/pageContent.ts create mode 100644 src-migrate/types/product.ts create mode 100644 src-migrate/types/productVariant.ts create mode 100644 src-migrate/types/promotion.ts create mode 100644 src-migrate/types/promotionProgram.ts create mode 100644 src-migrate/types/solr.ts create mode 100644 src-migrate/validations/auth.ts (limited to 'src-migrate') diff --git a/src-migrate/common/components/elements/Modal.tsx b/src-migrate/common/components/elements/Modal.tsx deleted file mode 100644 index c9c621e0..00000000 --- a/src-migrate/common/components/elements/Modal.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { XMarkIcon } from "@heroicons/react/24/outline"; -import { AnimatePresence, motion } from "framer-motion" -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; -import ReactDOM from "react-dom"; -import { useWindowSize } from "usehooks-ts"; -import clsxm from "~/common/libs/clsxm"; - - -type Props = { - children: React.ReactNode - active: boolean - title?: string - close?: () => void, - className?: string, - mode?: "mobile" | "desktop" -} - -const Modal = ({ - children, - active = false, - title, - close, - className, - mode -}: Props) => { - const router = useRouter() - const { width } = useWindowSize() - const [rendered, setRendered] = useState(false) - - mode = mode || width >= 768 ? "desktop" : "mobile" - - useEffect(() => { - setRendered(true) - }, []) - - const modalClassNames = clsxm( - "fixed bg-white max-h-[80vh] overflow-auto p-4 pt-0 z-[60] border-gray_r-6", - { - "left-1/2 -translate-x-1/2 translate-y-1/2 bottom-1/2 w-11/12 md:w-[500px] border rounded-xl": mode === 'desktop', - "left-0 w-full border-t bottom-0 rounded-t-xl": mode === 'mobile' - }, - className - ) - - const variant = { - initial: { bottom: mode === 'desktop' ? '45%' : '-100%', opacity: 0 }, - animate: { bottom: mode === 'desktop' ? '50%' : 0, opacity: 1 }, - exit: { bottom: mode === 'desktop' ? '55%' : '-100%', opacity: 0 }, - transition: { ease: 'linear', duration: 0.25 } - } - - return rendered && ReactDOM.createPortal( - - {active && ( - - )} - - {active && ( - -
-
- {title} -
- {close && ( - - )} -
- - {children} -
- )} - -
, - document.querySelector('body')! - ) -} - -export default Modal \ No newline at end of file diff --git a/src-migrate/common/components/elements/ReCaptcha.tsx b/src-migrate/common/components/elements/ReCaptcha.tsx deleted file mode 100644 index 1bc31d90..00000000 --- a/src-migrate/common/components/elements/ReCaptcha.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import ReCAPTCHA, { ReCAPTCHAProps } from "react-google-recaptcha" - -const GOOGLE_RECAPTCHA_KEY = process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE || '' - -type Props = Omit & { - sitekey?: string; -} - -const ReCaptcha = (props: Props) => { - const { sitekey, ...rest } = props - - return ( - - ) -} - -export default ReCaptcha \ No newline at end of file diff --git a/src-migrate/common/components/elements/Seo.tsx b/src-migrate/common/components/elements/Seo.tsx deleted file mode 100644 index 2245663a..00000000 --- a/src-migrate/common/components/elements/Seo.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { useRouter } from 'next/router' -import React from 'react' -import { NextSeo } from "next-seo" -import { MetaTag, NextSeoProps } from 'next-seo/lib/types'; - -const Seo = (props: NextSeoProps) => { - const router = useRouter() - - const additionalMetaTags: MetaTag[] = [ - { - property: 'fb:app_id', - content: '270830718811' - }, - { - property: 'fb:page_id', - content: '101759953569' - }, - ] - - if (!!props.additionalMetaTags) additionalMetaTags.push(...props.additionalMetaTags) - - return ( - - ) -} - -export default Seo \ No newline at end of file diff --git a/src-migrate/common/components/skeleton/PageContentSkeleton.tsx b/src-migrate/common/components/skeleton/PageContentSkeleton.tsx deleted file mode 100644 index bf85cff1..00000000 --- a/src-migrate/common/components/skeleton/PageContentSkeleton.tsx +++ /dev/null @@ -1,19 +0,0 @@ -const PageContentSkeleton = () => { - return ( -
-
-
-
-
-
-
-
-
-
-
-
-
- ) -} - -export default PageContentSkeleton \ No newline at end of file diff --git a/src-migrate/common/constants/menu.ts b/src-migrate/common/constants/menu.ts deleted file mode 100644 index 853da507..00000000 --- a/src-migrate/common/constants/menu.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { SecondaryNavItemProps } from '../types/nav' - -export const SECONDARY_MENU_ITEMS: SecondaryNavItemProps[] = [ - { - label: 'Semua Brand', - href: '/shop/brands' - }, - { - label: 'Ready Stock', - href: '/shop/search?orderBy=stock' - }, - { - label: 'Blog Indoteknik', - href: 'https://blog.indoteknik.com/' - }, - { - label: 'Indoteknik TV', - href: '/video' - } -] diff --git a/src-migrate/common/libs/auth.ts b/src-migrate/common/libs/auth.ts deleted file mode 100644 index fb4e836a..00000000 --- a/src-migrate/common/libs/auth.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { deleteCookie, getCookie, setCookie } from 'cookies-next'; -import { AuthProps } from '../types/auth'; - -const COOKIE_KEY = 'auth'; - -export const getAuth = (): AuthProps | boolean => { - const auth = getCookie(COOKIE_KEY); - - if (typeof auth === 'string') { - return JSON.parse(auth); - } - - return false; -}; - -export const setAuth = (user: AuthProps): boolean => { - setCookie(COOKIE_KEY, JSON.stringify(user)); - - return true; -}; - -export const deleteAuth = (): boolean => { - deleteCookie(COOKIE_KEY); - - return true; -}; diff --git a/src-migrate/common/libs/clsxm.ts b/src-migrate/common/libs/clsxm.ts deleted file mode 100644 index 0fc10317..00000000 --- a/src-migrate/common/libs/clsxm.ts +++ /dev/null @@ -1,6 +0,0 @@ -import clsx, { ClassValue } from 'clsx'; -import { twMerge } from 'tw-merge'; - -export default function clsxm(...classes: ClassValue[]) { - return twMerge(clsx(...classes)); -} diff --git a/src-migrate/common/libs/formatCurrency.ts b/src-migrate/common/libs/formatCurrency.ts deleted file mode 100644 index 41db4a6f..00000000 --- a/src-migrate/common/libs/formatCurrency.ts +++ /dev/null @@ -1,5 +0,0 @@ -const formatCurrency = (value: number) => { - return value.toLocaleString('id-ID'); -}; - -export default formatCurrency; diff --git a/src-migrate/common/libs/odooApi.ts b/src-migrate/common/libs/odooApi.ts deleted file mode 100644 index 2dbc18d3..00000000 --- a/src-migrate/common/libs/odooApi.ts +++ /dev/null @@ -1,81 +0,0 @@ -import axios, { AxiosRequestConfig, Method } from 'axios'; -import { getCookie, setCookie } from 'cookies-next'; -import { getAuth } from './auth'; -import { AuthApiProps, AuthProps } from '../types/auth'; - -const ODOO_HOST = process.env.NEXT_PUBLIC_ODOO_API_HOST as string; - -const renewToken = async () => { - let token = await axios.get(`${ODOO_HOST}/api/token`); - setCookie('token', token.data.result); - - return token.data.result; -}; - -const getToken = async () => { - let token = getCookie('token'); - if (token == undefined) token = await renewToken(); - - return token; -}; - -const maxConnectionAttempt = 15; -let connectionAttempt = 0; - -const odooApi = async ( - method: Method, - url: string, - data = {}, - headers = {} -): Promise => { - connectionAttempt++; - - try { - let token = await getToken(); - const auth = getAuth(); - - let axiosParameter: AxiosRequestConfig = { - method, - url: process.env.NEXT_PUBLIC_ODOO_API_HOST + url, - headers: { Authorization: token, ...headers }, - }; - - if (typeof auth === 'object' && 'token' in auth) { - axiosParameter.headers = { - ...axiosParameter.headers, - Token: auth.token, - }; - } - - if (method.toUpperCase() === 'POST') { - axiosParameter.headers = { - ...axiosParameter.headers, - 'Content-Type': 'application/x-www-form-urlencoded', - }; - } - - if (Object.keys(data).length > 0) { - axiosParameter.data = new URLSearchParams( - Object.entries(data) - ).toString(); - } - - let res = await axios(axiosParameter); - const authResponse: AuthApiProps = res.data; - - if ( - authResponse.status.code == 401 && - connectionAttempt < maxConnectionAttempt - ) { - await renewToken(); - return odooApi(method, url, data, headers); - } - - return authResponse.result || null; - } catch (error) { - console.log(error); - return null; - } -}; - -export default odooApi; diff --git a/src-migrate/common/libs/parse b/src-migrate/common/libs/parse deleted file mode 100644 index e69de29b..00000000 diff --git a/src-migrate/common/stores/useRegisterStore.ts b/src-migrate/common/stores/useRegisterStore.ts deleted file mode 100644 index 90ce8a2b..00000000 --- a/src-migrate/common/stores/useRegisterStore.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { create } from 'zustand'; -import { RegisterProps } from '../types/auth'; -import { registerSchema } from '../validations/auth'; -import { ZodError } from 'zod'; - -type State = { - form: RegisterProps; - errors: { - [key in keyof RegisterProps]?: string; - }; - isCheckedTNC: boolean; - isOpenTNC: boolean; - isValidCaptcha: boolean; -}; - -type Action = { - updateForm: (name: string, value: string) => void; - updateValidCaptcha: (value: boolean) => void; - toggleCheckTNC: () => void; - openTNC: () => void; - closeTNC: () => void; - validate: () => void; -}; - -export const useRegisterStore = create((set, get) => ({ - form: { - company: '', - name: '', - email: '', - password: '', - phone: '', - }, - updateForm: (name, value) => - set((state) => ({ form: { ...state.form, [name]: value } })), - - errors: {}, - validate: () => { - try { - registerSchema.parse(get().form); - set({ errors: {} }); - } catch (error) { - if (error instanceof ZodError) { - const errors: State['errors'] = {}; - error.errors.forEach( - (e) => (errors[e.path[0] as keyof RegisterProps] = e.message) - ); - set({ errors }); - } - } - }, - isCheckedTNC: false, - toggleCheckTNC: () => set((state) => ({ isCheckedTNC: !state.isCheckedTNC })), - - isOpenTNC: false, - openTNC: () => set(() => ({ isOpenTNC: true })), - closeTNC: () => set(() => ({ isOpenTNC: false })), - - isValidCaptcha: false, - updateValidCaptcha: (value) => set(() => ({ isValidCaptcha: value })), -})); diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Black.woff b/src-migrate/common/styles/fonts/Inter/Inter-Black.woff deleted file mode 100644 index a18593a0..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Black.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Black.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-Black.woff2 deleted file mode 100644 index 68f64c9e..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Black.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff b/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff deleted file mode 100644 index b6b01943..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff2 deleted file mode 100644 index 1c9c7ca8..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-BlackItalic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff b/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff deleted file mode 100644 index eaf3d4bf..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff2 deleted file mode 100644 index 2846f29c..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Bold.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff b/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff deleted file mode 100644 index 32750761..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff2 deleted file mode 100644 index 0b1fe8e1..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-BoldItalic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff b/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff deleted file mode 100644 index c2c17ede..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff2 deleted file mode 100644 index c24c2bdc..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBold.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff b/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff deleted file mode 100644 index c42f7052..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 deleted file mode 100644 index 4a81dc79..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff b/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff deleted file mode 100644 index d0de5f39..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff2 deleted file mode 100644 index f2ea706f..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLight.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff b/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff deleted file mode 100644 index 81f1a28e..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 deleted file mode 100644 index 9af717ba..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff b/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff deleted file mode 100644 index a806b382..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff2 deleted file mode 100644 index a619fc54..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Italic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Light.woff b/src-migrate/common/styles/fonts/Inter/Inter-Light.woff deleted file mode 100644 index c496464d..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Light.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Light.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-Light.woff2 deleted file mode 100644 index bc4be665..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Light.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff b/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff deleted file mode 100644 index f84a9de3..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff2 deleted file mode 100644 index 842b2dfc..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-LightItalic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff b/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff deleted file mode 100644 index d546843f..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff2 deleted file mode 100644 index f92498a2..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Medium.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff b/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff deleted file mode 100644 index 459a6568..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff2 deleted file mode 100644 index 0e3019f4..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-MediumItalic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff b/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff deleted file mode 100644 index 62d3a618..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff2 deleted file mode 100644 index 6c2b6893..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Regular.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff b/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff deleted file mode 100644 index a815f43a..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff2 deleted file mode 100644 index 611e90c9..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-SemiBold.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff b/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff deleted file mode 100644 index 909e43a9..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 deleted file mode 100644 index 545685bd..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff b/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff deleted file mode 100644 index 62bc58cd..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff2 deleted file mode 100644 index abbc3a5c..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-Thin.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff b/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff deleted file mode 100644 index 700a7f06..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff2 deleted file mode 100644 index ab0b2002..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-ThinItalic.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-italic.var.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-italic.var.woff2 deleted file mode 100644 index b826d5af..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-italic.var.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter-roman.var.woff2 b/src-migrate/common/styles/fonts/Inter/Inter-roman.var.woff2 deleted file mode 100644 index 6a256a06..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter-roman.var.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/Inter.var.woff2 b/src-migrate/common/styles/fonts/Inter/Inter.var.woff2 deleted file mode 100644 index 365eedc5..00000000 Binary files a/src-migrate/common/styles/fonts/Inter/Inter.var.woff2 and /dev/null differ diff --git a/src-migrate/common/styles/fonts/Inter/inter.css b/src-migrate/common/styles/fonts/Inter/inter.css deleted file mode 100644 index de6ce273..00000000 --- a/src-migrate/common/styles/fonts/Inter/inter.css +++ /dev/null @@ -1,199 +0,0 @@ -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 100; - font-display: swap; - src: url('Inter-Thin.woff2?v=3.19') format('woff2'), - url('Inter-Thin.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 100; - font-display: swap; - src: url('Inter-ThinItalic.woff2?v=3.19') format('woff2'), - url('Inter-ThinItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 200; - font-display: swap; - src: url('Inter-ExtraLight.woff2?v=3.19') format('woff2'), - url('Inter-ExtraLight.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 200; - font-display: swap; - src: url('Inter-ExtraLightItalic.woff2?v=3.19') format('woff2'), - url('Inter-ExtraLightItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url('Inter-Light.woff2?v=3.19') format('woff2'), - url('Inter-Light.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 300; - font-display: swap; - src: url('Inter-LightItalic.woff2?v=3.19') format('woff2'), - url('Inter-LightItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url('Inter-Regular.woff2?v=3.19') format('woff2'), - url('Inter-Regular.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 400; - font-display: swap; - src: url('Inter-Italic.woff2?v=3.19') format('woff2'), - url('Inter-Italic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 500; - font-display: swap; - src: url('Inter-Medium.woff2?v=3.19') format('woff2'), - url('Inter-Medium.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 500; - font-display: swap; - src: url('Inter-MediumItalic.woff2?v=3.19') format('woff2'), - url('Inter-MediumItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url('Inter-SemiBold.woff2?v=3.19') format('woff2'), - url('Inter-SemiBold.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 600; - font-display: swap; - src: url('Inter-SemiBoldItalic.woff2?v=3.19') format('woff2'), - url('Inter-SemiBoldItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url('Inter-Bold.woff2?v=3.19') format('woff2'), - url('Inter-Bold.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 700; - font-display: swap; - src: url('Inter-BoldItalic.woff2?v=3.19') format('woff2'), - url('Inter-BoldItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 800; - font-display: swap; - src: url('Inter-ExtraBold.woff2?v=3.19') format('woff2'), - url('Inter-ExtraBold.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 800; - font-display: swap; - src: url('Inter-ExtraBoldItalic.woff2?v=3.19') format('woff2'), - url('Inter-ExtraBoldItalic.woff?v=3.19') format('woff'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 900; - font-display: swap; - src: url('Inter-Black.woff2?v=3.19') format('woff2'), - url('Inter-Black.woff?v=3.19') format('woff'); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 900; - font-display: swap; - src: url('Inter-BlackItalic.woff2?v=3.19') format('woff2'), - url('Inter-BlackItalic.woff?v=3.19') format('woff'); -} - -/* ------------------------------------------------------- -Variable font. -Usage: - - html { font-family: 'Inter', sans-serif; } - @supports (font-variation-settings: normal) { - html { font-family: 'Inter var', sans-serif; } - } -*/ -@font-face { - font-family: 'Inter var'; - font-weight: 100 900; - font-display: swap; - font-style: normal; - font-named-instance: 'Regular'; - src: url('Inter-roman.var.woff2?v=3.19') format('woff2'); -} -@font-face { - font-family: 'Inter var'; - font-weight: 100 900; - font-display: swap; - font-style: italic; - font-named-instance: 'Italic'; - src: url('Inter-italic.var.woff2?v=3.19') format('woff2'); -} - -/* -------------------------------------------------------------------------- -[EXPERIMENTAL] Multi-axis, single variable font. - -Slant axis is not yet widely supported (as of February 2019) and thus this -multi-axis single variable font is opt-in rather than the default. - -When using this, you will probably need to set font-variation-settings -explicitly, e.g. - - * { font-variation-settings: "slnt" 0deg } - .italic { font-variation-settings: "slnt" 10deg } - -*/ -@font-face { - font-family: 'Inter var experimental'; - font-weight: 100 900; - font-display: swap; - font-style: oblique 0deg 10deg; - src: url('Inter.var.woff2?v=3.19') format('woff2'); -} diff --git a/src-migrate/common/styles/globals.css b/src-migrate/common/styles/globals.css deleted file mode 100644 index ea20b247..00000000 --- a/src-migrate/common/styles/globals.css +++ /dev/null @@ -1,674 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -* { - -webkit-tap-highlight-color: transparent; -} - -html, -body { - @apply w-screen - text-body-2 - text-gray_r-12 - bg-gray_r-1 - overflow-x-clip; -} - -#__next main { - @apply min-h-screen; -} - -button { - @apply block; -} - -@layer base { - input[type='number']::-webkit-inner-spin-button, - input[type='number']::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; - } - - input[type='number'] { - -moz-appearance: textfield; - } -} - -@layer components { - .badge-red, - .badge-solid-red, - .badge-gray, - .badge-yellow, - .badge-blue, - .badge-green, - .badge-solid-green { - @apply text-[11px] - leading-none - font-medium - px-1 - py-1 - rounded - w-fit; - } - - .badge-red { - @apply bg-danger-100 - text-danger-600; - } - - .badge-solid-red { - @apply bg-danger-500 - text-white; - } - - .badge-gray { - @apply bg-gray_r-5 - text-gray_r-10; - } - - .badge-yellow { - @apply bg-warning-500 - text-warning-900; - } - - .badge-blue { - @apply bg-blue-200 - text-blue-600; - } - - .badge-green { - @apply bg-success-100 - text-success-600; - } - - .badge-solid-green { - @apply bg-success-500 - text-white; - } - - .form-label { - @apply font-medium - block; - } - - .form-input { - @apply p-3 - rounded - border - text-gray_r-12 - border-gray_r-7 - !bg-white - bg-transparent - w-full - leading-none - focus:outline-none - focus:border-warning-500 - disabled:bg-gray_r-5; - } - - .form-input[aria-invalid] { - @apply border-danger-500 - focus:border-danger-500; - } - - .form-input[type='file'] { - @apply py-2; - } - - .btn-yellow, - .btn-light, - .btn-red, - .btn-solid-red { - @apply block - w-fit - py-3 - px-6 - rounded - border - text-center - font-medium - ease-linear - duration-150; - } - - .btn-yellow { - @apply bg-warning-500 - border-warning-500 - hover:bg-warning-500/80 - disabled:text-gray_r-10 - disabled:bg-warning-200 - disabled:border-warning-200; - } - - .btn-red { - @apply bg-danger-100 - border-danger-300 - text-danger-500 - disabled:text-danger-400 - disabled:bg-danger-200; - } - - .btn-solid-red { - @apply bg-danger-500 - border-danger-500 - text-gray_r-1 - hover:bg-danger-500/80 - disabled:text-gray_r-1 - disabled:bg-danger-200 - disabled:border-danger-200; - } - - .btn-light { - @apply bg-gray_r-3 - border-gray_r-6 - disabled:text-gray_r-10 - disabled:bg-gray_r-6; - } - - .product-card { - @apply w-full - h-full - border - border-gray_r-3 - shadow - bg-white - rounded - relative - flex - flex-col; - } - - .product-card__image { - @apply w-full - h-[160px] - object-contain - object-center - border-b - border-gray_r-6; - } - - .product-card__content { - @apply p-2 - pb-3 - flex-1; - } - - .product-card__title { - @apply text-caption-1 - text-gray_r-12 - leading-5; - } - - .product-card__brand { - @apply text-caption-1 - mb-1 - block; - } - - .product__description { - @apply text-gray_r-12/90; - } - - .product__description br { - @apply block my-1; - } - - .product__description b { - @apply font-semibold; - } -} - -@layer utilities { - .wrap-line-ellipsis-1, - .wrap-line-ellipsis-2, - .wrap-line-ellipsis-3 { - display: -webkit-box; - -webkit-box-orient: vertical; - overflow: hidden; - text-overflow: ellipsis; - } - - .wrap-line-ellipsis-1 { - -webkit-line-clamp: 1; - } - - .wrap-line-ellipsis-2 { - -webkit-line-clamp: 2; - } - - .wrap-line-ellipsis-3 { - -webkit-line-clamp: 3; - } -} - -.menu-wrapper { - @apply fixed - top-0 - left-0 - bg-white - w-[80%] - h-full - z-[60] - overflow-y-auto - translate-x-[-100%] - ease-linear - duration-150; -} - -.menu-wrapper.active { - @apply translate-x-0; -} - -.overlay { - @apply fixed - top-0 - left-0 - w-full - h-full - z-[55] - bg-gray_r-12/40; -} - -.sticky-header { - @apply px-4 - py-3 - bg-gray_r-1/90 - backdrop-blur-lg - sticky - top-0 - border-b - border-gray_r-7 - z-50; -} - -.content-container { - @apply max-w-full - overflow-x-hidden; -} - -#indoteknik_toast { - @apply fixed - bottom-4 - translate-y-[200%] - left-[50%] - translate-x-[-50%] - z-[100] - flex - items-center - p-4 - mb-4 - w-[90%] - text-gray-500 - bg-white - border - border-gray-300 - rounded-lg - shadow - ease-linear - duration-300; -} - -#indoteknik_toast.active { - @apply translate-y-0; -} - -.category-menu { - @apply hidden; -} - -.swiper-slide { - @apply !h-auto; -} - -.lazy-load-image-background { - @apply !block - w-full; -} - -.swiper-pagination-bullet-active { - @apply !bg-danger-500; -} - -.pagination { - @apply flex - justify-center - gap-x-1; -} - -.pagination-item { - @apply p-1 - flex - justify-center - items-center - w-10 - rounded - ease-linear - duration-150 - border - border-gray_r-6 - bg-gray_r-3 - hover:bg-gray_r-5 - text-gray_r-12; -} - -.pagination-item--active { - @apply border-warning-500 - bg-warning-500 - hover:bg-warning-500; -} - -.pagination-dots { - @apply p-1 - flex - justify-center - items-end - w-10 - rounded - ease-linear - bg-gray_r-3 - text-caption-2; -} - -.idt-transition { - @apply transition-all - ease-out - duration-200; -} - -.form-select__placeholder { - @apply !text-gray_r-9; -} - -.form-select__control { - @apply !shadow-none - !border-gray_r-7; -} - -.form-select__control--menu-is-open { - @apply !border-warning-500; -} - -.table-specification { - @apply max-h-[500px] overflow-y-auto border border-gray_r-6; -} - -.table-specification > table { - @apply table-auto - border-collapse - w-full; -} - -.table-specification > table > thead > tr > th:last-child { - @apply w-3/12; -} - -.table-specification > table > thead { - @apply sticky top-0 border-b; -} - -.table-specification > table > thead > tr { - @apply bg-gray_r-1/80 backdrop-blur-lg; -} - -.table-specification th { - @apply font-semibold; -} - -.table-specification th, -.table-specification td { - @apply p-4 text-center; -} - -.table-specification > table > tbody > tr { - @apply odd:bg-gray_r-3 even:bg-gray_r-1; -} - -.table-cart, -.table-checkout { - @apply w-full - table-auto - border-collapse; -} - -.table-cart tr, -.table-checkout tr { - @apply border-y - border-gray_r-6 - first:border-t-0; -} - -.table-cart th, -.table-cart td, -.table-checkout th, -.table-checkout td { - @apply py-4 - px-3 - text-center - text-gray_r-12/90; -} - -.table-cart th, -.table-cart td { - @apply first:w-12; -} - -.table-cart th, -.table-checkout th { - @apply font-medium; -} - -.table-data { - @apply w-full - table-auto - border-collapse; -} - -.table-data thead tr { - @apply bg-gray_r-3; -} - -.table-data thead th { - @apply font-medium whitespace-nowrap; -} - -.table-data thead th, -.table-data tbody td { - @apply px-3 - py-4 - text-center; -} - -.table-data tbody td { - @apply text-gray_r-12/90; -} - -.table-data tbody tr { - @apply border-b - border-gray_r-6; -} - -.navbar-user-dropdown-button { - @apply flex-1 - flex - gap-x-2 - p-4 - items-center - bg-danger-500 - font-medium - !text-gray_r-1 - rounded-none - rounded-t-xl; -} - -.navbar-user-dropdown-button span { - @apply line-clamp-1; -} - -.navbar-user-dropdown-wrapper a, -.navbar-user-dropdown-wrapper button { - @apply text-gray_r-12/80 hover:bg-gray_r-5 font-medium py-2 px-4 w-full text-left; -} - -.navbar-user-dropdown { - @apply bg-white - border - border-gray_r-6 - py-2 - w-full - shadow; -} - -.category-mega-box-wrapper, -.navbar-user-dropdown-wrapper { - @apply absolute - opacity-0 - left-0 - top-[125%] - flex - w-full - z-10 - transition-all - ease-in - duration-200 - pointer-events-none - text-left; -} - -.category-mega-box-wrapper.show, -.navbar-user-dropdown-button:hover ~ .navbar-user-dropdown-wrapper, -.navbar-user-dropdown-wrapper:hover { - @apply top-[100%] - opacity-100 - pointer-events-auto; -} - -.category-mega-box { - @apply relative - py-2 - border - border-t-0 - bg-white - border-gray_r-6 - h-full - w-full; -} - -.category-mega-box > div { - @apply text-gray_r-12/80; -} - -.category-mega-box > div:hover .category-mega-box__parent { - @apply bg-gray_r-5; -} - -.category-mega-box > div:hover .category-mega-box__child-wrapper { - @apply opacity-100 - top-0 - pointer-events-auto; -} - -.category-mega-box .category-mega-box__parent { - @apply py-2.5 - px-4 - text-gray_r-12/80 - font-normal; -} - -.category-mega-box__child-wrapper { - @apply absolute - left-[100%] - top-12 - w-[40vw] - bg-gray_r-1/90 - backdrop-blur-md - border - border-gray_r-6 - p-6 - opacity-0 - h-full - transition-all - ease-in - duration-200 - pointer-events-none - z-50; -} - -.category-mega-box__child-one { - @apply text-gray_r-12/80 - hover:text-danger-500 - transition-colors - ease-linear - duration-100 - font-semibold; -} - -.category-mega-box__child-two { - @apply text-gray_r-12/80 - hover:text-danger-500 - transition-colors - ease-linear - duration-100 - font-normal; -} - -@keyframes page-loader { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } -} - -.page-loader { - animation-name: page-loader; - animation-duration: 1000ms; - animation-delay: 50ms; - animation-timing-function: ease-in-out; - animation-iteration-count: infinite; -} - -@keyframes shake { - 0% { - transform: translateX(0); - } - 10%, - 90% { - transform: translateX(-10px); - } - 20%, - 80% { - transform: translateX(10px); - } - 30%, - 50%, - 70% { - transform: translateX(-10px); - } - 40%, - 60% { - transform: translateX(10px); - } - 100% { - transform: translateX(0); - } -} - -.blink-color-flash-sale { - @apply text-body-1 md:text-title-sm; - transform: rotateY(180deg) rotateZ(120deg); - animation-name: blink-color-flash-sale; - animation-duration: 300ms; - animation-iteration-count: infinite; - animation-timing-function: linear; -} - -@keyframes blink-color-flash-sale { - from { - @apply text-danger-500; - } - to { - @apply text-warning-500; - } -} diff --git a/src-migrate/common/types/auth.ts b/src-migrate/common/types/auth.ts deleted file mode 100644 index 65fd06c7..00000000 --- a/src-migrate/common/types/auth.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { registerSchema } from '../validations/auth'; -import { OdooApiProps } from './odoo'; -import { z } from 'zod'; - -export type AuthProps = { - id: number; - parent_id: number; - parent_name: string; - partner_id: number; - name: string; - email: string; - phone: string; - mobile: string; - external: boolean; - company: boolean; - pricelist: string | null; - token: string; -}; - -export type AuthApiProps = OdooApiProps & { result: AuthProps }; - -export type RegisterProps = z.infer; - -export type RegisterResApiProps = { - register: boolean; - reason: 'EMAIL_USED' | 'NOT_ACTIVE' | null; -}; - -type ActivationResProps = { - activation: boolean; - user: AuthProps | null; -}; - -export type ActivationTokenProps = { - token: string; -}; - -export type ActivationTokenResApiProps = ActivationResProps & { - reason: 'INVALID_TOKEN' | null; -}; - -export type ActivationOtpProps = { - email: string; - otp: string; -}; - -export type ActivationOtpResApiProps = ActivationResProps & { - reason: 'INVALID_OTP' | null; -}; - -export type ActivationReqProps = { - email: string; -}; - -export type ActivationReqResApiProps = { - activation_request: boolean; - reason: 'NOT_FOUND' | 'ACTIVE' | null; -}; diff --git a/src-migrate/common/types/cart.ts b/src-migrate/common/types/cart.ts deleted file mode 100644 index 3aceeac4..00000000 --- a/src-migrate/common/types/cart.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { CategoryPromo } from "./promotion"; - -type Price = { - price: number; - discount_percentage: number; - price_discount: number; -}; - -export type CartProduct = { - id: number; - image: string; - display_name: string; - name: string; - code: string; - price: Price; - qty: number; - weight: number; - package_weight: number; -}; - -export type CartItem = { - cart_id: number; - quantity: number; - selected: boolean; - can_buy: boolean; - cart_type: 'product' | 'promotion'; - id: number; - name: string; - stock: number; - weight: number; - attributes: string[]; - parent: { - id: number; - name: string; - image: string; - }; - price: Price; - manufacture: { - id: number; - name: string; - }; - has_flashsale: boolean; - subtotal: number; - - code?: string; - - image?: string; - remaining_time?: number; - promotion_type?: { - value?: CategoryPromo; - label?: string; - }; - limit_qty?: { - all?: number; - user?: number; - transaction?: number; - }; - remaining_qty?: { - all?: number; - user?: number; - transaction?: number; - }; - used_percentage?: number; - products?: CartProduct[]; - free_products?: CartProduct[]; - package_price?: number; -}; - -export type CartProps = { - product_total: number; - products: CartItem[]; -}; diff --git a/src-migrate/common/types/checkout.ts b/src-migrate/common/types/checkout.ts deleted file mode 100644 index dc1365d8..00000000 --- a/src-migrate/common/types/checkout.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CartItem } from './cart'; - -export interface ICheckout { - total_purchase: number; - total_discount: number; - discount_voucher: number; - subtotal: number; - tax: number; - grand_total: number; - total_weight: { - kg: number; - g: number; - }; - has_product_without_weight: boolean; - products: CartItem[]; -} diff --git a/src-migrate/common/types/nav.ts b/src-migrate/common/types/nav.ts deleted file mode 100644 index ba97b1bf..00000000 --- a/src-migrate/common/types/nav.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type SecondaryNavItemProps = { - label: string - href: string -} diff --git a/src-migrate/common/types/odoo.ts b/src-migrate/common/types/odoo.ts deleted file mode 100644 index b34bc667..00000000 --- a/src-migrate/common/types/odoo.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type OdooApiProps = { - status: { - code: number; - description: string; - }; -}; diff --git a/src-migrate/common/types/pageContent.ts b/src-migrate/common/types/pageContent.ts deleted file mode 100644 index 4361deb7..00000000 --- a/src-migrate/common/types/pageContent.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type PageContentProps = { - id: number; - url_path: string; - content: string; -} | null; diff --git a/src-migrate/common/types/productVariant.ts b/src-migrate/common/types/productVariant.ts deleted file mode 100644 index c4aa9534..00000000 --- a/src-migrate/common/types/productVariant.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface IProductVariant { - id: number; - parent_id: number; - display_name: string; - image: string; - name: string; - default_code: string; - price: { - price: number; - discount_percentage: number; - price_discount: number; - }; -} diff --git a/src-migrate/common/types/promotion.ts b/src-migrate/common/types/promotion.ts deleted file mode 100644 index 1f8316cf..00000000 --- a/src-migrate/common/types/promotion.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { IProductVariant } from './productVariant'; - -export interface IPromotion { - id: number; - program_id: number; - name: string; - type: { - value: CategoryPromo; - label: string; - }; - limit: number; - limit_user: number; - limit_trx: number; - price: number; - total_qty: number; - products: { - product_id: number; - qty: number; - }[]; - free_products: { - product_id: number; - qty: number; - }[]; -} - -export interface IProductVariantPromo extends IProductVariant { - qty: number; -} - -export type CategoryPromo = 'bundling' | 'discount_loading' | 'merchandise'; - -export interface ICategoryPromo { - value: CategoryPromo; - label: string; -} diff --git a/src-migrate/common/types/promotionProgram.ts b/src-migrate/common/types/promotionProgram.ts deleted file mode 100644 index 205884b6..00000000 --- a/src-migrate/common/types/promotionProgram.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type IPromotionProgram = { - id: number; - name: string; - start_time: string; - end_time: string; - applies_to: string; - time_left: number; -}; diff --git a/src-migrate/common/types/solr.ts b/src-migrate/common/types/solr.ts deleted file mode 100644 index d231c305..00000000 --- a/src-migrate/common/types/solr.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type SolrResponse = { - response: { - numFound: number; - start: number; - docs: T; - }; -}; diff --git a/src-migrate/common/validations/auth.ts b/src-migrate/common/validations/auth.ts deleted file mode 100644 index 78fc5e71..00000000 --- a/src-migrate/common/validations/auth.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { z } from 'zod'; - -export const registerSchema = z.object({ - name: z.string().min(1, { message: 'Nama harus diisi' }), - email: z - .string() - .min(1, { message: 'Email harus diisi' }) - .email({ message: 'Email harus menggunakan format example@mail.com' }), - password: z.string().min(6, { message: 'Password minimal 6 karakter' }), - company: z.string().optional(), - phone: z - .string() - .min(1, { message: 'Nomor telepon harus diisi' }) - .refine((val) => /^\d{10,12}$/.test(val), { - message: 'Format nomor telepon tidak valid, contoh: 081234567890', - }), -}); diff --git a/src-migrate/components/seo.tsx b/src-migrate/components/seo.tsx new file mode 100644 index 00000000..1e78ed4d --- /dev/null +++ b/src-migrate/components/seo.tsx @@ -0,0 +1,32 @@ +import { useRouter } from 'next/router' +import React from 'react' +import { NextSeo } from "next-seo" +import { MetaTag, NextSeoProps } from 'next-seo/lib/types'; + +export const Seo = (props: NextSeoProps) => { + const router = useRouter() + + const additionalMetaTags: MetaTag[] = [ + { + property: 'fb:app_id', + content: '270830718811' + }, + { + property: 'fb:page_id', + content: '101759953569' + }, + ] + + if (!!props.additionalMetaTags) additionalMetaTags.push(...props.additionalMetaTags) + + return ( + + ) +} \ No newline at end of file diff --git a/src-migrate/components/ui/image.tsx b/src-migrate/components/ui/image.tsx new file mode 100644 index 00000000..a91b2a9d --- /dev/null +++ b/src-migrate/components/ui/image.tsx @@ -0,0 +1,46 @@ +import clsx from 'clsx'; +import NextImage, { ImageProps as NextImageProps } from 'next/image'; +import { useState } from 'react'; + +import clsxm from '~/libs/clsxm'; + +type ImageProps = { + rounded?: string; + classNames?: { + wrapper: string + } +} & NextImageProps; + +const Image = (props: ImageProps) => { + const { alt, src, className, classNames, rounded, ...rest } = props; + const [isLoading, setLoading] = useState(true); + + return ( +
+ setLoading(false)} + {...rest} + /> +
+ ); +}; +export default Image; \ No newline at end of file diff --git a/src-migrate/components/ui/modal.tsx b/src-migrate/components/ui/modal.tsx new file mode 100644 index 00000000..34e1d1c3 --- /dev/null +++ b/src-migrate/components/ui/modal.tsx @@ -0,0 +1,87 @@ +import { useEffect, useState } from "react"; +import ReactDOM from "react-dom"; +import { useRouter } from "next/router"; +import { AnimatePresence, motion } from "framer-motion" +import { useWindowSize } from "usehooks-ts"; +import { XMarkIcon } from "@heroicons/react/24/outline"; +import clsxm from "~/libs/clsxm"; + +export interface ModalProps { + children: React.ReactNode + active: boolean + title?: string + close?: () => void, + className?: string, + mode?: "mobile" | "desktop" +} + +export const Modal = ({ + children, + active = false, + title, + close, + className, + mode +}: ModalProps) => { + const router = useRouter() + const { width } = useWindowSize() + const [rendered, setRendered] = useState(false) + + mode = mode || width >= 768 ? "desktop" : "mobile" + + useEffect(() => { + setRendered(true) + }, []) + + const modalClassNames = clsxm( + "fixed bg-white max-h-[80vh] overflow-auto p-4 pt-0 z-[60] border-gray_r-6", + { + "left-1/2 -translate-x-1/2 translate-y-1/2 bottom-1/2 w-11/12 md:w-[500px] border rounded-xl": mode === 'desktop', + "left-0 w-full border-t bottom-0 rounded-t-xl": mode === 'mobile' + }, + className + ) + + const variant = { + initial: { bottom: mode === 'desktop' ? '45%' : '-100%', opacity: 0 }, + animate: { bottom: mode === 'desktop' ? '50%' : 0, opacity: 1 }, + exit: { bottom: mode === 'desktop' ? '55%' : '-100%', opacity: 0 }, + transition: { ease: 'linear', duration: 0.25 } + } + + return rendered && ReactDOM.createPortal( + + {active && ( + + )} + + {active && ( + +
+
+ {title} +
+ {close && ( + + )} +
+ + {children} +
+ )} + +
, + document.querySelector('body')! + ) +} \ No newline at end of file diff --git a/src-migrate/components/ui/re-captcha.tsx b/src-migrate/components/ui/re-captcha.tsx new file mode 100644 index 00000000..e31aa1e3 --- /dev/null +++ b/src-migrate/components/ui/re-captcha.tsx @@ -0,0 +1,15 @@ +import ReCAPTCHA, { ReCAPTCHAProps } from "react-google-recaptcha" + +const GOOGLE_RECAPTCHA_KEY = process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE || '' + +export interface ReCaptchaProps extends Omit { + sitekey?: string; +} + +export const ReCaptcha = (props: ReCaptchaProps) => { + const { sitekey, ...rest } = props + + return ( + + ) +} diff --git a/src-migrate/constants/menu.ts b/src-migrate/constants/menu.ts new file mode 100644 index 00000000..d1adebca --- /dev/null +++ b/src-migrate/constants/menu.ts @@ -0,0 +1,20 @@ +import { SecondaryNavItemProps } from '~/types/nav'; + +export const SECONDARY_MENU_ITEMS: SecondaryNavItemProps[] = [ + { + label: 'Semua Brand', + href: '/shop/brands', + }, + { + label: 'Ready Stock', + href: '/shop/search?orderBy=stock', + }, + { + label: 'Blog Indoteknik', + href: 'https://blog.indoteknik.com/', + }, + { + label: 'Indoteknik TV', + href: '/video', + }, +]; diff --git a/src-migrate/libs/auth.ts b/src-migrate/libs/auth.ts new file mode 100644 index 00000000..86ce26e1 --- /dev/null +++ b/src-migrate/libs/auth.ts @@ -0,0 +1,26 @@ +import { deleteCookie, getCookie, setCookie } from 'cookies-next'; +import { AuthProps } from '~/types/auth'; + +const COOKIE_KEY = 'auth'; + +export const getAuth = (): AuthProps | boolean => { + const auth = getCookie(COOKIE_KEY); + + if (typeof auth === 'string') { + return JSON.parse(auth); + } + + return false; +}; + +export const setAuth = (user: AuthProps): boolean => { + setCookie(COOKIE_KEY, JSON.stringify(user)); + + return true; +}; + +export const deleteAuth = (): boolean => { + deleteCookie(COOKIE_KEY); + + return true; +}; diff --git a/src-migrate/libs/clsxm.ts b/src-migrate/libs/clsxm.ts new file mode 100644 index 00000000..0fc10317 --- /dev/null +++ b/src-migrate/libs/clsxm.ts @@ -0,0 +1,6 @@ +import clsx, { ClassValue } from 'clsx'; +import { twMerge } from 'tw-merge'; + +export default function clsxm(...classes: ClassValue[]) { + return twMerge(clsx(...classes)); +} diff --git a/src-migrate/libs/formatCurrency.ts b/src-migrate/libs/formatCurrency.ts new file mode 100644 index 00000000..41db4a6f --- /dev/null +++ b/src-migrate/libs/formatCurrency.ts @@ -0,0 +1,5 @@ +const formatCurrency = (value: number) => { + return value.toLocaleString('id-ID'); +}; + +export default formatCurrency; diff --git a/src-migrate/libs/formatNumber.ts b/src-migrate/libs/formatNumber.ts new file mode 100644 index 00000000..da243418 --- /dev/null +++ b/src-migrate/libs/formatNumber.ts @@ -0,0 +1,8 @@ +export const formatToShortText = (number: number) => { + if (number > 1000) { + return `${Math.floor(number / 1000)}rb+`; + } else if (number > 100) { + return `${Math.floor(number / 100) * 100}+`; + } + return number.toString(); +}; diff --git a/src-migrate/libs/odooApi.ts b/src-migrate/libs/odooApi.ts new file mode 100644 index 00000000..9482542b --- /dev/null +++ b/src-migrate/libs/odooApi.ts @@ -0,0 +1,81 @@ +import axios, { AxiosRequestConfig, Method } from 'axios'; +import { getCookie, setCookie } from 'cookies-next'; +import { getAuth } from './auth'; +import { AuthApiProps } from '~/types/auth'; + +const ODOO_HOST = process.env.NEXT_PUBLIC_ODOO_API_HOST as string; + +const renewToken = async () => { + let token = await axios.get(`${ODOO_HOST}/api/token`); + setCookie('token', token.data.result); + + return token.data.result; +}; + +const getToken = async () => { + let token = getCookie('token'); + if (token == undefined) token = await renewToken(); + + return token; +}; + +const maxConnectionAttempt = 15; +let connectionAttempt = 0; + +const odooApi = async ( + method: Method, + url: string, + data = {}, + headers = {} +): Promise => { + connectionAttempt++; + + try { + let token = await getToken(); + const auth = getAuth(); + + let axiosParameter: AxiosRequestConfig = { + method, + url: process.env.NEXT_PUBLIC_ODOO_API_HOST + url, + headers: { Authorization: token, ...headers }, + }; + + if (typeof auth === 'object' && 'token' in auth) { + axiosParameter.headers = { + ...axiosParameter.headers, + Token: auth.token, + }; + } + + if (method.toUpperCase() === 'POST') { + axiosParameter.headers = { + ...axiosParameter.headers, + 'Content-Type': 'application/x-www-form-urlencoded', + }; + } + + if (Object.keys(data).length > 0) { + axiosParameter.data = new URLSearchParams( + Object.entries(data) + ).toString(); + } + + let res = await axios(axiosParameter); + const authResponse: AuthApiProps = res.data; + + if ( + authResponse.status.code == 401 && + connectionAttempt < maxConnectionAttempt + ) { + await renewToken(); + return odooApi(method, url, data, headers); + } + + return authResponse.result || null; + } catch (error) { + console.log(error); + return null; + } +}; + +export default odooApi; diff --git a/src-migrate/libs/slug.ts b/src-migrate/libs/slug.ts new file mode 100644 index 00000000..5ab3b3dd --- /dev/null +++ b/src-migrate/libs/slug.ts @@ -0,0 +1,34 @@ +import { toTitleCase } from './toTitleCase'; + +export const createSlug = ( + prefix: string, + name: string, + id: string, + withHost = false +) => { + const cleanName = name + .trim() + .replace(new RegExp(/[^A-Za-z0-9]/, 'g'), '-') + .toLowerCase(); + + let slug = `${cleanName}-${id}`; + const splitSlug = slug.split('-'); + const filterSlug = splitSlug.filter((x) => x !== ''); + + slug = `${prefix}${filterSlug.join('-')}`; + + if (withHost) slug = process.env.NEXT_PUBLIC_SELF_HOST + slug; + + return slug; +}; + +export const getIdFromSlug = (slug: string) => { + let id = slug.split('-'); + return id[id.length - 1]; +}; + +export const getNameFromSlug = (slug: string) => { + let name = slug.split('-'); + name.pop(); + return toTitleCase(name.join(' ')); +}; diff --git a/src-migrate/libs/toTitleCase.ts b/src-migrate/libs/toTitleCase.ts new file mode 100644 index 00000000..dad66813 --- /dev/null +++ b/src-migrate/libs/toTitleCase.ts @@ -0,0 +1,5 @@ +export const toTitleCase = (val: string) => { + return val.replace(/\w\S*/g, function (txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + }); +}; diff --git a/src-migrate/modules/account-activation/components/FormEmail.tsx b/src-migrate/modules/account-activation/components/FormEmail.tsx index ec300ba4..f7925481 100644 --- a/src-migrate/modules/account-activation/components/FormEmail.tsx +++ b/src-migrate/modules/account-activation/components/FormEmail.tsx @@ -3,9 +3,9 @@ import Link from "next/link" import { useRouter } from "next/router" import { ChangeEvent, useEffect, useState } from "react" import { useMutation } from "react-query" -import Modal from "~/common/components/elements/Modal" -import { useRegisterStore } from "~/common/stores/useRegisterStore" -import { ActivationReqProps } from "~/common/types/auth" +import { Modal } from "~/components/ui/modal" +import { useRegisterStore } from "~/modules/register/stores/useRegisterStore" +import { ActivationReqProps } from "~/types/auth" import { activationReq } from "~/services/auth" const FormEmail = () => { diff --git a/src-migrate/modules/account-activation/components/FormOTP.tsx b/src-migrate/modules/account-activation/components/FormOTP.tsx index 6815a088..cf4da2db 100644 --- a/src-migrate/modules/account-activation/components/FormOTP.tsx +++ b/src-migrate/modules/account-activation/components/FormOTP.tsx @@ -3,9 +3,9 @@ import { useRouter } from "next/router" import { useEffect, useState } from "react" import { useMutation } from "react-query" import { useCountdown } from "usehooks-ts" -import Modal from '~/common/components/elements/Modal' -import { setAuth } from "~/common/libs/auth" -import { ActivationOtpProps, ActivationReqProps } from "~/common/types/auth" +import { Modal } from "~/components/ui/modal" +import { setAuth } from "~/libs/auth" +import { ActivationOtpProps, ActivationReqProps } from "~/types/auth" import { activationReq, activationUserOTP } from "~/services/auth" const FormOTP = () => { diff --git a/src-migrate/modules/account-activation/components/FormToken.tsx b/src-migrate/modules/account-activation/components/FormToken.tsx index b68b244f..2835ec0e 100644 --- a/src-migrate/modules/account-activation/components/FormToken.tsx +++ b/src-migrate/modules/account-activation/components/FormToken.tsx @@ -4,10 +4,10 @@ import { useEffect, useState } from "react" import Link from "next/link" import { useMutation } from "react-query" -import Modal from "~/common/components/elements/Modal" -import { ActivationTokenProps } from "~/common/types/auth" +import { Modal } from "~/components/ui/modal" +import { ActivationTokenProps } from "~/types/auth" import { activationUserToken } from "~/services/auth" -import { setAuth } from "~/common/libs/auth" +import { setAuth } from "~/libs/auth" const FormToken = () => { const router = useRouter() diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx index baf48bb6..08823d19 100644 --- a/src-migrate/modules/cart/components/Item.tsx +++ b/src-migrate/modules/cart/components/Item.tsx @@ -7,8 +7,8 @@ import { InfoIcon } from 'lucide-react' import { PROMO_CATEGORY } from '~/constants/promotion' -import formatCurrency from '~/common/libs/formatCurrency' -import { CartItem as CartItemProps } from '~/common/types/cart' +import formatCurrency from '~/libs/formatCurrency' +import { CartItem as CartItemProps } from '~/types/cart' import CartItemPromo from './ItemPromo' import CartItemAction from './ItemAction' diff --git a/src-migrate/modules/cart/components/ItemAction.tsx b/src-migrate/modules/cart/components/ItemAction.tsx index 3e264aef..859c758c 100644 --- a/src-migrate/modules/cart/components/ItemAction.tsx +++ b/src-migrate/modules/cart/components/ItemAction.tsx @@ -5,8 +5,8 @@ import React, { useEffect, useState } from 'react' import { Spinner, Tooltip } from '@chakra-ui/react' import { MinusIcon, PlusIcon, Trash2Icon } from 'lucide-react' -import { CartItem } from '~/common/types/cart' -import { getAuth } from '~/common/libs/auth' +import { CartItem } from '~/types/cart' +import { getAuth } from '~/libs/auth' import { deleteUserCart, upsertUserCart } from '~/services/cart' import { useDebounce } from 'usehooks-ts' diff --git a/src-migrate/modules/cart/components/ItemPromo.tsx b/src-migrate/modules/cart/components/ItemPromo.tsx index bb286e8b..bc507578 100644 --- a/src-migrate/modules/cart/components/ItemPromo.tsx +++ b/src-migrate/modules/cart/components/ItemPromo.tsx @@ -3,7 +3,7 @@ import style from '../styles/item-promo.module.css' import Image from 'next/image' import React from 'react' -import { CartProduct } from '~/common/types/cart' +import { CartProduct } from '~/types/cart' type Props = { product: CartProduct diff --git a/src-migrate/modules/cart/components/ItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx index 10d7493a..1d8886a2 100644 --- a/src-migrate/modules/cart/components/ItemSelect.tsx +++ b/src-migrate/modules/cart/components/ItemSelect.tsx @@ -1,8 +1,8 @@ import { Checkbox, Spinner } from '@chakra-ui/react' import React, { useState } from 'react' -import { getAuth } from '~/common/libs/auth' -import { CartItem } from '~/common/types/cart' +import { getAuth } from '~/libs/auth' +import { CartItem } from '~/types/cart' import { upsertUserCart } from '~/services/cart' import { useCartStore } from '../stores/useCartStore' diff --git a/src-migrate/modules/cart/components/Summary.tsx b/src-migrate/modules/cart/components/Summary.tsx index a835bca9..2e55c8df 100644 --- a/src-migrate/modules/cart/components/Summary.tsx +++ b/src-migrate/modules/cart/components/Summary.tsx @@ -1,8 +1,8 @@ import style from '../styles/summary.module.css' import React from 'react' -import formatCurrency from '~/common/libs/formatCurrency' -import clsxm from '~/common/libs/clsxm' +import formatCurrency from '~/libs/formatCurrency' +import clsxm from '~/libs/clsxm' import { Skeleton } from '@chakra-ui/react' import _ from 'lodash' diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts index 0643b8e6..3d9a0aed 100644 --- a/src-migrate/modules/cart/stores/useCartStore.ts +++ b/src-migrate/modules/cart/stores/useCartStore.ts @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import { CartProps } from '~/common/types/cart'; +import { CartProps } from '~/types/cart'; import { getUserCart } from '~/services/cart'; type State = { diff --git a/src-migrate/modules/header/components/HeaderDesktop.tsx b/src-migrate/modules/header/components/HeaderDesktop.tsx index 3860bded..8f5a8efa 100644 --- a/src-migrate/modules/header/components/HeaderDesktop.tsx +++ b/src-migrate/modules/header/components/HeaderDesktop.tsx @@ -8,7 +8,7 @@ import Link from 'next/link' import SearchBar from "./SearchBar"; // Constants -import { SECONDARY_MENU_ITEMS } from "~/common/constants/menu"; +import { SECONDARY_MENU_ITEMS } from "~/constants/menu"; const LOGO_WIDTH = 210; const LOGO_HEIGHT = LOGO_WIDTH / 3; diff --git a/src-migrate/modules/page-content/index.tsx b/src-migrate/modules/page-content/index.tsx index 608079f8..547b1957 100644 --- a/src-migrate/modules/page-content/index.tsx +++ b/src-migrate/modules/page-content/index.tsx @@ -1,7 +1,6 @@ import { useMemo } from "react" import { useQuery } from "react-query" -import PageContentSkeleton from "~/common/components/skeleton/PageContentSkeleton" -import { PageContentProps } from "~/common/types/pageContent" +import { PageContentProps } from "~/types/pageContent" import { getPageContent } from "~/services/pageContent" type Props = { @@ -26,4 +25,20 @@ const PageContent = ({ path }: Props) => { ) } +const PageContentSkeleton = () => ( +
+
+
+
+
+
+
+
+
+
+
+
+
+) + export default PageContent \ No newline at end of file diff --git a/src-migrate/modules/popup-information/index.tsx b/src-migrate/modules/popup-information/index.tsx index cd1fd5f2..3d537236 100644 --- a/src-migrate/modules/popup-information/index.tsx +++ b/src-migrate/modules/popup-information/index.tsx @@ -1,7 +1,7 @@ import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; -import Modal from '~/common/components/elements/Modal'; -import { getAuth } from '~/common/libs/auth'; +import { Modal } from "~/components/ui/modal" +import { getAuth } from '~/libs/auth'; import PageContent from '../page-content'; import Link from 'next/link'; diff --git a/src-migrate/modules/product-card/components/ProductCard.tsx b/src-migrate/modules/product-card/components/ProductCard.tsx new file mode 100644 index 00000000..8cd96ce8 --- /dev/null +++ b/src-migrate/modules/product-card/components/ProductCard.tsx @@ -0,0 +1,104 @@ +import style from '../styles/product-card.module.css' + +import Link from 'next/link' +import React from 'react' +import Image from '~/components/ui/image' +import clsxm from '~/libs/clsxm' +import formatCurrency from '~/libs/formatCurrency' +import { formatToShortText } from '~/libs/formatNumber' +import { createSlug } from '~/libs/slug' +import { IProduct } from '~/types/product' + +type Props = { + product: IProduct + layout?: 'vertical' | 'horizontal' +} + +const ProductCard = ({ product, layout = 'vertical' }: Props) => { + const URL = { + product: createSlug('/shop/product/', product.name, product.id.toString()), + manufacture: createSlug('/shop/brands/', product.manufacture.name, product.manufacture.id.toString()), + } + + return ( +
+
+ + {product.name} + +
+ +
+ + {product.manufacture.name} + + +
+ + + {product.name} + +
+ +
+ Rp {formatCurrency(product.lowest_price.price)} +
+ +
+ +
+ Inc PPN: + Rp {formatCurrency(Math.round(product.lowest_price.price * 1.11))} +
+ +
+ +
+ {product.stock_total > 0 && ( +
+ Ready Stock +
+ )} + {product.qty_sold > 0 && ( +
+ {formatToShortText(product.qty_sold)} Terjual +
+ )} +
+ +
+
+ ) +} + +const classPrefix = ({ layout }: Props) => { + +} + +export default ProductCard \ No newline at end of file diff --git a/src-migrate/modules/product-card/index.tsx b/src-migrate/modules/product-card/index.tsx new file mode 100644 index 00000000..c87167bc --- /dev/null +++ b/src-migrate/modules/product-card/index.tsx @@ -0,0 +1,3 @@ +import ProductCard from "./components/ProductCard"; + +export default ProductCard \ No newline at end of file diff --git a/src-migrate/modules/product-card/styles/product-card.module.css b/src-migrate/modules/product-card/styles/product-card.module.css new file mode 100644 index 00000000..38b895f9 --- /dev/null +++ b/src-migrate/modules/product-card/styles/product-card.module.css @@ -0,0 +1,50 @@ +.wrapper { + @apply w-full flex; +} +.wrapper-v { + @apply flex-col border border-gray-300 rounded-md h-[350px]; +} +.wrapper-h { + @apply flex-row gap-x-2 pt-4; +} + +.image-v { + @apply w-full h-48 px-4 border-b border-gray-300; +} +.image-h { + @apply w-4/12 h-24 px-1; +} + +.content-v { + @apply w-full p-2; +} +.content-h { + @apply w-8/12; +} + +.brand { + @apply text-danger-500 font-medium block; +} + +.name { + @apply text-gray-700 font-medium line-clamp-3; +} +.name-v { + @apply min-h-[64px]; +} +.name-h { + @apply min-h-[32px]; +} + +.price { + @apply text-danger-500 font-medium; +} + +.ready-stock { + @apply bg-danger-500 text-white text-[11px] px-2 py-1 rounded-md; +} + +.price-inc, +.sold { + @apply text-gray-600 text-[11px]; +} diff --git a/src-migrate/modules/product-detail/components/AddToCart.tsx b/src-migrate/modules/product-detail/components/AddToCart.tsx new file mode 100644 index 00000000..4accab17 --- /dev/null +++ b/src-migrate/modules/product-detail/components/AddToCart.tsx @@ -0,0 +1,79 @@ +import React from 'react' +import { Button, useToast } from '@chakra-ui/react' +import { getAuth } from '~/libs/auth' +import { useRouter } from 'next/router' +import Link from 'next/link' +import { upsertUserCart } from '~/services/cart' + +type Props = { + variantId: number | null, + quantity?: number; + source?: 'buy' | 'add_to_cart'; +} + +const AddToCart = ({ + variantId, + quantity = 1, + source = 'add_to_cart' +}: Props) => { + const auth = getAuth() + const router = useRouter() + const toast = useToast({ + position: 'top', + isClosable: true + }) + + const handleClick = async () => { + if (typeof auth !== 'object') { + const currentUrl = encodeURIComponent(router.asPath) + toast({ + title: 'Masuk Akun', + description: <> + Masuk akun untuk dapat menambahkan barang ke keranjang belanja. {' '} + Klik disini + , + status: 'error', + duration: 4000, + }) + return; + } + + if ( + !variantId || + isNaN(quantity) || + typeof auth !== 'object' + ) return; + + toast.promise( + upsertUserCart(auth.id, 'product', variantId, quantity, true, source), + { + loading: { title: 'Menambahkan ke keranjang', description: 'Mohon tunggu...' }, + success: { title: 'Menambahkan ke keranjang', description: 'Berhasil menambahkan ke keranjang belanja' }, + error: { title: 'Menambahkan ke keranjang', description: 'Gagal menambahkan ke keranjang belanja' }, + } + ) + + if (source === 'buy') { + router.push('/shop/checkout?source=buy') + } + } + + const btnConfig = { + 'add_to_cart': { + colorScheme: 'yellow', + text: 'Keranjang' + }, + 'buy': { + colorScheme: 'red', + text: 'Beli' + } + } + + return ( + + ) +} + +export default AddToCart \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/AddToWishlist.tsx b/src-migrate/modules/product-detail/components/AddToWishlist.tsx new file mode 100644 index 00000000..eab3c7be --- /dev/null +++ b/src-migrate/modules/product-detail/components/AddToWishlist.tsx @@ -0,0 +1,17 @@ +import { Button } from '@chakra-ui/react' +import { HeartIcon } from 'lucide-react' +import React from 'react' + +const AddToWishlist = () => { + return ( + + ) +} + +export default AddToWishlist \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx new file mode 100644 index 00000000..361580ea --- /dev/null +++ b/src-migrate/modules/product-detail/components/Image.tsx @@ -0,0 +1,37 @@ +import React from 'react' +import { InfoIcon } from 'lucide-react' +import { Tooltip } from '@chakra-ui/react' + +import { IProductDetail } from '~/types/product' +import ImageUI from '~/components/ui/image' + +type Props = { + product: IProductDetail +} + +const Image = ({ product }: Props) => { + return ( +
+ +
+ +
+ +
+
+
+
+ ) +} + +export default Image \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/Information.tsx b/src-migrate/modules/product-detail/components/Information.tsx new file mode 100644 index 00000000..fd0e0b3c --- /dev/null +++ b/src-migrate/modules/product-detail/components/Information.tsx @@ -0,0 +1,84 @@ +import style from '../styles/information.module.css' + +import React from 'react' +import dynamic from 'next/dynamic' +import Link from 'next/link' +import { useQuery } from 'react-query' + +import { IProductDetail } from '~/types/product' +import { IProductVariantSLA } from '~/types/productVariant' +import { createSlug } from '~/libs/slug' +import { getVariantSLA } from '~/services/productVariant' + +const Skeleton = dynamic(() => import('@chakra-ui/react').then((mod) => mod.Skeleton)) + +type Props = { + product: IProductDetail +} + +const Information = ({ product }: Props) => { + const querySLA = useQuery({ + queryKey: ['variant-sla', product.variants[0].id], + queryFn: () => getVariantSLA(product.variants[0].id), + enabled: product.variant_total === 1 + }) + + const sla = querySLA?.data + + return ( +
+
+
SKU Number
+
SKU-{product.id}
+
+ {/*
+
Part Number
+
{product.code || '-'}
+
*/} +
+
Manufacture
+
+ {!!product.manufacture.name ? ( + + {product.manufacture.name} + + ) : '-'} +
+
+ {/*
+
Preparation Time
+
+ {product.variant_total > 1 && 'Lihat Variant'} + {product.variant_total === 1 && ( + + {sla?.sla_date} + + )} +
+
+
+
Stock
+
+ {product.variant_total > 1 && 'Lihat Variant'} + {product.variant_total === 1 && ( + + {sla?.qty && sla.qty > 0 ? sla?.qty : '-'} + + )} +
+
+
+
Weight
+
+ {product.variant_total > 1 && 'Lihat Variant'} + {product.variant_total === 1 && (product.weight > 0 ? `${product.weight} kg` : '-')} +
+
*/} +
+ ) +} + +export default Information \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx new file mode 100644 index 00000000..8189e5bd --- /dev/null +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -0,0 +1,53 @@ +import style from '../styles/price-action.module.css' + +import React, { useEffect } from 'react' +import formatCurrency from '~/libs/formatCurrency' +import { formatToShortText } from '~/libs/formatNumber' +import { IProductDetail } from '~/types/product' +import { useProductDetail } from '../stores/useProductDetail' +import AddToCart from './AddToCart' + +type Props = { + product: IProductDetail +} + +const PriceAction = ({ product }: Props) => { + const { activePrice, setActive, activeVariantId, quantityInput, setQuantityInput } = useProductDetail() + + useEffect(() => { + setActive(product.variants[0]) + }, [product, setActive]); + + return ( +
+ {product.qty_sold > 0 && ( +
+ {formatToShortText(product.qty_sold)} Terjual +
+ )} +
+
+ Rp {formatCurrency(activePrice?.price || 0)} +
+
+
+ {!!activePrice && ( + <> + Termasuk PPN: {' '} + Rp {formatCurrency(Math.round(activePrice?.price * 1.11))} + + )} +
+ +
+ +
+ setQuantityInput(e.target.value)} className={style['quantity-input']} /> + + +
+
+ ) +} + +export default PriceAction \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx new file mode 100644 index 00000000..b752a138 --- /dev/null +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -0,0 +1,126 @@ +import style from '../styles/product-detail.module.css' + +import React from 'react' +import Link from 'next/link' +import { MessageCircleIcon } from 'lucide-react' +import { Button } from '@chakra-ui/react' + +import { IProductDetail } from '~/types/product' + +import ProductImage from './Image' +import Information from './Information' +import AddToWishlist from './AddToWishlist' +import VariantList from './VariantList' +import SimilarSide from './SimilarSide' +import SimilarBottom from './SimilarBottom' +import useDevice from '@/core/hooks/useDevice' +import PriceAction from './PriceAction' + +type Props = { + product: IProductDetail +} + +const ProductDetail = ({ product }: Props) => { + const { isDesktop, isMobile } = useDevice() + + return ( + <> +
+
+
+
+ +
+ +
+
+ +

+ {product.name} +

+ +
+ + + +
+ + +
+
+ +
+ {isMobile && ( +
+ +
+ )} + +
+ +
+

+ Variant ({product.variant_total}) +

+
+ +
+ +
+ +
+

+ Informasi Produk +

+
+

' ? 'Belum ada deskripsi' : product.description }} + /> +
+
+
+ + {isDesktop && ( +
+ + + + +
+ +
+ Produk Serupa +
+ +
+ + +
+ )} + +
+
+ Kamu Mungkin Juga Suka +
+ +
+ + +
+ +
+
+ + ) +} + +export default ProductDetail \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/SimilarBottom.tsx b/src-migrate/modules/product-detail/components/SimilarBottom.tsx new file mode 100644 index 00000000..9a12a6ef --- /dev/null +++ b/src-migrate/modules/product-detail/components/SimilarBottom.tsx @@ -0,0 +1,21 @@ +import React from 'react' +import useProductSimilar from '~/modules/product-similar/hooks/useProductSimilar' +import ProductSlider from '~/modules/product-slider' +import { IProductDetail } from '~/types/product' + +type Props = { + product: IProductDetail +} + +const SimilarBottom = ({ product }: Props) => { + const productSimilar = useProductSimilar({ + name: product.name, + except: { productId: product.id } + }) + + const products = productSimilar.data?.products || [] + + return ; +} + +export default SimilarBottom \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/SimilarSide.tsx b/src-migrate/modules/product-detail/components/SimilarSide.tsx new file mode 100644 index 00000000..646a1c51 --- /dev/null +++ b/src-migrate/modules/product-detail/components/SimilarSide.tsx @@ -0,0 +1,34 @@ +import style from '../styles/side-similar.module.css' + +import React from 'react' + +import ProductCard from '~/modules/product-card' +import useProductSimilar from '~/modules/product-similar/hooks/useProductSimilar' +import { IProductDetail } from '~/types/product' + +type Props = { + product: IProductDetail +} + +const SimilarSide = ({ product }: Props) => { + const productSimilar = useProductSimilar({ + name: product.name, + except: { productId: product.id, manufactureId: product.manufacture.id }, + }) + + const products = productSimilar.data?.products || [] + + return ( +
+ {products.map((product) => ( + + ))} +
+ ) +} + +export default SimilarSide \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx new file mode 100644 index 00000000..d07e6b23 --- /dev/null +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -0,0 +1,85 @@ +import style from '../styles/variant-list.module.css' + +import React from 'react' +import { Button, Skeleton } from '@chakra-ui/react' + +import formatCurrency from '~/libs/formatCurrency' +import clsxm from '~/libs/clsxm' +import { IProductVariantDetail, IProductVariantSLA } from '~/types/productVariant' +import { useProductDetail } from '../stores/useProductDetail' +import { LazyLoadComponent } from 'react-lazy-load-image-component'; +import { getVariantSLA } from '~/services/productVariant' +import { useQuery } from 'react-query' + +type Props = { + variants: IProductVariantDetail[] +} + +const VariantList = ({ variants }: Props) => { + return ( +
+
+
+
Part Number
+
Variant
+
Stock
+
Time
+
Weight
+
Price
+
+ {variants.map((variant) => ( + + + + ))} +
+
+ ) +} + +const Row = ({ variant }: { variant: IProductVariantDetail }) => { + const { activeVariantId, setActive } = useProductDetail() + const querySLA = useQuery({ + queryKey: ['variant-sla', variant.id], + queryFn: () => getVariantSLA(variant.id), + }) + + const sla = querySLA?.data + + return ( +
+
{variant.code}
+
{variant.attributes.join(', ')}
+
+ + {sla?.qty} + +
+
+ + {sla?.sla_date} + +
+
+ {variant.weight > 0 ? `${variant.weight} Kg` : '-'} +
+
+ Rp {formatCurrency(variant.price.price)} +
+
+ +
+
+ ) +} + +export default VariantList \ No newline at end of file diff --git a/src-migrate/modules/product-detail/index.ts b/src-migrate/modules/product-detail/index.ts new file mode 100644 index 00000000..246bc06a --- /dev/null +++ b/src-migrate/modules/product-detail/index.ts @@ -0,0 +1,3 @@ +import ProductDetail from './components/ProductDetail'; + +export default ProductDetail; diff --git a/src-migrate/modules/product-detail/stores/useProductDetail.ts b/src-migrate/modules/product-detail/stores/useProductDetail.ts new file mode 100644 index 00000000..984d7948 --- /dev/null +++ b/src-migrate/modules/product-detail/stores/useProductDetail.ts @@ -0,0 +1,25 @@ +import { create } from 'zustand'; +import { IProductVariantDetail } from '~/types/productVariant'; + +type State = { + activeVariantId: number | null; + activePrice: IProductVariantDetail['price'] | null; + quantityInput: string; +}; + +type Action = { + setActive: (variant: IProductVariantDetail) => void; + setQuantityInput: (value: string) => void; +}; + +export const useProductDetail = create((set, get) => ({ + activeVariantId: null, + activePrice: null, + quantityInput: '1', + setActive: (variant) => { + set({ activeVariantId: variant.id, activePrice: variant.price }); + }, + setQuantityInput: (value: string) => { + set({ quantityInput: value }); + }, +})); diff --git a/src-migrate/modules/product-detail/styles/information.module.css b/src-migrate/modules/product-detail/styles/information.module.css new file mode 100644 index 00000000..c9b29020 --- /dev/null +++ b/src-migrate/modules/product-detail/styles/information.module.css @@ -0,0 +1,19 @@ +.wrapper { + @apply grid grid-cols-1; +} + +.row { + @apply flex p-3 rounded; +} + +.row:nth-child(odd) { + @apply bg-gray-100; +} + +.label { + @apply w-1/2 md:w-1/3 font-medium text-gray-500; +} + +.value { + @apply w-1/2 md:w-3/4 text-gray-950; +} diff --git a/src-migrate/modules/product-detail/styles/price-action.module.css b/src-migrate/modules/product-detail/styles/price-action.module.css new file mode 100644 index 00000000..594167af --- /dev/null +++ b/src-migrate/modules/product-detail/styles/price-action.module.css @@ -0,0 +1,12 @@ +.secondary-text { + @apply font-medium text-gray-500; +} +.main-price { + @apply font-medium text-danger-500 text-title-md; +} +.action-wrapper { + @apply flex gap-x-2.5; +} +.quantity-input { + @apply px-2 rounded text-center border border-gray-300 w-14 h-10 focus:outline-none; +} \ No newline at end of file diff --git a/src-migrate/modules/product-detail/styles/product-detail.module.css b/src-migrate/modules/product-detail/styles/product-detail.module.css new file mode 100644 index 00000000..c668167c --- /dev/null +++ b/src-migrate/modules/product-detail/styles/product-detail.module.css @@ -0,0 +1,15 @@ +.title { + @apply font-medium text-h-lg leading-8 md:text-title-md md:leading-10; +} + +.section-card { + @apply p-4 md:p-6 md:bg-gray-50 rounded-xl; +} + +.heading { + @apply text-h-md md:text-h-lg font-medium; +} + +.description { + @apply leading-relaxed text-gray-700; +} diff --git a/src-migrate/modules/product-detail/styles/side-similar.module.css b/src-migrate/modules/product-detail/styles/side-similar.module.css new file mode 100644 index 00000000..08692efa --- /dev/null +++ b/src-migrate/modules/product-detail/styles/side-similar.module.css @@ -0,0 +1,3 @@ +.wrapper { + @apply max-h-[500px] overflow-auto grid grid-cols-1 gap-y-4 divide-y divide-gray-300 border border-gray-300 rounded-lg; +} diff --git a/src-migrate/modules/product-detail/styles/variant-list.module.css b/src-migrate/modules/product-detail/styles/variant-list.module.css new file mode 100644 index 00000000..40cbd1bb --- /dev/null +++ b/src-migrate/modules/product-detail/styles/variant-list.module.css @@ -0,0 +1,19 @@ +.wrapper { + @apply grid grid-cols-1 w-[200%] md:w-full; +} + +.header { + @apply flex py-2.5 px-4 font-medium bg-gray-200 rounded-md; +} + +.row { + @apply flex items-center py-2.5 px-4 text-gray-800; +} + +.select-btn { + @apply !bg-gray-200 hover:!bg-danger-500 hover:!text-white; +} + +.select-btn--active { + @apply !text-white !bg-danger-500 hover:!text-white; +} diff --git a/src-migrate/modules/product-promo/components/AddToCart.tsx b/src-migrate/modules/product-promo/components/AddToCart.tsx index 58bb2ad7..3bac3c66 100644 --- a/src-migrate/modules/product-promo/components/AddToCart.tsx +++ b/src-migrate/modules/product-promo/components/AddToCart.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useState } from 'react' import { CheckIcon, PlusIcon } from 'lucide-react' -import { IPromotion } from '~/common/types/promotion' +import { IPromotion } from '~/types/promotion' import { upsertUserCart } from '~/services/cart' -import { getAuth } from '~/common/libs/auth' +import { getAuth } from '~/libs/auth' import { Button, Spinner, useToast } from '@chakra-ui/react' import Link from 'next/link' import { useRouter } from 'next/router' diff --git a/src-migrate/modules/product-promo/components/Card.tsx b/src-migrate/modules/product-promo/components/Card.tsx index e894c143..59110098 100644 --- a/src-migrate/modules/product-promo/components/Card.tsx +++ b/src-migrate/modules/product-promo/components/Card.tsx @@ -6,11 +6,11 @@ import { Skeleton, Tooltip } from '@chakra-ui/react' import { motion } from "framer-motion" import { PROMO_CATEGORY } from "~/constants/promotion" -import { getVariantById } from "~/services/variant" +import { getVariantById } from "~/services/productVariant" -import { IProductVariantPromo, IPromotion } from '~/common/types/promotion' -import formatCurrency from '~/common/libs/formatCurrency' -import clsxm from '~/common/libs/clsxm' +import { IProductVariantPromo, IPromotion } from '~/types/promotion' +import formatCurrency from '~/libs/formatCurrency' +import clsxm from '~/libs/clsxm' import ProductPromoItem from './Item' import ProductPromoAddToCart from "./AddToCart" diff --git a/src-migrate/modules/product-promo/components/CardCountdown.tsx b/src-migrate/modules/product-promo/components/CardCountdown.tsx index e398a390..b61ad115 100644 --- a/src-migrate/modules/product-promo/components/CardCountdown.tsx +++ b/src-migrate/modules/product-promo/components/CardCountdown.tsx @@ -6,8 +6,8 @@ import { ClockIcon } from 'lucide-react' import { Skeleton } from '@chakra-ui/react' import moment from 'moment' -import clsxm from '~/common/libs/clsxm' -import { IPromotion } from '~/common/types/promotion' +import clsxm from '~/libs/clsxm' +import { IPromotion } from '~/types/promotion' import { getPromotionProgram } from '~/services/promotionProgram' type Props = { diff --git a/src-migrate/modules/product-promo/components/CategoryTab.tsx b/src-migrate/modules/product-promo/components/CategoryTab.tsx index edc4aa92..c8e698c2 100644 --- a/src-migrate/modules/product-promo/components/CategoryTab.tsx +++ b/src-migrate/modules/product-promo/components/CategoryTab.tsx @@ -1,8 +1,8 @@ import React from 'react' import style from '../styles/category-tab.module.css' import { useModalStore } from '../stores/useModalStore' -import clsxm from '~/common/libs/clsxm' -import { ICategoryPromo } from '~/common/types/promotion' +import clsxm from '~/libs/clsxm' +import { ICategoryPromo } from '~/types/promotion' const TABS: ICategoryPromo[] = [ { value: 'bundling', label: 'Bundling' }, diff --git a/src-migrate/modules/product-promo/components/Item.tsx b/src-migrate/modules/product-promo/components/Item.tsx index 15ca4878..6c5a14ce 100644 --- a/src-migrate/modules/product-promo/components/Item.tsx +++ b/src-migrate/modules/product-promo/components/Item.tsx @@ -3,7 +3,7 @@ import style from '../styles/item.module.css' import React from 'react' import Image from 'next/image' -import { IProductVariantPromo } from '~/common/types/promotion' +import { IProductVariantPromo } from '~/types/promotion' type Props = { variant: IProductVariantPromo, diff --git a/src-migrate/modules/product-promo/components/Modal.tsx b/src-migrate/modules/product-promo/components/Modal.tsx index 598b7bbe..0de672c2 100644 --- a/src-migrate/modules/product-promo/components/Modal.tsx +++ b/src-migrate/modules/product-promo/components/Modal.tsx @@ -1,5 +1,5 @@ import React from 'react' -import Modal from '~/common/components/elements/Modal' +import { Modal } from "~/components/ui/modal" import { useModalStore } from '../stores/useModalStore' import ProductPromoCategoryTab from './CategoryTab' import ProductPromoModalContent from './ModalContent' diff --git a/src-migrate/modules/product-promo/components/ModalContent.tsx b/src-migrate/modules/product-promo/components/ModalContent.tsx index 90cf79e7..ab5129f8 100644 --- a/src-migrate/modules/product-promo/components/ModalContent.tsx +++ b/src-migrate/modules/product-promo/components/ModalContent.tsx @@ -1,7 +1,7 @@ import { useQuery } from "react-query" import { Skeleton } from "@chakra-ui/react" -import { getVariantPromoByCategory } from "~/services/variant" +import { getVariantPromoByCategory } from "~/services/productVariant" import { useModalStore } from "../stores/useModalStore" import ProductPromoCard from "./Card" diff --git a/src-migrate/modules/product-promo/components/Section.tsx b/src-migrate/modules/product-promo/components/Section.tsx index 47e1de29..04cf1363 100644 --- a/src-migrate/modules/product-promo/components/Section.tsx +++ b/src-migrate/modules/product-promo/components/Section.tsx @@ -5,7 +5,7 @@ import { useQuery } from 'react-query' import { Button, Skeleton } from '@chakra-ui/react' import ProductPromoCard from './Card' -import { IPromotion } from '~/common/types/promotion' +import { IPromotion } from '~/types/promotion' import ProductPromoModal from "./Modal" import { useModalStore } from "../stores/useModalStore" diff --git a/src-migrate/modules/product-promo/stores/useModalStore.ts b/src-migrate/modules/product-promo/stores/useModalStore.ts index bbb2b1fb..464bb598 100644 --- a/src-migrate/modules/product-promo/stores/useModalStore.ts +++ b/src-migrate/modules/product-promo/stores/useModalStore.ts @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import { CategoryPromo } from '~/common/types/promotion'; +import { CategoryPromo } from '~/types/promotion'; type State = { active: boolean; diff --git a/src-migrate/modules/product-similar/hooks/useProductSimilar.tsx b/src-migrate/modules/product-similar/hooks/useProductSimilar.tsx new file mode 100644 index 00000000..f2c49472 --- /dev/null +++ b/src-migrate/modules/product-similar/hooks/useProductSimilar.tsx @@ -0,0 +1,15 @@ +import { useQuery } from 'react-query' +import { GetProductSimilarProps, getProductSimilar } from '~/services/product' + +type Props = GetProductSimilarProps + +const useProductSimilar = (props: Props) => { + const similarQuery = useQuery({ + queryKey: ['product-similar', props], + queryFn: () => getProductSimilar(props), + }) + + return similarQuery +} + +export default useProductSimilar \ No newline at end of file diff --git a/src-migrate/modules/product-slider/components/ProductSlider.tsx b/src-migrate/modules/product-slider/components/ProductSlider.tsx new file mode 100644 index 00000000..6ef9f688 --- /dev/null +++ b/src-migrate/modules/product-slider/components/ProductSlider.tsx @@ -0,0 +1,42 @@ +import 'swiper/css' + +import React from 'react' +import { Swiper, SwiperSlide } from 'swiper/react' +import { FreeMode } from 'swiper' + +import ProductCard from '~/modules/product-card' +import { IProduct } from '~/types/product' +import useDevice from '@/core/hooks/useDevice' + +type Props = { + products: IProduct[], + productLayout?: 'vertical' | 'horizontal', +} + +const ProductSlider = ({ products, productLayout }: Props) => { + const { isDesktop, isMobile } = useDevice() + + return ( +
+ + {products.map((product) => ( + + + + ))} + +
+ ) +} + +export default ProductSlider \ No newline at end of file diff --git a/src-migrate/modules/product-slider/index.ts b/src-migrate/modules/product-slider/index.ts new file mode 100644 index 00000000..1593a543 --- /dev/null +++ b/src-migrate/modules/product-slider/index.ts @@ -0,0 +1,3 @@ +import ProductSlider from './components/ProductSlider'; + +export default ProductSlider; diff --git a/src-migrate/modules/register/components/Form.tsx b/src-migrate/modules/register/components/Form.tsx index dc9107b2..b834f97a 100644 --- a/src-migrate/modules/register/components/Form.tsx +++ b/src-migrate/modules/register/components/Form.tsx @@ -1,7 +1,7 @@ import { ChangeEvent, useMemo } from "react"; import { useMutation } from "react-query"; -import { useRegisterStore } from "~/common/stores/useRegisterStore"; -import { RegisterProps } from "~/common/types/auth"; +import { useRegisterStore } from "../stores/useRegisterStore"; +import { RegisterProps } from "~/types/auth"; import { registerUser } from "~/services/auth"; import TermCondition from "./TermCondition"; import FormCaptcha from "./FormCaptcha"; diff --git a/src-migrate/modules/register/components/FormCaptcha.tsx b/src-migrate/modules/register/components/FormCaptcha.tsx index 967be017..fbea2b10 100644 --- a/src-migrate/modules/register/components/FormCaptcha.tsx +++ b/src-migrate/modules/register/components/FormCaptcha.tsx @@ -1,5 +1,5 @@ -import ReCaptcha from '~/common/components/elements/ReCaptcha' -import { useRegisterStore } from '~/common/stores/useRegisterStore' +import { ReCaptcha } from '~/components/ui/re-captcha' +import { useRegisterStore } from "../stores/useRegisterStore"; const FormCaptcha = () => { const { updateValidCaptcha } = useRegisterStore() diff --git a/src-migrate/modules/register/components/TermCondition.tsx b/src-migrate/modules/register/components/TermCondition.tsx index 6b95ba19..b7729deb 100644 --- a/src-migrate/modules/register/components/TermCondition.tsx +++ b/src-migrate/modules/register/components/TermCondition.tsx @@ -1,7 +1,7 @@ import { Checkbox } from '@chakra-ui/react' import React from 'react' -import Modal from '~/common/components/elements/Modal' -import { useRegisterStore } from '~/common/stores/useRegisterStore' +import { Modal } from '~/components/ui/modal' +import { useRegisterStore } from "../stores/useRegisterStore"; import PageContent from '~/modules/page-content' const TermCondition = () => { diff --git a/src-migrate/modules/register/stores/useRegisterStore.ts b/src-migrate/modules/register/stores/useRegisterStore.ts new file mode 100644 index 00000000..d8abf52b --- /dev/null +++ b/src-migrate/modules/register/stores/useRegisterStore.ts @@ -0,0 +1,60 @@ +import { create } from 'zustand'; +import { RegisterProps } from '~/types/auth'; +import { registerSchema } from '~/validations/auth'; +import { ZodError } from 'zod'; + +type State = { + form: RegisterProps; + errors: { + [key in keyof RegisterProps]?: string; + }; + isCheckedTNC: boolean; + isOpenTNC: boolean; + isValidCaptcha: boolean; +}; + +type Action = { + updateForm: (name: string, value: string) => void; + updateValidCaptcha: (value: boolean) => void; + toggleCheckTNC: () => void; + openTNC: () => void; + closeTNC: () => void; + validate: () => void; +}; + +export const useRegisterStore = create((set, get) => ({ + form: { + company: '', + name: '', + email: '', + password: '', + phone: '', + }, + updateForm: (name, value) => + set((state) => ({ form: { ...state.form, [name]: value } })), + + errors: {}, + validate: () => { + try { + registerSchema.parse(get().form); + set({ errors: {} }); + } catch (error) { + if (error instanceof ZodError) { + const errors: State['errors'] = {}; + error.errors.forEach( + (e) => (errors[e.path[0] as keyof RegisterProps] = e.message) + ); + set({ errors }); + } + } + }, + isCheckedTNC: false, + toggleCheckTNC: () => set((state) => ({ isCheckedTNC: !state.isCheckedTNC })), + + isOpenTNC: false, + openTNC: () => set(() => ({ isOpenTNC: true })), + closeTNC: () => set(() => ({ isOpenTNC: false })), + + isValidCaptcha: false, + updateValidCaptcha: (value) => set(() => ({ isValidCaptcha: value })), +})); diff --git a/src-migrate/pages/_app.tsx b/src-migrate/pages/_app.tsx index 2dc82559..36640c04 100644 --- a/src-migrate/pages/_app.tsx +++ b/src-migrate/pages/_app.tsx @@ -1,5 +1,5 @@ -import '~/common/styles/fonts/Inter/inter.css' -import '~/common/styles/globals.css' +import '~/styles/fonts/Inter/inter.css' +import '~/styles/globals.css' import type { AppProps } from "next/app" export default function MyApp({ Component, pageProps }: AppProps) { diff --git a/src-migrate/pages/api/product-variant/[id].tsx b/src-migrate/pages/api/product-variant/[id].tsx index b3bd4096..c25c10ac 100644 --- a/src-migrate/pages/api/product-variant/[id].tsx +++ b/src-migrate/pages/api/product-variant/[id].tsx @@ -1,5 +1,5 @@ import { NextApiRequest, NextApiResponse } from "next"; -import { SolrResponse } from "~/common/types/solr"; +import { SolrResponse } from "~/types/solr"; const SOLR_HOST = process.env.SOLR_HOST as string diff --git a/src-migrate/pages/api/product-variant/[id]/promotion/[category].tsx b/src-migrate/pages/api/product-variant/[id]/promotion/[category].tsx index 745f9944..50671afd 100644 --- a/src-migrate/pages/api/product-variant/[id]/promotion/[category].tsx +++ b/src-migrate/pages/api/product-variant/[id]/promotion/[category].tsx @@ -1,5 +1,5 @@ import { NextApiRequest, NextApiResponse } from "next"; -import { SolrResponse } from "~/common/types/solr"; +import { SolrResponse } from "~/types/solr"; const SOLR_HOST = process.env.SOLR_HOST as string diff --git a/src-migrate/pages/api/product-variant/[id]/promotion/highlight.tsx b/src-migrate/pages/api/product-variant/[id]/promotion/highlight.tsx index 0fe8fd1b..8153f346 100644 --- a/src-migrate/pages/api/product-variant/[id]/promotion/highlight.tsx +++ b/src-migrate/pages/api/product-variant/[id]/promotion/highlight.tsx @@ -1,5 +1,5 @@ import { NextApiRequest, NextApiResponse } from "next"; -import { SolrResponse } from "~/common/types/solr"; +import { SolrResponse } from "~/types/solr"; const SOLR_HOST = process.env.SOLR_HOST as string diff --git a/src-migrate/pages/api/promotion-program/[id].tsx b/src-migrate/pages/api/promotion-program/[id].tsx index ba716e85..c509b802 100644 --- a/src-migrate/pages/api/promotion-program/[id].tsx +++ b/src-migrate/pages/api/promotion-program/[id].tsx @@ -1,6 +1,5 @@ import { NextApiRequest, NextApiResponse } from "next"; -import { SolrResponse } from "~/common/types/solr"; -import moment from 'moment' +import { SolrResponse } from "~/types/solr"; const SOLR_HOST = process.env.SOLR_HOST as string diff --git a/src-migrate/pages/register.tsx b/src-migrate/pages/register.tsx index 1246c6f5..136eaa3b 100644 --- a/src-migrate/pages/register.tsx +++ b/src-migrate/pages/register.tsx @@ -1,7 +1,7 @@ import BasicLayout from "@/core/components/layouts/BasicLayout" import { useWindowSize } from "usehooks-ts" -import Seo from "~/common/components/elements/Seo" +import { Seo } from "~/components/seo" import Register from "~/modules/register" const RegisterPage = () => { diff --git a/src-migrate/pages/shop/cart.module.css b/src-migrate/pages/shop/cart.module.css deleted file mode 100644 index d523a55a..00000000 --- a/src-migrate/pages/shop/cart.module.css +++ /dev/null @@ -1,31 +0,0 @@ -.title { - @apply text-h-lg font-semibold; -} - -.content { - @apply flex flex-wrap; -} - -.item-wrapper { - @apply w-full md:w-3/4; -} - -.item-skeleton { - @apply grid grid-cols-1 gap-y-4; -} - -.items { - @apply flex flex-col gap-y-6 border-t border-gray-300 pt-6; -} - -.summary-wrapper { - @apply w-full md:w-1/4 md:pl-6 mt-6 md:mt-0; -} - -.summary { - @apply border border-gray-300 p-4 rounded-md sticky top-[180px]; -} - -.summary-buttons { - @apply grid grid-cols-2 gap-x-3 mt-6; -} diff --git a/src-migrate/pages/shop/cart.tsx b/src-migrate/pages/shop/cart.tsx deleted file mode 100644 index 5016c9b5..00000000 --- a/src-migrate/pages/shop/cart.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import style from './cart.module.css' - -import React, { useEffect, useMemo } from 'react' -import Link from 'next/link' -import { Button, Tooltip } from '@chakra-ui/react' - -import { getAuth } from '~/common/libs/auth' -import { useCartStore } from '~/modules/cart/stores/useCartStore' - -import CartItem from '~/modules/cart/components/Item' -import CartSummary from '~/modules/cart/components/Summary' - -const CartPage = () => { - const auth = getAuth() - - const { loadCart, cart, summary } = useCartStore() - - useEffect(() => { - if (typeof auth === 'object' && !cart) loadCart(auth.id) - }, [auth, loadCart, cart]) - - const hasSelectedPromo = useMemo(() => { - if (!cart) return false - for (const item of cart.products) { - if (item.cart_type === 'promotion' && item.selected) return true - } - return false - }, [cart]) - - const hasSelected = useMemo(() => { - if (!cart) return false - for (const item of cart.products) { - if (item.selected) return true - } - return false - }, [cart]) - - return ( - <> -
- Keranjang Belanja -
- -
- -
-
-
- {!cart && } -
- -
- {cart?.products.map((item) => )} -
-
- -
-
- - -
- - - - - - - -
-
-
-
- - ) -} - -export default CartPage \ No newline at end of file diff --git a/src-migrate/pages/shop/cart/cart.module.css b/src-migrate/pages/shop/cart/cart.module.css new file mode 100644 index 00000000..d523a55a --- /dev/null +++ b/src-migrate/pages/shop/cart/cart.module.css @@ -0,0 +1,31 @@ +.title { + @apply text-h-lg font-semibold; +} + +.content { + @apply flex flex-wrap; +} + +.item-wrapper { + @apply w-full md:w-3/4; +} + +.item-skeleton { + @apply grid grid-cols-1 gap-y-4; +} + +.items { + @apply flex flex-col gap-y-6 border-t border-gray-300 pt-6; +} + +.summary-wrapper { + @apply w-full md:w-1/4 md:pl-6 mt-6 md:mt-0; +} + +.summary { + @apply border border-gray-300 p-4 rounded-md sticky top-[180px]; +} + +.summary-buttons { + @apply grid grid-cols-2 gap-x-3 mt-6; +} diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx new file mode 100644 index 00000000..397852f9 --- /dev/null +++ b/src-migrate/pages/shop/cart/index.tsx @@ -0,0 +1,93 @@ +import style from './cart.module.css' + +import React, { useEffect, useMemo } from 'react' +import Link from 'next/link' +import { Button, Tooltip } from '@chakra-ui/react' + +import { getAuth } from '~/libs/auth' +import { useCartStore } from '~/modules/cart/stores/useCartStore' + +import CartItem from '~/modules/cart/components/Item' +import CartSummary from '~/modules/cart/components/Summary' + +const CartPage = () => { + const auth = getAuth() + + const { loadCart, cart, summary } = useCartStore() + + useEffect(() => { + if (typeof auth === 'object' && !cart) loadCart(auth.id) + }, [auth, loadCart, cart]) + + const hasSelectedPromo = useMemo(() => { + if (!cart) return false + for (const item of cart.products) { + if (item.cart_type === 'promotion' && item.selected) return true + } + return false + }, [cart]) + + const hasSelected = useMemo(() => { + if (!cart) return false + for (const item of cart.products) { + if (item.selected) return true + } + return false + }, [cart]) + + return ( + <> +
+ Keranjang Belanja +
+ +
+ +
+
+
+ {!cart && } +
+ +
+ {cart?.products.map((item) => )} +
+
+ +
+
+ + +
+ + + + + + + +
+
+
+
+ + ) +} + +export default CartPage \ No newline at end of file diff --git a/src-migrate/pages/shop/product/[slug].tsx b/src-migrate/pages/shop/product/[slug].tsx new file mode 100644 index 00000000..883532ed --- /dev/null +++ b/src-migrate/pages/shop/product/[slug].tsx @@ -0,0 +1,73 @@ +import style from './product.module.css' + +import { GetServerSideProps, NextPage } from 'next' +import React from 'react' +import dynamic from 'next/dynamic' +import cookie from 'cookie' + +import { getProductById } from '~/services/product' +import { getIdFromSlug } from '~/libs/slug' +import { IProductDetail } from '~/types/product' + +import { Seo } from '~/components/seo' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout'), { ssr: false }) +const ProductDetail = dynamic(() => import('~/modules/product-detail'), { ssr: false }) + +type PageProps = { + product: IProductDetail +} + +export const getServerSideProps: GetServerSideProps = (async (context) => { + const { slug } = context.query + const cookieString = context.req.headers.cookie; + const cookies = cookieString ? cookie.parse(cookieString) : {}; + const auth = cookies?.auth ? JSON.parse(cookies.auth) : {}; + const tier = auth?.pricelist || '' + + const productId = getIdFromSlug(slug as string) + + const product = await getProductById(productId, tier) + + if (!product) return { notFound: true } + + return { + props: { product } + } +}) + +const ProductDetailPage: NextPage = ({ product }) => { + return ( + + + +
+ +
+
+ ) +} + +export default ProductDetailPage \ No newline at end of file diff --git a/src-migrate/pages/shop/product/product.module.css b/src-migrate/pages/shop/product/product.module.css new file mode 100644 index 00000000..e69de29b diff --git a/src-migrate/services/auth.ts b/src-migrate/services/auth.ts index 1cc09c10..35ba290a 100644 --- a/src-migrate/services/auth.ts +++ b/src-migrate/services/auth.ts @@ -1,4 +1,4 @@ -import odooApi from '~/common/libs/odooApi'; +import odooApi from '~/libs/odooApi'; import { RegisterResApiProps, RegisterProps, @@ -8,7 +8,7 @@ import { ActivationOtpResApiProps, ActivationReqProps, ActivationReqResApiProps, -} from '~/common/types/auth'; +} from '~/types/auth'; const BASE_PATH = '/api/v1/user'; diff --git a/src-migrate/services/cart.ts b/src-migrate/services/cart.ts index b238be3d..73967073 100644 --- a/src-migrate/services/cart.ts +++ b/src-migrate/services/cart.ts @@ -1,4 +1,4 @@ -import odooApi from '~/common/libs/odooApi'; +import odooApi from '~/libs/odooApi'; export const getUserCart = async (userId: number) => { return await odooApi('GET', `/api/v1/user/${userId}/cart`); diff --git a/src-migrate/services/checkout.ts b/src-migrate/services/checkout.ts index 3dd1c8e8..3eff95a8 100644 --- a/src-migrate/services/checkout.ts +++ b/src-migrate/services/checkout.ts @@ -1,4 +1,4 @@ -import odooApi from '~/common/libs/odooApi'; +import odooApi from '~/libs/odooApi'; export const getUserCheckout = async (userId: number) => { return await odooApi('GET', `/api/v1/user/${userId}/sale_order/checkout`); diff --git a/src-migrate/services/pageContent.ts b/src-migrate/services/pageContent.ts index 16146059..516b4bed 100644 --- a/src-migrate/services/pageContent.ts +++ b/src-migrate/services/pageContent.ts @@ -1,4 +1,4 @@ -import odooApi from '~/common/libs/odooApi'; +import odooApi from '~/libs/odooApi'; export const getPageContent = async ({ path }: { path: string }) => { const params = new URLSearchParams({ url_path: path }); diff --git a/src-migrate/services/product.ts b/src-migrate/services/product.ts new file mode 100644 index 00000000..c9e93396 --- /dev/null +++ b/src-migrate/services/product.ts @@ -0,0 +1,59 @@ +import { IProduct, IProductDetail } from '~/types/product'; +import snakeCase from 'snakecase-keys'; + +const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST; + +export const getProductById = async ( + id: string, + tier: string +): Promise => { + const url = `${SELF_HOST}/api/shop/product-detail`; + const params = new URLSearchParams({ id, auth: tier }); + return await fetch(`${url}?${params.toString()}`) + .then((res) => res.json()) + .then((res) => { + if (res.length > 0) return snakeCase(res[0]) as IProductDetail; + + return null; + }); +}; + +export interface GetProductSimilarProps { + name: string; + except?: { + productId?: number; + manufactureId?: number; + }; + limit?: number; +} + +export interface GetProductSimilarRes { + products: IProduct[]; + num_found: number; + num_found_exact: boolean; + start: number; +} + +export const getProductSimilar = async ({ + name, + except, + limit = 30, +}: GetProductSimilarProps): Promise => { + const query = [ + `q=${name}`, + 'page=1', + 'orderBy=popular-weekly', + 'operation=OR', + 'priceFrom=1', + ]; + + if (except?.productId) query.push(`fq=-product_id_i:${except.productId}`); + if (except?.manufactureId) + query.push(`fq=-manufacture_id_i:${except.manufactureId}`); + + const url = `${SELF_HOST}/api/shop/search?${query.join('&')}`; + + return await fetch(url) + .then((res) => res.json()) + .then((res) => snakeCase(res.response)); +}; diff --git a/src-migrate/services/productVariant.ts b/src-migrate/services/productVariant.ts new file mode 100644 index 00000000..9fec4d1f --- /dev/null +++ b/src-migrate/services/productVariant.ts @@ -0,0 +1,23 @@ +import odooApi from '~/libs/odooApi'; +import { IProductVariantSLA } from '~/types/productVariant'; +import { CategoryPromo, IPromotion } from '~/types/promotion'; + +export const getVariantById = async (variantId: number) => { + const url = `/api/product-variant/${variantId}`; + return await fetch(url).then((res) => res.json()); +}; + +export const getVariantPromoByCategory = async ( + variantId: number, + type: CategoryPromo +): Promise<{ data: IPromotion[] }> => { + const url = `/api/product-variant/${variantId}/promotion/${type}`; + return await fetch(url).then((res) => res.json()); +}; + +export const getVariantSLA = async ( + variantId: number +): Promise => { + const url = `/api/v1/product_variant/${variantId}/stock`; + return await odooApi('GET', url); +}; diff --git a/src-migrate/services/promotionProgram.ts b/src-migrate/services/promotionProgram.ts index a5026c71..c8c46c65 100644 --- a/src-migrate/services/promotionProgram.ts +++ b/src-migrate/services/promotionProgram.ts @@ -1,4 +1,4 @@ -import { IPromotionProgram } from '~/common/types/promotionProgram'; +import { IPromotionProgram } from '~/types/promotionProgram'; export const getPromotionProgram = async ( programId: number diff --git a/src-migrate/services/variant.ts b/src-migrate/services/variant.ts deleted file mode 100644 index 213187d2..00000000 --- a/src-migrate/services/variant.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CategoryPromo, IPromotion } from '~/common/types/promotion'; - -export const getVariantById = async (variantId: number) => { - const url = `/api/product-variant/${variantId}`; - return await fetch(url).then((res) => res.json()); -}; - -export const getVariantPromoByCategory = async ( - variantId: number, - type: CategoryPromo -): Promise<{ data: IPromotion[] }> => { - const url = `/api/product-variant/${variantId}/promotion/${type}`; - return await fetch(url).then((res) => res.json()); -}; diff --git a/src-migrate/styles/fonts/Inter/Inter-Black.woff b/src-migrate/styles/fonts/Inter/Inter-Black.woff new file mode 100644 index 00000000..a18593a0 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Black.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Black.woff2 b/src-migrate/styles/fonts/Inter/Inter-Black.woff2 new file mode 100644 index 00000000..68f64c9e Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Black.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff b/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff new file mode 100644 index 00000000..b6b01943 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff2 new file mode 100644 index 00000000..1c9c7ca8 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-BlackItalic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Bold.woff b/src-migrate/styles/fonts/Inter/Inter-Bold.woff new file mode 100644 index 00000000..eaf3d4bf Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Bold.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Bold.woff2 b/src-migrate/styles/fonts/Inter/Inter-Bold.woff2 new file mode 100644 index 00000000..2846f29c Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Bold.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff b/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff new file mode 100644 index 00000000..32750761 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff2 new file mode 100644 index 00000000..0b1fe8e1 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-BoldItalic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff b/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff new file mode 100644 index 00000000..c2c17ede Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff2 b/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff2 new file mode 100644 index 00000000..c24c2bdc Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ExtraBold.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff b/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff new file mode 100644 index 00000000..c42f7052 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 new file mode 100644 index 00000000..4a81dc79 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff b/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff new file mode 100644 index 00000000..d0de5f39 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff2 b/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff2 new file mode 100644 index 00000000..f2ea706f Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ExtraLight.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff b/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff new file mode 100644 index 00000000..81f1a28e Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 new file mode 100644 index 00000000..9af717ba Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ExtraLightItalic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Italic.woff b/src-migrate/styles/fonts/Inter/Inter-Italic.woff new file mode 100644 index 00000000..a806b382 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Italic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Italic.woff2 b/src-migrate/styles/fonts/Inter/Inter-Italic.woff2 new file mode 100644 index 00000000..a619fc54 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Italic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Light.woff b/src-migrate/styles/fonts/Inter/Inter-Light.woff new file mode 100644 index 00000000..c496464d Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Light.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Light.woff2 b/src-migrate/styles/fonts/Inter/Inter-Light.woff2 new file mode 100644 index 00000000..bc4be665 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Light.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff b/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff new file mode 100644 index 00000000..f84a9de3 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff2 new file mode 100644 index 00000000..842b2dfc Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-LightItalic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Medium.woff b/src-migrate/styles/fonts/Inter/Inter-Medium.woff new file mode 100644 index 00000000..d546843f Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Medium.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Medium.woff2 b/src-migrate/styles/fonts/Inter/Inter-Medium.woff2 new file mode 100644 index 00000000..f92498a2 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Medium.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff b/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff new file mode 100644 index 00000000..459a6568 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff2 new file mode 100644 index 00000000..0e3019f4 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-MediumItalic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Regular.woff b/src-migrate/styles/fonts/Inter/Inter-Regular.woff new file mode 100644 index 00000000..62d3a618 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Regular.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Regular.woff2 b/src-migrate/styles/fonts/Inter/Inter-Regular.woff2 new file mode 100644 index 00000000..6c2b6893 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Regular.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff b/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff new file mode 100644 index 00000000..a815f43a Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff2 b/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff2 new file mode 100644 index 00000000..611e90c9 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-SemiBold.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff b/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff new file mode 100644 index 00000000..909e43a9 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 new file mode 100644 index 00000000..545685bd Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-SemiBoldItalic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Thin.woff b/src-migrate/styles/fonts/Inter/Inter-Thin.woff new file mode 100644 index 00000000..62bc58cd Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Thin.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-Thin.woff2 b/src-migrate/styles/fonts/Inter/Inter-Thin.woff2 new file mode 100644 index 00000000..abbc3a5c Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-Thin.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff b/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff new file mode 100644 index 00000000..700a7f06 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff differ diff --git a/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff2 b/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff2 new file mode 100644 index 00000000..ab0b2002 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-ThinItalic.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-italic.var.woff2 b/src-migrate/styles/fonts/Inter/Inter-italic.var.woff2 new file mode 100644 index 00000000..b826d5af Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-italic.var.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter-roman.var.woff2 b/src-migrate/styles/fonts/Inter/Inter-roman.var.woff2 new file mode 100644 index 00000000..6a256a06 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter-roman.var.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/Inter.var.woff2 b/src-migrate/styles/fonts/Inter/Inter.var.woff2 new file mode 100644 index 00000000..365eedc5 Binary files /dev/null and b/src-migrate/styles/fonts/Inter/Inter.var.woff2 differ diff --git a/src-migrate/styles/fonts/Inter/inter.css b/src-migrate/styles/fonts/Inter/inter.css new file mode 100644 index 00000000..de6ce273 --- /dev/null +++ b/src-migrate/styles/fonts/Inter/inter.css @@ -0,0 +1,199 @@ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url('Inter-Thin.woff2?v=3.19') format('woff2'), + url('Inter-Thin.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url('Inter-ThinItalic.woff2?v=3.19') format('woff2'), + url('Inter-ThinItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url('Inter-ExtraLight.woff2?v=3.19') format('woff2'), + url('Inter-ExtraLight.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url('Inter-ExtraLightItalic.woff2?v=3.19') format('woff2'), + url('Inter-ExtraLightItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url('Inter-Light.woff2?v=3.19') format('woff2'), + url('Inter-Light.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url('Inter-LightItalic.woff2?v=3.19') format('woff2'), + url('Inter-LightItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('Inter-Regular.woff2?v=3.19') format('woff2'), + url('Inter-Regular.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url('Inter-Italic.woff2?v=3.19') format('woff2'), + url('Inter-Italic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url('Inter-Medium.woff2?v=3.19') format('woff2'), + url('Inter-Medium.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url('Inter-MediumItalic.woff2?v=3.19') format('woff2'), + url('Inter-MediumItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url('Inter-SemiBold.woff2?v=3.19') format('woff2'), + url('Inter-SemiBold.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url('Inter-SemiBoldItalic.woff2?v=3.19') format('woff2'), + url('Inter-SemiBoldItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url('Inter-Bold.woff2?v=3.19') format('woff2'), + url('Inter-Bold.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url('Inter-BoldItalic.woff2?v=3.19') format('woff2'), + url('Inter-BoldItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 800; + font-display: swap; + src: url('Inter-ExtraBold.woff2?v=3.19') format('woff2'), + url('Inter-ExtraBold.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 800; + font-display: swap; + src: url('Inter-ExtraBoldItalic.woff2?v=3.19') format('woff2'), + url('Inter-ExtraBoldItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url('Inter-Black.woff2?v=3.19') format('woff2'), + url('Inter-Black.woff?v=3.19') format('woff'); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url('Inter-BlackItalic.woff2?v=3.19') format('woff2'), + url('Inter-BlackItalic.woff?v=3.19') format('woff'); +} + +/* ------------------------------------------------------- +Variable font. +Usage: + + html { font-family: 'Inter', sans-serif; } + @supports (font-variation-settings: normal) { + html { font-family: 'Inter var', sans-serif; } + } +*/ +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: normal; + font-named-instance: 'Regular'; + src: url('Inter-roman.var.woff2?v=3.19') format('woff2'); +} +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: italic; + font-named-instance: 'Italic'; + src: url('Inter-italic.var.woff2?v=3.19') format('woff2'); +} + +/* -------------------------------------------------------------------------- +[EXPERIMENTAL] Multi-axis, single variable font. + +Slant axis is not yet widely supported (as of February 2019) and thus this +multi-axis single variable font is opt-in rather than the default. + +When using this, you will probably need to set font-variation-settings +explicitly, e.g. + + * { font-variation-settings: "slnt" 0deg } + .italic { font-variation-settings: "slnt" 10deg } + +*/ +@font-face { + font-family: 'Inter var experimental'; + font-weight: 100 900; + font-display: swap; + font-style: oblique 0deg 10deg; + src: url('Inter.var.woff2?v=3.19') format('woff2'); +} diff --git a/src-migrate/styles/globals.css b/src-migrate/styles/globals.css new file mode 100644 index 00000000..ea20b247 --- /dev/null +++ b/src-migrate/styles/globals.css @@ -0,0 +1,674 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +* { + -webkit-tap-highlight-color: transparent; +} + +html, +body { + @apply w-screen + text-body-2 + text-gray_r-12 + bg-gray_r-1 + overflow-x-clip; +} + +#__next main { + @apply min-h-screen; +} + +button { + @apply block; +} + +@layer base { + input[type='number']::-webkit-inner-spin-button, + input[type='number']::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; + } + + input[type='number'] { + -moz-appearance: textfield; + } +} + +@layer components { + .badge-red, + .badge-solid-red, + .badge-gray, + .badge-yellow, + .badge-blue, + .badge-green, + .badge-solid-green { + @apply text-[11px] + leading-none + font-medium + px-1 + py-1 + rounded + w-fit; + } + + .badge-red { + @apply bg-danger-100 + text-danger-600; + } + + .badge-solid-red { + @apply bg-danger-500 + text-white; + } + + .badge-gray { + @apply bg-gray_r-5 + text-gray_r-10; + } + + .badge-yellow { + @apply bg-warning-500 + text-warning-900; + } + + .badge-blue { + @apply bg-blue-200 + text-blue-600; + } + + .badge-green { + @apply bg-success-100 + text-success-600; + } + + .badge-solid-green { + @apply bg-success-500 + text-white; + } + + .form-label { + @apply font-medium + block; + } + + .form-input { + @apply p-3 + rounded + border + text-gray_r-12 + border-gray_r-7 + !bg-white + bg-transparent + w-full + leading-none + focus:outline-none + focus:border-warning-500 + disabled:bg-gray_r-5; + } + + .form-input[aria-invalid] { + @apply border-danger-500 + focus:border-danger-500; + } + + .form-input[type='file'] { + @apply py-2; + } + + .btn-yellow, + .btn-light, + .btn-red, + .btn-solid-red { + @apply block + w-fit + py-3 + px-6 + rounded + border + text-center + font-medium + ease-linear + duration-150; + } + + .btn-yellow { + @apply bg-warning-500 + border-warning-500 + hover:bg-warning-500/80 + disabled:text-gray_r-10 + disabled:bg-warning-200 + disabled:border-warning-200; + } + + .btn-red { + @apply bg-danger-100 + border-danger-300 + text-danger-500 + disabled:text-danger-400 + disabled:bg-danger-200; + } + + .btn-solid-red { + @apply bg-danger-500 + border-danger-500 + text-gray_r-1 + hover:bg-danger-500/80 + disabled:text-gray_r-1 + disabled:bg-danger-200 + disabled:border-danger-200; + } + + .btn-light { + @apply bg-gray_r-3 + border-gray_r-6 + disabled:text-gray_r-10 + disabled:bg-gray_r-6; + } + + .product-card { + @apply w-full + h-full + border + border-gray_r-3 + shadow + bg-white + rounded + relative + flex + flex-col; + } + + .product-card__image { + @apply w-full + h-[160px] + object-contain + object-center + border-b + border-gray_r-6; + } + + .product-card__content { + @apply p-2 + pb-3 + flex-1; + } + + .product-card__title { + @apply text-caption-1 + text-gray_r-12 + leading-5; + } + + .product-card__brand { + @apply text-caption-1 + mb-1 + block; + } + + .product__description { + @apply text-gray_r-12/90; + } + + .product__description br { + @apply block my-1; + } + + .product__description b { + @apply font-semibold; + } +} + +@layer utilities { + .wrap-line-ellipsis-1, + .wrap-line-ellipsis-2, + .wrap-line-ellipsis-3 { + display: -webkit-box; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + } + + .wrap-line-ellipsis-1 { + -webkit-line-clamp: 1; + } + + .wrap-line-ellipsis-2 { + -webkit-line-clamp: 2; + } + + .wrap-line-ellipsis-3 { + -webkit-line-clamp: 3; + } +} + +.menu-wrapper { + @apply fixed + top-0 + left-0 + bg-white + w-[80%] + h-full + z-[60] + overflow-y-auto + translate-x-[-100%] + ease-linear + duration-150; +} + +.menu-wrapper.active { + @apply translate-x-0; +} + +.overlay { + @apply fixed + top-0 + left-0 + w-full + h-full + z-[55] + bg-gray_r-12/40; +} + +.sticky-header { + @apply px-4 + py-3 + bg-gray_r-1/90 + backdrop-blur-lg + sticky + top-0 + border-b + border-gray_r-7 + z-50; +} + +.content-container { + @apply max-w-full + overflow-x-hidden; +} + +#indoteknik_toast { + @apply fixed + bottom-4 + translate-y-[200%] + left-[50%] + translate-x-[-50%] + z-[100] + flex + items-center + p-4 + mb-4 + w-[90%] + text-gray-500 + bg-white + border + border-gray-300 + rounded-lg + shadow + ease-linear + duration-300; +} + +#indoteknik_toast.active { + @apply translate-y-0; +} + +.category-menu { + @apply hidden; +} + +.swiper-slide { + @apply !h-auto; +} + +.lazy-load-image-background { + @apply !block + w-full; +} + +.swiper-pagination-bullet-active { + @apply !bg-danger-500; +} + +.pagination { + @apply flex + justify-center + gap-x-1; +} + +.pagination-item { + @apply p-1 + flex + justify-center + items-center + w-10 + rounded + ease-linear + duration-150 + border + border-gray_r-6 + bg-gray_r-3 + hover:bg-gray_r-5 + text-gray_r-12; +} + +.pagination-item--active { + @apply border-warning-500 + bg-warning-500 + hover:bg-warning-500; +} + +.pagination-dots { + @apply p-1 + flex + justify-center + items-end + w-10 + rounded + ease-linear + bg-gray_r-3 + text-caption-2; +} + +.idt-transition { + @apply transition-all + ease-out + duration-200; +} + +.form-select__placeholder { + @apply !text-gray_r-9; +} + +.form-select__control { + @apply !shadow-none + !border-gray_r-7; +} + +.form-select__control--menu-is-open { + @apply !border-warning-500; +} + +.table-specification { + @apply max-h-[500px] overflow-y-auto border border-gray_r-6; +} + +.table-specification > table { + @apply table-auto + border-collapse + w-full; +} + +.table-specification > table > thead > tr > th:last-child { + @apply w-3/12; +} + +.table-specification > table > thead { + @apply sticky top-0 border-b; +} + +.table-specification > table > thead > tr { + @apply bg-gray_r-1/80 backdrop-blur-lg; +} + +.table-specification th { + @apply font-semibold; +} + +.table-specification th, +.table-specification td { + @apply p-4 text-center; +} + +.table-specification > table > tbody > tr { + @apply odd:bg-gray_r-3 even:bg-gray_r-1; +} + +.table-cart, +.table-checkout { + @apply w-full + table-auto + border-collapse; +} + +.table-cart tr, +.table-checkout tr { + @apply border-y + border-gray_r-6 + first:border-t-0; +} + +.table-cart th, +.table-cart td, +.table-checkout th, +.table-checkout td { + @apply py-4 + px-3 + text-center + text-gray_r-12/90; +} + +.table-cart th, +.table-cart td { + @apply first:w-12; +} + +.table-cart th, +.table-checkout th { + @apply font-medium; +} + +.table-data { + @apply w-full + table-auto + border-collapse; +} + +.table-data thead tr { + @apply bg-gray_r-3; +} + +.table-data thead th { + @apply font-medium whitespace-nowrap; +} + +.table-data thead th, +.table-data tbody td { + @apply px-3 + py-4 + text-center; +} + +.table-data tbody td { + @apply text-gray_r-12/90; +} + +.table-data tbody tr { + @apply border-b + border-gray_r-6; +} + +.navbar-user-dropdown-button { + @apply flex-1 + flex + gap-x-2 + p-4 + items-center + bg-danger-500 + font-medium + !text-gray_r-1 + rounded-none + rounded-t-xl; +} + +.navbar-user-dropdown-button span { + @apply line-clamp-1; +} + +.navbar-user-dropdown-wrapper a, +.navbar-user-dropdown-wrapper button { + @apply text-gray_r-12/80 hover:bg-gray_r-5 font-medium py-2 px-4 w-full text-left; +} + +.navbar-user-dropdown { + @apply bg-white + border + border-gray_r-6 + py-2 + w-full + shadow; +} + +.category-mega-box-wrapper, +.navbar-user-dropdown-wrapper { + @apply absolute + opacity-0 + left-0 + top-[125%] + flex + w-full + z-10 + transition-all + ease-in + duration-200 + pointer-events-none + text-left; +} + +.category-mega-box-wrapper.show, +.navbar-user-dropdown-button:hover ~ .navbar-user-dropdown-wrapper, +.navbar-user-dropdown-wrapper:hover { + @apply top-[100%] + opacity-100 + pointer-events-auto; +} + +.category-mega-box { + @apply relative + py-2 + border + border-t-0 + bg-white + border-gray_r-6 + h-full + w-full; +} + +.category-mega-box > div { + @apply text-gray_r-12/80; +} + +.category-mega-box > div:hover .category-mega-box__parent { + @apply bg-gray_r-5; +} + +.category-mega-box > div:hover .category-mega-box__child-wrapper { + @apply opacity-100 + top-0 + pointer-events-auto; +} + +.category-mega-box .category-mega-box__parent { + @apply py-2.5 + px-4 + text-gray_r-12/80 + font-normal; +} + +.category-mega-box__child-wrapper { + @apply absolute + left-[100%] + top-12 + w-[40vw] + bg-gray_r-1/90 + backdrop-blur-md + border + border-gray_r-6 + p-6 + opacity-0 + h-full + transition-all + ease-in + duration-200 + pointer-events-none + z-50; +} + +.category-mega-box__child-one { + @apply text-gray_r-12/80 + hover:text-danger-500 + transition-colors + ease-linear + duration-100 + font-semibold; +} + +.category-mega-box__child-two { + @apply text-gray_r-12/80 + hover:text-danger-500 + transition-colors + ease-linear + duration-100 + font-normal; +} + +@keyframes page-loader { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.page-loader { + animation-name: page-loader; + animation-duration: 1000ms; + animation-delay: 50ms; + animation-timing-function: ease-in-out; + animation-iteration-count: infinite; +} + +@keyframes shake { + 0% { + transform: translateX(0); + } + 10%, + 90% { + transform: translateX(-10px); + } + 20%, + 80% { + transform: translateX(10px); + } + 30%, + 50%, + 70% { + transform: translateX(-10px); + } + 40%, + 60% { + transform: translateX(10px); + } + 100% { + transform: translateX(0); + } +} + +.blink-color-flash-sale { + @apply text-body-1 md:text-title-sm; + transform: rotateY(180deg) rotateZ(120deg); + animation-name: blink-color-flash-sale; + animation-duration: 300ms; + animation-iteration-count: infinite; + animation-timing-function: linear; +} + +@keyframes blink-color-flash-sale { + from { + @apply text-danger-500; + } + to { + @apply text-warning-500; + } +} diff --git a/src-migrate/types/auth.ts b/src-migrate/types/auth.ts new file mode 100644 index 00000000..464bc12a --- /dev/null +++ b/src-migrate/types/auth.ts @@ -0,0 +1,58 @@ +import { registerSchema } from '~/validations/auth'; +import { OdooApiProps } from './odoo'; +import { z } from 'zod'; + +export type AuthProps = { + id: number; + parent_id: number; + parent_name: string; + partner_id: number; + name: string; + email: string; + phone: string; + mobile: string; + external: boolean; + company: boolean; + pricelist: string | null; + token: string; +}; + +export type AuthApiProps = OdooApiProps & { result: AuthProps }; + +export type RegisterProps = z.infer; + +export type RegisterResApiProps = { + register: boolean; + reason: 'EMAIL_USED' | 'NOT_ACTIVE' | null; +}; + +type ActivationResProps = { + activation: boolean; + user: AuthProps | null; +}; + +export type ActivationTokenProps = { + token: string; +}; + +export type ActivationTokenResApiProps = ActivationResProps & { + reason: 'INVALID_TOKEN' | null; +}; + +export type ActivationOtpProps = { + email: string; + otp: string; +}; + +export type ActivationOtpResApiProps = ActivationResProps & { + reason: 'INVALID_OTP' | null; +}; + +export type ActivationReqProps = { + email: string; +}; + +export type ActivationReqResApiProps = { + activation_request: boolean; + reason: 'NOT_FOUND' | 'ACTIVE' | null; +}; diff --git a/src-migrate/types/cart.ts b/src-migrate/types/cart.ts new file mode 100644 index 00000000..3aceeac4 --- /dev/null +++ b/src-migrate/types/cart.ts @@ -0,0 +1,72 @@ +import { CategoryPromo } from "./promotion"; + +type Price = { + price: number; + discount_percentage: number; + price_discount: number; +}; + +export type CartProduct = { + id: number; + image: string; + display_name: string; + name: string; + code: string; + price: Price; + qty: number; + weight: number; + package_weight: number; +}; + +export type CartItem = { + cart_id: number; + quantity: number; + selected: boolean; + can_buy: boolean; + cart_type: 'product' | 'promotion'; + id: number; + name: string; + stock: number; + weight: number; + attributes: string[]; + parent: { + id: number; + name: string; + image: string; + }; + price: Price; + manufacture: { + id: number; + name: string; + }; + has_flashsale: boolean; + subtotal: number; + + code?: string; + + image?: string; + remaining_time?: number; + promotion_type?: { + value?: CategoryPromo; + label?: string; + }; + limit_qty?: { + all?: number; + user?: number; + transaction?: number; + }; + remaining_qty?: { + all?: number; + user?: number; + transaction?: number; + }; + used_percentage?: number; + products?: CartProduct[]; + free_products?: CartProduct[]; + package_price?: number; +}; + +export type CartProps = { + product_total: number; + products: CartItem[]; +}; diff --git a/src-migrate/types/checkout.ts b/src-migrate/types/checkout.ts new file mode 100644 index 00000000..dc1365d8 --- /dev/null +++ b/src-migrate/types/checkout.ts @@ -0,0 +1,16 @@ +import { CartItem } from './cart'; + +export interface ICheckout { + total_purchase: number; + total_discount: number; + discount_voucher: number; + subtotal: number; + tax: number; + grand_total: number; + total_weight: { + kg: number; + g: number; + }; + has_product_without_weight: boolean; + products: CartItem[]; +} diff --git a/src-migrate/types/nav.ts b/src-migrate/types/nav.ts new file mode 100644 index 00000000..ba97b1bf --- /dev/null +++ b/src-migrate/types/nav.ts @@ -0,0 +1,4 @@ +export type SecondaryNavItemProps = { + label: string + href: string +} diff --git a/src-migrate/types/odoo.ts b/src-migrate/types/odoo.ts new file mode 100644 index 00000000..b34bc667 --- /dev/null +++ b/src-migrate/types/odoo.ts @@ -0,0 +1,6 @@ +export type OdooApiProps = { + status: { + code: number; + description: string; + }; +}; diff --git a/src-migrate/types/pageContent.ts b/src-migrate/types/pageContent.ts new file mode 100644 index 00000000..4361deb7 --- /dev/null +++ b/src-migrate/types/pageContent.ts @@ -0,0 +1,5 @@ +export type PageContentProps = { + id: number; + url_path: string; + content: string; +} | null; diff --git a/src-migrate/types/product.ts b/src-migrate/types/product.ts new file mode 100644 index 00000000..b411224b --- /dev/null +++ b/src-migrate/types/product.ts @@ -0,0 +1,39 @@ +import { IProductVariantDetail } from './productVariant'; + +export interface IProduct { + id: number; + image: string; + code: string; + display_name: string; + name: string; + weight: number; + qty_sold: number; + stock_total: number; + variant_total: number; + description: string; + categories: { + id: string; + name: string; + }[]; + flash_sale: { + id: string; + remaining_time: { + remaining_time: number; + is_flashsale: boolean; + }; + tag: string; + }; + lowest_price: { + price: number; + price_discount: number; + discount_percentage: number; + }; + manufacture: { + id: number; + name: string; + }; +} + +export interface IProductDetail extends IProduct { + variants: IProductVariantDetail[]; +} diff --git a/src-migrate/types/productVariant.ts b/src-migrate/types/productVariant.ts new file mode 100644 index 00000000..861b216a --- /dev/null +++ b/src-migrate/types/productVariant.ts @@ -0,0 +1,33 @@ +export interface IProductVariantDetail { + id: number; + image: string; + code: string; + name: string; + weight: number; + is_flashsale: { + remaining_time: number; + is_flashsale: boolean; + }; + price: { + price: number; + price_discount: number; + discount_percentage: number; + }; + manufacture: + | { + id: string; + name: string; + } + | {}; + parent: { + id: string; + name: string; + image: string; + }; + attributes: string[]; +} + +export interface IProductVariantSLA { + qty: number; + sla_date: string; +} diff --git a/src-migrate/types/promotion.ts b/src-migrate/types/promotion.ts new file mode 100644 index 00000000..85190aad --- /dev/null +++ b/src-migrate/types/promotion.ts @@ -0,0 +1,44 @@ +export interface IPromotion { + id: number; + program_id: number; + name: string; + type: { + value: CategoryPromo; + label: string; + }; + limit: number; + limit_user: number; + limit_trx: number; + price: number; + total_qty: number; + products: { + product_id: number; + qty: number; + }[]; + free_products: { + product_id: number; + qty: number; + }[]; +} + +export interface IProductVariantPromo { + id: number; + parent_id: number; + display_name: string; + image: string; + name: string; + default_code: string; + price: { + price: number; + discount_percentage: number; + price_discount: number; + }; + qty: number; +} + +export type CategoryPromo = 'bundling' | 'discount_loading' | 'merchandise'; + +export interface ICategoryPromo { + value: CategoryPromo; + label: string; +} diff --git a/src-migrate/types/promotionProgram.ts b/src-migrate/types/promotionProgram.ts new file mode 100644 index 00000000..205884b6 --- /dev/null +++ b/src-migrate/types/promotionProgram.ts @@ -0,0 +1,8 @@ +export type IPromotionProgram = { + id: number; + name: string; + start_time: string; + end_time: string; + applies_to: string; + time_left: number; +}; diff --git a/src-migrate/types/solr.ts b/src-migrate/types/solr.ts new file mode 100644 index 00000000..d231c305 --- /dev/null +++ b/src-migrate/types/solr.ts @@ -0,0 +1,7 @@ +export type SolrResponse = { + response: { + numFound: number; + start: number; + docs: T; + }; +}; diff --git a/src-migrate/validations/auth.ts b/src-migrate/validations/auth.ts new file mode 100644 index 00000000..78fc5e71 --- /dev/null +++ b/src-migrate/validations/auth.ts @@ -0,0 +1,17 @@ +import { z } from 'zod'; + +export const registerSchema = z.object({ + name: z.string().min(1, { message: 'Nama harus diisi' }), + email: z + .string() + .min(1, { message: 'Email harus diisi' }) + .email({ message: 'Email harus menggunakan format example@mail.com' }), + password: z.string().min(6, { message: 'Password minimal 6 karakter' }), + company: z.string().optional(), + phone: z + .string() + .min(1, { message: 'Nomor telepon harus diisi' }) + .refine((val) => /^\d{10,12}$/.test(val), { + message: 'Format nomor telepon tidak valid, contoh: 081234567890', + }), +}); -- cgit v1.2.3