@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,389 @@
|
|
|
1
|
+
|
|
2
|
+
"use client"
|
|
3
|
+
|
|
4
|
+
import { useActionState, useEffect, useState } from "react"
|
|
5
|
+
import { HttpTypes } from "@medusajs/types"
|
|
6
|
+
import { createSwapRequest } from "@core/data/swaps"
|
|
7
|
+
import { listProducts } from "@core/data/products"
|
|
8
|
+
import { enhanceItemsWithReturnStatus } from "@core/util/returns"
|
|
9
|
+
import { Button, Heading, Text, clx, Select, Textarea } from "@medusajs/ui"
|
|
10
|
+
import LocalizedClientLink from "@modules/common/components/localized-client-link"
|
|
11
|
+
import Thumbnail from "@modules/products/components/thumbnail"
|
|
12
|
+
import { convertToLocale } from "@core/util/money"
|
|
13
|
+
import { Minus, Plus } from "@medusajs/icons"
|
|
14
|
+
import { sdk } from "@core/config"
|
|
15
|
+
|
|
16
|
+
type ExchangeRequestTemplateProps = {
|
|
17
|
+
order: HttpTypes.StoreOrder
|
|
18
|
+
returnReasons: HttpTypes.StoreReturnReason[]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const initialState = {
|
|
22
|
+
success: false,
|
|
23
|
+
error: null,
|
|
24
|
+
swap: null,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const ExchangeRequestTemplate = ({
|
|
28
|
+
order,
|
|
29
|
+
returnReasons,
|
|
30
|
+
}: ExchangeRequestTemplateProps) => {
|
|
31
|
+
// We reuse the enhancement logic to know which items are returnable/exchangeable
|
|
32
|
+
const [items, setItems] = useState(enhanceItemsWithReturnStatus(order.items || []))
|
|
33
|
+
const [enrichedProducts, setEnrichedProducts] = useState<Record<string, any>>({})
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const fetchProductVariants = async () => {
|
|
37
|
+
const productIds = Array.from(new Set(items.map(i => i.product_id || (i.variant as any)?.product_id).filter(Boolean))) as string[]
|
|
38
|
+
|
|
39
|
+
if (productIds.length > 0) {
|
|
40
|
+
try {
|
|
41
|
+
const { response: { products } } = await listProducts({
|
|
42
|
+
regionId: order.region_id || undefined,
|
|
43
|
+
queryParams: {
|
|
44
|
+
id: productIds,
|
|
45
|
+
fields: "*variants"
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const productMap = products.reduce((acc: any, p: any) => {
|
|
50
|
+
acc[p.id] = p
|
|
51
|
+
return acc
|
|
52
|
+
}, {})
|
|
53
|
+
|
|
54
|
+
setEnrichedProducts(productMap)
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// Silence error
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fetchProductVariants()
|
|
62
|
+
}, [items, order.region_id])
|
|
63
|
+
|
|
64
|
+
// State for selected items to exchange
|
|
65
|
+
const [selectedExchange, setSelectedExchange] = useState<Record<string, {
|
|
66
|
+
return_item_id: string
|
|
67
|
+
quantity: number
|
|
68
|
+
reason: string
|
|
69
|
+
new_variant_id: string | null
|
|
70
|
+
note?: string
|
|
71
|
+
}>>({})
|
|
72
|
+
|
|
73
|
+
const [state, formAction] = useActionState(createSwapRequest, initialState)
|
|
74
|
+
|
|
75
|
+
const handleSubmit = (formData: FormData) => {
|
|
76
|
+
const exchangeItems = Object.values(selectedExchange).filter(e => e.new_variant_id)
|
|
77
|
+
|
|
78
|
+
if (exchangeItems.length === 0) {
|
|
79
|
+
// This should be handled by button disabled state, but safety first
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const return_items = exchangeItems.map(e => ({
|
|
84
|
+
item_id: e.return_item_id,
|
|
85
|
+
quantity: e.quantity,
|
|
86
|
+
reason_id: e.reason,
|
|
87
|
+
// The plugin might want the original variant_id too
|
|
88
|
+
variant_id: items.find(i => i.id === e.return_item_id)?.variant_id
|
|
89
|
+
}))
|
|
90
|
+
|
|
91
|
+
const new_items = exchangeItems.map(e => ({
|
|
92
|
+
variant_id: e.new_variant_id!,
|
|
93
|
+
quantity: e.quantity
|
|
94
|
+
}))
|
|
95
|
+
|
|
96
|
+
formData.append("order_id", order.id)
|
|
97
|
+
formData.append("return_items", JSON.stringify(return_items))
|
|
98
|
+
formData.append("new_items", JSON.stringify(new_items))
|
|
99
|
+
// We can append a global note/reason if needed, but per-item is better handled by json
|
|
100
|
+
|
|
101
|
+
formAction(formData)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const handleQuantityChange = (itemId: string, quantity: number) => {
|
|
105
|
+
if (quantity <= 0) {
|
|
106
|
+
const newState = { ...selectedExchange }
|
|
107
|
+
delete newState[itemId]
|
|
108
|
+
setSelectedExchange(newState)
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const item = items.find(i => i.id === itemId)
|
|
113
|
+
const maxQty = item?.returnable_quantity || 0
|
|
114
|
+
const finalQty = Math.min(quantity, maxQty)
|
|
115
|
+
|
|
116
|
+
setSelectedExchange(prev => ({
|
|
117
|
+
...prev,
|
|
118
|
+
[itemId]: {
|
|
119
|
+
...(prev[itemId] || {
|
|
120
|
+
return_item_id: itemId,
|
|
121
|
+
reason: returnReasons[0]?.label || "Size exchange",
|
|
122
|
+
new_variant_id: null
|
|
123
|
+
}),
|
|
124
|
+
quantity: finalQty
|
|
125
|
+
}
|
|
126
|
+
}))
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const isGuest = !order.customer_id
|
|
130
|
+
const backToOrderLink = isGuest ? `/orders/${order.id}` : `/account/orders`
|
|
131
|
+
|
|
132
|
+
if (state.success && state.swap) {
|
|
133
|
+
const exchangeReference =
|
|
134
|
+
state.swap.display_id ||
|
|
135
|
+
state.swap.id ||
|
|
136
|
+
state.swap.swap_id ||
|
|
137
|
+
`EX-${order.display_id}`
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<div className="max-w-md mx-auto pt-16 sm:pt-20 pb-6 sm:pb-8 px-4 animate-in fade-in slide-in-from-bottom-4 duration-500">
|
|
141
|
+
<div className="bg-white border border-gray-200 rounded-2xl shadow-sm p-5 sm:p-6 space-y-4">
|
|
142
|
+
<div className="flex flex-col items-center text-center space-y-2">
|
|
143
|
+
<div className="w-14 h-14 bg-brand-accent-muted rounded-full flex items-center justify-center shadow-sm border border-brand-accent-border">
|
|
144
|
+
<svg
|
|
145
|
+
className="w-7 h-7 text-brand-accent"
|
|
146
|
+
viewBox="0 0 24 24"
|
|
147
|
+
fill="none"
|
|
148
|
+
stroke="currentColor"
|
|
149
|
+
strokeWidth="2.5"
|
|
150
|
+
strokeLinecap="round"
|
|
151
|
+
strokeLinejoin="round"
|
|
152
|
+
aria-hidden="true"
|
|
153
|
+
>
|
|
154
|
+
<path d="M7 16V4m0 0L3 8m4-4 4 4" />
|
|
155
|
+
<path d="M17 8v12m0 0 4-4m-4 4-4-4" />
|
|
156
|
+
</svg>
|
|
157
|
+
</div>
|
|
158
|
+
<Heading level="h1" className="text-2xl sm:text-3xl font-extrabold text-[#0D1B3E] tracking-tight">
|
|
159
|
+
Exchange Submitted!
|
|
160
|
+
</Heading>
|
|
161
|
+
<Text className="text-gray-500 text-sm sm:text-base max-w-sm leading-snug">
|
|
162
|
+
Your exchange for order{" "}
|
|
163
|
+
<span className="text-[#0D1B3E] font-bold">#{order.display_id}</span>{" "}
|
|
164
|
+
has been received. You'll get an email with return label and instructions.
|
|
165
|
+
</Text>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<div className="space-y-3">
|
|
169
|
+
<div className="bg-gray-50/50 rounded-xl px-4 py-3 flex flex-col items-center gap-1 border border-gray-200">
|
|
170
|
+
<span className="text-[10px] font-bold text-gray-400 uppercase tracking-[0.15em]">
|
|
171
|
+
Exchange Reference
|
|
172
|
+
</span>
|
|
173
|
+
<span className="text-sm font-mono font-bold text-[#0D1B3E] break-all select-all text-center">
|
|
174
|
+
{exchangeReference}
|
|
175
|
+
</span>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
<div className="bg-brand-accent-muted/40 rounded-xl px-3 py-2.5 border border-brand-accent-border flex items-center gap-2.5 text-left">
|
|
179
|
+
<div className="w-7 h-7 rounded-lg bg-brand-accent/10 flex items-center justify-center shrink-0">
|
|
180
|
+
<svg className="w-3.5 h-3.5 text-brand-accent" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2.5">
|
|
181
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
|
182
|
+
</svg>
|
|
183
|
+
</div>
|
|
184
|
+
<p className="text-xs sm:text-sm text-gray-600 leading-snug">
|
|
185
|
+
Check your inbox for next steps. Keep this reference for support.
|
|
186
|
+
</p>
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
<LocalizedClientLink href={backToOrderLink} className="block">
|
|
190
|
+
<Button className="w-full rounded-xl bg-[#0D1B3E] hover:bg-black text-inverse h-11 font-bold text-sm shadow-md shadow-gray-200/80 transition-all active:scale-95">
|
|
191
|
+
Back to Order Details
|
|
192
|
+
</Button>
|
|
193
|
+
</LocalizedClientLink>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<div className="max-w-4xl mx-auto py-16 px-6">
|
|
202
|
+
<div className="mb-8 sm:mb-12">
|
|
203
|
+
<LocalizedClientLink href={`/orders/${order.id}`} className="text-[10px] sm:text-xs text-gray-400 hover:text-brand-accent mb-6 inline-flex gap-2 items-center font-bold tracking-[0.2em] transition-colors uppercase">
|
|
204
|
+
<svg width="14" height="14" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2.5"><path d="M15 19l-7-7 7-7" /></svg>
|
|
205
|
+
BACK TO ORDER #{order.display_id}
|
|
206
|
+
</LocalizedClientLink>
|
|
207
|
+
<Heading level="h1" className="text-3xl sm:text-4xl md:text-5xl font-extrabold tracking-tight text-[#0D1B3E]">Exchange Items</Heading>
|
|
208
|
+
<p className="text-gray-400 font-medium text-sm sm:text-base mt-2">Select the items you'd like to exchange and choose your replacement options below.</p>
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
<form action={handleSubmit} className="space-y-8">
|
|
212
|
+
{state.error && (
|
|
213
|
+
<div className="p-4 bg-red-50 border border-red-100 rounded-xl text-red-700 text-sm flex items-start gap-3 animate-in fade-in slide-in-from-top-2">
|
|
214
|
+
<svg className="w-5 h-5 mt-0.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
|
|
215
|
+
<span className="font-medium">{state.error}</span>
|
|
216
|
+
</div>
|
|
217
|
+
)}
|
|
218
|
+
|
|
219
|
+
<div className="space-y-4">
|
|
220
|
+
{items.map((item) => {
|
|
221
|
+
const isSelected = !!selectedExchange[item.id]
|
|
222
|
+
const productId = item.product_id || (item.variant as any)?.product_id
|
|
223
|
+
const product = enrichedProducts[productId] || (item.variant as any)?.product || (item as any).product
|
|
224
|
+
const canExchange = item.returnable_quantity > 0
|
|
225
|
+
|
|
226
|
+
return (
|
|
227
|
+
<div key={item.id} className={clx(
|
|
228
|
+
"group border rounded-3xl p-4 sm:p-5 transition-all duration-300 relative",
|
|
229
|
+
isSelected ? "border-brand-accent shadow-lg bg-white" :
|
|
230
|
+
(canExchange ? "border-gray-200 hover:border-gray-300 bg-white" : "border-gray-100 opacity-50 bg-gray-50/50 grayscale pointer-events-none")
|
|
231
|
+
)}>
|
|
232
|
+
<div className="flex gap-4 sm:gap-6">
|
|
233
|
+
{/* Left: Thumbnail & Checkbox */}
|
|
234
|
+
<div className="relative shrink-0">
|
|
235
|
+
<div
|
|
236
|
+
className="w-20 h-24 sm:w-24 sm:h-32 bg-gray-50 rounded-2xl overflow-hidden border border-gray-100 cursor-pointer"
|
|
237
|
+
onClick={() => canExchange && handleQuantityChange(item.id, isSelected ? 0 : 1)}
|
|
238
|
+
>
|
|
239
|
+
<Thumbnail thumbnail={item.thumbnail} size="full" className="w-full h-full object-cover" />
|
|
240
|
+
</div>
|
|
241
|
+
<div
|
|
242
|
+
className={clx(
|
|
243
|
+
"absolute -top-2 -left-2 w-8 h-8 rounded-full border-2 flex items-center justify-center transition-all duration-300 cursor-pointer shadow-sm z-20",
|
|
244
|
+
isSelected ? "bg-brand-accent border-white scale-110" : "bg-white border-gray-200"
|
|
245
|
+
)}
|
|
246
|
+
onClick={() => canExchange && handleQuantityChange(item.id, isSelected ? 0 : 1)}
|
|
247
|
+
>
|
|
248
|
+
{isSelected && <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M10 3L4.5 8.5L2 6" stroke="white" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" /></svg>}
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
|
|
252
|
+
{/* Middle: Info */}
|
|
253
|
+
<div className="flex-1 flex flex-col justify-between py-1 min-w-0">
|
|
254
|
+
<div className="space-y-1">
|
|
255
|
+
<h3 className="text-sm sm:text-base font-bold text-heading line-clamp-1">{item.title}</h3>
|
|
256
|
+
<p className="text-xs font-medium text-gray-500">{item.variant?.title}</p>
|
|
257
|
+
<div className="mt-1">
|
|
258
|
+
<span className="text-brand-accent font-bold text-sm">
|
|
259
|
+
{convertToLocale({ amount: item.unit_price, currency_code: order.currency_code })}
|
|
260
|
+
</span>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
{isSelected && (
|
|
265
|
+
<div className="flex items-center gap-3">
|
|
266
|
+
<div className="flex items-center bg-gray-50 rounded-xl border border-gray-100 p-1">
|
|
267
|
+
<button
|
|
268
|
+
type="button"
|
|
269
|
+
className="w-7 h-7 flex items-center justify-center rounded-lg hover:bg-white text-gray-400 hover:text-heading transition-all shadow-sm"
|
|
270
|
+
onClick={() => handleQuantityChange(item.id, (selectedExchange[item.id]?.quantity || 1) - 1)}
|
|
271
|
+
>
|
|
272
|
+
<Minus className="w-3" />
|
|
273
|
+
</button>
|
|
274
|
+
<span className="w-8 text-center text-xs font-bold tabular-nums">{selectedExchange[item.id]?.quantity || 0}</span>
|
|
275
|
+
<button
|
|
276
|
+
type="button"
|
|
277
|
+
className="w-7 h-7 flex items-center justify-center rounded-lg hover:bg-white text-gray-400 hover:text-heading transition-all shadow-sm disabled:opacity-50"
|
|
278
|
+
onClick={() => handleQuantityChange(item.id, (selectedExchange[item.id]?.quantity || 0) + 1)}
|
|
279
|
+
disabled={(selectedExchange[item.id]?.quantity || 0) >= item.returnable_quantity}
|
|
280
|
+
>
|
|
281
|
+
<Plus className="w-3" />
|
|
282
|
+
</button>
|
|
283
|
+
</div>
|
|
284
|
+
<span className="text-[10px] font-bold text-gray-400 uppercase">Qty to exchange</span>
|
|
285
|
+
</div>
|
|
286
|
+
)}
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
289
|
+
|
|
290
|
+
{/* Expandable Action Area */}
|
|
291
|
+
<div className={clx(
|
|
292
|
+
"grid transition-all duration-300 ease-in-out",
|
|
293
|
+
isSelected ? "grid-rows-[1fr] opacity-100 mt-4 pt-4 border-t border-gray-50" : "grid-rows-[0fr] opacity-0 overflow-hidden"
|
|
294
|
+
)}>
|
|
295
|
+
<div className="min-h-0 flex flex-col gap-4 pb-4">
|
|
296
|
+
<div className="flex flex-col sm:flex-row gap-4 max-w-2xl">
|
|
297
|
+
<div className="w-full sm:w-52 space-y-1.5">
|
|
298
|
+
<label className="text-[10px] font-bold text-gray-400 uppercase tracking-wider shrink-0">Reason for exchange:</label>
|
|
299
|
+
<Select
|
|
300
|
+
value={selectedExchange[item.id]?.reason || ""}
|
|
301
|
+
onValueChange={(val) => setSelectedExchange(prev => ({
|
|
302
|
+
...prev,
|
|
303
|
+
[item.id]: { ...prev[item.id], reason: val }
|
|
304
|
+
}))}
|
|
305
|
+
>
|
|
306
|
+
<Select.Trigger className="rounded-xl h-10 bg-gray-50/50 border-gray-100 text-xs font-medium">
|
|
307
|
+
<Select.Value placeholder="Select reason" />
|
|
308
|
+
</Select.Trigger>
|
|
309
|
+
<Select.Content className="z-[9999]" position="popper">
|
|
310
|
+
{returnReasons.map(r => (
|
|
311
|
+
<Select.Item key={r.id} value={r.label}>{r.label}</Select.Item>
|
|
312
|
+
))}
|
|
313
|
+
<Select.Item value="Other">Other</Select.Item>
|
|
314
|
+
</Select.Content>
|
|
315
|
+
</Select>
|
|
316
|
+
</div>
|
|
317
|
+
|
|
318
|
+
<div className="w-full sm:w-52 space-y-1.5">
|
|
319
|
+
<label className="text-[10px] font-bold text-gray-400 uppercase tracking-wider shrink-0">Select replacement</label>
|
|
320
|
+
<Select
|
|
321
|
+
value={selectedExchange[item.id]?.new_variant_id || ""}
|
|
322
|
+
onValueChange={(val) => setSelectedExchange(prev => ({
|
|
323
|
+
...prev,
|
|
324
|
+
[item.id]: { ...prev[item.id], new_variant_id: val }
|
|
325
|
+
}))}
|
|
326
|
+
>
|
|
327
|
+
<Select.Trigger className="rounded-xl h-10 bg-gray-50/50 border-gray-100 text-xs font-medium">
|
|
328
|
+
<Select.Value placeholder={product?.variants ? "Choose variant" : "Loading..."} />
|
|
329
|
+
</Select.Trigger>
|
|
330
|
+
<Select.Content className="z-[9999]" position="popper">
|
|
331
|
+
{product?.variants?.filter((v: any) => v.id !== item.variant_id).map((v: any) => {
|
|
332
|
+
const inStock = v.manage_inventory === false || v.allow_backorder || (v.inventory_quantity !== null && v.inventory_quantity > 0);
|
|
333
|
+
return (
|
|
334
|
+
<Select.Item
|
|
335
|
+
key={v.id}
|
|
336
|
+
value={v.id}
|
|
337
|
+
disabled={!inStock}
|
|
338
|
+
className={clx(!inStock && "opacity-40 select-none", "transition-opacity")}
|
|
339
|
+
>
|
|
340
|
+
{v.title} {!inStock ? "(Out of stock)" : ""}
|
|
341
|
+
</Select.Item>
|
|
342
|
+
)
|
|
343
|
+
})}
|
|
344
|
+
</Select.Content>
|
|
345
|
+
</Select>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
)
|
|
352
|
+
})}
|
|
353
|
+
</div>
|
|
354
|
+
{/* OVERALL NOTE SECTION */}
|
|
355
|
+
<div className="space-y-4 animate-in fade-in slide-in-from-bottom-4 duration-500">
|
|
356
|
+
<div className="flex items-center gap-3 px-2">
|
|
357
|
+
<div className="w-6 h-6 rounded-lg bg-brand-accent text-inverse flex items-center justify-center font-bold text-[10px]">!</div>
|
|
358
|
+
<h2 className="text-sm font-bold text-[#0D1B3E] uppercase tracking-wider">Additional Details (Optional)</h2>
|
|
359
|
+
</div>
|
|
360
|
+
<div className="bg-white rounded-[2.5rem] border border-gray-100 shadow-sm p-4 sm:p-8">
|
|
361
|
+
<textarea
|
|
362
|
+
name="note"
|
|
363
|
+
placeholder="Tell us any extra details about this exchange..."
|
|
364
|
+
className="w-full min-h-[120px] rounded-2xl border-gray-100 bg-gray-50/50 p-4 text-sm font-medium text-gray-700 outline-none focus:border-brand-accent/30 focus:ring-0 transition-all placeholder:text-gray-300 resize-none font-sans"
|
|
365
|
+
/>
|
|
366
|
+
</div>
|
|
367
|
+
</div>
|
|
368
|
+
|
|
369
|
+
<div className="flex flex-col sm:flex-row items-center justify-end gap-3 pt-8 border-t border-gray-100 mt-8 mb-12">
|
|
370
|
+
<LocalizedClientLink href={`/orders/${order.id}`} className="w-full sm:w-auto">
|
|
371
|
+
<Button variant="secondary" type="button" className="w-full h-11 rounded-3xl px-10 font-bold text-gray-400 border-none hover:bg-gray-50 transition-all uppercase tracking-widest text-[10px]">
|
|
372
|
+
Cancel
|
|
373
|
+
</Button>
|
|
374
|
+
</LocalizedClientLink>
|
|
375
|
+
|
|
376
|
+
<Button
|
|
377
|
+
type="submit"
|
|
378
|
+
disabled={Object.values(selectedExchange).length === 0 || Object.values(selectedExchange).some(e => !e.new_variant_id || !e.reason)}
|
|
379
|
+
className="w-full sm:w-auto h-11 rounded-3xl bg-[#0D1B3E] hover:bg-black text-inverse px-12 font-black text-xs uppercase tracking-widest shadow-lg shadow-gray-200 transition-all active:scale-95 disabled:opacity-20"
|
|
380
|
+
>
|
|
381
|
+
{Object.values(selectedExchange).length === 0 ? "Select items" : Object.values(selectedExchange).some(e => !e.new_variant_id) ? "Choose replacement" : Object.values(selectedExchange).some(e => !e.reason) ? "Select reason" : "Confirm Exchange Request"}
|
|
382
|
+
</Button>
|
|
383
|
+
</div>
|
|
384
|
+
</form>
|
|
385
|
+
</div>
|
|
386
|
+
)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export default ExchangeRequestTemplate
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { useSearchParams, useRouter } from "next/navigation"
|
|
4
|
+
import { useEffect, useState } from "react"
|
|
5
|
+
import { listGuestOrders } from "@core/data/guest"
|
|
6
|
+
import OrderOverview from "@modules/account/components/order-overview"
|
|
7
|
+
import { Spinner } from "@medusajs/icons"
|
|
8
|
+
import { Heading, Text } from "@medusajs/ui"
|
|
9
|
+
|
|
10
|
+
const GuestOrdersTemplate = () => {
|
|
11
|
+
const router = useRouter()
|
|
12
|
+
// We can read 'token' from URL query if verify API passed it, or sessionStorage/cookie
|
|
13
|
+
// For security, HttpOnly cookie is best, but here we assume the login modal
|
|
14
|
+
// redirected with a token in URL or stored it in document.cookie as per previous context.
|
|
15
|
+
// Let's try to get it from a cookie named 'guest_token'.
|
|
16
|
+
|
|
17
|
+
const [loading, setLoading] = useState(true)
|
|
18
|
+
const [error, setError] = useState<string | null>(null)
|
|
19
|
+
const [orders, setOrders] = useState<any[]>([])
|
|
20
|
+
|
|
21
|
+
const getCookie = (name: string) => {
|
|
22
|
+
const value = `; ${document.cookie}`;
|
|
23
|
+
const parts = value.split(`; ${name}=`);
|
|
24
|
+
if (parts.length === 2) return parts.pop()?.split(';').shift();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const fetchOrders = async () => {
|
|
29
|
+
const token = getCookie("_medusa_guest_token")
|
|
30
|
+
|
|
31
|
+
if (!token) {
|
|
32
|
+
setError("No verification token found. Please verify your email again.")
|
|
33
|
+
setLoading(false)
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const data = await listGuestOrders(token)
|
|
39
|
+
if (data && data.orders) {
|
|
40
|
+
// Sort orders by created_at descending (latest first)
|
|
41
|
+
const sortedOrders = [...data.orders].sort((a: any, b: any) => {
|
|
42
|
+
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
|
43
|
+
})
|
|
44
|
+
setOrders(sortedOrders)
|
|
45
|
+
}
|
|
46
|
+
} catch (err: any) {
|
|
47
|
+
setError(err.message || "Failed to load orders")
|
|
48
|
+
} finally {
|
|
49
|
+
setLoading(false)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fetchOrders()
|
|
54
|
+
}, [])
|
|
55
|
+
|
|
56
|
+
if (loading) {
|
|
57
|
+
return (
|
|
58
|
+
<div className="flex justify-center items-center py-20">
|
|
59
|
+
<Spinner className="animate-spin text-brand-accent" />
|
|
60
|
+
</div>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (error) {
|
|
65
|
+
return (
|
|
66
|
+
<div className="flex flex-col items-center justify-center py-20 px-4 text-center">
|
|
67
|
+
<h1 className="text-2xl font-bold mb-4">Access Denied</h1>
|
|
68
|
+
<p className="text-gray-600 mb-6">{error}</p>
|
|
69
|
+
<button
|
|
70
|
+
onClick={() => router.push("/account")}
|
|
71
|
+
className="bg-brand-accent text-inverse px-6 py-2 rounded-full hover:bg-brand-accent-hover"
|
|
72
|
+
>
|
|
73
|
+
Go to Login
|
|
74
|
+
</button>
|
|
75
|
+
</div>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const handleClearGuestSession = () => {
|
|
80
|
+
document.cookie = "_medusa_guest_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"
|
|
81
|
+
router.push("/account")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<div className="max-w-5xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
|
|
86
|
+
<div className="mb-8 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
|
87
|
+
<div>
|
|
88
|
+
<Heading level="h1" className="text-2xl sm:text-3xl font-bold text-heading mb-2">
|
|
89
|
+
My Orders
|
|
90
|
+
</Heading>
|
|
91
|
+
<Text className="text-gray-500">
|
|
92
|
+
View your order history and status.
|
|
93
|
+
</Text>
|
|
94
|
+
</div>
|
|
95
|
+
<div className="flex items-center gap-4">
|
|
96
|
+
{orders.length > 0 && (
|
|
97
|
+
<span className="hidden md:inline-block text-gray-500 text-sm font-medium bg-gray-50 px-3 py-1 rounded-full border border-gray-100">
|
|
98
|
+
{orders[0].email}
|
|
99
|
+
</span>
|
|
100
|
+
)}
|
|
101
|
+
<button
|
|
102
|
+
onClick={handleClearGuestSession}
|
|
103
|
+
className="whitespace-nowrap px-4 py-2 border border-brand-accent text-brand-accent rounded-full hover:bg-brand-accent-muted transition-colors text-sm font-medium"
|
|
104
|
+
>
|
|
105
|
+
Check Different User
|
|
106
|
+
</button>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
{orders.length === 0 ? (
|
|
111
|
+
<div className="text-center py-10 bg-gray-50 rounded-lg">
|
|
112
|
+
<p className="text-gray-600">No orders found associated with this email.</p>
|
|
113
|
+
</div>
|
|
114
|
+
) : (
|
|
115
|
+
<div className="flex flex-col gap-y-4">
|
|
116
|
+
<OrderOverview orders={orders} />
|
|
117
|
+
</div>
|
|
118
|
+
)}
|
|
119
|
+
</div>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default GuestOrdersTemplate
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { useState } from "react"
|
|
4
|
+
|
|
5
|
+
import { LOGIN_VIEW } from "@core/types/account"
|
|
6
|
+
import Login from "@modules/account/components/login"
|
|
7
|
+
import Register from "@modules/account/components/register"
|
|
8
|
+
import ForgotPassword from "@modules/account/components/forgot-password"
|
|
9
|
+
|
|
10
|
+
export { LOGIN_VIEW }
|
|
11
|
+
|
|
12
|
+
const LoginTemplate = () => {
|
|
13
|
+
const [currentView, setCurrentView] = useState(LOGIN_VIEW.SIGN_IN)
|
|
14
|
+
|
|
15
|
+
const renderView = () => {
|
|
16
|
+
switch (currentView) {
|
|
17
|
+
case LOGIN_VIEW.REGISTER:
|
|
18
|
+
return <Register setCurrentView={setCurrentView} />
|
|
19
|
+
case LOGIN_VIEW.FORGOT_PASSWORD:
|
|
20
|
+
return <ForgotPassword setCurrentView={setCurrentView} />
|
|
21
|
+
default:
|
|
22
|
+
return <Login setCurrentView={setCurrentView} />
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div className="min-h-screen w-full flex flex-col bg-page-bg">
|
|
28
|
+
<div className="flex-1 flex flex-col items-center justify-start px-2 min-[340px]:px-3 min-[550px]:px-4 sm:px-6 md:px-8 pt-2 min-[340px]:pt-3 min-[550px]:pt-4 sm:pt-4 md:pt-6 pb-6 min-[340px]:pb-8 min-[550px]:pb-8 sm:pb-8 md:pb-8">
|
|
29
|
+
<h1 className="text-2xl min-[340px]:text-3xl min-[550px]:text-3xl sm:text-4xl md:text-4xl font-bold text-heading mb-4 min-[340px]:mb-6 min-[550px]:mb-8 sm:mb-8 md:mb-8 text-center">
|
|
30
|
+
My Account
|
|
31
|
+
</h1>
|
|
32
|
+
|
|
33
|
+
<div
|
|
34
|
+
className="w-full bg-page-bg rounded-2xl shadow-lg p-4 min-[340px]:p-5 min-[550px]:p-6 sm:p-7 md:p-8"
|
|
35
|
+
style={{ maxWidth: "560px" }}
|
|
36
|
+
>
|
|
37
|
+
{renderView()}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default LoginTemplate
|