@pradip1995/create-storefront 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/create-storefront.js +239 -0
- package/lib/kit-next-config.js +84 -0
- package/package.json +32 -0
- package/templates/storefront/.eslintrc.json +3 -0
- package/templates/storefront/README.md +35 -0
- package/templates/storefront/check-env-variables.js +51 -0
- package/templates/storefront/kit-next-config.js +71 -0
- package/templates/storefront/next-env.d.ts +5 -0
- package/templates/storefront/next.config.js +25 -0
- package/templates/storefront/package.json +56 -0
- package/templates/storefront/postcss.config.js +6 -0
- package/templates/storefront/public/favicon.png +0 -0
- package/templates/storefront/src/app/[countryCode]/(checkout)/checkout/page.tsx +23 -0
- package/templates/storefront/src/app/[countryCode]/(checkout)/checkout/payment/page.tsx +47 -0
- package/templates/storefront/src/app/[countryCode]/(checkout)/layout.tsx +31 -0
- package/templates/storefront/src/app/[countryCode]/(checkout)/not-found.tsx +19 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/addresses/page.tsx +31 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/loading.tsx +9 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/orders/details/[id]/page.tsx +35 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/orders/exchange/[id]/page.tsx +47 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/orders/page.tsx +28 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/orders/return/[id]/page.tsx +66 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/page.tsx +22 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/payment-methods/page.tsx +23 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/profile/page.tsx +43 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@login/default.tsx +11 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/@login/page.tsx +18 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/guest-orders/page.tsx +13 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/layout.tsx +22 -0
- package/templates/storefront/src/app/[countryCode]/(main)/account/loading.tsx +9 -0
- package/templates/storefront/src/app/[countryCode]/(main)/cart/loading.tsx +5 -0
- package/templates/storefront/src/app/[countryCode]/(main)/cart/not-found.tsx +21 -0
- package/templates/storefront/src/app/[countryCode]/(main)/cart/page.tsx +23 -0
- package/templates/storefront/src/app/[countryCode]/(main)/categories/[...category]/page.tsx +11 -0
- package/templates/storefront/src/app/[countryCode]/(main)/collections/[handle]/page.tsx +11 -0
- package/templates/storefront/src/app/[countryCode]/(main)/contact/page.tsx +21 -0
- package/templates/storefront/src/app/[countryCode]/(main)/guest-orders/page.tsx +12 -0
- package/templates/storefront/src/app/[countryCode]/(main)/help/page.tsx +28 -0
- package/templates/storefront/src/app/[countryCode]/(main)/layout.tsx +21 -0
- package/templates/storefront/src/app/[countryCode]/(main)/not-found.tsx +20 -0
- package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/confirmed/loading.tsx +5 -0
- package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/confirmed/page.tsx +23 -0
- package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/transfer/[token]/accept/page.tsx +41 -0
- package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/transfer/[token]/decline/page.tsx +41 -0
- package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/transfer/[token]/page.tsx +38 -0
- package/templates/storefront/src/app/[countryCode]/(main)/order/exchange/[id]/page.tsx +47 -0
- package/templates/storefront/src/app/[countryCode]/(main)/order/return/[id]/page.tsx +61 -0
- package/templates/storefront/src/app/[countryCode]/(main)/orders/[id]/page.tsx +33 -0
- package/templates/storefront/src/app/[countryCode]/(main)/page.tsx +24 -0
- package/templates/storefront/src/app/[countryCode]/(main)/privacy-policy/page.tsx +173 -0
- package/templates/storefront/src/app/[countryCode]/(main)/products/[handle]/page.tsx +193 -0
- package/templates/storefront/src/app/[countryCode]/(main)/reset-password/page.tsx +192 -0
- package/templates/storefront/src/app/[countryCode]/(main)/store/page.tsx +72 -0
- package/templates/storefront/src/app/[countryCode]/(main)/terms-of-use/page.tsx +179 -0
- package/templates/storefront/src/app/[countryCode]/(main)/wishlist/page.tsx +19 -0
- package/templates/storefront/src/app/api/meta/event/route.ts +63 -0
- package/templates/storefront/src/app/auth/customer/google/callback/page.tsx +126 -0
- package/templates/storefront/src/app/layout.tsx +104 -0
- package/templates/storefront/src/app/not-found.tsx +30 -0
- package/templates/storefront/src/app/opengraph-image.jpg +0 -0
- package/templates/storefront/src/app/robots.ts +15 -0
- package/templates/storefront/src/app/sitemap.ts +65 -0
- package/templates/storefront/src/app/twitter-image.jpg +0 -0
- package/templates/storefront/src/modules/account/components/account-deletion/index.tsx +160 -0
- package/templates/storefront/src/modules/account/components/account-info/index.tsx +145 -0
- package/templates/storefront/src/modules/account/components/account-nav/icons.tsx +43 -0
- package/templates/storefront/src/modules/account/components/account-nav/index.tsx +318 -0
- package/templates/storefront/src/modules/account/components/account-nav/logout-modal.tsx +92 -0
- package/templates/storefront/src/modules/account/components/account-nav/payment-methods-icon.tsx +9 -0
- package/templates/storefront/src/modules/account/components/address-book/index.tsx +47 -0
- package/templates/storefront/src/modules/account/components/address-card/add-address.tsx +377 -0
- package/templates/storefront/src/modules/account/components/address-card/edit-address-modal.tsx +468 -0
- package/templates/storefront/src/modules/account/components/deletion-pending-modal/index.tsx +213 -0
- package/templates/storefront/src/modules/account/components/forgot-password/index.tsx +1 -0
- package/templates/storefront/src/modules/account/components/login/index.tsx +1 -0
- package/templates/storefront/src/modules/account/components/order-card/index.tsx +221 -0
- package/templates/storefront/src/modules/account/components/order-overview/index.tsx +159 -0
- package/templates/storefront/src/modules/account/components/overview/index.tsx +189 -0
- package/templates/storefront/src/modules/account/components/profile-billing-address/index.tsx +447 -0
- package/templates/storefront/src/modules/account/components/profile-email/index.tsx +75 -0
- package/templates/storefront/src/modules/account/components/profile-form/index.tsx +416 -0
- package/templates/storefront/src/modules/account/components/profile-name/index.tsx +76 -0
- package/templates/storefront/src/modules/account/components/profile-password/index.tsx +70 -0
- package/templates/storefront/src/modules/account/components/profile-phone/index.tsx +185 -0
- package/templates/storefront/src/modules/account/components/register/index.tsx +1 -0
- package/templates/storefront/src/modules/account/components/return-item-selector/index.tsx +187 -0
- package/templates/storefront/src/modules/account/components/return-shipping-selector/index.tsx +118 -0
- package/templates/storefront/src/modules/account/components/transfer-request-form/index.tsx +81 -0
- package/templates/storefront/src/modules/account/templates/account-layout.tsx +38 -0
- package/templates/storefront/src/modules/account/templates/exchange-request-template.tsx +389 -0
- package/templates/storefront/src/modules/account/templates/guest-orders-template.tsx +123 -0
- package/templates/storefront/src/modules/account/templates/login-template.tsx +44 -0
- package/templates/storefront/src/modules/account/templates/payment-methods-template.tsx +478 -0
- package/templates/storefront/src/modules/account/templates/return-request-template.tsx +300 -0
- package/templates/storefront/src/modules/cart/components/abandoned-carts/ScrollToPendingOrdersButton.tsx +21 -0
- package/templates/storefront/src/modules/cart/components/abandoned-carts/index.tsx +335 -0
- package/templates/storefront/src/modules/cart/components/applied-promotions/index.tsx +121 -0
- package/templates/storefront/src/modules/cart/components/cart-delivery-selection/index.tsx +203 -0
- package/templates/storefront/src/modules/cart/components/cart-item-card/index.tsx +476 -0
- package/templates/storefront/src/modules/cart/components/cart-item-select/index.tsx +73 -0
- package/templates/storefront/src/modules/cart/components/cart-view-tracker/index.tsx +44 -0
- package/templates/storefront/src/modules/cart/components/delivery-information/index.tsx +89 -0
- package/templates/storefront/src/modules/cart/components/empty-cart-message/index.tsx +38 -0
- package/templates/storefront/src/modules/cart/components/item/index.tsx +150 -0
- package/templates/storefront/src/modules/cart/components/pincode-checker/index.tsx +174 -0
- package/templates/storefront/src/modules/cart/components/sign-in-prompt/index.tsx +26 -0
- package/templates/storefront/src/modules/cart/components/you-may-also-like/index.tsx +137 -0
- package/templates/storefront/src/modules/cart/templates/index.tsx +88 -0
- package/templates/storefront/src/modules/cart/templates/items.tsx +49 -0
- package/templates/storefront/src/modules/cart/templates/preview.tsx +51 -0
- package/templates/storefront/src/modules/cart/templates/summary.tsx +29 -0
- package/templates/storefront/src/modules/checkout/components/add-address-modal/index.tsx +390 -0
- package/templates/storefront/src/modules/checkout/components/address-card/index.tsx +135 -0
- package/templates/storefront/src/modules/checkout/components/address-select/index.tsx +116 -0
- package/templates/storefront/src/modules/checkout/components/addresses/index.tsx +605 -0
- package/templates/storefront/src/modules/checkout/components/back-link/index.tsx +32 -0
- package/templates/storefront/src/modules/checkout/components/billing_address/index.tsx +301 -0
- package/templates/storefront/src/modules/checkout/components/checkout-begin-tracker/index.tsx +45 -0
- package/templates/storefront/src/modules/checkout/components/checkout-leave-guard/index.tsx +109 -0
- package/templates/storefront/src/modules/checkout/components/checkout-shipping-tracker/index.tsx +45 -0
- package/templates/storefront/src/modules/checkout/components/country-select/index.tsx +50 -0
- package/templates/storefront/src/modules/checkout/components/discount-code/index.tsx +220 -0
- package/templates/storefront/src/modules/checkout/components/error-message/index.tsx +13 -0
- package/templates/storefront/src/modules/checkout/components/payment/index.tsx +572 -0
- package/templates/storefront/src/modules/checkout/components/payment-button/index.tsx +257 -0
- package/templates/storefront/src/modules/checkout/components/payment-button/razorpay-payment-button.tsx +136 -0
- package/templates/storefront/src/modules/checkout/components/payment-container/index.tsx +129 -0
- package/templates/storefront/src/modules/checkout/components/payment-test/index.tsx +12 -0
- package/templates/storefront/src/modules/checkout/components/payment-wrapper/index.tsx +50 -0
- package/templates/storefront/src/modules/checkout/components/payment-wrapper/stripe-wrapper.tsx +54 -0
- package/templates/storefront/src/modules/checkout/components/processing-overlay/index.tsx +83 -0
- package/templates/storefront/src/modules/checkout/components/review/index.tsx +60 -0
- package/templates/storefront/src/modules/checkout/components/select-address-modal/index.tsx +103 -0
- package/templates/storefront/src/modules/checkout/components/shipping/index.tsx +533 -0
- package/templates/storefront/src/modules/checkout/components/shipping-address/index.tsx +521 -0
- package/templates/storefront/src/modules/checkout/components/submit-button/index.tsx +32 -0
- package/templates/storefront/src/modules/checkout/templates/checkout-form/index.tsx +38 -0
- package/templates/storefront/src/modules/checkout/templates/checkout-summary/index.tsx +274 -0
- package/templates/storefront/src/modules/common/components/breadcrumb/index.tsx +43 -0
- package/templates/storefront/src/modules/common/components/cart-totals/index.tsx +473 -0
- package/templates/storefront/src/modules/common/components/checkbox/index.tsx +98 -0
- package/templates/storefront/src/modules/common/components/delete-button/index.tsx +156 -0
- package/templates/storefront/src/modules/common/components/divider/index.tsx +9 -0
- package/templates/storefront/src/modules/common/components/filter-checkbox-group/index.tsx +134 -0
- package/templates/storefront/src/modules/common/components/filter-radio-group/index.tsx +62 -0
- package/templates/storefront/src/modules/common/components/input/index.tsx +79 -0
- package/templates/storefront/src/modules/common/components/interactive-link/index.tsx +33 -0
- package/templates/storefront/src/modules/common/components/line-item-options/index.tsx +26 -0
- package/templates/storefront/src/modules/common/components/line-item-price/index.tsx +64 -0
- package/templates/storefront/src/modules/common/components/line-item-unit-price/index.tsx +61 -0
- package/templates/storefront/src/modules/common/components/localized-client-link/index.tsx +32 -0
- package/templates/storefront/src/modules/common/components/login-popup/index.tsx +78 -0
- package/templates/storefront/src/modules/common/components/modal/index.tsx +123 -0
- package/templates/storefront/src/modules/common/components/native-select/index.tsx +75 -0
- package/templates/storefront/src/modules/common/components/obfuscated-email/index.tsx +30 -0
- package/templates/storefront/src/modules/common/components/product/product-rating/index.tsx +172 -0
- package/templates/storefront/src/modules/common/components/product/review-modal/index.tsx +333 -0
- package/templates/storefront/src/modules/common/components/product/share-button/index.tsx +227 -0
- package/templates/storefront/src/modules/common/components/product/wishlist-icon/index.tsx +46 -0
- package/templates/storefront/src/modules/common/components/radio/index.tsx +27 -0
- package/templates/storefront/src/modules/common/components/select/index.tsx +164 -0
- package/templates/storefront/src/modules/common/components/side-panel/index.tsx +65 -0
- package/templates/storefront/src/modules/common/icons/arrow-left.tsx +36 -0
- package/templates/storefront/src/modules/common/icons/back.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/bancontact.tsx +26 -0
- package/templates/storefront/src/modules/common/icons/chevron-down.tsx +30 -0
- package/templates/storefront/src/modules/common/icons/delivered.tsx +29 -0
- package/templates/storefront/src/modules/common/icons/envelope.tsx +27 -0
- package/templates/storefront/src/modules/common/icons/eye-off.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/eye.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/fast-delivery.tsx +65 -0
- package/templates/storefront/src/modules/common/icons/ideal.tsx +26 -0
- package/templates/storefront/src/modules/common/icons/lock.tsx +31 -0
- package/templates/storefront/src/modules/common/icons/map-pin.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/medusa.tsx +27 -0
- package/templates/storefront/src/modules/common/icons/menu.tsx +45 -0
- package/templates/storefront/src/modules/common/icons/nextjs.tsx +27 -0
- package/templates/storefront/src/modules/common/icons/package.tsx +44 -0
- package/templates/storefront/src/modules/common/icons/paypal.tsx +30 -0
- package/templates/storefront/src/modules/common/icons/phone.tsx +30 -0
- package/templates/storefront/src/modules/common/icons/placeholder-image.tsx +44 -0
- package/templates/storefront/src/modules/common/icons/refresh.tsx +51 -0
- package/templates/storefront/src/modules/common/icons/spinner.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/trash.tsx +51 -0
- package/templates/storefront/src/modules/common/icons/user.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/x.tsx +37 -0
- package/templates/storefront/src/modules/contact/templates/index.tsx +272 -0
- package/templates/storefront/src/modules/help/templates/index.tsx +629 -0
- package/templates/storefront/src/modules/home/components/dynamic-banner/index.tsx +190 -0
- package/templates/storefront/src/modules/home/components/featured-products/index.tsx +16 -0
- package/templates/storefront/src/modules/home/components/featured-products/product-rail/index.tsx +51 -0
- package/templates/storefront/src/modules/home/components/features/index.tsx +1 -0
- package/templates/storefront/src/modules/home/components/hero/index.tsx +1 -0
- package/templates/storefront/src/modules/home/components/loved-by-moms/index.tsx +1 -0
- package/templates/storefront/src/modules/home/components/new-arrivals/index.tsx +1 -0
- package/templates/storefront/src/modules/home/components/shop-by-age/index.tsx +1 -0
- package/templates/storefront/src/modules/home/components/shop-by-category/index.tsx +1 -0
- package/templates/storefront/src/modules/home/components/testimonials/index.tsx +1 -0
- package/templates/storefront/src/modules/home/components/why-choose-us/dynamic-features.tsx +93 -0
- package/templates/storefront/src/modules/home/components/why-choose-us/index.tsx +1 -0
- package/templates/storefront/src/modules/layout/components/account-dropdown/index.tsx +56 -0
- package/templates/storefront/src/modules/layout/components/cart-button/index.tsx +8 -0
- package/templates/storefront/src/modules/layout/components/cart-dropdown/index.tsx +424 -0
- package/templates/storefront/src/modules/layout/components/cart-mismatch-banner/index.tsx +57 -0
- package/templates/storefront/src/modules/layout/components/cookie-consent/index.tsx +116 -0
- package/templates/storefront/src/modules/layout/components/country-select/index.tsx +135 -0
- package/templates/storefront/src/modules/layout/components/desktop-search/index.tsx +148 -0
- package/templates/storefront/src/modules/layout/components/dynamic-logo/index.tsx +27 -0
- package/templates/storefront/src/modules/layout/components/footer-categories/index.tsx +34 -0
- package/templates/storefront/src/modules/layout/components/footer-contact/index.tsx +87 -0
- package/templates/storefront/src/modules/layout/components/footer-description/index.tsx +12 -0
- package/templates/storefront/src/modules/layout/components/footer-logo/index.tsx +22 -0
- package/templates/storefront/src/modules/layout/components/footer-newsletter/index.tsx +100 -0
- package/templates/storefront/src/modules/layout/components/language-select/index.tsx +192 -0
- package/templates/storefront/src/modules/layout/components/medusa-cta/index.tsx +21 -0
- package/templates/storefront/src/modules/layout/components/mobile-menu/index.tsx +296 -0
- package/templates/storefront/src/modules/layout/components/nav-links/index.tsx +66 -0
- package/templates/storefront/src/modules/layout/components/nav-wrapper/index.tsx +14 -0
- package/templates/storefront/src/modules/layout/components/promo-bar/index.tsx +7 -0
- package/templates/storefront/src/modules/layout/components/promo-bar/promo-bar-content.tsx +174 -0
- package/templates/storefront/src/modules/layout/components/push-notification-manager/index.tsx +191 -0
- package/templates/storefront/src/modules/layout/components/search-panel/index.tsx +136 -0
- package/templates/storefront/src/modules/layout/components/side-menu/index.tsx +144 -0
- package/templates/storefront/src/modules/layout/components/verification-banner/index.tsx +217 -0
- package/templates/storefront/src/modules/layout/components/wishlist-counter/index.tsx +17 -0
- package/templates/storefront/src/modules/layout/templates/footer/index.tsx +7 -0
- package/templates/storefront/src/modules/layout/templates/nav/index.tsx +14 -0
- package/templates/storefront/src/modules/order/components/cancel-order-modal/index.tsx +168 -0
- package/templates/storefront/src/modules/order/components/help/index.tsx +25 -0
- package/templates/storefront/src/modules/order/components/item/index.tsx +62 -0
- package/templates/storefront/src/modules/order/components/items/index.tsx +44 -0
- package/templates/storefront/src/modules/order/components/onboarding-cta/index.tsx +28 -0
- package/templates/storefront/src/modules/order/components/order-confirmation-back-handler/index.tsx +28 -0
- package/templates/storefront/src/modules/order/components/order-details/index.tsx +63 -0
- package/templates/storefront/src/modules/order/components/order-purchase-tracker/index.tsx +48 -0
- package/templates/storefront/src/modules/order/components/order-redesign/index.tsx +887 -0
- package/templates/storefront/src/modules/order/components/order-summary/index.tsx +60 -0
- package/templates/storefront/src/modules/order/components/payment-details/index.tsx +63 -0
- package/templates/storefront/src/modules/order/components/shipping-details/index.tsx +73 -0
- package/templates/storefront/src/modules/order/components/transfer-actions/index.tsx +81 -0
- package/templates/storefront/src/modules/order/components/transfer-image/index.tsx +275 -0
- package/templates/storefront/src/modules/order/templates/order-completed-template.tsx +233 -0
- package/templates/storefront/src/modules/order/templates/order-details-template.tsx +128 -0
- package/templates/storefront/src/modules/products/components/image-gallery/index.tsx +297 -0
- package/templates/storefront/src/modules/products/components/product-actions/index.tsx +1400 -0
- package/templates/storefront/src/modules/products/components/product-actions/mobile-actions.tsx +217 -0
- package/templates/storefront/src/modules/products/components/product-actions/option-select.tsx +62 -0
- package/templates/storefront/src/modules/products/components/product-onboarding-cta/index.tsx +30 -0
- package/templates/storefront/src/modules/products/components/product-preview/index.tsx +5 -0
- package/templates/storefront/src/modules/products/components/product-preview/price.tsx +29 -0
- package/templates/storefront/src/modules/products/components/product-price/index.tsx +58 -0
- package/templates/storefront/src/modules/products/components/product-rating/index.tsx +1 -0
- package/templates/storefront/src/modules/products/components/product-tabs/accordion.tsx +100 -0
- package/templates/storefront/src/modules/products/components/product-tabs/index.tsx +127 -0
- package/templates/storefront/src/modules/products/components/product-tabs/ratings-tab.tsx +598 -0
- package/templates/storefront/src/modules/products/components/product-view-tracker/index.tsx +53 -0
- package/templates/storefront/src/modules/products/components/related-products/index.tsx +152 -0
- package/templates/storefront/src/modules/products/components/review-modal/index.tsx +1 -0
- package/templates/storefront/src/modules/products/components/share-button/index.tsx +1 -0
- package/templates/storefront/src/modules/products/components/thumbnail/index.tsx +91 -0
- package/templates/storefront/src/modules/products/components/wishlist-icon/index.tsx +1 -0
- package/templates/storefront/src/modules/products/context/product-context.tsx +52 -0
- package/templates/storefront/src/modules/products/templates/index.tsx +26 -0
- package/templates/storefront/src/modules/products/templates/product-actions-wrapper/index.tsx +1 -0
- package/templates/storefront/src/modules/products/templates/product-info/index.tsx +2 -0
- package/templates/storefront/src/modules/shipping/components/free-shipping-price-nudge/index.tsx +283 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-button/index.tsx +5 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-card-details/index.tsx +10 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-cart-item/index.tsx +35 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-cart-totals/index.tsx +30 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-code-form/index.tsx +13 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-line-item/index.tsx +35 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-confirmed-header/index.tsx +14 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-information/index.tsx +36 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-items/index.tsx +43 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-summary/index.tsx +15 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-product-preview/index.tsx +15 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-cart-page/index.tsx +65 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-order-confirmed/index.tsx +21 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-product-grid/index.tsx +23 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-related-products/index.tsx +25 -0
- package/templates/storefront/src/modules/store/components/client-paginated-products.tsx +108 -0
- package/templates/storefront/src/modules/store/components/mobile-filters/index.tsx +135 -0
- package/templates/storefront/src/modules/store/components/pagination/index.tsx +118 -0
- package/templates/storefront/src/modules/store/components/product-list-view-tracker/index.tsx +43 -0
- package/templates/storefront/src/modules/store/components/refinement-list/index.tsx +299 -0
- package/templates/storefront/src/modules/store/components/refinement-list/sort-products/index.tsx +120 -0
- package/templates/storefront/src/modules/store/components/store-header/index.tsx +67 -0
- package/templates/storefront/src/modules/store/templates/index.tsx +1 -0
- package/templates/storefront/src/modules/store/templates/paginated-products.tsx +175 -0
- package/templates/storefront/src/modules/wishlist/components/wishlist-item/index.tsx +797 -0
- package/templates/storefront/src/modules/wishlist/templates/index.tsx +176 -0
- package/templates/storefront/src/storefront.config.ts +12 -0
- package/templates/storefront/src/styles/globals.css +326 -0
- package/templates/storefront/src/theme/valero/blocks/home/Features/index.tsx +61 -0
- package/templates/storefront/src/theme/valero/blocks/home/Hero/index.tsx +102 -0
- package/templates/storefront/src/theme/valero/blocks/home/LovedByMoms/index.tsx +407 -0
- package/templates/storefront/src/theme/valero/blocks/home/NewArrivals/index.tsx +48 -0
- package/templates/storefront/src/theme/valero/blocks/home/ShopByAge/index.tsx +128 -0
- package/templates/storefront/src/theme/valero/blocks/home/ShopByCategory/index.tsx +409 -0
- package/templates/storefront/src/theme/valero/blocks/home/Testimonials/index.tsx +697 -0
- package/templates/storefront/src/theme/valero/blocks/home/WhyChooseUs/index.tsx +62 -0
- package/templates/storefront/src/theme/valero/layouts/MainLayoutShell.tsx +14 -0
- package/templates/storefront/src/theme/valero/primitives/Button.tsx +28 -0
- package/templates/storefront/src/theme/valero/primitives/Card.tsx +32 -0
- package/templates/storefront/src/theme/valero/primitives/index.ts +2 -0
- package/templates/storefront/src/theme/valero/slots/account/ForgotPassword/index.tsx +1 -0
- package/templates/storefront/src/theme/valero/slots/account/Login/index.tsx +1 -0
- package/templates/storefront/src/theme/valero/slots/account/LoginTemplate/index.tsx +44 -0
- package/templates/storefront/src/theme/valero/slots/account/Register/index.tsx +1 -0
- package/templates/storefront/src/theme/valero/slots/cart/CartItem/index.tsx +11 -0
- package/templates/storefront/src/theme/valero/slots/cart/CartSummary/index.tsx +13 -0
- package/templates/storefront/src/theme/valero/slots/checkout/CheckoutForm/index.tsx +1 -0
- package/templates/storefront/src/theme/valero/slots/checkout/CheckoutSummary/index.tsx +1 -0
- package/templates/storefront/src/theme/valero/slots/layout/Footer/index.tsx +104 -0
- package/templates/storefront/src/theme/valero/slots/layout/Nav/index.tsx +97 -0
- package/templates/storefront/src/theme/valero/slots/layout/PromoBar/index.tsx +19 -0
- package/templates/storefront/src/theme/valero/slots/layout/PromoBar/promo-bar-content.tsx +174 -0
- package/templates/storefront/src/theme/valero/slots/order/OrderDetails/index.tsx +12 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductCTASection.tsx +191 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductDetailsSection.tsx +137 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductFeaturePanel.tsx +245 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductHighlightsSection.tsx +98 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductOptionsSection.tsx +233 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductPriceSection.tsx +53 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductTrustSection.tsx +84 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductActions/index.tsx +161 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductCard/index.tsx +132 -0
- package/templates/storefront/src/theme/valero/slots/product/ProductInfo/index.tsx +40 -0
- package/templates/storefront/src/theme/valero/templates/StorePage/index.tsx +154 -0
- package/templates/storefront/src/theme/valero/tokens/colors.js +16 -0
- package/templates/storefront/src/theme/valero/tokens/colors.ts +21 -0
- package/templates/storefront/src/theme/valero/tokens/fonts.ts +13 -0
- package/templates/storefront/src/theme/valero/tokens/index.ts +3 -0
- package/templates/storefront/src/theme/valero/tokens/spacing.ts +9 -0
- package/templates/storefront/src/theme/valero/tokens/theme.css +91 -0
- package/templates/storefront/tailwind.config.js +221 -0
- package/templates/storefront/tsconfig.json +30 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { useState } from "react"
|
|
4
|
+
import Link from "next/link"
|
|
5
|
+
import { Copy, Check } from "lucide-react"
|
|
6
|
+
|
|
7
|
+
export default function PromoBarContent({ text, code: explicitCode, value: explicitValue }: { text: string; code: string | null; value: string | null }) {
|
|
8
|
+
const [copied, setCopied] = useState(false)
|
|
9
|
+
|
|
10
|
+
// Regex for code and value
|
|
11
|
+
const codeRegex = /\b[A-Z0-9]{4,}\b/;
|
|
12
|
+
const valueRegex = /(\d+%\s?(OFF)?)|([₹$]\d+)|(\d+\s?(Rs|₹|%|OFF))/gi;
|
|
13
|
+
|
|
14
|
+
let currentText = text;
|
|
15
|
+
let codeToCopy = explicitCode || "";
|
|
16
|
+
|
|
17
|
+
// Find code part
|
|
18
|
+
let codeMatch = explicitCode && currentText.includes(explicitCode)
|
|
19
|
+
? { text: explicitCode, index: currentText.indexOf(explicitCode) }
|
|
20
|
+
: null;
|
|
21
|
+
|
|
22
|
+
if (!codeMatch) {
|
|
23
|
+
const regMatch = currentText.match(codeRegex);
|
|
24
|
+
if (regMatch) {
|
|
25
|
+
codeMatch = { text: regMatch[0], index: regMatch.index! };
|
|
26
|
+
if (!explicitCode) codeToCopy = regMatch[0];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Find value part
|
|
31
|
+
let valueMatch = explicitValue && currentText.includes(explicitValue)
|
|
32
|
+
? { text: explicitValue, index: currentText.indexOf(explicitValue) }
|
|
33
|
+
: null;
|
|
34
|
+
|
|
35
|
+
if (!valueMatch) {
|
|
36
|
+
const regMatch = Array.from(currentText.matchAll(valueRegex));
|
|
37
|
+
if (regMatch.length > 0) {
|
|
38
|
+
const firstValue = regMatch[0];
|
|
39
|
+
valueMatch = { text: firstValue[0], index: firstValue.index! };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Handle priority: if explicitCode/explicitValue exist but not found in text,
|
|
44
|
+
// we replace the detected ones or append if none detected?
|
|
45
|
+
// User said "replace" essentially by saying priority.
|
|
46
|
+
|
|
47
|
+
// To render precisely, we need to collect all segments.
|
|
48
|
+
const segments: Array<{ text: string; type: 'text' | 'code' | 'value' }> = [];
|
|
49
|
+
let lastIndex = 0;
|
|
50
|
+
|
|
51
|
+
const matches = [
|
|
52
|
+
...(codeMatch ? [{ ...codeMatch, type: 'code' as const }] : []),
|
|
53
|
+
...(valueMatch ? [{ ...valueMatch, type: 'value' as const }] : [])
|
|
54
|
+
].sort((a, b) => a.index - b.index);
|
|
55
|
+
|
|
56
|
+
// Avoid overlaps
|
|
57
|
+
let filteredMatches: typeof matches = [];
|
|
58
|
+
let currentPos = 0;
|
|
59
|
+
for (const match of matches) {
|
|
60
|
+
if (match.index >= currentPos) {
|
|
61
|
+
filteredMatches.push(match);
|
|
62
|
+
currentPos = match.index + match.text.length;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
filteredMatches.forEach(match => {
|
|
67
|
+
if (match.index > lastIndex) {
|
|
68
|
+
segments.push({ text: currentText.substring(lastIndex, match.index), type: 'text' });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Use explicit values if they exist, even if the text match was different (Priority logic)
|
|
72
|
+
const displayText = match.type === 'code' ? (explicitCode || match.text) : (explicitValue || match.text);
|
|
73
|
+
segments.push({ text: displayText, type: match.type });
|
|
74
|
+
lastIndex = match.index + match.text.length;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (lastIndex < currentText.length) {
|
|
78
|
+
segments.push({ text: currentText.substring(lastIndex), type: 'text' });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Fallback for cases where no match was found but explicit values exist:
|
|
82
|
+
// (Optional: we could append them, but usually text should contain them)
|
|
83
|
+
|
|
84
|
+
const handleCopy = () => {
|
|
85
|
+
navigator.clipboard.writeText(codeToCopy || text)
|
|
86
|
+
setCopied(true)
|
|
87
|
+
setTimeout(() => setCopied(false), 2000)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<div className="max-w-[1440px] mx-auto w-full relative z-10 flex flex-row items-center justify-start lg:justify-center gap-x-4 text-center font-medium overflow-hidden whitespace-nowrap py-0.5">
|
|
92
|
+
{/* Visual Feedback Overlay for Copy Success - Mobile Only */}
|
|
93
|
+
{copied && (
|
|
94
|
+
<div className="absolute inset-0 z-50 flex sm:hidden items-center justify-center bg-gradient-to-r from-[#8B5AB1] via-[#9B6BC1] to-[#8B5AB1] animate-in fade-in zoom-in duration-200">
|
|
95
|
+
<span className="text-yellow-300 text-[11px] sm:text-[13px] font-extrabold tracking-wider uppercase flex items-center gap-2 drop-shadow-md">
|
|
96
|
+
PROMOCODE COPIED! APPLY AT CHECKOUT 🎁
|
|
97
|
+
</span>
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
|
|
101
|
+
<div className="flex items-center lg:animate-none animate-marquee whitespace-nowrap min-w-full lg:min-w-0">
|
|
102
|
+
<button
|
|
103
|
+
onClick={handleCopy}
|
|
104
|
+
className="group/btn flex items-center justify-center gap-1.5 focus:outline-none flex-shrink-0"
|
|
105
|
+
title={codeToCopy ? `Click to copy promo code: ${codeToCopy}` : "Click to copy"}
|
|
106
|
+
>
|
|
107
|
+
{/* Main Content Segment */}
|
|
108
|
+
<div className="flex items-center gap-1.5 px-2 sm:px-0">
|
|
109
|
+
<span className="text-[11px] sm:text-[12.5px] font-bold tracking-[0.05em] uppercase drop-shadow-sm group-hover/btn:text-yellow-100 transition-colors flex items-center">
|
|
110
|
+
{segments.length > 0 ? segments.map((s, i) => (
|
|
111
|
+
s.type === 'text' ? (
|
|
112
|
+
<span key={i}>{s.text}</span>
|
|
113
|
+
) : (
|
|
114
|
+
<span key={i} className="text-yellow-300 text-[12px] sm:text-[13.5px] mx-1 font-extrabold shadow-sm group-hover/btn:text-yellow-200 transition-colors drop-shadow-md">
|
|
115
|
+
"{s.text}"
|
|
116
|
+
</span>
|
|
117
|
+
)
|
|
118
|
+
)) : text}
|
|
119
|
+
</span>
|
|
120
|
+
<span className="bg-white/20 p-1 rounded-md group-hover/btn:bg-white/30 transition-colors flex items-center justify-center flex-shrink-0 ml-1">
|
|
121
|
+
{copied ? (
|
|
122
|
+
<Check size={13} className="text-green-300" strokeWidth={3} />
|
|
123
|
+
) : (
|
|
124
|
+
<Copy size={13} className="text-white/80 group-hover/btn:text-white" strokeWidth={2.5} />
|
|
125
|
+
)}
|
|
126
|
+
</span>
|
|
127
|
+
</div>
|
|
128
|
+
</button>
|
|
129
|
+
|
|
130
|
+
<div className="mx-4 h-3 w-px bg-white/30 flex-shrink-0" />
|
|
131
|
+
|
|
132
|
+
<Link
|
|
133
|
+
href="/store"
|
|
134
|
+
className="text-[11px] sm:text-[12.5px] font-bold tracking-[0.02em] uppercase text-yellow-300 hover:text-white underline underline-offset-4 decoration-white/40 hover:decoration-white transition-all flex items-center group/link flex-shrink-0 mr-8 sm:mr-0"
|
|
135
|
+
>
|
|
136
|
+
SHOP NOW
|
|
137
|
+
<svg
|
|
138
|
+
className="ml-1 w-3 h-3 transform group-hover/link:translate-x-1 transition-transform"
|
|
139
|
+
fill="none"
|
|
140
|
+
viewBox="0 0 24 24"
|
|
141
|
+
stroke="currentColor"
|
|
142
|
+
>
|
|
143
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M9 5l7 7-7 7" />
|
|
144
|
+
</svg>
|
|
145
|
+
</Link>
|
|
146
|
+
|
|
147
|
+
{/* Duplicated Content for Seamless Loop on Mobile and Tablet */}
|
|
148
|
+
<div className="flex lg:hidden items-center gap-x-4">
|
|
149
|
+
<div className="mx-4 h-3 w-px bg-white/30 flex-shrink-0" />
|
|
150
|
+
<div className="flex items-center gap-1.5 px-2">
|
|
151
|
+
<span className="text-[11px] font-bold tracking-[0.05em] uppercase drop-shadow-sm flex items-center">
|
|
152
|
+
{segments.length > 0 ? segments.map((s, i) => (
|
|
153
|
+
s.type === 'text' ? (
|
|
154
|
+
<span key={i}>{s.text}</span>
|
|
155
|
+
) : (
|
|
156
|
+
<span key={i} className="text-yellow-300 text-[12px] mx-1 font-extrabold">
|
|
157
|
+
"{s.text}"
|
|
158
|
+
</span>
|
|
159
|
+
)
|
|
160
|
+
)) : text}
|
|
161
|
+
</span>
|
|
162
|
+
<span className="bg-white/20 p-1 rounded-md flex items-center justify-center flex-shrink-0 ml-1">
|
|
163
|
+
<Copy size={13} className="text-white/80" strokeWidth={2.5} />
|
|
164
|
+
</span>
|
|
165
|
+
</div>
|
|
166
|
+
<div className="mx-4 h-3 w-px bg-white/30 flex-shrink-0" />
|
|
167
|
+
<span className="text-[11px] font-bold tracking-[0.02em] uppercase text-yellow-300 flex items-center mr-8">
|
|
168
|
+
SHOP NOW
|
|
169
|
+
</span>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
)
|
|
174
|
+
}
|
package/templates/storefront/src/modules/layout/components/push-notification-manager/index.tsx
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useState } from "react"
|
|
4
|
+
import { registerNotificationToken } from "@core/data/notifications"
|
|
5
|
+
import { Button, IconButton } from "@medusajs/ui"
|
|
6
|
+
import { XMark } from "@medusajs/icons"
|
|
7
|
+
|
|
8
|
+
interface PushNotificationManagerProps {
|
|
9
|
+
customerId?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const PushNotificationManager: React.FC<PushNotificationManagerProps> = ({ customerId }) => {
|
|
13
|
+
const [showPrompt, setShowPrompt] = useState(false)
|
|
14
|
+
const [status, setStatus] = useState<"idle" | "requesting" | "registered" | "denied">("idle")
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const checkStatus = async () => {
|
|
20
|
+
if (typeof window === "undefined") return
|
|
21
|
+
|
|
22
|
+
const permission = Notification.permission
|
|
23
|
+
const storageKey = customerId ? `fcm_reg_${customerId}` : "fcm_reg_guest"
|
|
24
|
+
const alreadyRegistered = localStorage.getItem(storageKey)
|
|
25
|
+
|
|
26
|
+
console.log("DEBUG: PushNotification Status", {
|
|
27
|
+
customerId,
|
|
28
|
+
permission,
|
|
29
|
+
alreadyRegistered,
|
|
30
|
+
isDismissed: localStorage.getItem("push_notification_dismissed")
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
if (permission === "default") {
|
|
34
|
+
const isDismissed = localStorage.getItem("push_notification_dismissed")
|
|
35
|
+
if (isDismissed === "true") return
|
|
36
|
+
setShowPrompt(true)
|
|
37
|
+
} else if (permission === "granted") {
|
|
38
|
+
if (!alreadyRegistered) {
|
|
39
|
+
handleAllow(true)
|
|
40
|
+
} else {
|
|
41
|
+
setStatus("registered")
|
|
42
|
+
}
|
|
43
|
+
} else if (permission === "denied") {
|
|
44
|
+
setStatus("denied")
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setTimeout(checkStatus, 1000)
|
|
49
|
+
|
|
50
|
+
// Listen for foreground messages
|
|
51
|
+
const setupListener = async () => {
|
|
52
|
+
try {
|
|
53
|
+
const { onMessageListener } = await import("@core/firebase")
|
|
54
|
+
onMessageListener().then((payload: any) => {
|
|
55
|
+
|
|
56
|
+
if (Notification.permission === "granted") {
|
|
57
|
+
new Notification(payload.notification.title, {
|
|
58
|
+
body: payload.notification.body,
|
|
59
|
+
icon: "/Logo.png"
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
} catch (err) {
|
|
64
|
+
// Listener setup error
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
setupListener()
|
|
68
|
+
}, [customerId])
|
|
69
|
+
|
|
70
|
+
const handleAllow = async (isBackground = false) => {
|
|
71
|
+
if (!isBackground) setStatus("requesting")
|
|
72
|
+
try {
|
|
73
|
+
const { requestNotificationPermission } = await import("@core/firebase")
|
|
74
|
+
const token = await requestNotificationPermission()
|
|
75
|
+
if (token) {
|
|
76
|
+
const deviceInfo = {
|
|
77
|
+
userAgent: navigator.userAgent,
|
|
78
|
+
platform: navigator.platform,
|
|
79
|
+
language: navigator.language,
|
|
80
|
+
}
|
|
81
|
+
const success = await registerNotificationToken(token, deviceInfo)
|
|
82
|
+
if (success) {
|
|
83
|
+
const storageKey = customerId ? `fcm_reg_${customerId}` : "fcm_reg_guest"
|
|
84
|
+
localStorage.setItem(storageKey, "true")
|
|
85
|
+
setStatus("registered")
|
|
86
|
+
setShowPrompt(false)
|
|
87
|
+
if (!isBackground) alert("Notifications enabled successfully!")
|
|
88
|
+
} else {
|
|
89
|
+
setStatus("idle")
|
|
90
|
+
if (!isBackground) alert("Failed to register token with backend.")
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
setStatus("denied")
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
setStatus("idle")
|
|
97
|
+
if (!isBackground) alert("Failed to enable notifications. Please check your browser's settings.")
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const handleDismiss = () => {
|
|
102
|
+
setShowPrompt(false)
|
|
103
|
+
localStorage.setItem("push_notification_dismissed", "true")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!customerId || !showPrompt || status === "registered") return null
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<div
|
|
110
|
+
id="push-notification-prompt"
|
|
111
|
+
className="fixed inset-0 z-[999999] flex items-center justify-center p-6"
|
|
112
|
+
>
|
|
113
|
+
{/* Backdrop with elegant blur */}
|
|
114
|
+
<div
|
|
115
|
+
className="absolute inset-0 bg-black/40 backdrop-blur-sm animate-in fade-in duration-500"
|
|
116
|
+
onClick={handleDismiss}
|
|
117
|
+
/>
|
|
118
|
+
|
|
119
|
+
<div className="bg-white dark:bg-neutral-900 w-full max-w-[440px] rounded-[32px] shadow-[0_32px_128px_-16px_rgba(0,0,0,0.3)] border border-neutral-100 dark:border-neutral-800 relative overflow-hidden animate-in zoom-in-95 fade-in slide-in-from-bottom-20 duration-500">
|
|
120
|
+
{/* Subtle Brand Background Blobs */}
|
|
121
|
+
<div className="absolute top-0 right-0 -mt-16 -mr-16 w-48 h-48 bg-[#8B5AB1]/10 rounded-full blur-[60px]" />
|
|
122
|
+
|
|
123
|
+
<div className="relative z-10 p-10">
|
|
124
|
+
<div className="flex justify-between items-start mb-8">
|
|
125
|
+
<div className="bg-gradient-to-br from-[#A879CF] to-[#8B5AB1] w-16 h-16 rounded-[24px] shadow-[0_20px_40px_-10px_rgba(139,90,177,0.6)] grid place-items-center flex-shrink-0 border border-white/20 relative group">
|
|
126
|
+
<div className="absolute inset-0 bg-white/10 opacity-0 group-hover:opacity-100 transition-opacity rounded-[24px]" />
|
|
127
|
+
<svg
|
|
128
|
+
width="34"
|
|
129
|
+
height="34"
|
|
130
|
+
viewBox="0 0 24 24"
|
|
131
|
+
fill="none"
|
|
132
|
+
stroke="white"
|
|
133
|
+
strokeWidth="2.2"
|
|
134
|
+
strokeLinecap="round"
|
|
135
|
+
strokeLinejoin="round"
|
|
136
|
+
className="drop-shadow-sm"
|
|
137
|
+
>
|
|
138
|
+
<path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" />
|
|
139
|
+
<path d="M10.3 21a1.94 1.94 0 0 0 3.4 0" />
|
|
140
|
+
</svg>
|
|
141
|
+
</div>
|
|
142
|
+
<button
|
|
143
|
+
onClick={handleDismiss}
|
|
144
|
+
className="p-2.5 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-full transition-all group active:scale-90"
|
|
145
|
+
>
|
|
146
|
+
<XMark className="w-6 h-6 text-neutral-300 group-hover:text-neutral-900 dark:group-hover:text-white" />
|
|
147
|
+
</button>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<div className="text-left">
|
|
151
|
+
<h3 className="text-2xl sm:text-3xl font-black text-neutral-900 dark:text-white mb-3 tracking-tight">
|
|
152
|
+
{status === "denied" ? "Notifications Blocked" : "Enable Notifications?"}
|
|
153
|
+
</h3>
|
|
154
|
+
<p className="text-neutral-500 dark:text-neutral-400 text-base sm:text-lg mb-10 leading-relaxed">
|
|
155
|
+
{status === "denied"
|
|
156
|
+
? "Please enable notifications in your browser settings to stay updated."
|
|
157
|
+
: "Don't miss out! Get real-time updates for your order status and exclusive member-only offers."}
|
|
158
|
+
</p>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
{status !== "denied" && (
|
|
162
|
+
<div className="flex flex-col gap-4">
|
|
163
|
+
<button
|
|
164
|
+
className="w-full rounded-[20px] h-14 bg-gradient-to-r from-[#8B5AB1] to-[#784ca1] hover:bg-[#7a4f9b] text-white font-bold text-lg shadow-[0_12px_32px_rgba(139,90,177,0.25)] hover:shadow-[0_16px_40px_rgba(139,90,177,0.35)] active:scale-[0.98] transition-all flex items-center justify-center gap-3 disabled:opacity-75"
|
|
165
|
+
onClick={() => handleAllow()}
|
|
166
|
+
disabled={status === "requesting"}
|
|
167
|
+
>
|
|
168
|
+
{status === "requesting" ? (
|
|
169
|
+
<>
|
|
170
|
+
<div className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
|
171
|
+
<span>Connecting...</span>
|
|
172
|
+
</>
|
|
173
|
+
) : (
|
|
174
|
+
"Yes, Notify Me"
|
|
175
|
+
)}
|
|
176
|
+
</button>
|
|
177
|
+
<button
|
|
178
|
+
className="w-full rounded-[20px] h-14 bg-white dark:bg-neutral-800 border-2 border-neutral-100 dark:border-neutral-800 text-neutral-500 dark:text-neutral-300 font-bold text-lg hover:bg-neutral-50 dark:hover:bg-neutral-700/50 hover:text-neutral-900 dark:hover:text-white transition-all active:scale-[0.98]"
|
|
179
|
+
onClick={handleDismiss}
|
|
180
|
+
>
|
|
181
|
+
Maybe Later
|
|
182
|
+
</button>
|
|
183
|
+
</div>
|
|
184
|
+
)}
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export default PushNotificationManager
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Popover, PopoverPanel, Transition } from "@headlessui/react"
|
|
4
|
+
import { XMark } from "@medusajs/icons"
|
|
5
|
+
import { Fragment, useState, useEffect, useRef } from "react"
|
|
6
|
+
import { useSearchParams } from "next/navigation"
|
|
7
|
+
import Image from "next/image"
|
|
8
|
+
import LocalizedClientLink from "@modules/common/components/localized-client-link"
|
|
9
|
+
|
|
10
|
+
type SearchPanelProps = {
|
|
11
|
+
countryCode: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const SearchPanel = ({ countryCode }: SearchPanelProps) => {
|
|
15
|
+
const searchParams = useSearchParams()
|
|
16
|
+
const q = searchParams.get("q") || ""
|
|
17
|
+
const [searchQuery, setSearchQuery] = useState(q)
|
|
18
|
+
const prevOpenRef = useRef(false)
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
setSearchQuery(q)
|
|
22
|
+
}, [q])
|
|
23
|
+
|
|
24
|
+
// Cleanup on unmount
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
return () => {
|
|
27
|
+
document.body.style.overflow = "unset"
|
|
28
|
+
}
|
|
29
|
+
}, [])
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className="h-full">
|
|
33
|
+
<div className="flex items-center h-full">
|
|
34
|
+
<Popover className="h-full flex">
|
|
35
|
+
{({ open, close }) => {
|
|
36
|
+
// Lock body scroll when panel opens/closes
|
|
37
|
+
if (open !== prevOpenRef.current) {
|
|
38
|
+
prevOpenRef.current = open
|
|
39
|
+
if (open) {
|
|
40
|
+
document.body.style.overflow = "hidden"
|
|
41
|
+
} else {
|
|
42
|
+
document.body.style.overflow = "unset"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<>
|
|
48
|
+
<Popover.Button
|
|
49
|
+
data-testid="search-panel-button"
|
|
50
|
+
className="relative h-full flex items-center transition-all ease-out duration-200 focus:outline-none hover:opacity-80"
|
|
51
|
+
>
|
|
52
|
+
<Image
|
|
53
|
+
src="/Search.svg"
|
|
54
|
+
alt="Search"
|
|
55
|
+
width={26}
|
|
56
|
+
height={26}
|
|
57
|
+
className="w-5 h-5"
|
|
58
|
+
/>
|
|
59
|
+
</Popover.Button>
|
|
60
|
+
|
|
61
|
+
{open && (
|
|
62
|
+
<div
|
|
63
|
+
className="fixed inset-0 z-[50] bg-black/20 backdrop-blur-sm pointer-events-auto"
|
|
64
|
+
onClick={close}
|
|
65
|
+
data-testid="search-panel-backdrop"
|
|
66
|
+
/>
|
|
67
|
+
)}
|
|
68
|
+
|
|
69
|
+
<Transition
|
|
70
|
+
show={open}
|
|
71
|
+
as={Fragment}
|
|
72
|
+
enter="transition ease-out duration-200"
|
|
73
|
+
enterFrom="translate-x-full opacity-0"
|
|
74
|
+
enterTo="translate-x-0 opacity-100"
|
|
75
|
+
leave="transition ease-in duration-150"
|
|
76
|
+
leaveFrom="translate-x-0 opacity-100"
|
|
77
|
+
leaveTo="translate-x-full opacity-0"
|
|
78
|
+
>
|
|
79
|
+
<PopoverPanel className="fixed right-0 top-0 h-full w-full max-w-[400px] min-[300px]:max-w-[300px] min-[400px]:max-w-[320px] min-[640px]:max-w-[400px] bg-page-bg shadow-2xl z-[51] flex flex-col">
|
|
80
|
+
<div className="flex flex-col h-full">
|
|
81
|
+
<div className="flex items-center justify-between p-6 border-b border-[var(--color-border)]">
|
|
82
|
+
<h2 className="text-xl font-bold text-heading">Search</h2>
|
|
83
|
+
<button
|
|
84
|
+
data-testid="close-search-button"
|
|
85
|
+
onClick={close}
|
|
86
|
+
className="p-2 hover:bg-surface-muted transition-colors"
|
|
87
|
+
>
|
|
88
|
+
<XMark className="w-5 h-5 text-muted" />
|
|
89
|
+
</button>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div className="p-6 border-b border-[var(--color-border)]">
|
|
93
|
+
<div className="relative">
|
|
94
|
+
<input
|
|
95
|
+
type="text"
|
|
96
|
+
placeholder="Search products..."
|
|
97
|
+
value={searchQuery}
|
|
98
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
99
|
+
className="w-full pl-4 pr-12 py-3 border border-[var(--color-border)] bg-surface-muted focus:bg-surface focus:outline-none focus:ring-2 focus:ring-brand-accent transition-all"
|
|
100
|
+
autoFocus
|
|
101
|
+
/>
|
|
102
|
+
<LocalizedClientLink
|
|
103
|
+
href={`/store?q=${encodeURIComponent(searchQuery)}`}
|
|
104
|
+
onClick={close}
|
|
105
|
+
className="absolute right-3 top-1/2 -translate-y-1/2 p-2 hover:bg-surface-muted transition-colors"
|
|
106
|
+
>
|
|
107
|
+
<Image
|
|
108
|
+
src="/Search.svg"
|
|
109
|
+
alt="Search"
|
|
110
|
+
width={20}
|
|
111
|
+
height={20}
|
|
112
|
+
className="w-5 h-5"
|
|
113
|
+
/>
|
|
114
|
+
</LocalizedClientLink>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div className="flex-1 overflow-y-auto p-6">
|
|
119
|
+
<div className="flex flex-col items-center justify-center py-12 text-center">
|
|
120
|
+
<p className="text-muted">Start typing to search...</p>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</PopoverPanel>
|
|
125
|
+
</Transition>
|
|
126
|
+
</>
|
|
127
|
+
)
|
|
128
|
+
}}
|
|
129
|
+
</Popover>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export default SearchPanel
|
|
136
|
+
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Popover, PopoverPanel, Transition } from "@headlessui/react"
|
|
4
|
+
import { ArrowRightMini, XMark } from "@medusajs/icons"
|
|
5
|
+
import { Text, clx, useToggleState } from "@medusajs/ui"
|
|
6
|
+
import { Fragment } from "react"
|
|
7
|
+
|
|
8
|
+
import LocalizedClientLink from "@modules/common/components/localized-client-link"
|
|
9
|
+
import CountrySelect from "../country-select"
|
|
10
|
+
import LanguageSelect from "../language-select"
|
|
11
|
+
import { HttpTypes } from "@medusajs/types"
|
|
12
|
+
import { Locale } from "@core/data/locales"
|
|
13
|
+
|
|
14
|
+
const SideMenuItems = {
|
|
15
|
+
Home: "/",
|
|
16
|
+
Store: "/store",
|
|
17
|
+
Account: "/account",
|
|
18
|
+
Cart: "/cart",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type SideMenuProps = {
|
|
22
|
+
regions: HttpTypes.StoreRegion[] | null
|
|
23
|
+
locales: Locale[] | null
|
|
24
|
+
currentLocale: string | null
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const SideMenu = ({ regions, locales, currentLocale }: SideMenuProps) => {
|
|
28
|
+
const countryToggleState = useToggleState()
|
|
29
|
+
const languageToggleState = useToggleState()
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className="h-full">
|
|
33
|
+
<div className="flex items-center h-full">
|
|
34
|
+
<Popover className="h-full flex">
|
|
35
|
+
{({ open, close }) => (
|
|
36
|
+
<>
|
|
37
|
+
<div className="relative flex h-full">
|
|
38
|
+
<Popover.Button
|
|
39
|
+
data-testid="nav-menu-button"
|
|
40
|
+
className="relative h-full flex items-center transition-all ease-out duration-200 focus:outline-none hover:text-ui-fg-base"
|
|
41
|
+
>
|
|
42
|
+
Menu
|
|
43
|
+
</Popover.Button>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
{open && (
|
|
47
|
+
<div
|
|
48
|
+
className="fixed inset-0 z-[50] bg-black/0 pointer-events-auto"
|
|
49
|
+
onClick={close}
|
|
50
|
+
data-testid="side-menu-backdrop"
|
|
51
|
+
/>
|
|
52
|
+
)}
|
|
53
|
+
|
|
54
|
+
<Transition
|
|
55
|
+
show={open}
|
|
56
|
+
as={Fragment}
|
|
57
|
+
enter="transition ease-out duration-150"
|
|
58
|
+
enterFrom="opacity-0"
|
|
59
|
+
enterTo="opacity-100 backdrop-blur-2xl"
|
|
60
|
+
leave="transition ease-in duration-150"
|
|
61
|
+
leaveFrom="opacity-100 backdrop-blur-2xl"
|
|
62
|
+
leaveTo="opacity-0"
|
|
63
|
+
>
|
|
64
|
+
<PopoverPanel className="flex flex-col absolute w-full pr-4 sm:pr-0 sm:w-1/3 2xl:w-1/4 sm:min-w-min h-[calc(100vh-1rem)] z-[51] inset-x-0 text-sm text-ui-fg-on-color m-2 backdrop-blur-2xl">
|
|
65
|
+
<div
|
|
66
|
+
data-testid="nav-menu-popup"
|
|
67
|
+
className="flex flex-col h-full bg-[rgba(3,7,18,0.5)] rounded-rounded justify-between p-6"
|
|
68
|
+
>
|
|
69
|
+
<div className="flex justify-end" id="xmark">
|
|
70
|
+
<button data-testid="close-menu-button" onClick={close}>
|
|
71
|
+
<XMark />
|
|
72
|
+
</button>
|
|
73
|
+
</div>
|
|
74
|
+
<ul className="flex flex-col gap-6 items-start justify-start">
|
|
75
|
+
{Object.entries(SideMenuItems).map(([name, href]) => {
|
|
76
|
+
return (
|
|
77
|
+
<li key={name}>
|
|
78
|
+
<LocalizedClientLink
|
|
79
|
+
href={href}
|
|
80
|
+
className="text-3xl leading-10 hover:text-ui-fg-disabled"
|
|
81
|
+
onClick={close}
|
|
82
|
+
data-testid={`${name.toLowerCase()}-link`}
|
|
83
|
+
>
|
|
84
|
+
{name}
|
|
85
|
+
</LocalizedClientLink>
|
|
86
|
+
</li>
|
|
87
|
+
)
|
|
88
|
+
})}
|
|
89
|
+
</ul>
|
|
90
|
+
<div className="flex flex-col gap-y-6">
|
|
91
|
+
{!!locales?.length && (
|
|
92
|
+
<div
|
|
93
|
+
className="flex justify-between"
|
|
94
|
+
onMouseEnter={languageToggleState.open}
|
|
95
|
+
onMouseLeave={languageToggleState.close}
|
|
96
|
+
>
|
|
97
|
+
<LanguageSelect
|
|
98
|
+
toggleState={languageToggleState}
|
|
99
|
+
locales={locales}
|
|
100
|
+
currentLocale={currentLocale}
|
|
101
|
+
/>
|
|
102
|
+
<ArrowRightMini
|
|
103
|
+
className={clx(
|
|
104
|
+
"transition-transform duration-150",
|
|
105
|
+
languageToggleState.state ? "-rotate-90" : ""
|
|
106
|
+
)}
|
|
107
|
+
/>
|
|
108
|
+
</div>
|
|
109
|
+
)}
|
|
110
|
+
<div
|
|
111
|
+
className="flex justify-between"
|
|
112
|
+
onMouseEnter={countryToggleState.open}
|
|
113
|
+
onMouseLeave={countryToggleState.close}
|
|
114
|
+
>
|
|
115
|
+
{regions && (
|
|
116
|
+
<CountrySelect
|
|
117
|
+
toggleState={countryToggleState}
|
|
118
|
+
regions={regions}
|
|
119
|
+
/>
|
|
120
|
+
)}
|
|
121
|
+
<ArrowRightMini
|
|
122
|
+
className={clx(
|
|
123
|
+
"transition-transform duration-150",
|
|
124
|
+
countryToggleState.state ? "-rotate-90" : ""
|
|
125
|
+
)}
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
<Text className="flex justify-between txt-compact-small">
|
|
129
|
+
© {new Date().getFullYear()} Chocomelon. All rights
|
|
130
|
+
reserved.
|
|
131
|
+
</Text>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</PopoverPanel>
|
|
135
|
+
</Transition>
|
|
136
|
+
</>
|
|
137
|
+
)}
|
|
138
|
+
</Popover>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export default SideMenu
|