@salifbiaye/create-boutique 0.1.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/README.md +1 -0
- package/cli/dist/commands.js +382 -0
- package/cli/dist/create.js +194 -0
- package/cli/dist/docker.js +19 -0
- package/cli/dist/generate.js +322 -0
- package/cli/dist/guide.js +72 -0
- package/cli/dist/index.js +156 -0
- package/cli/dist/paths.js +29 -0
- package/cli/dist/ports.js +54 -0
- package/cli/dist/project.js +119 -0
- package/cli/dist/themes.js +24 -0
- package/docs/fiche-client.en.html +137 -0
- package/docs/fiche-client.html +137 -0
- package/docs/guide-complet.en.html +259 -0
- package/docs/guide-complet.fr.html +259 -0
- package/package.json +51 -0
- package/templates/backend/.dockerignore +9 -0
- package/templates/backend/Dockerfile +30 -0
- package/templates/backend/README.md +78 -0
- package/templates/backend/TEMPLATE_VERSION +1 -0
- package/templates/backend/docker/entrypoint.sh +28 -0
- package/templates/backend/instrumentation.ts +24 -0
- package/templates/backend/medusa-config.ts +114 -0
- package/templates/backend/package-lock.json +16222 -0
- package/templates/backend/package.json +39 -0
- package/templates/backend/src/admin/README.md +33 -0
- package/templates/backend/src/admin/components/image-field.tsx +61 -0
- package/templates/backend/src/admin/i18n/README.md +58 -0
- package/templates/backend/src/admin/i18n/index.ts +8 -0
- package/templates/backend/src/admin/i18n/json/en.json +66 -0
- package/templates/backend/src/admin/i18n/json/fr.json +66 -0
- package/templates/backend/src/admin/lib/client.ts +9 -0
- package/templates/backend/src/admin/routes/boutique-campaigns/campaign-drawer.tsx +286 -0
- package/templates/backend/src/admin/routes/boutique-campaigns/page.tsx +113 -0
- package/templates/backend/src/admin/tsconfig.json +24 -0
- package/templates/backend/src/admin/vite-env.d.ts +1 -0
- package/templates/backend/src/admin/widgets/category-image.tsx +56 -0
- package/templates/backend/src/api/README.md +135 -0
- package/templates/backend/src/api/admin/boutique-campaigns/[salesChannelId]/route.ts +30 -0
- package/templates/backend/src/api/admin/boutique-campaigns/route.ts +24 -0
- package/templates/backend/src/api/middlewares.ts +28 -0
- package/templates/backend/src/api/rate-limit.ts +30 -0
- package/templates/backend/src/api/route.ts +6 -0
- package/templates/backend/src/api/store/campaign/route.ts +25 -0
- package/templates/backend/src/api/store/order-lookup/route.ts +74 -0
- package/templates/backend/src/emails/en.json +64 -0
- package/templates/backend/src/emails/fr.json +64 -0
- package/templates/backend/src/jobs/README.md +38 -0
- package/templates/backend/src/lib/emails.ts +94 -0
- package/templates/backend/src/lib/notify.ts +148 -0
- package/templates/backend/src/lib/project.ts +146 -0
- package/templates/backend/src/links/README.md +26 -0
- package/templates/backend/src/links/campaign-sales-channel.ts +9 -0
- package/templates/backend/src/modules/README.md +117 -0
- package/templates/backend/src/modules/campaign/index.ts +9 -0
- package/templates/backend/src/modules/campaign/migrations/.snapshot-boutique-campaign.json +272 -0
- package/templates/backend/src/modules/campaign/migrations/Migration20260928141440.ts +16 -0
- package/templates/backend/src/modules/campaign/migrations/Migration20260928145243.ts +13 -0
- package/templates/backend/src/modules/campaign/models/campaign.ts +28 -0
- package/templates/backend/src/modules/campaign/service.ts +6 -0
- package/templates/backend/src/modules/campaign/validators.ts +94 -0
- package/templates/backend/src/modules/resend/index.ts +6 -0
- package/templates/backend/src/modules/resend/service.ts +63 -0
- package/templates/backend/src/scripts/README.md +63 -0
- package/templates/backend/src/scripts/campaign-export.ts +15 -0
- package/templates/backend/src/scripts/campaign-import.ts +38 -0
- package/templates/backend/src/scripts/price-report.ts +34 -0
- package/templates/backend/src/scripts/seed.ts +418 -0
- package/templates/backend/src/scripts/storage.ts +63 -0
- package/templates/backend/src/subscribers/README.md +61 -0
- package/templates/backend/src/subscribers/account-emails.ts +27 -0
- package/templates/backend/src/subscribers/fulfillment-emails.ts +42 -0
- package/templates/backend/src/subscribers/order-emails.ts +12 -0
- package/templates/backend/src/subscribers/return-refund-emails.ts +50 -0
- package/templates/backend/src/workflows/README.md +81 -0
- package/templates/backend/src/workflows/steps/upsert-campaign.ts +53 -0
- package/templates/backend/src/workflows/upsert-campaign.ts +30 -0
- package/templates/backend/tsconfig.json +36 -0
- package/templates/storefront/.dockerignore +7 -0
- package/templates/storefront/.github/ISSUE_TEMPLATE/bug-report.yml +71 -0
- package/templates/storefront/.prettierrc +8 -0
- package/templates/storefront/Dockerfile +37 -0
- package/templates/storefront/LICENSE +21 -0
- package/templates/storefront/README.md +127 -0
- package/templates/storefront/locales/en.json +269 -0
- package/templates/storefront/locales/fr.json +269 -0
- package/templates/storefront/next-env.d.ts +7 -0
- package/templates/storefront/next-sitemap.js +19 -0
- package/templates/storefront/next.config.js +29 -0
- package/templates/storefront/package-lock.json +9031 -0
- package/templates/storefront/package.json +49 -0
- package/templates/storefront/postcss.config.js +6 -0
- package/templates/storefront/public/favicon.ico +0 -0
- package/templates/storefront/scripts/sync-design.mjs +30 -0
- package/templates/storefront/src/app/(checkout)/checkout/page.tsx +31 -0
- package/templates/storefront/src/app/(checkout)/layout.tsx +29 -0
- package/templates/storefront/src/app/(checkout)/not-found.tsx +20 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/addresses/page.tsx +34 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/loading.tsx +9 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/orders/details/[id]/page.tsx +33 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/orders/page.tsx +37 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/page.tsx +22 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/profile/page.tsx +53 -0
- package/templates/storefront/src/app/(main)/account/@login/page.tsx +12 -0
- package/templates/storefront/src/app/(main)/account/layout.tsx +20 -0
- package/templates/storefront/src/app/(main)/account/loading.tsx +9 -0
- package/templates/storefront/src/app/(main)/cart/loading.tsx +5 -0
- package/templates/storefront/src/app/(main)/cart/not-found.tsx +21 -0
- package/templates/storefront/src/app/(main)/cart/page.tsx +21 -0
- package/templates/storefront/src/app/(main)/categories/[...category]/page.tsx +55 -0
- package/templates/storefront/src/app/(main)/collections/[handle]/page.tsx +55 -0
- package/templates/storefront/src/app/(main)/layout.tsx +43 -0
- package/templates/storefront/src/app/(main)/legal/[page]/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/not-found.tsx +21 -0
- package/templates/storefront/src/app/(main)/order/[id]/confirmed/loading.tsx +5 -0
- package/templates/storefront/src/app/(main)/order/[id]/confirmed/page.tsx +23 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/accept/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/decline/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/page.tsx +35 -0
- package/templates/storefront/src/app/(main)/order/track/page.tsx +32 -0
- package/templates/storefront/src/app/(main)/page.tsx +68 -0
- package/templates/storefront/src/app/(main)/products/[handle]/page.tsx +86 -0
- package/templates/storefront/src/app/(main)/store/page.tsx +28 -0
- package/templates/storefront/src/app/api/health/route.ts +13 -0
- package/templates/storefront/src/app/layout.tsx +42 -0
- package/templates/storefront/src/app/not-found.tsx +21 -0
- package/templates/storefront/src/app/opengraph-image.jpg +0 -0
- package/templates/storefront/src/app/twitter-image.jpg +0 -0
- package/templates/storefront/src/instrumentation-node.ts +18 -0
- package/templates/storefront/src/instrumentation.ts +9 -0
- package/templates/storefront/src/lib/boutique/campaign.ts +116 -0
- package/templates/storefront/src/lib/boutique/config.ts +152 -0
- package/templates/storefront/src/lib/boutique/fonts.ts +29 -0
- package/templates/storefront/src/lib/boutique/i18n-client.tsx +34 -0
- package/templates/storefront/src/lib/boutique/i18n.ts +43 -0
- package/templates/storefront/src/lib/boutique/schema.ts +131 -0
- package/templates/storefront/src/lib/config.ts +39 -0
- package/templates/storefront/src/lib/constants.tsx +75 -0
- package/templates/storefront/src/lib/context/modal-context.tsx +34 -0
- package/templates/storefront/src/lib/data/cart.ts +434 -0
- package/templates/storefront/src/lib/data/categories.ts +49 -0
- package/templates/storefront/src/lib/data/collections.ts +59 -0
- package/templates/storefront/src/lib/data/cookies.ts +103 -0
- package/templates/storefront/src/lib/data/customer.ts +261 -0
- package/templates/storefront/src/lib/data/fulfillment.ts +68 -0
- package/templates/storefront/src/lib/data/onboarding.ts +9 -0
- package/templates/storefront/src/lib/data/order-lookup.ts +34 -0
- package/templates/storefront/src/lib/data/orders.ts +112 -0
- package/templates/storefront/src/lib/data/payment.ts +35 -0
- package/templates/storefront/src/lib/data/products.ts +127 -0
- package/templates/storefront/src/lib/data/regions.ts +70 -0
- package/templates/storefront/src/lib/data/variants.ts +38 -0
- package/templates/storefront/src/lib/hooks/use-in-view.tsx +29 -0
- package/templates/storefront/src/lib/hooks/use-toggle-state.tsx +46 -0
- package/templates/storefront/src/lib/util/compare-addresses.ts +28 -0
- package/templates/storefront/src/lib/util/get-percentage-diff.ts +6 -0
- package/templates/storefront/src/lib/util/get-product-price.ts +79 -0
- package/templates/storefront/src/lib/util/isEmpty.ts +11 -0
- package/templates/storefront/src/lib/util/medusa-error.ts +22 -0
- package/templates/storefront/src/lib/util/money.ts +35 -0
- package/templates/storefront/src/lib/util/product.ts +5 -0
- package/templates/storefront/src/lib/util/repeat.ts +5 -0
- package/templates/storefront/src/lib/util/sort-products.ts +50 -0
- package/templates/storefront/src/modules/account/components/account-info/index.tsx +140 -0
- package/templates/storefront/src/modules/account/components/account-nav/index.tsx +198 -0
- package/templates/storefront/src/modules/account/components/address-book/index.tsx +28 -0
- package/templates/storefront/src/modules/account/components/address-card/add-address.tsx +169 -0
- package/templates/storefront/src/modules/account/components/address-card/edit-address-modal.tsx +241 -0
- package/templates/storefront/src/modules/account/components/login/index.tsx +65 -0
- package/templates/storefront/src/modules/account/components/order-card/index.tsx +88 -0
- package/templates/storefront/src/modules/account/components/order-overview/index.tsx +47 -0
- package/templates/storefront/src/modules/account/components/overview/index.tsx +169 -0
- package/templates/storefront/src/modules/account/components/profile-billing-address/index.tsx +193 -0
- package/templates/storefront/src/modules/account/components/profile-email/index.tsx +75 -0
- package/templates/storefront/src/modules/account/components/profile-name/index.tsx +79 -0
- package/templates/storefront/src/modules/account/components/profile-password/index.tsx +72 -0
- package/templates/storefront/src/modules/account/components/profile-phone/index.tsx +74 -0
- package/templates/storefront/src/modules/account/components/register/index.tsx +107 -0
- package/templates/storefront/src/modules/account/components/transfer-request-form/index.tsx +83 -0
- package/templates/storefront/src/modules/account/templates/account-layout.tsx +43 -0
- package/templates/storefront/src/modules/account/templates/login-template.tsx +27 -0
- package/templates/storefront/src/modules/cart/components/cart-item-select/index.tsx +75 -0
- package/templates/storefront/src/modules/cart/components/empty-cart-message/index.tsx +25 -0
- package/templates/storefront/src/modules/cart/components/item/index.tsx +144 -0
- package/templates/storefront/src/modules/cart/components/sign-in-prompt/index.tsx +27 -0
- package/templates/storefront/src/modules/cart/templates/index.tsx +51 -0
- package/templates/storefront/src/modules/cart/templates/items.tsx +58 -0
- package/templates/storefront/src/modules/cart/templates/preview.tsx +51 -0
- package/templates/storefront/src/modules/cart/templates/summary.tsx +50 -0
- package/templates/storefront/src/modules/categories/templates/index.tsx +94 -0
- package/templates/storefront/src/modules/checkout/components/address-select/index.tsx +117 -0
- package/templates/storefront/src/modules/checkout/components/addresses/index.tsx +186 -0
- package/templates/storefront/src/modules/checkout/components/billing_address/index.tsx +114 -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 +181 -0
- package/templates/storefront/src/modules/checkout/components/error-message/index.tsx +13 -0
- package/templates/storefront/src/modules/checkout/components/payment/index.tsx +261 -0
- package/templates/storefront/src/modules/checkout/components/payment-button/index.tsx +195 -0
- package/templates/storefront/src/modules/checkout/components/payment-container/index.tsx +130 -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 +42 -0
- package/templates/storefront/src/modules/checkout/components/payment-wrapper/stripe-wrapper.tsx +54 -0
- package/templates/storefront/src/modules/checkout/components/review/index.tsx +54 -0
- package/templates/storefront/src/modules/checkout/components/shipping/index.tsx +417 -0
- package/templates/storefront/src/modules/checkout/components/shipping-address/index.tsx +219 -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 +31 -0
- package/templates/storefront/src/modules/collections/templates/index.tsx +44 -0
- package/templates/storefront/src/modules/common/components/cart-totals/index.tsx +84 -0
- package/templates/storefront/src/modules/common/components/checkbox/index.tsx +44 -0
- package/templates/storefront/src/modules/common/components/delete-button/index.tsx +42 -0
- package/templates/storefront/src/modules/common/components/divider/index.tsx +9 -0
- package/templates/storefront/src/modules/common/components/filter-radio-group/index.tsx +61 -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 +63 -0
- package/templates/storefront/src/modules/common/components/line-item-unit-price/index.tsx +62 -0
- package/templates/storefront/src/modules/common/components/localized-client-link/index.tsx +29 -0
- package/templates/storefront/src/modules/common/components/modal/index.tsx +118 -0
- package/templates/storefront/src/modules/common/components/native-select/index.tsx +76 -0
- package/templates/storefront/src/modules/common/components/radio/index.tsx +27 -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/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/map-pin.tsx +37 -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/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/layout/components/cart-mismatch-banner/index.tsx +59 -0
- package/templates/storefront/src/modules/order/components/help/index.tsx +26 -0
- package/templates/storefront/src/modules/order/components/item/index.tsx +57 -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-details/index.tsx +64 -0
- package/templates/storefront/src/modules/order/components/order-summary/index.tsx +61 -0
- package/templates/storefront/src/modules/order/components/payment-details/index.tsx +64 -0
- package/templates/storefront/src/modules/order/components/shipping-details/index.tsx +74 -0
- package/templates/storefront/src/modules/order/components/transfer-actions/index.tsx +83 -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 +53 -0
- package/templates/storefront/src/modules/order/templates/order-details-template.tsx +46 -0
- package/templates/storefront/src/modules/products/components/thumbnail/index.tsx +70 -0
- package/templates/storefront/src/modules/products/templates/index.tsx +118 -0
- package/templates/storefront/src/modules/shipping/components/free-shipping-price-nudge/index.tsx +285 -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/store/components/pagination/index.tsx +114 -0
- package/templates/storefront/src/modules/store/components/refinement-list/index.tsx +41 -0
- package/templates/storefront/src/modules/store/components/refinement-list/sort-products/index.tsx +48 -0
- package/templates/storefront/src/modules/store/templates/index.tsx +42 -0
- package/templates/storefront/src/modules/store/templates/paginated-products.tsx +80 -0
- package/templates/storefront/src/modules/ub/button.tsx +41 -0
- package/templates/storefront/src/modules/ub/campaign-blocks.tsx +197 -0
- package/templates/storefront/src/modules/ub/campaign-ended.tsx +28 -0
- package/templates/storefront/src/modules/ub/category-tiles.tsx +41 -0
- package/templates/storefront/src/modules/ub/countdown.tsx +46 -0
- package/templates/storefront/src/modules/ub/footer.tsx +56 -0
- package/templates/storefront/src/modules/ub/icons.tsx +42 -0
- package/templates/storefront/src/modules/ub/nav.tsx +90 -0
- package/templates/storefront/src/modules/ub/pdp/buy-box.tsx +140 -0
- package/templates/storefront/src/modules/ub/pdp/gallery.tsx +40 -0
- package/templates/storefront/src/modules/ub/product-card.tsx +66 -0
- package/templates/storefront/src/modules/ub/top-bar.tsx +20 -0
- package/templates/storefront/src/modules/ub/track-form.tsx +92 -0
- package/templates/storefront/src/proxy.ts +89 -0
- package/templates/storefront/src/styles/globals.css +98 -0
- package/templates/storefront/src/styles/ub/bundle.css +372 -0
- package/templates/storefront/src/styles/ub/fonts.css +17 -0
- package/templates/storefront/src/styles/ub/medusa-ui.css +90 -0
- package/templates/storefront/src/styles/ub/overrides.css +12 -0
- package/templates/storefront/src/styles/ub/tokens.css +9 -0
- package/templates/storefront/src/types/global.ts +24 -0
- package/templates/storefront/src/types/icon.ts +4 -0
- package/templates/storefront/tailwind.config.js +164 -0
- package/templates/storefront/themes/black-friday/campaign.en.json +31 -0
- package/templates/storefront/themes/black-friday/campaign.fr.json +31 -0
- package/templates/storefront/themes/black-friday/theme.json +9 -0
- package/templates/storefront/themes/cyber-monday/campaign.en.json +31 -0
- package/templates/storefront/themes/cyber-monday/campaign.fr.json +31 -0
- package/templates/storefront/themes/cyber-monday/theme.json +9 -0
- package/templates/storefront/themes/halloween/campaign.en.json +31 -0
- package/templates/storefront/themes/halloween/campaign.fr.json +31 -0
- package/templates/storefront/themes/halloween/theme.json +9 -0
- package/templates/storefront/themes/noel/campaign.en.json +31 -0
- package/templates/storefront/themes/noel/campaign.fr.json +31 -0
- package/templates/storefront/themes/noel/theme.json +9 -0
- package/templates/storefront/themes/nouvel-an/campaign.en.json +31 -0
- package/templates/storefront/themes/nouvel-an/campaign.fr.json +31 -0
- package/templates/storefront/themes/nouvel-an/theme.json +9 -0
- package/templates/storefront/themes/thanksgiving/campaign.en.json +31 -0
- package/templates/storefront/themes/thanksgiving/campaign.fr.json +31 -0
- package/templates/storefront/themes/thanksgiving/theme.json +9 -0
- package/templates/storefront/tsconfig.json +53 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>{{STORE_NAME}} — complete guide</title>
|
|
6
|
+
<style>
|
|
7
|
+
@page { size: A4; margin: 16mm 15mm; }
|
|
8
|
+
:root{ --ink:#16181d; --muted:#5b616e; --line:#e3e5ea; --soft:#f5f6f8; --accent:#2b4fd8; --accent-soft:#eef1fd; --warn:#9a4a07; --warn-soft:#fdf3e7; --ok:#166534; --ok-soft:#ecfdf3; }
|
|
9
|
+
*{box-sizing:border-box}
|
|
10
|
+
body{font-family:"Carlito","Liberation Sans",Arial,sans-serif;color:var(--ink);font-size:10.2pt;line-height:1.45;margin:0;-webkit-print-color-adjust:exact;print-color-adjust:exact}
|
|
11
|
+
h1{font-size:24pt;margin:0 0 2mm}
|
|
12
|
+
h2{font-size:15pt;margin:8mm 0 2mm;padding-bottom:1.5mm;border-bottom:2px solid var(--ink);break-after:avoid}
|
|
13
|
+
h3{font-size:11.5pt;margin:5mm 0 1.5mm;break-after:avoid}
|
|
14
|
+
p{margin:1.5mm 0}
|
|
15
|
+
ol,ul{margin:1mm 0 2mm;padding-left:6mm} li{margin:.6mm 0}
|
|
16
|
+
code{background:var(--soft);padding:.2mm 1.2mm;border-radius:1mm;font-size:9.4pt}
|
|
17
|
+
pre{background:var(--soft);padding:2.5mm 3.5mm;border-radius:2mm;font-size:9pt;white-space:pre-wrap;margin:1.5mm 0 2.5mm}
|
|
18
|
+
table{width:100%;border-collapse:collapse;margin:2mm 0 3mm;font-size:9.4pt;break-inside:avoid}
|
|
19
|
+
th,td{border:1px solid var(--line);padding:1.3mm 2mm;text-align:left;vertical-align:top}
|
|
20
|
+
th{background:var(--soft)}
|
|
21
|
+
.menu{color:var(--accent);background:var(--accent-soft);padding:.2mm 1.6mm;border-radius:1mm;font-size:9.2pt;white-space:nowrap}
|
|
22
|
+
.box{border-radius:2mm;padding:2.5mm 3.5mm;margin:2mm 0 3mm;break-inside:avoid}
|
|
23
|
+
.warn{background:var(--warn-soft);color:var(--warn)} .ok{background:var(--ok-soft);color:var(--ok)} .info{background:var(--accent-soft)}
|
|
24
|
+
.part{break-before:page}
|
|
25
|
+
.cover p.sub{color:var(--muted);font-size:12pt;margin:0 0 6mm}
|
|
26
|
+
.toc{columns:2;font-size:9.8pt}
|
|
27
|
+
.muted{color:var(--muted)}
|
|
28
|
+
</style>
|
|
29
|
+
</head>
|
|
30
|
+
<body>
|
|
31
|
+
|
|
32
|
+
<section class="cover">
|
|
33
|
+
<h1>{{STORE_NAME}}</h1>
|
|
34
|
+
<p class="sub">Complete guide: put the stores online, then manage everything from the admin.</p>
|
|
35
|
+
<table>
|
|
36
|
+
<tr><th>Admin</th><td>{{ADMIN_URL}}</td></tr>
|
|
37
|
+
<tr><th>Admin email</th><td>{{ADMIN_EMAIL}}</td></tr>
|
|
38
|
+
<tr><th>Password</th><td class="muted">sent separately — never written in this document</td></tr>
|
|
39
|
+
<tr><th>Currencies</th><td>{{CURRENCIES}}</td></tr>
|
|
40
|
+
<tr><th>Project</th><td><code>{{PROJECT}}</code></td></tr>
|
|
41
|
+
</table>
|
|
42
|
+
<table>
|
|
43
|
+
<tr><th>Store</th><th>Identifier (sales channel)</th><th>Theme</th><th>Currency</th><th>Address</th></tr>
|
|
44
|
+
{{STORES_HTML}}
|
|
45
|
+
</table>
|
|
46
|
+
<div class="toc">
|
|
47
|
+
<b>A. Going live (team)</b>
|
|
48
|
+
<ol><li>Create and start the project</li><li>Admin credentials</li><li>Stripe payments</li><li>Emails</li><li>Domains and HTTPS</li><li>Pre-delivery checklist</li></ol>
|
|
49
|
+
<b>B. Day-to-day management (client)</b>
|
|
50
|
+
<ol><li>Sign in, team, password</li><li>Orders</li><li>Returns, exchanges, refunds</li><li>Products and variants</li><li>Prices per currency and sale prices</li><li>Categories and collections</li><li>Stores (sales channels)</li><li>Stock</li><li>Campaigns (texts, images, logo)</li><li>Discount codes and promotions</li><li>Customers and groups</li><li>Shipping and taxes</li><li>Do not touch</li><li>Troubleshooting</li></ol>
|
|
51
|
+
</div>
|
|
52
|
+
</section>
|
|
53
|
+
|
|
54
|
+
<section class="part">
|
|
55
|
+
<h2>A1. Create and start the project</h2>
|
|
56
|
+
<p>On a machine with <b>Docker</b> and <b>Node.js 20+</b>:</p>
|
|
57
|
+
<pre>npx @salifbiaye/create-boutique {{PROJECT}} # questions: name, email, currency, country, language, themes, Stripe, catalog
|
|
58
|
+
cd {{PROJECT}}
|
|
59
|
+
docker compose up -d # first start: 5 to 10 min (images are built)
|
|
60
|
+
docker compose logs -f backend # wait for "[backend] 4/4 démarrage"
|
|
61
|
+
create-boutique check . # a test order in each store: OK / KO</pre>
|
|
62
|
+
<p>The folder contains: <code>storefront/</code> and <code>backend/</code> (the code, do not edit), <code>config/project.json</code> (the stores), <code>config/campaigns/</code> (initial texts), <code>seed/</code> (initial catalog), <code>.env</code> (secrets), <code>README.md</code>, this guide and the one-page <code>GUIDE-CLIENT.pdf</code>.</p>
|
|
63
|
+
<div class="box info">On first start, the backend creates everything by itself: the database, the admin account, one region per currency, one store (sales channel + key) per line of <code>project.json</code>, the campaigns and the products of <code>seed/products.csv</code>. Restarting creates nothing twice.</div>
|
|
64
|
+
|
|
65
|
+
<h3>Changing the structure (team)</h3>
|
|
66
|
+
<table>
|
|
67
|
+
<tr><th>Need</th><th>Command</th></tr>
|
|
68
|
+
<tr><td>Add a store (gets the whole existing catalog)</td><td><code>create-boutique add . --boutique store-name:black-friday</code></td></tr>
|
|
69
|
+
<tr><td>Remove a store (its orders stay in the admin)</td><td><code>create-boutique remove . --boutique store-name</code></td></tr>
|
|
70
|
+
<tr><td>Rename a store, change its theme, currency, country</td><td><code>create-boutique set . --boutique store-name --name "…" --theme noel --currency eur --country fr</code></td></tr>
|
|
71
|
+
<tr><td>Shared name, currency, country, language</td><td><code>create-boutique set . --name "…" --currency usd --country us --language en</code></td></tr>
|
|
72
|
+
<tr><td>After editing <code>config/project.json</code> by hand</td><td><code>create-boutique apply .</code></td></tr>
|
|
73
|
+
<tr><td>Update the code (config, .env and data kept)</td><td><code>create-boutique update .</code></td></tr>
|
|
74
|
+
<tr><td>Backup database + images</td><td><code>create-boutique backup .</code></td></tr>
|
|
75
|
+
<tr><td>Campaign texts: database → files / files → database</td><td><code>create-boutique campaign export .</code> / <code>campaign import .</code></td></tr>
|
|
76
|
+
</table>
|
|
77
|
+
<div class="box warn">Rules: a country has only one currency in a project; never rename a store identifier (slug); never edit <code>docker-compose.yml</code> by hand.</div>
|
|
78
|
+
|
|
79
|
+
<h2>A2. Admin credentials</h2>
|
|
80
|
+
<pre>create-boutique admin . # address, email and password (read from .env)</pre>
|
|
81
|
+
<p>Send the password to the client through another channel than this guide. They can change it with “Forgot password?” (see B1) once emails are configured.</p>
|
|
82
|
+
|
|
83
|
+
<h2>A3. Stripe payments</h2>
|
|
84
|
+
<ol>
|
|
85
|
+
<li>In Stripe (test mode to try): <span class="menu">Developers → API keys</span>. Copy the publishable key <code>pk_…</code> and the secret key <code>sk_…</code>.</li>
|
|
86
|
+
<li>In <code>.env</code>: <code>STRIPE_PUBLISHABLE_KEY=pk_…</code> and <code>STRIPE_API_KEY=sk_…</code>.</li>
|
|
87
|
+
<li>Easiest, once the backend is online over HTTPS: <code>create-boutique stripe-webhook {{PROJECT}} --url https://api.your-domain.com</code> (creates the endpoint, writes the secret to <code>.env</code> and restarts the backend). Otherwise, by hand: Stripe → <span class="menu">Developers → Webhooks → Add endpoint</span>: URL <code><public backend address>/hooks/payment/stripe_stripe</code>, events <code>payment_intent.succeeded</code>, <code>payment_intent.payment_failed</code>, <code>payment_intent.amount_capturable_updated</code>, <code>payment_intent.partially_funded</code>.</li>
|
|
88
|
+
<li>Copy the <code>whsec_…</code> secret into <code>STRIPE_WEBHOOK_SECRET</code>, then <code>docker compose up -d</code> (the backend restarts with the keys and enables Stripe on every region).</li>
|
|
89
|
+
<li>Test: an order with card <code>4242 4242 4242 4242</code>, any future date, any CVC.</li>
|
|
90
|
+
<li>Apple Pay: Stripe → <span class="menu">Settings → Payment methods → Apple Pay</span>, register each store's domain.</li>
|
|
91
|
+
</ol>
|
|
92
|
+
<div class="box info">Without a Stripe key, only manual payment exists (useful for testing, not for production).</div>
|
|
93
|
+
|
|
94
|
+
<h2>A4. Emails</h2>
|
|
95
|
+
<ol>
|
|
96
|
+
<li>A Resend account (one key for all projects) with the platform sending domain verified (SPF/DKIM).</li>
|
|
97
|
+
<li>In <code>.env</code>: <code>RESEND_API_KEY=re_…</code> and <code>EMAIL_FROM=orders@mail.your-domain.com</code>, then <code>docker compose up -d</code>.</li>
|
|
98
|
+
<li>Emails are sent under the store's name; “Reply” goes to the merchant's email.</li>
|
|
99
|
+
</ol>
|
|
100
|
+
<p>Emails sent: order confirmation (+ copy to the merchant), shipped (with tracking), delivered, canceled, refunded, return requested / received, forgot password (admin), team invitation.</p>
|
|
101
|
+
|
|
102
|
+
<h2>A5. Domains and HTTPS (production)</h2>
|
|
103
|
+
<ol>
|
|
104
|
+
<li>One domain per store (e.g. <code>blackfriday.brand.com</code>) and one for the admin (e.g. <code>admin.brand.com</code>), pointing to the server.</li>
|
|
105
|
+
<li>A reverse proxy (Caddy, Nginx, Traefik) sends each domain to its store's port (see the table on the first page) and the admin to the backend port, over HTTPS.</li>
|
|
106
|
+
<li>In <code>config/project.json</code>, add <code>"url": "https://blackfriday.brand.com"</code> to each store, then <code>create-boutique apply .</code> (CORS and links updated).</li>
|
|
107
|
+
<li>In <code>.env</code>: <code>ADMIN_CORS</code>, <code>AUTH_CORS</code> and <code>ADMIN_URL</code> = HTTPS admin address; <code>S3_FILE_URL</code> = public images address.</li>
|
|
108
|
+
</ol>
|
|
109
|
+
|
|
110
|
+
<h2>A6. Pre-delivery checklist</h2>
|
|
111
|
+
<ul>
|
|
112
|
+
<li>☐ Each store opens at its address, with its theme, logo and currency.</li>
|
|
113
|
+
<li>☐ Each product is published, has a price in the currency of each store where it is sold, stock and at least one image.</li>
|
|
114
|
+
<li>☐ Campaigns: texts, dates, images checked (B9).</li>
|
|
115
|
+
<li>☐ Stripe: keys + webhook; one successful card test order.</li>
|
|
116
|
+
<li>☐ Emails: confirmation received by the customer and copy by the merchant; “forgot password” tested.</li>
|
|
117
|
+
<li>☐ Shipping rates and taxes checked (B12).</li>
|
|
118
|
+
<li>☐ <code>create-boutique check .</code>: OK everywhere; then cancel the test orders (check@example.com).</li>
|
|
119
|
+
<li>☐ Backup: <code>create-boutique backup .</code> scheduled (daily task).</li>
|
|
120
|
+
</ul>
|
|
121
|
+
</section>
|
|
122
|
+
|
|
123
|
+
<section class="part">
|
|
124
|
+
<h2>B1. Sign in, team, password</h2>
|
|
125
|
+
<ul>
|
|
126
|
+
<li><b>Sign in</b>: {{ADMIN_URL}} with your email and password.</li>
|
|
127
|
+
<li><b>Forgot or change your password</b>: sign-in page → <span class="menu">Forgot password?</span>, enter your email, follow the link you receive.</li>
|
|
128
|
+
<li><b>Admin language</b>: <span class="menu">Settings → Profile</span> → Language.</li>
|
|
129
|
+
<li><b>Invite a colleague</b>: <span class="menu">Settings → Users → Invite</span>. They receive an email to create their account. To remove access: same screen, delete the user.</li>
|
|
130
|
+
</ul>
|
|
131
|
+
|
|
132
|
+
<h2>B2. Orders</h2>
|
|
133
|
+
<p><span class="menu">Orders</span>: all stores in one place. The <b>Sales channel</b> column / filter shows which store each order comes from.</p>
|
|
134
|
+
<table>
|
|
135
|
+
<tr><th>Step</th><th>Where / how</th><th>The customer receives</th></tr>
|
|
136
|
+
<tr><td>Paid</td><td>Automatic (card). Manual payment: <b>Capture</b> button in the Payment section.</td><td>Order confirmation</td></tr>
|
|
137
|
+
<tr><td>Fulfill</td><td><b>Fulfillment</b> section → <b>Create fulfillment</b>, pick the items and the location.</td><td>—</td></tr>
|
|
138
|
+
<tr><td>Ship</td><td>On the fulfillment → <b>Mark as shipped</b>, enter the tracking number and link.</td><td>“Your package is on its way” + tracking</td></tr>
|
|
139
|
+
<tr><td>Deliver</td><td>On the fulfillment → <b>Mark as delivered</b>.</td><td>“Your order has been delivered”</td></tr>
|
|
140
|
+
<tr><td>Cancel</td><td>“…” menu at the top of the order → <b>Cancel</b> (before shipping).</td><td>Cancellation confirmation</td></tr>
|
|
141
|
+
</table>
|
|
142
|
+
<p>Also in an order: edit the items (<b>Edit order</b>), add an internal note, see the full history (activity).</p>
|
|
143
|
+
|
|
144
|
+
<h2>B3. Returns, exchanges, refunds</h2>
|
|
145
|
+
<ul>
|
|
146
|
+
<li><b>Return</b>: in the order → <b>Request return</b>, pick the items and the reason. When the package arrives: <b>Receive</b> the return. The customer is notified at each step.</li>
|
|
147
|
+
<li><b>Exchange</b>: <b>Create exchange</b> (items returned + items sent instead).</li>
|
|
148
|
+
<li><b>Claim</b> (damaged, missing item): <b>Create claim</b>, with replacement or refund.</li>
|
|
149
|
+
<li><b>Refund</b>: Payment section → <b>Refund</b>, amount and reason. The customer receives an email with the amount.</li>
|
|
150
|
+
<li>Return reasons: <span class="menu">Settings → Return reasons</span>.</li>
|
|
151
|
+
</ul>
|
|
152
|
+
|
|
153
|
+
<h2>B4. Products and variants</h2>
|
|
154
|
+
<ol>
|
|
155
|
+
<li><span class="menu">Products → Create</span>: title, subtitle, description, URL identifier (handle).</li>
|
|
156
|
+
<li><b>Media</b>: drop the photos; the first one is the thumbnail on the site.</li>
|
|
157
|
+
<li><b>Options and variants</b>: e.g. option “Color” (Black, White) and “Size” (S, M, L) → one variant per combination, each with its SKU, price and stock.</li>
|
|
158
|
+
<li><b>Sales channels</b>: tick the stores where the product appears (see B7).</li>
|
|
159
|
+
<li><b>Organize</b>: category(ies), collection, type, tags.</li>
|
|
160
|
+
<li><b>Status</b>: <b>Published</b>. A draft appears nowhere.</li>
|
|
161
|
+
</ol>
|
|
162
|
+
<p><b>Many products?</b> <span class="menu">Products → Import</span> a CSV file (template downloadable on the same screen); <b>Export</b> to edit them in a spreadsheet.</p>
|
|
163
|
+
|
|
164
|
+
<h2>B5. Prices per currency and sale prices</h2>
|
|
165
|
+
<div class="box warn">Each variant must have a price <b>in the currency of each store where it is sold</b> ({{CURRENCIES}}). Without a price in a currency, the product does not appear in that store.</div>
|
|
166
|
+
<ul>
|
|
167
|
+
<li><b>Regular price</b>: product → variant → <b>Edit prices</b>: one column per currency.</li>
|
|
168
|
+
<li><b>Sale price (strikethrough)</b>: <span class="menu">Price Lists → Create</span>, type <b>Sale</b>, start and end dates, add the products and the sale price per currency. The site shows the old price struck through and the percentage.</li>
|
|
169
|
+
<li><b>Prices for a group</b> (e.g. VIP customers, resellers): price list of type <b>Override</b> limited to a customer group (B11).</li>
|
|
170
|
+
</ul>
|
|
171
|
+
|
|
172
|
+
<h2>B6. Categories and collections</h2>
|
|
173
|
+
<ul>
|
|
174
|
+
<li><span class="menu">Products → Categories</span>: create (name, handle), organize as a tree, add products. Top-level categories are shown as tiles on each store's home page.</li>
|
|
175
|
+
<li><b>Category image</b>: open the category → <b>Category image</b> block (right column) → choose the file → <b>Save image</b>.</li>
|
|
176
|
+
<li><span class="menu">Products → Collections</span>: free groupings (e.g. “Gift ideas”); related products on a product page come from the same collection.</li>
|
|
177
|
+
</ul>
|
|
178
|
+
|
|
179
|
+
<h2>B7. Stores (sales channels)</h2>
|
|
180
|
+
<p>Each store is a <b>sales channel</b> (<span class="menu">Settings → Sales Channels</span>), named after its identifier (first page). The same product can be sold in several stores; stock is shared.</p>
|
|
181
|
+
<ul>
|
|
182
|
+
<li>Put a product in a store: product → <b>Sales channels</b> → tick; or from the sales channel → <b>Add products</b> (several at once).</li>
|
|
183
|
+
<li>Remove a product from a store: untick. It stays sold elsewhere.</li>
|
|
184
|
+
</ul>
|
|
185
|
+
<div class="box warn">Do not rename or delete a sales channel or its API key: the matching store would stop working. New store = ask the team (A1).</div>
|
|
186
|
+
|
|
187
|
+
<h2>B8. Stock</h2>
|
|
188
|
+
<ul>
|
|
189
|
+
<li><span class="menu">Inventory</span>: available quantity per item and per location; <b>reserved</b> = orders not shipped yet.</li>
|
|
190
|
+
<li>Stock goes down with each order and back up on cancellation or when a return is received.</li>
|
|
191
|
+
<li>Out of stock: the site shows “Out of stock”. To keep selling: variant → <b>Allow backorders</b>.</li>
|
|
192
|
+
</ul>
|
|
193
|
+
|
|
194
|
+
<h2>B9. Campaigns: texts, images, logo, countdown</h2>
|
|
195
|
+
<p><span class="menu">Campaigns</span> (menu added for your stores) → store row → <b>Edit</b>. Visible on the site within about a minute.</p>
|
|
196
|
+
<table>
|
|
197
|
+
<tr><th>Section</th><th>Fields</th></tr>
|
|
198
|
+
<tr><td>Identity</td><td><b>Logo</b> (replaces the colored mark; also the browser tab icon), <b>countdown</b>: as the theme / always / never.</td></tr>
|
|
199
|
+
<tr><td>Dates</td><td>Start and end of the offer (countdown, and “This sale has ended” page afterwards); <b>next campaign</b>: store offered when this one is over.</td></tr>
|
|
200
|
+
<tr><td>Variables</td><td>Discount (e.g. 30%) and free shipping threshold, used in the theme texts.</td></tr>
|
|
201
|
+
<tr><td>Hero</td><td>Eyebrow, title, <b>highlighted words</b> (must be part of the title), subtitle, 2 buttons, bubble (3 texts), <b>image</b>.</td></tr>
|
|
202
|
+
<tr><td>Top bar</td><td>Up to 3 messages.</td></tr>
|
|
203
|
+
<tr><td>Promo banner</td><td>Eyebrow, title, text, button, seal, <b>image</b>.</td></tr>
|
|
204
|
+
</table>
|
|
205
|
+
<p>An empty field uses the theme text. <b>Reset to theme texts</b> clears your texts (images, logo and dates are kept). Plain text only; images jpg, png or webp, 5 MB max.</p>
|
|
206
|
+
<div class="box info">Not to be confused with Medusa's <span class="menu">Promotions → Campaigns</span>, which groups discount codes with a budget (B10).</div>
|
|
207
|
+
|
|
208
|
+
<h2>B10. Discount codes and promotions</h2>
|
|
209
|
+
<p><span class="menu">Promotions → Create</span>:</p>
|
|
210
|
+
<table>
|
|
211
|
+
<tr><th>Type</th><th>Example</th></tr>
|
|
212
|
+
<tr><td>% or amount off the order</td><td><code>BF20</code> = −20% on the whole cart</td></tr>
|
|
213
|
+
<tr><td>Discount on some products</td><td>−10 on the Audio category</td></tr>
|
|
214
|
+
<tr><td>Buy X get Y</td><td>buy 2, get the 3rd free</td></tr>
|
|
215
|
+
<tr><td>Free shipping</td><td>code <code>SHIPFREE</code></td></tr>
|
|
216
|
+
</table>
|
|
217
|
+
<ul>
|
|
218
|
+
<li><b>Code</b> (entered by the customer in the cart) or <b>automatic</b> (applied without a code).</li>
|
|
219
|
+
<li><b>Conditions</b>: products, categories, collections, customer groups, currency, minimum amount…</li>
|
|
220
|
+
<li><b>Limits and dates</b>: attach the promotion to a <b>promotion campaign</b> (start/end dates, budget in number of uses or amount).</li>
|
|
221
|
+
<li>Disable: set the promotion to <b>Draft</b>.</li>
|
|
222
|
+
</ul>
|
|
223
|
+
<div class="box warn">An amount discount (e.g. −10) applies in the chosen currency: create one promotion per currency if needed. Test each code in the right store before announcing it.</div>
|
|
224
|
+
|
|
225
|
+
<h2>B11. Customers and groups</h2>
|
|
226
|
+
<ul>
|
|
227
|
+
<li><span class="menu">Customers</span>: accounts created on the stores (one account works in all of them), addresses, order history.</li>
|
|
228
|
+
<li><span class="menu">Customers → Groups</span>: e.g. “VIP”, for reserved price lists (B5) or promotions (B10).</li>
|
|
229
|
+
</ul>
|
|
230
|
+
|
|
231
|
+
<h2>B12. Shipping and taxes</h2>
|
|
232
|
+
<ul>
|
|
233
|
+
<li><b>Rates</b>: <span class="menu">Settings → Locations & Shipping</span> → Entrepôt principal → Shipping → zone <b>Monde</b> → <b>Standard</b> and <b>Express</b> options → <b>Edit prices</b> (one price per currency). You can add an option (e.g. store pickup).</li>
|
|
234
|
+
<li><b>Free shipping above an amount</b>: automatic free-shipping promotion with a minimum amount condition (B10). Put the threshold in the campaign variable (B9).</li>
|
|
235
|
+
<li><b>Taxes</b>: 0% by default (prices shown tax included). To apply VAT / sales tax: <span class="menu">Settings → Tax Regions</span> → country → default rate.</li>
|
|
236
|
+
</ul>
|
|
237
|
+
|
|
238
|
+
<h2>B13. Do not touch</h2>
|
|
239
|
+
<ul>
|
|
240
|
+
<li><span class="menu">Settings → Regions</span>: generated from the project configuration (one per currency). Changing a country or currency = ask the team.</li>
|
|
241
|
+
<li><span class="menu">Settings → Sales Channels</span> and <span class="menu">Publishable API Keys</span>: one per store.</li>
|
|
242
|
+
<li><span class="menu">Settings → Store</span>: store currencies.</li>
|
|
243
|
+
</ul>
|
|
244
|
+
|
|
245
|
+
<h2>B14. Troubleshooting</h2>
|
|
246
|
+
<table>
|
|
247
|
+
<tr><th>Problem</th><th>Check</th></tr>
|
|
248
|
+
<tr><td>Product not visible in a store</td><td>Published? ticked in this store's sales channel? price in its currency? (wait 1 min)</td></tr>
|
|
249
|
+
<tr><td>“This sale has ended”</td><td>Campaign end date passed (B9): extend it or set the next campaign.</td></tr>
|
|
250
|
+
<tr><td>Change not visible</td><td>Wait a minute then reload the page.</td></tr>
|
|
251
|
+
<tr><td>Customer gets no email</td><td>Spam folder; emails configured (A4); customer address correct in the order.</td></tr>
|
|
252
|
+
<tr><td>Card payment impossible</td><td>Stripe keys and webhook (A3); Stripe account activated for live payments.</td></tr>
|
|
253
|
+
<tr><td>Discount code refused</td><td>Dates, budget, conditions (products, currency, minimum amount), status not draft.</td></tr>
|
|
254
|
+
<tr><td>Other</td><td>Contact: {{SUPPORT}}</td></tr>
|
|
255
|
+
</table>
|
|
256
|
+
</section>
|
|
257
|
+
|
|
258
|
+
</body>
|
|
259
|
+
</html>
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="fr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>{{STORE_NAME}} — guide complet</title>
|
|
6
|
+
<style>
|
|
7
|
+
@page { size: A4; margin: 16mm 15mm; }
|
|
8
|
+
:root{ --ink:#16181d; --muted:#5b616e; --line:#e3e5ea; --soft:#f5f6f8; --accent:#2b4fd8; --accent-soft:#eef1fd; --warn:#9a4a07; --warn-soft:#fdf3e7; --ok:#166534; --ok-soft:#ecfdf3; }
|
|
9
|
+
*{box-sizing:border-box}
|
|
10
|
+
body{font-family:"Carlito","Liberation Sans",Arial,sans-serif;color:var(--ink);font-size:10.2pt;line-height:1.45;margin:0;-webkit-print-color-adjust:exact;print-color-adjust:exact}
|
|
11
|
+
h1{font-size:24pt;margin:0 0 2mm}
|
|
12
|
+
h2{font-size:15pt;margin:8mm 0 2mm;padding-bottom:1.5mm;border-bottom:2px solid var(--ink);break-after:avoid}
|
|
13
|
+
h3{font-size:11.5pt;margin:5mm 0 1.5mm;break-after:avoid}
|
|
14
|
+
p{margin:1.5mm 0}
|
|
15
|
+
ol,ul{margin:1mm 0 2mm;padding-left:6mm} li{margin:.6mm 0}
|
|
16
|
+
code{background:var(--soft);padding:.2mm 1.2mm;border-radius:1mm;font-size:9.4pt}
|
|
17
|
+
pre{background:var(--soft);padding:2.5mm 3.5mm;border-radius:2mm;font-size:9pt;white-space:pre-wrap;margin:1.5mm 0 2.5mm}
|
|
18
|
+
table{width:100%;border-collapse:collapse;margin:2mm 0 3mm;font-size:9.4pt;break-inside:avoid}
|
|
19
|
+
th,td{border:1px solid var(--line);padding:1.3mm 2mm;text-align:left;vertical-align:top}
|
|
20
|
+
th{background:var(--soft)}
|
|
21
|
+
.menu{color:var(--accent);background:var(--accent-soft);padding:.2mm 1.6mm;border-radius:1mm;font-size:9.2pt;white-space:nowrap}
|
|
22
|
+
.box{border-radius:2mm;padding:2.5mm 3.5mm;margin:2mm 0 3mm;break-inside:avoid}
|
|
23
|
+
.warn{background:var(--warn-soft);color:var(--warn)} .ok{background:var(--ok-soft);color:var(--ok)} .info{background:var(--accent-soft)}
|
|
24
|
+
.part{break-before:page}
|
|
25
|
+
.cover p.sub{color:var(--muted);font-size:12pt;margin:0 0 6mm}
|
|
26
|
+
.toc{columns:2;font-size:9.8pt}
|
|
27
|
+
.muted{color:var(--muted)}
|
|
28
|
+
</style>
|
|
29
|
+
</head>
|
|
30
|
+
<body>
|
|
31
|
+
|
|
32
|
+
<section class="cover">
|
|
33
|
+
<h1>{{STORE_NAME}}</h1>
|
|
34
|
+
<p class="sub">Guide complet : mettre les boutiques en ligne, puis tout gérer depuis l'admin.</p>
|
|
35
|
+
<table>
|
|
36
|
+
<tr><th>Admin</th><td>{{ADMIN_URL}}</td></tr>
|
|
37
|
+
<tr><th>E-mail admin</th><td>{{ADMIN_EMAIL}}</td></tr>
|
|
38
|
+
<tr><th>Mot de passe</th><td class="muted">transmis à part — jamais écrit dans ce document</td></tr>
|
|
39
|
+
<tr><th>Devises</th><td>{{CURRENCIES}}</td></tr>
|
|
40
|
+
<tr><th>Projet</th><td><code>{{PROJECT}}</code></td></tr>
|
|
41
|
+
</table>
|
|
42
|
+
<table>
|
|
43
|
+
<tr><th>Boutique</th><th>Identifiant (canal de vente)</th><th>Thème</th><th>Devise</th><th>Adresse</th></tr>
|
|
44
|
+
{{STORES_HTML}}
|
|
45
|
+
</table>
|
|
46
|
+
<div class="toc">
|
|
47
|
+
<b>A. Mise en ligne (équipe)</b>
|
|
48
|
+
<ol><li>Créer et lancer le projet</li><li>Identifiants admin</li><li>Paiement Stripe</li><li>E-mails</li><li>Domaines et HTTPS</li><li>Checklist avant livraison</li></ol>
|
|
49
|
+
<b>B. Gestion au quotidien (client)</b>
|
|
50
|
+
<ol><li>Se connecter, équipe, mot de passe</li><li>Commandes</li><li>Retours, échanges, remboursements</li><li>Produits et variantes</li><li>Prix par devise et prix barrés</li><li>Catégories et collections</li><li>Boutiques (canaux de vente)</li><li>Stock</li><li>Campagnes (textes, images, logo)</li><li>Codes promo et promotions</li><li>Clients et groupes</li><li>Livraison et taxes</li><li>À ne pas toucher</li><li>Dépannage</li></ol>
|
|
51
|
+
</div>
|
|
52
|
+
</section>
|
|
53
|
+
|
|
54
|
+
<section class="part">
|
|
55
|
+
<h2>A1. Créer et lancer le projet</h2>
|
|
56
|
+
<p>Sur une machine avec <b>Docker</b> et <b>Node.js 20+</b> :</p>
|
|
57
|
+
<pre>npx @salifbiaye/create-boutique {{PROJECT}} # questions : nom, e-mail, devise, pays, langue, thèmes, Stripe, catalogue
|
|
58
|
+
cd {{PROJECT}}
|
|
59
|
+
docker compose up -d # premier démarrage : 5 à 10 min (construction des images)
|
|
60
|
+
docker compose logs -f backend # attendre « [backend] 4/4 démarrage »
|
|
61
|
+
create-boutique check . # une commande test dans chaque boutique : OK / KO</pre>
|
|
62
|
+
<p>Le dossier contient : <code>storefront/</code> et <code>backend/</code> (le code, à ne pas modifier), <code>config/project.json</code> (les boutiques), <code>config/campaigns/</code> (textes initiaux), <code>seed/</code> (catalogue initial), <code>.env</code> (secrets), <code>README.md</code>, ce guide et la fiche <code>GUIDE-CLIENT.pdf</code>.</p>
|
|
63
|
+
<div class="box info">Au premier démarrage, le backend crée tout seul : la base, le compte admin, une région par devise, une boutique (canal de vente + clé) par ligne de <code>project.json</code>, les campagnes et les produits de <code>seed/products.csv</code>. Relancer ne recrée rien.</div>
|
|
64
|
+
|
|
65
|
+
<h3>Changer la structure (équipe)</h3>
|
|
66
|
+
<table>
|
|
67
|
+
<tr><th>Besoin</th><th>Commande</th></tr>
|
|
68
|
+
<tr><td>Ajouter une boutique (reçoit tout le catalogue existant)</td><td><code>create-boutique add . --boutique nom-boutique:black-friday</code></td></tr>
|
|
69
|
+
<tr><td>Retirer une boutique (ses commandes restent dans l'admin)</td><td><code>create-boutique remove . --boutique nom-boutique</code></td></tr>
|
|
70
|
+
<tr><td>Renommer une boutique, changer son thème, sa devise, son pays</td><td><code>create-boutique set . --boutique nom-boutique --name "…" --theme noel --currency eur --country fr</code></td></tr>
|
|
71
|
+
<tr><td>Nom, devise, pays, langue communs</td><td><code>create-boutique set . --name "…" --currency usd --country us --language fr</code></td></tr>
|
|
72
|
+
<tr><td>Après une modification à la main de <code>config/project.json</code></td><td><code>create-boutique apply .</code></td></tr>
|
|
73
|
+
<tr><td>Mettre à jour le code (config, .env et données conservés)</td><td><code>create-boutique update .</code></td></tr>
|
|
74
|
+
<tr><td>Sauvegarde base + images</td><td><code>create-boutique backup .</code></td></tr>
|
|
75
|
+
<tr><td>Textes des campagnes : base → fichiers / fichiers → base</td><td><code>create-boutique campaign export .</code> / <code>campaign import .</code></td></tr>
|
|
76
|
+
</table>
|
|
77
|
+
<div class="box warn">Règles : un pays n'a qu'une devise dans un projet ; ne jamais renommer l'identifiant (slug) d'une boutique ; ne jamais modifier <code>docker-compose.yml</code> à la main.</div>
|
|
78
|
+
|
|
79
|
+
<h2>A2. Identifiants admin</h2>
|
|
80
|
+
<pre>create-boutique admin . # adresse, e-mail et mot de passe (lus dans .env)</pre>
|
|
81
|
+
<p>Transmettez le mot de passe au client par un autre canal que ce guide. Il pourra le changer avec « Mot de passe oublié ? » (voir B1) une fois les e-mails configurés.</p>
|
|
82
|
+
|
|
83
|
+
<h2>A3. Paiement Stripe</h2>
|
|
84
|
+
<ol>
|
|
85
|
+
<li>Dans Stripe (mode test pour essayer) : <span class="menu">Développeurs → Clés API</span>. Copier la clé publique <code>pk_…</code> et la clé secrète <code>sk_…</code>.</li>
|
|
86
|
+
<li>Dans <code>.env</code> : <code>STRIPE_PUBLISHABLE_KEY=pk_…</code> et <code>STRIPE_API_KEY=sk_…</code>.</li>
|
|
87
|
+
<li>Le plus simple, une fois le backend en ligne en HTTPS : <code>create-boutique stripe-webhook {{PROJECT}} --url https://api.votre-domaine.com</code> (crée l’endpoint, écrit le secret dans <code>.env</code> et relance le backend). Sinon, à la main : Stripe → <span class="menu">Développeurs → Webhooks → Ajouter un endpoint</span> : URL <code><adresse publique du backend>/hooks/payment/stripe_stripe</code>, événements <code>payment_intent.succeeded</code>, <code>payment_intent.payment_failed</code>, <code>payment_intent.amount_capturable_updated</code>, <code>payment_intent.partially_funded</code>.</li>
|
|
88
|
+
<li>Copier le secret <code>whsec_…</code> dans <code>STRIPE_WEBHOOK_SECRET</code>, puis <code>docker compose up -d</code> (le backend redémarre avec les clés et active Stripe sur toutes les régions).</li>
|
|
89
|
+
<li>Tester : commande avec la carte <code>4242 4242 4242 4242</code>, date future, CVC quelconque.</li>
|
|
90
|
+
<li>Apple Pay : Stripe → <span class="menu">Paramètres → Moyens de paiement → Apple Pay</span>, déclarer le domaine de chaque boutique.</li>
|
|
91
|
+
</ol>
|
|
92
|
+
<div class="box info">Sans clé Stripe, seul le paiement manuel existe (utile pour tester, à ne pas laisser en production).</div>
|
|
93
|
+
|
|
94
|
+
<h2>A4. E-mails</h2>
|
|
95
|
+
<ol>
|
|
96
|
+
<li>Un compte Resend (une seule clé pour tous les projets) avec le domaine d'envoi de la plateforme vérifié (SPF/DKIM).</li>
|
|
97
|
+
<li>Dans <code>.env</code> : <code>RESEND_API_KEY=re_…</code> et <code>EMAIL_FROM=orders@mail.votre-domaine.com</code>, puis <code>docker compose up -d</code>.</li>
|
|
98
|
+
<li>Les e-mails partent au nom de la boutique ; « Répondre » va à l'e-mail du marchand.</li>
|
|
99
|
+
</ol>
|
|
100
|
+
<p>E-mails envoyés : confirmation de commande (+ copie au marchand), colis expédié (avec suivi), livré, annulé, remboursé, retour demandé / reçu, mot de passe oublié (admin), invitation d'un membre de l'équipe.</p>
|
|
101
|
+
|
|
102
|
+
<h2>A5. Domaines et HTTPS (production)</h2>
|
|
103
|
+
<ol>
|
|
104
|
+
<li>Un nom de domaine par boutique (ex. <code>blackfriday.marque.com</code>) et un pour l'admin (ex. <code>admin.marque.com</code>), qui pointent vers le serveur.</li>
|
|
105
|
+
<li>Un reverse proxy (Caddy, Nginx, Traefik) envoie chaque domaine vers le port de sa boutique (voir le tableau en première page) et l'admin vers le port du backend, en HTTPS.</li>
|
|
106
|
+
<li>Dans <code>config/project.json</code>, ajouter <code>"url": "https://blackfriday.marque.com"</code> à chaque boutique, puis <code>create-boutique apply .</code> (CORS et liens mis à jour).</li>
|
|
107
|
+
<li>Dans <code>.env</code> : <code>ADMIN_CORS</code>, <code>AUTH_CORS</code> et <code>ADMIN_URL</code> = adresse HTTPS de l'admin ; <code>S3_FILE_URL</code> = adresse publique des images.</li>
|
|
108
|
+
</ol>
|
|
109
|
+
|
|
110
|
+
<h2>A6. Checklist avant livraison</h2>
|
|
111
|
+
<ul>
|
|
112
|
+
<li>☐ Chaque boutique s'ouvre à son adresse, avec son thème, son logo et sa devise.</li>
|
|
113
|
+
<li>☐ Chaque produit est publié, a un prix dans la devise de chaque boutique où il est vendu, du stock et au moins une image.</li>
|
|
114
|
+
<li>☐ Campagnes : textes, dates, visuels vérifiés (B9).</li>
|
|
115
|
+
<li>☐ Stripe : clés + webhook ; une commande test par carte réussie.</li>
|
|
116
|
+
<li>☐ E-mails : confirmation reçue par le client et copie par le marchand ; « mot de passe oublié » testé.</li>
|
|
117
|
+
<li>☐ Tarifs de livraison et taxes vérifiés (B12).</li>
|
|
118
|
+
<li>☐ <code>create-boutique check .</code> : OK partout ; annuler ensuite les commandes de test (check@example.com).</li>
|
|
119
|
+
<li>☐ Sauvegarde : <code>create-boutique backup .</code> programmée (tâche planifiée quotidienne).</li>
|
|
120
|
+
</ul>
|
|
121
|
+
</section>
|
|
122
|
+
|
|
123
|
+
<section class="part">
|
|
124
|
+
<h2>B1. Se connecter, équipe, mot de passe</h2>
|
|
125
|
+
<ul>
|
|
126
|
+
<li><b>Connexion</b> : {{ADMIN_URL}} avec votre e-mail et votre mot de passe.</li>
|
|
127
|
+
<li><b>Mot de passe oublié / le changer</b> : page de connexion → <span class="menu">Mot de passe oublié ?</span>, saisir votre e-mail, suivre le lien reçu.</li>
|
|
128
|
+
<li><b>Langue de l'admin</b> : <span class="menu">Paramètres → Profil</span> → Langue (Français).</li>
|
|
129
|
+
<li><b>Inviter un collègue</b> : <span class="menu">Paramètres → Utilisateurs → Inviter</span>. Il reçoit un e-mail pour créer son compte. Retirer un accès : même écran, supprimer l'utilisateur.</li>
|
|
130
|
+
</ul>
|
|
131
|
+
|
|
132
|
+
<h2>B2. Commandes</h2>
|
|
133
|
+
<p><span class="menu">Commandes (Orders)</span> : toutes les boutiques au même endroit. La colonne / le filtre <b>Canal de vente</b> indique de quelle boutique vient chaque commande.</p>
|
|
134
|
+
<table>
|
|
135
|
+
<tr><th>Étape</th><th>Où / comment</th><th>Le client reçoit</th></tr>
|
|
136
|
+
<tr><td>Payée</td><td>Automatique (carte). Paiement manuel : bouton <b>Capturer</b> dans la partie Paiement.</td><td>Confirmation de commande</td></tr>
|
|
137
|
+
<tr><td>Préparer</td><td>Partie <b>Traitement (Fulfillment)</b> → <b>Créer un traitement</b>, choisir les articles et l'entrepôt.</td><td>—</td></tr>
|
|
138
|
+
<tr><td>Expédier</td><td>Sur le traitement → <b>Marquer comme expédié</b>, saisir le numéro et le lien de suivi.</td><td>« Votre colis est en route » + suivi</td></tr>
|
|
139
|
+
<tr><td>Livrer</td><td>Sur le traitement → <b>Marquer comme livré</b>.</td><td>« Votre commande est livrée »</td></tr>
|
|
140
|
+
<tr><td>Annuler</td><td>Menu « … » en haut de la commande → <b>Annuler</b> (avant expédition).</td><td>Confirmation d'annulation</td></tr>
|
|
141
|
+
</table>
|
|
142
|
+
<p>Aussi dans une commande : modifier les articles (<b>Modifier la commande</b>), ajouter une note interne, voir l'historique complet (activité).</p>
|
|
143
|
+
|
|
144
|
+
<h2>B3. Retours, échanges, remboursements</h2>
|
|
145
|
+
<ul>
|
|
146
|
+
<li><b>Retour</b> : dans la commande → <b>Demander un retour</b>, choisir les articles et le motif. À réception du colis : <b>Recevoir</b> le retour. Le client est prévenu à chaque étape.</li>
|
|
147
|
+
<li><b>Échange</b> : <b>Créer un échange</b> (articles rendus + articles envoyés à la place).</li>
|
|
148
|
+
<li><b>Réclamation</b> (produit abîmé, manquant) : <b>Créer une réclamation</b>, avec renvoi ou remboursement.</li>
|
|
149
|
+
<li><b>Rembourser</b> : partie Paiement → <b>Rembourser</b>, montant et motif. Le client reçoit un e-mail avec le montant.</li>
|
|
150
|
+
<li>Motifs de retour : <span class="menu">Paramètres → Motifs de retour</span>.</li>
|
|
151
|
+
</ul>
|
|
152
|
+
|
|
153
|
+
<h2>B4. Produits et variantes</h2>
|
|
154
|
+
<ol>
|
|
155
|
+
<li><span class="menu">Produits → Créer</span> : titre, sous-titre, description, identifiant d'URL (handle).</li>
|
|
156
|
+
<li><b>Médias</b> : glisser les photos ; la première sert de vignette sur le site.</li>
|
|
157
|
+
<li><b>Options et variantes</b> : ex. option « Couleur » (Noir, Blanc) et « Taille » (S, M, L) → une variante par combinaison, chacune avec son SKU, son prix et son stock.</li>
|
|
158
|
+
<li><b>Canaux de vente</b> : cocher les boutiques où le produit apparaît (voir B7).</li>
|
|
159
|
+
<li><b>Organisation</b> : catégorie(s), collection, type, tags.</li>
|
|
160
|
+
<li><b>Statut</b> : <b>Publié</b>. Un brouillon n'apparaît nulle part.</li>
|
|
161
|
+
</ol>
|
|
162
|
+
<p><b>Beaucoup de produits ?</b> <span class="menu">Produits → Importer</span> un fichier CSV (modèle téléchargeable sur le même écran) ; <b>Exporter</b> pour les modifier dans un tableur.</p>
|
|
163
|
+
|
|
164
|
+
<h2>B5. Prix par devise et prix barrés</h2>
|
|
165
|
+
<div class="box warn">Chaque variante doit avoir un prix <b>dans la devise de chaque boutique où elle est vendue</b> ({{CURRENCIES}}). Sans prix dans une devise, le produit n'apparaît pas dans la boutique concernée.</div>
|
|
166
|
+
<ul>
|
|
167
|
+
<li><b>Prix normal</b> : produit → variante → <b>Modifier les prix</b> : une colonne par devise.</li>
|
|
168
|
+
<li><b>Prix barré (soldes)</b> : <span class="menu">Listes de prix → Créer</span>, type <b>Soldes (Sale)</b>, dates de début et de fin, ajouter les produits et le prix soldé par devise. Le site affiche l'ancien prix barré et le pourcentage.</li>
|
|
169
|
+
<li><b>Prix réservés à un groupe</b> (ex. clients VIP, revendeurs) : liste de prix de type <b>Remplacement (Override)</b> limitée à un groupe de clients (B11).</li>
|
|
170
|
+
</ul>
|
|
171
|
+
|
|
172
|
+
<h2>B6. Catégories et collections</h2>
|
|
173
|
+
<ul>
|
|
174
|
+
<li><span class="menu">Produits → Catégories</span> : créer (nom, identifiant), organiser en arborescence, ajouter les produits. Les catégories principales s'affichent en tuiles sur l'accueil de chaque boutique.</li>
|
|
175
|
+
<li><b>Image d'une catégorie</b> : ouvrir la catégorie → bloc <b>Image de la catégorie</b> (colonne de droite) → choisir le fichier → <b>Enregistrer l'image</b>.</li>
|
|
176
|
+
<li><span class="menu">Produits → Collections</span> : regroupements libres (ex. « Idées cadeaux ») ; les produits liés d'une fiche produit viennent de la même collection.</li>
|
|
177
|
+
</ul>
|
|
178
|
+
|
|
179
|
+
<h2>B7. Boutiques (canaux de vente)</h2>
|
|
180
|
+
<p>Chaque boutique est un <b>canal de vente</b> (<span class="menu">Paramètres → Canaux de vente</span>), nommé par son identifiant (première page). Un même produit peut être vendu dans plusieurs boutiques ; le stock est commun.</p>
|
|
181
|
+
<ul>
|
|
182
|
+
<li>Mettre un produit dans une boutique : fiche produit → <b>Canaux de vente</b> → cocher ; ou depuis le canal de vente → <b>Ajouter des produits</b> (plusieurs à la fois).</li>
|
|
183
|
+
<li>Retirer un produit d'une boutique : décocher. Il reste vendu ailleurs.</li>
|
|
184
|
+
</ul>
|
|
185
|
+
<div class="box warn">Ne pas renommer ni supprimer un canal de vente, ni sa clé API : la boutique correspondante ne fonctionnerait plus. Nouvelle boutique = demande à l'équipe (A1).</div>
|
|
186
|
+
|
|
187
|
+
<h2>B8. Stock</h2>
|
|
188
|
+
<ul>
|
|
189
|
+
<li><span class="menu">Inventaire</span> : quantité disponible par article et par entrepôt ; <b>réservé</b> = commandes non encore expédiées.</li>
|
|
190
|
+
<li>Le stock baisse à chaque commande et remonte à l'annulation ou à la réception d'un retour.</li>
|
|
191
|
+
<li>Rupture : le site affiche « Rupture de stock ». Pour vendre quand même : variante → <b>Autoriser les commandes en rupture</b>.</li>
|
|
192
|
+
</ul>
|
|
193
|
+
|
|
194
|
+
<h2>B9. Campagnes : textes, images, logo, compte à rebours</h2>
|
|
195
|
+
<p><span class="menu">Campagnes</span> (menu ajouté pour vos boutiques) → ligne de la boutique → <b>Modifier</b>. Visible sur le site en environ une minute.</p>
|
|
196
|
+
<table>
|
|
197
|
+
<tr><th>Section</th><th>Champs</th></tr>
|
|
198
|
+
<tr><td>Identité</td><td><b>Logo</b> (remplace la pastille ; sert aussi d'icône d'onglet), <b>compte à rebours</b> : comme le thème / toujours / jamais.</td></tr>
|
|
199
|
+
<tr><td>Dates</td><td>Début et fin de l'offre (compte à rebours, et page « Cette vente est terminée » après la fin) ; <b>campagne suivante</b> : boutique proposée quand celle-ci est finie.</td></tr>
|
|
200
|
+
<tr><td>Variables</td><td>Remise (ex. 30%) et seuil de livraison offerte, repris dans les textes du thème.</td></tr>
|
|
201
|
+
<tr><td>Bannière principale</td><td>Sur-titre, titre, <b>mots mis en couleur</b> (doivent faire partie du titre), sous-titre, 2 boutons, bulle (3 textes), <b>visuel</b>.</td></tr>
|
|
202
|
+
<tr><td>Barre du haut</td><td>Jusqu'à 3 messages.</td></tr>
|
|
203
|
+
<tr><td>Bandeau promo</td><td>Sur-titre, titre, texte, bouton, pastille, <b>image</b>.</td></tr>
|
|
204
|
+
</table>
|
|
205
|
+
<p>Un champ laissé vide reprend le texte du thème. <b>Réinitialiser aux textes du thème</b> efface vos textes (images, logo et dates sont gardés). Texte simple uniquement ; images jpg, png ou webp, 5 Mo max.</p>
|
|
206
|
+
<div class="box info">Ne pas confondre avec <span class="menu">Promotions → Campagnes</span> de Medusa, qui regroupe des codes promo avec un budget (B10).</div>
|
|
207
|
+
|
|
208
|
+
<h2>B10. Codes promo et promotions</h2>
|
|
209
|
+
<p><span class="menu">Promotions → Créer</span> :</p>
|
|
210
|
+
<table>
|
|
211
|
+
<tr><th>Type</th><th>Exemple</th></tr>
|
|
212
|
+
<tr><td>Remise en % ou en montant sur la commande</td><td><code>BF20</code> = −20 % sur tout le panier</td></tr>
|
|
213
|
+
<tr><td>Remise sur certains produits</td><td>−10 € sur la catégorie Audio</td></tr>
|
|
214
|
+
<tr><td>Achetez X, obtenez Y</td><td>2 achetés = le 3e offert</td></tr>
|
|
215
|
+
<tr><td>Livraison offerte</td><td>code <code>SHIPFREE</code></td></tr>
|
|
216
|
+
</table>
|
|
217
|
+
<ul>
|
|
218
|
+
<li><b>Code</b> (saisi par le client dans le panier) ou <b>automatique</b> (appliqué sans code).</li>
|
|
219
|
+
<li><b>Conditions</b> : produits, catégories, collections, groupes de clients, devise, montant minimum…</li>
|
|
220
|
+
<li><b>Limites et dates</b> : rattacher la promotion à une <b>campagne de promotion</b> (dates de début/fin, budget en nombre d'utilisations ou en montant).</li>
|
|
221
|
+
<li>Désactiver : passer la promotion en <b>Brouillon</b>.</li>
|
|
222
|
+
</ul>
|
|
223
|
+
<div class="box warn">Une remise en montant (ex. −10) s'applique dans la devise choisie : créez une promotion par devise si besoin. Testez chaque code dans la bonne boutique avant de l'annoncer.</div>
|
|
224
|
+
|
|
225
|
+
<h2>B11. Clients et groupes</h2>
|
|
226
|
+
<ul>
|
|
227
|
+
<li><span class="menu">Clients</span> : comptes créés sur les boutiques (un compte fonctionne dans toutes), adresses, historique des commandes.</li>
|
|
228
|
+
<li><span class="menu">Clients → Groupes</span> : ex. « VIP », pour des listes de prix (B5) ou des promotions (B10) réservées.</li>
|
|
229
|
+
</ul>
|
|
230
|
+
|
|
231
|
+
<h2>B12. Livraison et taxes</h2>
|
|
232
|
+
<ul>
|
|
233
|
+
<li><b>Tarifs</b> : <span class="menu">Paramètres → Emplacements et livraison</span> → Entrepôt principal → Livraison → zone <b>Monde</b> → options <b>Standard</b> et <b>Express</b> → <b>Modifier les prix</b> (un prix par devise). Vous pouvez ajouter une option (ex. Retrait en magasin).</li>
|
|
234
|
+
<li><b>Livraison offerte au-delà d'un montant</b> : promotion de type livraison offerte, automatique, avec condition de montant minimum (B10). Indiquer le seuil dans la variable de campagne (B9).</li>
|
|
235
|
+
<li><b>Taxes</b> : par défaut 0 % (prix affichés TTC). Pour appliquer une TVA : <span class="menu">Paramètres → Régions de taxe</span> → pays → taux par défaut.</li>
|
|
236
|
+
</ul>
|
|
237
|
+
|
|
238
|
+
<h2>B13. À ne pas toucher</h2>
|
|
239
|
+
<ul>
|
|
240
|
+
<li><span class="menu">Paramètres → Régions</span> : générées depuis la configuration du projet (une par devise). Changer un pays ou une devise = demande à l'équipe.</li>
|
|
241
|
+
<li><span class="menu">Paramètres → Canaux de vente</span> et <span class="menu">Clés API publiables</span> : une par boutique.</li>
|
|
242
|
+
<li><span class="menu">Paramètres → Magasin</span> : devises du magasin.</li>
|
|
243
|
+
</ul>
|
|
244
|
+
|
|
245
|
+
<h2>B14. Dépannage</h2>
|
|
246
|
+
<table>
|
|
247
|
+
<tr><th>Problème</th><th>À vérifier</th></tr>
|
|
248
|
+
<tr><td>Produit invisible sur une boutique</td><td>Publié ? coché dans le canal de vente de cette boutique ? prix dans sa devise ? (attendre 1 min)</td></tr>
|
|
249
|
+
<tr><td>« Cette vente est terminée »</td><td>Date de fin de la campagne dépassée (B9) : prolonger ou renseigner la campagne suivante.</td></tr>
|
|
250
|
+
<tr><td>Modification pas visible</td><td>Attendre une minute puis recharger la page.</td></tr>
|
|
251
|
+
<tr><td>Le client ne reçoit pas d'e-mail</td><td>Dossier spam ; e-mails configurés (A4) ; adresse du client correcte dans la commande.</td></tr>
|
|
252
|
+
<tr><td>Paiement carte impossible</td><td>Clés Stripe et webhook (A3) ; compte Stripe activé en mode production.</td></tr>
|
|
253
|
+
<tr><td>Code promo refusé</td><td>Dates, budget, conditions (produits, devise, montant minimum), statut non brouillon.</td></tr>
|
|
254
|
+
<tr><td>Autre</td><td>Contact : {{SUPPORT}}</td></tr>
|
|
255
|
+
</table>
|
|
256
|
+
</section>
|
|
257
|
+
|
|
258
|
+
</body>
|
|
259
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@salifbiaye/create-boutique",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Usine à Boutiques : génère un projet complet (backend Medusa + une boutique Next.js par campagne) prêt pour docker compose",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"repository": { "type": "git", "url": "git+https://github.com/salifbiaye/create-boutique.git" },
|
|
7
|
+
"license": "UNLICENSED",
|
|
8
|
+
"bin": {
|
|
9
|
+
"create-boutique": "cli/dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"cli/dist",
|
|
13
|
+
"templates/storefront",
|
|
14
|
+
"!templates/storefront/node_modules",
|
|
15
|
+
"!templates/storefront/.next",
|
|
16
|
+
"!templates/storefront/.env*",
|
|
17
|
+
"!templates/storefront/**/*.log",
|
|
18
|
+
"templates/backend",
|
|
19
|
+
"!templates/backend/node_modules",
|
|
20
|
+
"!templates/backend/.medusa",
|
|
21
|
+
"!templates/backend/static",
|
|
22
|
+
"!templates/backend/uploads",
|
|
23
|
+
"!templates/backend/.env*",
|
|
24
|
+
"!templates/backend/**/*.log",
|
|
25
|
+
"docs/fiche-client.html",
|
|
26
|
+
"docs/fiche-client.en.html",
|
|
27
|
+
"docs/guide-complet.fr.html",
|
|
28
|
+
"docs/guide-complet.en.html"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p cli",
|
|
32
|
+
"dev": "tsc -p cli --watch",
|
|
33
|
+
"typecheck": "tsc -p cli --noEmit",
|
|
34
|
+
"prepare": "tsc -p cli"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=20.12"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@clack/prompts": "1.8.1",
|
|
44
|
+
"picocolors": "1.1.1",
|
|
45
|
+
"zod": "4.6.5"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "24.19.0",
|
|
49
|
+
"typescript": "5.9.3"
|
|
50
|
+
}
|
|
51
|
+
}
|