@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,119 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { themeIds } from "./themes.js";
|
|
5
|
+
/**
|
|
6
|
+
* config/project.json : source de vérité unique d'un projet généré.
|
|
7
|
+
* Même règles que le storefront (src/lib/boutique/schema.ts) et le backend (src/lib/project.ts).
|
|
8
|
+
*/
|
|
9
|
+
export const SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
10
|
+
const code2 = z.string().regex(/^[a-z]{2}$/, "code pays ISO à 2 lettres en minuscules (ex. us)");
|
|
11
|
+
const code3 = z.string().regex(/^[a-z]{3}$/, "code devise ISO à 3 lettres en minuscules (ex. usd)");
|
|
12
|
+
const shipsTo = z.union([z.literal("all"), z.array(code2).min(1)]);
|
|
13
|
+
export const projectSchema = z.object({
|
|
14
|
+
$schema: z.string().optional(),
|
|
15
|
+
project: z.string().regex(SLUG),
|
|
16
|
+
templateVersion: z.string().optional(),
|
|
17
|
+
apiPort: z.number().int().min(1).max(65535).default(9000),
|
|
18
|
+
storagePort: z.number().int().min(1).max(65535).default(9100),
|
|
19
|
+
defaults: z.looseObject({
|
|
20
|
+
storeName: z.string().min(1).max(60),
|
|
21
|
+
currency: code3,
|
|
22
|
+
country: code2,
|
|
23
|
+
language: z.string().regex(/^[a-z]{2}$/).default("en"),
|
|
24
|
+
shipsTo: shipsTo.default("all"),
|
|
25
|
+
merchantEmail: z.email().optional(),
|
|
26
|
+
email: z.object({ mode: z.enum(["platform", "merchant"]), from: z.email().optional() }).optional(),
|
|
27
|
+
}),
|
|
28
|
+
boutiques: z
|
|
29
|
+
.array(z.strictObject({
|
|
30
|
+
slug: z.string().regex(SLUG, "slug : minuscules, chiffres et tirets"),
|
|
31
|
+
theme: z.string(),
|
|
32
|
+
port: z.number().int().min(1).max(65535),
|
|
33
|
+
url: z.url().optional(),
|
|
34
|
+
storeName: z.string().min(1).max(60).optional(),
|
|
35
|
+
currency: code3.optional(),
|
|
36
|
+
country: code2.optional(),
|
|
37
|
+
shipsTo: shipsTo.optional(),
|
|
38
|
+
language: z.never({ error: "la langue se règle dans defaults, pas par boutique" }).optional(),
|
|
39
|
+
}))
|
|
40
|
+
.min(1, "au moins une boutique"),
|
|
41
|
+
});
|
|
42
|
+
export const projectFile = (dir) => path.join(dir, "config", "project.json");
|
|
43
|
+
export class ProjectError extends Error {
|
|
44
|
+
}
|
|
45
|
+
/** Valide le fichier : schéma, slugs uniques, thèmes existants, ports uniques, un pays = une devise. */
|
|
46
|
+
export function validateProject(raw) {
|
|
47
|
+
const res = projectSchema.safeParse(raw);
|
|
48
|
+
if (!res.success)
|
|
49
|
+
throw new ProjectError(z.prettifyError(res.error));
|
|
50
|
+
const p = res.data;
|
|
51
|
+
const errors = [];
|
|
52
|
+
const slugs = p.boutiques.map((b) => b.slug);
|
|
53
|
+
for (const s of new Set(slugs))
|
|
54
|
+
if (slugs.filter((x) => x === s).length > 1)
|
|
55
|
+
errors.push(`slug en double : ${s}`);
|
|
56
|
+
const themes = themeIds();
|
|
57
|
+
for (const b of p.boutiques)
|
|
58
|
+
if (!themes.includes(b.theme))
|
|
59
|
+
errors.push(`${b.slug} : thème inconnu « ${b.theme} » (disponibles : ${themes.join(", ")})`);
|
|
60
|
+
const ports = [p.apiPort, p.storagePort, ...p.boutiques.map((b) => b.port)];
|
|
61
|
+
for (const port of new Set(ports))
|
|
62
|
+
if (ports.filter((x) => x === port).length > 1)
|
|
63
|
+
errors.push(`port utilisé deux fois : ${port}`);
|
|
64
|
+
// Un pays ne peut appartenir qu'à une devise (une région Medusa par devise).
|
|
65
|
+
const owner = new Map();
|
|
66
|
+
for (const b of p.boutiques) {
|
|
67
|
+
const currency = b.currency ?? p.defaults.currency;
|
|
68
|
+
const country = b.country ?? p.defaults.country;
|
|
69
|
+
const list = b.shipsTo ?? p.defaults.shipsTo;
|
|
70
|
+
for (const c of [country, ...(Array.isArray(list) ? list : [])]) {
|
|
71
|
+
const o = owner.get(c);
|
|
72
|
+
if (o && o !== currency) {
|
|
73
|
+
const pair = [o, currency].sort().map((x) => x.toUpperCase());
|
|
74
|
+
errors.push(`le pays « ${c} » est demandé en ${pair[0]} et en ${pair[1]} : un pays = une devise`);
|
|
75
|
+
}
|
|
76
|
+
else
|
|
77
|
+
owner.set(c, currency);
|
|
78
|
+
}
|
|
79
|
+
if (Array.isArray(list) && !list.includes(country))
|
|
80
|
+
errors.push(`${b.slug} : le pays principal « ${country} » doit faire partie de shipsTo`);
|
|
81
|
+
}
|
|
82
|
+
if (errors.length)
|
|
83
|
+
throw new ProjectError([...new Set(errors)].map((e) => `- ${e}`).join("\n"));
|
|
84
|
+
return p;
|
|
85
|
+
}
|
|
86
|
+
export function readProject(dir) {
|
|
87
|
+
const file = projectFile(dir);
|
|
88
|
+
if (!fs.existsSync(file))
|
|
89
|
+
throw new ProjectError(`${file} introuvable : est-ce bien un dossier de projet ?`);
|
|
90
|
+
let raw;
|
|
91
|
+
try {
|
|
92
|
+
raw = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
throw new ProjectError(`${file} : JSON invalide (${e.message})`);
|
|
96
|
+
}
|
|
97
|
+
return validateProject(raw);
|
|
98
|
+
}
|
|
99
|
+
export function writeProject(dir, p) {
|
|
100
|
+
fs.mkdirSync(path.dirname(projectFile(dir)), { recursive: true });
|
|
101
|
+
const { $schema: _ignored, ...rest } = p;
|
|
102
|
+
fs.writeFileSync(projectFile(dir), JSON.stringify({ $schema: "./project.schema.json", ...rest }, null, 2) + "\n");
|
|
103
|
+
}
|
|
104
|
+
/** Valeurs effectives d'une boutique (defaults + surcharge). */
|
|
105
|
+
export function effective(p, b) {
|
|
106
|
+
return {
|
|
107
|
+
...b,
|
|
108
|
+
storeName: b.storeName ?? p.defaults.storeName,
|
|
109
|
+
currency: b.currency ?? p.defaults.currency,
|
|
110
|
+
country: b.country ?? p.defaults.country,
|
|
111
|
+
shipsTo: b.shipsTo ?? p.defaults.shipsTo,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export const currencies = (p) => [...new Set([p.defaults.currency, ...p.boutiques.map((b) => b.currency ?? p.defaults.currency)])];
|
|
115
|
+
/** Schéma JSON pour l'autocomplétion de project.json dans VS Code. */
|
|
116
|
+
export function writeJsonSchema(dir) {
|
|
117
|
+
const schema = z.toJSONSchema(projectSchema, { io: "input", unrepresentable: "any" });
|
|
118
|
+
fs.writeFileSync(path.join(dir, "config", "project.schema.json"), JSON.stringify(schema, null, 2) + "\n");
|
|
119
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { THEMES_DIR } from "./paths.js";
|
|
4
|
+
// Ordre des saisons ; un thème ajouté plus tard se range après, par ordre alphabétique.
|
|
5
|
+
const SEASONS = ["halloween", "thanksgiving", "black-friday", "cyber-monday", "noel", "nouvel-an"];
|
|
6
|
+
const rank = (id) => (SEASONS.includes(id) ? SEASONS.indexOf(id) : SEASONS.length);
|
|
7
|
+
/** Registre des thèmes : un dossier templates/storefront/themes/<id>/ avec theme.json. */
|
|
8
|
+
export function listThemes() {
|
|
9
|
+
if (!fs.existsSync(THEMES_DIR))
|
|
10
|
+
return [];
|
|
11
|
+
return fs
|
|
12
|
+
.readdirSync(THEMES_DIR, { withFileTypes: true })
|
|
13
|
+
.filter((d) => d.isDirectory() && fs.existsSync(path.join(THEMES_DIR, d.name, "theme.json")))
|
|
14
|
+
.map((d) => {
|
|
15
|
+
const theme = JSON.parse(fs.readFileSync(path.join(THEMES_DIR, d.name, "theme.json"), "utf8"));
|
|
16
|
+
const languages = fs
|
|
17
|
+
.readdirSync(path.join(THEMES_DIR, d.name))
|
|
18
|
+
.map((f) => f.match(/^campaign\.([a-z]{2})\.json$/)?.[1])
|
|
19
|
+
.filter((l) => !!l);
|
|
20
|
+
return { id: d.name, name: theme.name ?? d.name, languages };
|
|
21
|
+
})
|
|
22
|
+
.sort((a, b) => rank(a.id) - rank(b.id) || a.id.localeCompare(b.id));
|
|
23
|
+
}
|
|
24
|
+
export const themeIds = () => listThemes().map((t) => t.id);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Manage your store in 3 screens</title>
|
|
6
|
+
<style>
|
|
7
|
+
@page { size: A4; margin: 0; }
|
|
8
|
+
:root{
|
|
9
|
+
--ink:#16181d; --muted:#5b616e; --line:#e3e5ea; --soft:#f5f6f8;
|
|
10
|
+
--accent:#2b4fd8; --accent-soft:#eef1fd; --warn:#9a4a07; --warn-soft:#fdf3e7;
|
|
11
|
+
}
|
|
12
|
+
*{box-sizing:border-box}
|
|
13
|
+
html,body{margin:0;padding:0}
|
|
14
|
+
body{font-family:"Carlito","Liberation Sans",Arial,sans-serif;color:var(--ink);font-size:10.2pt;line-height:1.36;-webkit-print-color-adjust:exact;print-color-adjust:exact}
|
|
15
|
+
.page{width:210mm;height:296mm;overflow:hidden;padding:13mm 15mm 10mm;display:flex;flex-direction:column}
|
|
16
|
+
header{display:flex;justify-content:space-between;align-items:flex-end;border-bottom:2px solid var(--ink);padding-bottom:4mm;margin-bottom:4mm}
|
|
17
|
+
h1{font-size:23pt;line-height:1.05;margin:0 0 1.5mm;letter-spacing:-.01em}
|
|
18
|
+
.sub{color:var(--muted);font-size:11pt;margin:0}
|
|
19
|
+
.login{background:var(--soft);border-radius:3mm;padding:3mm 4mm;font-size:9.6pt;min-width:74mm}
|
|
20
|
+
.login span{white-space:nowrap}
|
|
21
|
+
.login b{display:block;font-size:8.4pt;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin-bottom:1mm}
|
|
22
|
+
.login div{display:flex;justify-content:space-between;gap:4mm}
|
|
23
|
+
.login span{color:var(--muted)}
|
|
24
|
+
.fill{border-bottom:1px dotted #9aa0ab;min-width:36mm;display:inline-block}
|
|
25
|
+
.screens{display:flex;flex-direction:column;gap:3mm}
|
|
26
|
+
.screen{display:grid;grid-template-columns:11mm 1fr;gap:4mm;border:1px solid var(--line);border-radius:3mm;padding:3.2mm 5mm}
|
|
27
|
+
.num{width:11mm;height:11mm;border-radius:50%;background:var(--ink);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:14pt}
|
|
28
|
+
h2{font-size:14pt;margin:0;display:flex;align-items:baseline;gap:3mm}
|
|
29
|
+
h2 small{font-size:9.4pt;font-weight:400;color:var(--muted)}
|
|
30
|
+
.where{font-size:9.2pt;color:var(--accent);background:var(--accent-soft);display:inline-block;padding:.4mm 2.2mm;border-radius:1.5mm;margin:1mm 0 1.5mm}
|
|
31
|
+
ol,ul{margin:0;padding-left:5mm}
|
|
32
|
+
li{margin:.3mm 0}
|
|
33
|
+
.flow{display:flex;align-items:center;gap:1.6mm;flex-wrap:wrap;margin:1.5mm 0 2mm;font-size:9.2pt}
|
|
34
|
+
.flow span{border:1px solid var(--line);background:var(--soft);border-radius:1.5mm;padding:.6mm 2mm;white-space:nowrap}
|
|
35
|
+
.flow i{font-style:normal;color:var(--muted)}
|
|
36
|
+
.tip{margin-top:2mm;font-size:9.4pt;color:var(--muted)}
|
|
37
|
+
.tip b{color:var(--ink)}
|
|
38
|
+
.warn{background:var(--warn-soft);color:var(--warn);border-radius:2mm;padding:1.6mm 3mm;font-size:9.4pt;margin-top:2mm}
|
|
39
|
+
.bottom{display:grid;grid-template-columns:1fr 1fr;gap:4mm;margin-top:3mm}
|
|
40
|
+
.box{border-radius:3mm;padding:3mm 4.5mm;font-size:9.6pt}
|
|
41
|
+
.box h3{font-size:11pt;margin:0 0 1.5mm}
|
|
42
|
+
.ok{background:var(--soft)}
|
|
43
|
+
.no{border:1px solid var(--line)}
|
|
44
|
+
footer{margin-top:auto;padding-bottom:0;border-top:1px solid var(--line);padding-top:3mm;display:flex;justify-content:space-between;font-size:9.2pt;color:var(--muted)}
|
|
45
|
+
footer b{color:var(--ink)}
|
|
46
|
+
</style>
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
<div class="page">
|
|
50
|
+
<header>
|
|
51
|
+
<div>
|
|
52
|
+
<h1>Manage your store<br>in 3 screens</h1>
|
|
53
|
+
<p class="sub">Everything happens in your admin. The rest is already set up for you.</p>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="login">
|
|
56
|
+
<b>Your access</b>
|
|
57
|
+
<div><span>Address</span><span class="fill">{{ADMIN_URL}}</span></div>
|
|
58
|
+
<div><span>Email</span><span class="fill">{{ADMIN_EMAIL}}</span></div>
|
|
59
|
+
<div><span>Password</span><span class="fill"> </span></div>
|
|
60
|
+
</div>
|
|
61
|
+
</header>
|
|
62
|
+
|
|
63
|
+
<section class="screens">
|
|
64
|
+
<div class="screen">
|
|
65
|
+
<div class="num">1</div>
|
|
66
|
+
<div>
|
|
67
|
+
<h2>Orders <small>view, ship, refund</small></h2>
|
|
68
|
+
<div class="where">Menu: Orders</div>
|
|
69
|
+
<div class="flow">
|
|
70
|
+
<span>Paid</span><i>→</i><span>Fulfilled</span><i>→</i><span>Shipped</span><i>→</i><span>Delivered (optional)</span>
|
|
71
|
+
</div>
|
|
72
|
+
<ol>
|
|
73
|
+
<li>Open the order: customer, address, items and total are shown. Card payments are captured automatically.</li>
|
|
74
|
+
<li><b>Fulfill</b>: in “Fulfillment”, click <b>Create fulfillment</b> and pick the items.</li>
|
|
75
|
+
<li><b>Ship</b>: click <b>Mark as shipped</b> and enter the tracking number. The customer gets an email with it.</li>
|
|
76
|
+
<li><b>Deliver</b>: <b>Mark as delivered</b> once the carrier confirms delivery.</li>
|
|
77
|
+
</ol>
|
|
78
|
+
<p class="tip"><b>Cancel or refund:</b> buttons at the top of the order and in the Payment section. The customer is notified by email.</p>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div class="screen">
|
|
83
|
+
<div class="num">2</div>
|
|
84
|
+
<div>
|
|
85
|
+
<h2>Products <small>add, edit, manage stock</small></h2>
|
|
86
|
+
<div class="where">Menu: Products</div>
|
|
87
|
+
<ol>
|
|
88
|
+
<li><b>Create</b>: title, description, photos (drop them into “Media”).</li>
|
|
89
|
+
<li><b>Variants</b>: add options (size, color) and a <b>price for each variant</b> in each currency.</li>
|
|
90
|
+
<li><b>Stores</b>: in “Sales channels”, tick the stores where the product must appear.</li>
|
|
91
|
+
<li><b>Publish</b>: status <b>Published</b>. A draft does not appear on the site.</li>
|
|
92
|
+
<li><b>Stock</b>: menu <b>Inventory</b>, enter the available quantity.</li>
|
|
93
|
+
</ol>
|
|
94
|
+
<div class="warn">Product not visible on the site? Check it is Published, has a price in the store's currency and is ticked for the right store.</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div class="screen">
|
|
99
|
+
<div class="num">3</div>
|
|
100
|
+
<div>
|
|
101
|
+
<h2>Campaigns <small>texts and images of each store</small></h2>
|
|
102
|
+
<div class="where">Menu: Campaigns</div>
|
|
103
|
+
<ol>
|
|
104
|
+
<li>Pick the store (Halloween, Black Friday, Christmas…) and click <b>Edit</b>.</li>
|
|
105
|
+
<li>Change the title, text, button, hero image, logo and the offer dates.</li>
|
|
106
|
+
<li>Click <b>Save</b>: the site is updated within about a minute.</li>
|
|
107
|
+
</ol>
|
|
108
|
+
<p class="tip"><b>Undo:</b> “Reset to theme texts” restores the original texts (images and dates are kept).</p>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</section>
|
|
112
|
+
|
|
113
|
+
<div class="bottom">
|
|
114
|
+
<div class="box ok">
|
|
115
|
+
<h3>Also useful</h3>
|
|
116
|
+
<ul>
|
|
117
|
+
<li><b>Discount codes</b>: menu Promotions (e.g. “BF20” = −20%).</li>
|
|
118
|
+
<li><b>Admin language</b>: Settings → Profile → Language.</li>
|
|
119
|
+
<li>Your customers' replies to emails reach your address.</li>
|
|
120
|
+
</ul>
|
|
121
|
+
</div>
|
|
122
|
+
<div class="box no">
|
|
123
|
+
<h3>No need to touch</h3>
|
|
124
|
+
<ul>
|
|
125
|
+
<li>Settings: regions, payments, shipping, sales channels, API keys.</li>
|
|
126
|
+
<li>They are configured for you. Need a change? Contact us.</li>
|
|
127
|
+
</ul>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<footer>
|
|
132
|
+
<span>Need help: <b class="fill" style="min-width:60mm">{{SUPPORT}}</b></span>
|
|
133
|
+
<span>Never share your password.</span>
|
|
134
|
+
</footer>
|
|
135
|
+
</div>
|
|
136
|
+
</body>
|
|
137
|
+
</html>
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="fr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Gérer votre boutique en 3 écrans</title>
|
|
6
|
+
<style>
|
|
7
|
+
@page { size: A4; margin: 0; }
|
|
8
|
+
:root{
|
|
9
|
+
--ink:#16181d; --muted:#5b616e; --line:#e3e5ea; --soft:#f5f6f8;
|
|
10
|
+
--accent:#2b4fd8; --accent-soft:#eef1fd; --warn:#9a4a07; --warn-soft:#fdf3e7;
|
|
11
|
+
}
|
|
12
|
+
*{box-sizing:border-box}
|
|
13
|
+
html,body{margin:0;padding:0}
|
|
14
|
+
body{font-family:"Carlito","Liberation Sans",Arial,sans-serif;color:var(--ink);font-size:10.2pt;line-height:1.36;-webkit-print-color-adjust:exact;print-color-adjust:exact}
|
|
15
|
+
.page{width:210mm;height:296mm;overflow:hidden;padding:13mm 15mm 10mm;display:flex;flex-direction:column}
|
|
16
|
+
header{display:flex;justify-content:space-between;align-items:flex-end;border-bottom:2px solid var(--ink);padding-bottom:4mm;margin-bottom:4mm}
|
|
17
|
+
h1{font-size:23pt;line-height:1.05;margin:0 0 1.5mm;letter-spacing:-.01em}
|
|
18
|
+
.sub{color:var(--muted);font-size:11pt;margin:0}
|
|
19
|
+
.login{background:var(--soft);border-radius:3mm;padding:3mm 4mm;font-size:9.6pt;min-width:74mm}
|
|
20
|
+
.login span{white-space:nowrap}
|
|
21
|
+
.login b{display:block;font-size:8.4pt;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin-bottom:1mm}
|
|
22
|
+
.login div{display:flex;justify-content:space-between;gap:4mm}
|
|
23
|
+
.login span{color:var(--muted)}
|
|
24
|
+
.fill{border-bottom:1px dotted #9aa0ab;min-width:36mm;display:inline-block}
|
|
25
|
+
.screens{display:flex;flex-direction:column;gap:3mm}
|
|
26
|
+
.screen{display:grid;grid-template-columns:11mm 1fr;gap:4mm;border:1px solid var(--line);border-radius:3mm;padding:3.2mm 5mm}
|
|
27
|
+
.num{width:11mm;height:11mm;border-radius:50%;background:var(--ink);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:14pt}
|
|
28
|
+
h2{font-size:14pt;margin:0;display:flex;align-items:baseline;gap:3mm}
|
|
29
|
+
h2 small{font-size:9.4pt;font-weight:400;color:var(--muted)}
|
|
30
|
+
.where{font-size:9.2pt;color:var(--accent);background:var(--accent-soft);display:inline-block;padding:.4mm 2.2mm;border-radius:1.5mm;margin:1mm 0 1.5mm}
|
|
31
|
+
ol,ul{margin:0;padding-left:5mm}
|
|
32
|
+
li{margin:.3mm 0}
|
|
33
|
+
.flow{display:flex;align-items:center;gap:1.6mm;flex-wrap:wrap;margin:1.5mm 0 2mm;font-size:9.2pt}
|
|
34
|
+
.flow span{border:1px solid var(--line);background:var(--soft);border-radius:1.5mm;padding:.6mm 2mm;white-space:nowrap}
|
|
35
|
+
.flow i{font-style:normal;color:var(--muted)}
|
|
36
|
+
.tip{margin-top:2mm;font-size:9.4pt;color:var(--muted)}
|
|
37
|
+
.tip b{color:var(--ink)}
|
|
38
|
+
.warn{background:var(--warn-soft);color:var(--warn);border-radius:2mm;padding:1.6mm 3mm;font-size:9.4pt;margin-top:2mm}
|
|
39
|
+
.bottom{display:grid;grid-template-columns:1fr 1fr;gap:4mm;margin-top:3mm}
|
|
40
|
+
.box{border-radius:3mm;padding:3mm 4.5mm;font-size:9.6pt}
|
|
41
|
+
.box h3{font-size:11pt;margin:0 0 1.5mm}
|
|
42
|
+
.ok{background:var(--soft)}
|
|
43
|
+
.no{border:1px solid var(--line)}
|
|
44
|
+
footer{margin-top:auto;padding-bottom:0;border-top:1px solid var(--line);padding-top:3mm;display:flex;justify-content:space-between;font-size:9.2pt;color:var(--muted)}
|
|
45
|
+
footer b{color:var(--ink)}
|
|
46
|
+
</style>
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
<div class="page">
|
|
50
|
+
<header>
|
|
51
|
+
<div>
|
|
52
|
+
<h1>Gérer votre boutique<br>en 3 écrans</h1>
|
|
53
|
+
<p class="sub">Tout se passe dans votre espace d'administration. Le reste est déjà configuré pour vous.</p>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="login">
|
|
56
|
+
<b>Votre accès</b>
|
|
57
|
+
<div><span>Adresse</span><span class="fill">{{ADMIN_URL}}</span></div>
|
|
58
|
+
<div><span>E-mail</span><span class="fill">{{ADMIN_EMAIL}}</span></div>
|
|
59
|
+
<div><span>Mot de passe</span><span class="fill"> </span></div>
|
|
60
|
+
</div>
|
|
61
|
+
</header>
|
|
62
|
+
|
|
63
|
+
<section class="screens">
|
|
64
|
+
<div class="screen">
|
|
65
|
+
<div class="num">1</div>
|
|
66
|
+
<div>
|
|
67
|
+
<h2>Commandes <small>voir, expédier, rembourser</small></h2>
|
|
68
|
+
<div class="where">Menu : Orders (Commandes)</div>
|
|
69
|
+
<div class="flow">
|
|
70
|
+
<span>Payée</span><i>→</i><span>Préparée</span><i>→</i><span>Expédiée</span><i>→</i><span>Livrée (facultatif)</span>
|
|
71
|
+
</div>
|
|
72
|
+
<ol>
|
|
73
|
+
<li>Ouvrez la commande : client, adresse, articles et total sont affichés. Le paiement par carte est encaissé automatiquement.</li>
|
|
74
|
+
<li><b>Préparer</b> : dans « Fulfillment », cliquez sur <b>Créer un traitement</b> et choisissez les articles.</li>
|
|
75
|
+
<li><b>Expédier</b> : cliquez sur <b>Marquer comme expédié</b> et saisissez le numéro de suivi. Le client reçoit un e-mail avec ce numéro.</li>
|
|
76
|
+
<li><b>Livrer</b> : <b>Marquer comme livré</b> quand le transporteur confirme la livraison.</li>
|
|
77
|
+
</ol>
|
|
78
|
+
<p class="tip"><b>Annuler ou rembourser :</b> boutons en haut de la commande et dans la partie Paiement. Le client est prévenu par e-mail.</p>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div class="screen">
|
|
83
|
+
<div class="num">2</div>
|
|
84
|
+
<div>
|
|
85
|
+
<h2>Produits <small>ajouter, modifier, gérer le stock</small></h2>
|
|
86
|
+
<div class="where">Menu : Products (Produits)</div>
|
|
87
|
+
<ol>
|
|
88
|
+
<li><b>Créer</b> : titre, description, photos (glissez-les dans « Media »).</li>
|
|
89
|
+
<li><b>Variantes</b> : ajoutez les options (taille, couleur) et un <b>prix pour chaque variante</b>.</li>
|
|
90
|
+
<li><b>Boutiques</b> : dans « Canaux de vente », cochez les boutiques où le produit doit apparaître.</li>
|
|
91
|
+
<li><b>Publier</b> : statut <b>Publié</b>. Un brouillon n'apparaît pas sur le site.</li>
|
|
92
|
+
<li><b>Stock</b> : menu <b>Inventory</b>, indiquez la quantité disponible.</li>
|
|
93
|
+
</ol>
|
|
94
|
+
<div class="warn">Un produit invisible sur le site ? Vérifiez qu'il est Publié, qu'il a un prix et qu'il est coché dans la bonne boutique.</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div class="screen">
|
|
99
|
+
<div class="num">3</div>
|
|
100
|
+
<div>
|
|
101
|
+
<h2>Campagnes <small>textes et images de chaque boutique</small></h2>
|
|
102
|
+
<div class="where">Menu : Campagnes</div>
|
|
103
|
+
<ol>
|
|
104
|
+
<li>Choisissez la boutique (Halloween, Black Friday, Noël…) et cliquez sur <b>Modifier</b>.</li>
|
|
105
|
+
<li>Changez le titre, le texte, le bouton, l'image principale, le logo et les dates de l'offre.</li>
|
|
106
|
+
<li>Cliquez sur <b>Enregistrer</b> : le site est à jour en environ une minute.</li>
|
|
107
|
+
</ol>
|
|
108
|
+
<p class="tip"><b>Retour en arrière :</b> « Réinitialiser aux textes du thème » restaure les textes d'origine (images et dates gardées).</p>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</section>
|
|
112
|
+
|
|
113
|
+
<div class="bottom">
|
|
114
|
+
<div class="box ok">
|
|
115
|
+
<h3>Utile aussi</h3>
|
|
116
|
+
<ul>
|
|
117
|
+
<li><b>Codes promo</b> : menu Promotions (ex. « BF20 » = −20 %).</li>
|
|
118
|
+
<li><b>Langue de l'admin</b> : Paramètres → Profil → Langue.</li>
|
|
119
|
+
<li>Les réponses de vos clients aux e-mails arrivent sur votre adresse.</li>
|
|
120
|
+
</ul>
|
|
121
|
+
</div>
|
|
122
|
+
<div class="box no">
|
|
123
|
+
<h3>Inutile d'y toucher</h3>
|
|
124
|
+
<ul>
|
|
125
|
+
<li>Paramètres : régions, paiements, livraison, canaux de vente, clés API.</li>
|
|
126
|
+
<li>Ils sont configurés pour vous. Un changement ? Contactez-nous.</li>
|
|
127
|
+
</ul>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<footer>
|
|
132
|
+
<span>Besoin d'aide : <b class="fill" style="min-width:60mm">{{SUPPORT}}</b></span>
|
|
133
|
+
<span>Ne partagez jamais votre mot de passe.</span>
|
|
134
|
+
</footer>
|
|
135
|
+
</div>
|
|
136
|
+
</body>
|
|
137
|
+
</html>
|