@salifbiaye/create-boutique 0.6.0 → 0.7.0

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.
Files changed (182) hide show
  1. package/cli/dist/code.js +110 -0
  2. package/cli/dist/commands.js +143 -10
  3. package/cli/dist/create.js +54 -7
  4. package/cli/dist/generate.js +65 -4
  5. package/cli/dist/guide.js +10 -2
  6. package/cli/dist/index.js +20 -7
  7. package/cli/dist/payments.js +150 -0
  8. package/docs/fiche-client.en.html +2 -2
  9. package/docs/fiche-client.html +2 -2
  10. package/docs/guide-complet.fr.html +681 -256
  11. package/docs/guide-images/categories.jpg +0 -0
  12. package/docs/guide-images/clients.jpg +0 -0
  13. package/docs/guide-images/collections.jpg +0 -0
  14. package/docs/guide-images/commande-detail.jpg +0 -0
  15. package/docs/guide-images/commande-expedier.jpg +0 -0
  16. package/docs/guide-images/commande-menu.jpg +0 -0
  17. package/docs/guide-images/commande-paiement.jpg +0 -0
  18. package/docs/guide-images/commandes-liste.jpg +0 -0
  19. package/docs/guide-images/connexion.jpg +0 -0
  20. package/docs/guide-images/groupes-clients.jpg +0 -0
  21. package/docs/guide-images/inventaire.jpg +0 -0
  22. package/docs/guide-images/listes-prix.jpg +0 -0
  23. package/docs/guide-images/menu.jpg +0 -0
  24. package/docs/guide-images/mes-boutiques-fermer.jpg +0 -0
  25. package/docs/guide-images/mes-boutiques-panneau.jpg +0 -0
  26. package/docs/guide-images/mes-boutiques.jpg +0 -0
  27. package/docs/guide-images/parametres-boutique.jpg +0 -0
  28. package/docs/guide-images/parametres-canaux.jpg +0 -0
  29. package/docs/guide-images/parametres-emplacements.jpg +0 -0
  30. package/docs/guide-images/parametres-profil.jpg +0 -0
  31. package/docs/guide-images/parametres-regions.jpg +0 -0
  32. package/docs/guide-images/parametres-utilisateurs.jpg +0 -0
  33. package/docs/guide-images/produit-creer-details.jpg +0 -0
  34. package/docs/guide-images/produit-detail.jpg +0 -0
  35. package/docs/guide-images/produit-variantes-menu.jpg +0 -0
  36. package/docs/guide-images/produit-variantes.jpg +0 -0
  37. package/docs/guide-images/produits-liste.jpg +0 -0
  38. package/docs/guide-images/promotion-details.jpg +0 -0
  39. package/docs/guide-images/promotion-type.jpg +0 -0
  40. package/docs/guide-images/promotions-liste.jpg +0 -0
  41. package/docs/guide-images/site-boutique.jpg +0 -0
  42. package/docs/guide-images/site-fermee.png +0 -0
  43. package/docs/guide-images/vue-ensemble.jpg +0 -0
  44. package/package.json +3 -2
  45. package/templates/backend/medusa-config.ts +31 -25
  46. package/templates/backend/package-lock.json +21 -0
  47. package/templates/backend/package.json +2 -0
  48. package/templates/backend/src/admin/i18n/json/en.json +51 -3
  49. package/templates/backend/src/admin/i18n/json/fr.json +51 -3
  50. package/templates/backend/src/admin/routes/boutique-campaigns/campaign-drawer.tsx +2 -0
  51. package/templates/backend/src/admin/routes/boutique-campaigns/page.tsx +36 -1
  52. package/templates/backend/src/admin/routes/reviews/page.tsx +259 -0
  53. package/templates/backend/src/api/admin/boutique-campaigns/route.ts +3 -1
  54. package/templates/backend/src/api/admin/boutique-online/[salesChannelId]/route.ts +22 -0
  55. package/templates/backend/src/api/admin/reviews/[id]/route.ts +15 -0
  56. package/templates/backend/src/api/admin/reviews/route.ts +47 -0
  57. package/templates/backend/src/api/middlewares.ts +7 -0
  58. package/templates/backend/src/api/store/campaign/route.ts +5 -1
  59. package/templates/backend/src/api/store/reviews/latest/route.ts +39 -0
  60. package/templates/backend/src/api/store/reviews/order/route.ts +36 -0
  61. package/templates/backend/src/api/store/reviews/route.ts +43 -0
  62. package/templates/backend/src/api/store/reviews/summary/route.ts +28 -0
  63. package/templates/backend/src/emails/en.json +3 -1
  64. package/templates/backend/src/emails/fr.json +3 -1
  65. package/templates/backend/src/lib/email-config.ts +14 -0
  66. package/templates/backend/src/lib/emails.ts +9 -0
  67. package/templates/backend/src/lib/notify.ts +14 -8
  68. package/templates/backend/src/lib/payment-config.ts +66 -0
  69. package/templates/backend/src/lib/project.ts +12 -0
  70. package/templates/backend/src/lib/redirect-payment.ts +264 -0
  71. package/templates/backend/src/lib/review-token.ts +40 -0
  72. package/templates/backend/src/lib/reviews.ts +25 -0
  73. package/templates/backend/src/modules/naboopay/index.ts +6 -0
  74. package/templates/backend/src/modules/naboopay/service.ts +92 -0
  75. package/templates/backend/src/modules/paydunya/index.ts +6 -0
  76. package/templates/backend/src/modules/paydunya/service.ts +89 -0
  77. package/templates/backend/src/modules/paytech/index.ts +6 -0
  78. package/templates/backend/src/modules/paytech/service.ts +114 -0
  79. package/templates/backend/src/modules/product-review/index.ts +8 -0
  80. package/templates/backend/src/modules/product-review/migrations/Migration20261001090000.ts +18 -0
  81. package/templates/backend/src/modules/product-review/models/review.ts +25 -0
  82. package/templates/backend/src/modules/product-review/service.ts +6 -0
  83. package/templates/backend/src/modules/product-review/validators.ts +27 -0
  84. package/templates/backend/src/modules/smtp/index.ts +6 -0
  85. package/templates/backend/src/modules/smtp/service.ts +73 -0
  86. package/templates/backend/src/scripts/seed.ts +52 -36
  87. package/templates/backend/src/subscribers/fulfillment-emails.ts +1 -1
  88. package/templates/backend/src/workflows/reviews.ts +21 -0
  89. package/templates/backend/src/workflows/steps/create-review.ts +52 -0
  90. package/templates/backend/src/workflows/steps/update-review.ts +36 -0
  91. package/templates/storefront/PERSONNALISER.md +134 -0
  92. package/templates/storefront/locales/en.json +198 -11
  93. package/templates/storefront/locales/fr.json +198 -11
  94. package/templates/storefront/public/custom/LISEZMOI.txt +2 -0
  95. package/templates/storefront/src/app/(checkout)/layout.tsx +1 -1
  96. package/templates/storefront/src/app/(main)/layout.tsx +8 -1
  97. package/templates/storefront/src/app/(main)/legal/[page]/page.tsx +42 -7
  98. package/templates/storefront/src/app/(main)/page.tsx +149 -4
  99. package/templates/storefront/src/app/(main)/review/page.tsx +60 -0
  100. package/templates/storefront/src/app/(main)/store/page.tsx +3 -1
  101. package/templates/storefront/src/app/(main)/template.tsx +17 -2
  102. package/templates/storefront/src/app/layout.tsx +13 -1
  103. package/templates/storefront/src/lib/boutique/campaign.ts +5 -1
  104. package/templates/storefront/src/lib/boutique/page-name.ts +25 -0
  105. package/templates/storefront/src/lib/boutique/schema.ts +3 -1
  106. package/templates/storefront/src/lib/constants.tsx +17 -0
  107. package/templates/storefront/src/lib/data/review-actions.ts +28 -0
  108. package/templates/storefront/src/lib/data/reviews.ts +64 -0
  109. package/templates/storefront/src/modules/checkout/components/payment/index.tsx +26 -4
  110. package/templates/storefront/src/modules/checkout/components/payment-button/index.tsx +85 -2
  111. package/templates/storefront/src/modules/products/templates/index.tsx +5 -0
  112. package/templates/storefront/src/modules/store/components/shop-search.tsx +85 -0
  113. package/templates/storefront/src/modules/store/templates/index.tsx +16 -8
  114. package/templates/storefront/src/modules/store/templates/paginated-products.tsx +15 -3
  115. package/templates/storefront/src/modules/ub/album.tsx +2 -0
  116. package/templates/storefront/src/modules/ub/arena.tsx +182 -0
  117. package/templates/storefront/src/modules/ub/campaign-blocks.tsx +3 -2
  118. package/templates/storefront/src/modules/ub/campaign-ended.tsx +27 -13
  119. package/templates/storefront/src/modules/ub/cinema.tsx +2 -0
  120. package/templates/storefront/src/modules/ub/cookie-banner.tsx +62 -0
  121. package/templates/storefront/src/modules/ub/gala.tsx +2 -0
  122. package/templates/storefront/src/modules/ub/grimoire.tsx +35 -8
  123. package/templates/storefront/src/modules/ub/harvest.tsx +2 -1
  124. package/templates/storefront/src/modules/ub/hero-image.tsx +14 -0
  125. package/templates/storefront/src/modules/ub/home-kit.ts +45 -0
  126. package/templates/storefront/src/modules/ub/lantern.tsx +244 -0
  127. package/templates/storefront/src/modules/ub/locker.tsx +180 -0
  128. package/templates/storefront/src/modules/ub/mosaic.tsx +189 -0
  129. package/templates/storefront/src/modules/ub/nav.tsx +8 -5
  130. package/templates/storefront/src/modules/ub/review-form.tsx +62 -0
  131. package/templates/storefront/src/modules/ub/reviews.tsx +131 -0
  132. package/templates/storefront/src/modules/ub/riviera.tsx +175 -0
  133. package/templates/storefront/src/modules/ub/souk.tsx +214 -0
  134. package/templates/storefront/src/modules/ub/sunset-checklist.tsx +95 -0
  135. package/templates/storefront/src/modules/ub/sunset.tsx +164 -0
  136. package/templates/storefront/src/modules/ub/tech.tsx +2 -2
  137. package/templates/storefront/src/modules/ub/training.tsx +196 -0
  138. package/templates/storefront/src/proxy.ts +2 -0
  139. package/templates/storefront/src/styles/custom.css +26 -0
  140. package/templates/storefront/src/styles/ub/album.css +1 -1
  141. package/templates/storefront/src/styles/ub/arena.css +120 -0
  142. package/templates/storefront/src/styles/ub/cinema.css +1 -1
  143. package/templates/storefront/src/styles/ub/gala.css +1 -1
  144. package/templates/storefront/src/styles/ub/grimoire.css +23 -7
  145. package/templates/storefront/src/styles/ub/harvest.css +7 -6
  146. package/templates/storefront/src/styles/ub/lantern.css +157 -0
  147. package/templates/storefront/src/styles/ub/locker.css +115 -0
  148. package/templates/storefront/src/styles/ub/media.css +10 -0
  149. package/templates/storefront/src/styles/ub/mosaic.css +118 -0
  150. package/templates/storefront/src/styles/ub/motion.css +0 -3
  151. package/templates/storefront/src/styles/ub/overrides.css +10 -0
  152. package/templates/storefront/src/styles/ub/pages.css +176 -0
  153. package/templates/storefront/src/styles/ub/reviews.css +85 -0
  154. package/templates/storefront/src/styles/ub/riviera.css +103 -0
  155. package/templates/storefront/src/styles/ub/souk.css +144 -0
  156. package/templates/storefront/src/styles/ub/sunset.css +123 -0
  157. package/templates/storefront/src/styles/ub/tech.css +2 -5
  158. package/templates/storefront/src/styles/ub/training.css +120 -0
  159. package/templates/storefront/themes/jeux/campaign.en.json +31 -0
  160. package/templates/storefront/themes/jeux/campaign.fr.json +31 -0
  161. package/templates/storefront/themes/jeux/theme.json +11 -0
  162. package/templates/storefront/themes/jeux-2/campaign.en.json +31 -0
  163. package/templates/storefront/themes/jeux-2/campaign.fr.json +31 -0
  164. package/templates/storefront/themes/jeux-2/theme.json +11 -0
  165. package/templates/storefront/themes/mubarak/campaign.en.json +31 -0
  166. package/templates/storefront/themes/mubarak/campaign.fr.json +31 -0
  167. package/templates/storefront/themes/mubarak/theme.json +11 -0
  168. package/templates/storefront/themes/mubarak-2/campaign.en.json +31 -0
  169. package/templates/storefront/themes/mubarak-2/campaign.fr.json +31 -0
  170. package/templates/storefront/themes/mubarak-2/theme.json +11 -0
  171. package/templates/storefront/themes/sport/campaign.en.json +31 -0
  172. package/templates/storefront/themes/sport/campaign.fr.json +31 -0
  173. package/templates/storefront/themes/sport/theme.json +11 -0
  174. package/templates/storefront/themes/sport-2/campaign.en.json +31 -0
  175. package/templates/storefront/themes/sport-2/campaign.fr.json +31 -0
  176. package/templates/storefront/themes/sport-2/theme.json +11 -0
  177. package/templates/storefront/themes/summer/campaign.en.json +31 -0
  178. package/templates/storefront/themes/summer/campaign.fr.json +31 -0
  179. package/templates/storefront/themes/summer/theme.json +11 -0
  180. package/templates/storefront/themes/summer-2/campaign.en.json +31 -0
  181. package/templates/storefront/themes/summer-2/campaign.fr.json +31 -0
  182. package/templates/storefront/themes/summer-2/theme.json +11 -0
@@ -0,0 +1,134 @@
1
+ # Personnaliser l'apparence d'un projet
2
+
3
+ Tout se fait dans **`storefront/src/styles/custom.css`** (+ images et polices dans `storefront/public/custom/`).
4
+ Ces deux emplacements sont **conservés par `create-boutique update`** ; le reste du code est remplacé à chaque mise à jour.
5
+ Après une modification : `docker compose up -d --build`.
6
+
7
+ Ce fichier-ci (`PERSONNALISER.md`) est remis à jour par `update` : il décrit toujours la version installée.
8
+
9
+ ## 1. Ce que custom.css permet, et ce qu'il ne permet pas
10
+
11
+ | Oui, avec custom.css | Non : il faut changer le code du modèle |
12
+ | --- | --- |
13
+ | Couleurs, polices, tailles, espacements, arrondis, ombres | Ajouter une nouvelle section ou un nouveau texte |
14
+ | Masquer un élément (`display: none`) | Changer ce qu'affiche une section (autres produits, autre logique) |
15
+ | Réordonner des blocs d'une même rangée (`order`, `flex-direction`) | Ajouter un champ au paiement, une page, un lien de menu |
16
+ | Image de fond, motif, décoration (`::before`, `::after`, `url("/custom/…")`) | Modifier un e-mail, une règle de prix, de livraison |
17
+ | Cibler une seule boutique, un thème, une page, l'ordinateur ou le mobile | |
18
+
19
+ Les **textes** (titres, sous-titres, bandeau, bouton, dates, visuels) se changent dans l'**admin → Mes boutiques**, pas ici.
20
+ Un besoin de la colonne de droite : on le fait dans le modèle (dépôt create-boutique), puis `create-boutique update` sur les projets.
21
+ Modifier directement un autre fichier du projet reste possible, mais `update` le remplacera (il le liste et le sauvegarde
22
+ dans `backups/` avant).
23
+
24
+ ## 2. Cibler
25
+
26
+ | Quoi | Sélecteur |
27
+ | --- | --- |
28
+ | Tout le projet | directement : `.ub-card { … }` |
29
+ | Une boutique | `[data-boutique="mon-slug"] .ub-card { … }` |
30
+ | Toutes les boutiques d'un thème | `[data-theme="halloween"] …` ; variante 2 : `[data-variant="halloween-2"] …` |
31
+ | Un événement (les 2 variantes) | `[data-event="noel"] …` |
32
+ | Une page (son contenu) | `[data-page="product"] .ub-pdp__title { … }` |
33
+ | L'en-tête ou le pied d'une page précise | `:root:has([data-page="home"]) .ub-nav { … }` |
34
+ | Ordinateur seulement | `@media (min-width: 1024px) { … }` |
35
+ | Mobile seulement | `@media (max-width: 600px) { … }` |
36
+
37
+ Pages (`data-page`) : `home`, `store` (catalogue), `search` (résultats de recherche), `product`, `category`, `collection`,
38
+ `cart`, `checkout`, `account`, `order` (confirmation), `track` (suivi de commande), `contact`, `shipping`, `returns`,
39
+ `privacy`, `terms`.
40
+
41
+ ## 3. Couleurs et polices du thème (le plus simple)
42
+
43
+ Changer une variable change tout le site d'un coup :
44
+
45
+ ```css
46
+ [data-boutique="yout-noel"] {
47
+ --primary: #b91c1c; /* boutons, liens, accents */
48
+ --on-primary: #fff; /* texte sur --primary */
49
+ --accent: #f59e0b;
50
+ --bg: #fffaf5; /* fond des pages */
51
+ --surface: #ffffff; /* cartes, blocs */
52
+ --ink: #1f2937; /* texte */
53
+ --ink-muted: #6b7280; /* texte secondaire */
54
+ --border: #e5e7eb;
55
+ --sale: #dc2626; /* prix barrés, remises */
56
+ --hero-bg: #0f172a; --hero-ink: #fff; /* hero de l'accueil */
57
+ --topbar-bg: #111; --topbar-ink: #fff; /* bandeau tout en haut */
58
+ --ub-r-card: 16px; --ub-r-btn: 999px; /* arrondis des cartes / boutons */
59
+ }
60
+ ```
61
+
62
+ Police à vous : mettre le fichier dans `public/custom/`, puis
63
+ `@font-face { font-family: "Ma police"; src: url("/custom/ma-police.woff2") format("woff2"); }`
64
+ et `[data-boutique="…"] { --ub-font-head: "Ma police", serif; }` (titres) ou `--ub-font-body` (texte).
65
+
66
+ ## 4. Plan du site : quelle classe pour quoi
67
+
68
+ **Partout**
69
+
70
+ | Élément | Classes |
71
+ | --- | --- |
72
+ | Bandeau du haut (messages défilants) | `.ub-topbar` |
73
+ | En-tête | `.ub-nav`, logo `.ub-logo`, menu `.ub-nav__links`, recherche `.ub-search`, icônes `.ub-nav__icons`, bouton `.ub-nav__cta` |
74
+ | Pied de page | bloc d'appel `.ub-footcta` (`__eyebrow`, `__sub`, `__btn`), pied `.ub-footer` (`__top`, `__bot`), moyens de paiement `.ub-pays` |
75
+ | Carte produit (toutes les listes) | `.ub-card`, image, `.ub-badge` (remise), `.ub-card__name`, `.ub-card__cat`, prix `.ub-price__now` / `.ub-price__was`, bouton panier `.ub-card__cart` |
76
+ | Grille de produits | `.ub-grid` |
77
+ | Bandeau cookies | `.ub-cookies` (`__title`, `__btn`) |
78
+ | Page « boutique fermée » | `.ub-closed` |
79
+ | Largeur du contenu | `.ub-wrap` |
80
+
81
+ **Accueil** (`data-page="home"`) : chaque thème a sa propre mise en page, préfixée :
82
+
83
+ | Thème (`home`) | Préfixe | Thème (`home`) | Préfixe |
84
+ | --- | --- | --- | --- |
85
+ | black-friday (default) | `.ub-hero`, `.ub-fold`, `.ub-spot`, `.ub-tiles` | summer (riviera) | `.ub-rv-` |
86
+ | cyber-monday (tech) | `.ub-tc-` | summer-2 (sunset) | `.ub-ss-` |
87
+ | halloween (cinema) | `.ub-cn-` | sport (locker) | `.ub-lk-` |
88
+ | halloween-2 (grimoire) | `.ub-gr-` | sport-2 (training) | `.ub-tr-` |
89
+ | noel (album) | `.ub-al-` | jeux (arena) | `.ub-ar-` |
90
+ | nouvel-an (gala) | `.ub-gl-` | jeux-2 (mosaic) | `.ub-mo-` |
91
+ | thanksgiving (harvest) | `.ub-hv-` | mubarak (lantern) | `.ub-ln-` |
92
+ | | | mubarak-2 (souk) | `.ub-sk-` |
93
+
94
+ Exemples : titre du hero Riviera `.ub-rv-title`, image du hero de tous les thèmes `.ub-heroimg`, compte à rebours `.ub-countdown`.
95
+
96
+ **Catalogue et recherche** (`store`, `search`, `category`, `collection`) : bandeau `.ub-shophero` (`__title`, `__sub`),
97
+ barre de filtres `.ub-shop__bar`, catégories `.ub-chips` / `.ub-chip`, recherche `.ub-shopsearch`, tri `.ub-sort` / `.ub-sort__opt`,
98
+ nombre de produits `.ub-shop__count`, aucun résultat `.ub-shop__empty`.
99
+
100
+ **Produit** (`product`) : `.ub-pdp`, titre `.ub-pdp__title`, sous-titre `.ub-pdp__subtitle`, infos `.ub-pdp__info`,
101
+ description `.ub-pdp__desc`, garanties `.ub-pdp__trust`, questions `.ub-faq`.
102
+
103
+ **Panier, paiement, confirmation** (`cart`, `checkout`, `order`) : composants de Medusa ; cibler la page puis l'attribut
104
+ `data-testid`, ex. `[data-page="checkout"] [data-testid="submit-order-button"] { … }`.
105
+
106
+ **Compte** (`account`) : `.ub-acc` (tableau de bord), menu `.ub-accnav`, commandes `.ub-acc__orders` / `.ub-acc__order`.
107
+
108
+ **Contact** (`contact`) : bandeau `.ub-shophero`, cartes `.ub-contact__cards` / `.ub-contact__card`, questions `.ub-contact__faq`.
109
+
110
+ **Pages légales** (`shipping`, `returns`, `privacy`, `terms`) : `.ub-legal`, sommaire `.ub-legal__toc`, sections `.ub-legal__sec`.
111
+
112
+ ## 5. Trouver la classe d'un élément précis
113
+
114
+ Sur la boutique, clic droit sur l'élément → **Inspecter** (ou F12) : la classe apparaît (`class="ub-…"`).
115
+ Ne pas s'appuyer sur les classes utilitaires sans préfixe `ub-` (ex. `flex`, `mt-4`) : elles peuvent changer d'une version à l'autre.
116
+
117
+ ## 6. Exemples
118
+
119
+ ```css
120
+ /* Masquer le bandeau défilant du haut sur une boutique */
121
+ [data-boutique="yout-noel"] .ub-topbar { display: none; }
122
+
123
+ /* Titres produits plus grands, sur la page produit seulement */
124
+ [data-page="product"] .ub-pdp__title { font-size: 44px; }
125
+
126
+ /* En-tête transparent sur l'accueil uniquement */
127
+ :root:has([data-page="home"]) .ub-nav { background: transparent; }
128
+
129
+ /* Motif de fond sur toutes les boutiques du thème Noël */
130
+ [data-event="noel"] body { background-image: url("/custom/flocons.png"); }
131
+
132
+ /* Cartes produits sans ombre, coins carrés, sur ordinateur */
133
+ @media (min-width: 1024px) { .ub-card { box-shadow: none; border-radius: 0; } }
134
+ ```
@@ -13,7 +13,7 @@
13
13
  "hero.trust.shipping": "Free Shipping",
14
14
  "hero.trust.shippingSub": "On eligible orders",
15
15
  "hero.trust.secure": "Secure Payment",
16
- "hero.trust.secureSub": "Encrypted by Stripe",
16
+ "hero.trust.secureSub": "Encrypted payment",
17
17
  "hero.trust.returns": "Easy Returns",
18
18
  "hero.trust.returnsSub": "Hassle free",
19
19
  "countdown.label": "Offer ends in",
@@ -52,12 +52,12 @@
52
52
  "pdp.trust.warranty": "2-Year Warranty",
53
53
  "pdp.faq": "Frequently asked questions",
54
54
  "pdp.faq.q1": "Which payment methods do you accept?",
55
- "pdp.faq.a1": "Cards, Apple Pay and Google Pay, processed securely by Stripe.",
55
+ "pdp.faq.a1": "Card, Wave, Orange Money and the other methods shown at checkout, processed by our secure payment partners.",
56
56
  "pdp.faq.q2": "How long does delivery take?",
57
57
  "pdp.faq.a2": "Shipping options and delivery times are shown at checkout.",
58
58
  "pdp.faq.q3": "Can I return my order?",
59
59
  "pdp.faq.a3": "Yes, you have 30 days to return an item in its original condition.",
60
- "footer.tagline": "Curated products, shipped with care. Secure checkout with Stripe.",
60
+ "footer.tagline": "Carefully chosen products, shipped with care. 100% secure payment.",
61
61
  "footer.shop": "Shop",
62
62
  "footer.help": "Help",
63
63
  "footer.company": "Company",
@@ -72,14 +72,10 @@
72
72
  "legal.contact": "Contact",
73
73
  "legal.shipping.body": "Orders are prepared within 1–2 business days. Shipping options, costs and estimated delivery times are shown at checkout before you pay.",
74
74
  "legal.returns.body": "You can return any item within 30 days of delivery, unused and in its original packaging. Contact us to start a return; refunds are issued to the original payment method.",
75
- "legal.privacy.body": "{storeName} only collects the data needed to process your order (name, address, email, phone). Card details are handled by Stripe and never stored by us. Contact us to access or delete your data.",
75
+ "legal.privacy.body": "{storeName} only collects the data needed for your order (name, address, e-mail, phone). Payments are processed by secure payment partners (card, Wave, Orange Money…): we never see or store your payment details. Cookies: only those needed for the site to work (cart, sign-in); no advertising or tracking cookies. Contact us to access or delete your data.",
76
76
  "legal.terms.body": "Prices include the discounts shown at the time of order. The amount charged is the one displayed at checkout. {storeName} may cancel an order in case of an obvious pricing error; you would then be fully refunded.",
77
77
  "legal.contact.body": "Questions about an order? Write to us and we will answer as soon as possible.",
78
78
  "legal.contact.email": "Email: {email}",
79
- "ended.title": "This sale has ended",
80
- "ended.text": "Thank you for shopping with {storeName}. Our next sale is already waiting for you.",
81
- "ended.cta": "See the next sale",
82
- "ended.soon": "Our next sale is coming soon.",
83
79
  "upcoming.title": "Coming soon",
84
80
  "upcoming.text": "This sale starts on {date}.",
85
81
  "notFound.title": "Page not found",
@@ -89,7 +85,7 @@
89
85
  "track.text": "Sign in to your account to follow your orders, or check the confirmation email we sent you.",
90
86
  "track.cta": "Go to my account",
91
87
  "checkout.back": "Back to cart",
92
- "checkout.secure": "Payments are encrypted and processed by Stripe.",
88
+ "checkout.secure": "Payments are encrypted and processed by our secure payment partners.",
93
89
  "form.select": "Select…",
94
90
  "form.firstName": "First name",
95
91
  "form.lastName": "Last name",
@@ -292,7 +288,7 @@
292
288
  "contact.faq.q2": "How do I return an item?",
293
289
  "contact.faq.a2": "Email us within 30 days with your order number and we'll send return instructions. Refunds are issued as soon as we receive it.",
294
290
  "contact.faq.q3": "Is payment secure?",
295
- "contact.faq.a3": "Yes. Payments are processed by Stripe (card, Apple Pay, Google Pay): {storeName} never sees or stores your card details.",
291
+ "contact.faq.a3": "Yes. Payments are processed by secure payment partners (card, Wave, Orange Money…): {storeName} never sees or stores your payment details.",
296
292
  "contact.faq.q4": "Can I change or cancel my order?",
297
293
  "contact.faq.a4": "Yes, as long as it hasn't shipped: contact us as soon as possible with your order number.",
298
294
  "section.fold": "Top deals right now",
@@ -331,5 +327,196 @@
331
327
  "grimoire.draw": "Draw a card",
332
328
  "grimoire.drawSub": "Three cards, three bewitched deals. Hover a card to turn it over.",
333
329
  "grimoire.reveal": "Turn over",
334
- "grimoire.shelf": "The apothecary shelf"
330
+ "grimoire.shelf": "The apothecary shelf",
331
+ "closed.title": "This store is closed for now",
332
+ "closed.text": "Thank you for visiting {storeName}. The store will reopen soon.",
333
+ "closed.cta": "Visit our other store",
334
+ "closed.track": "Track my order",
335
+ "riviera.looksKicker": "The lookbook",
336
+ "riviera.look": "Look No.{n}",
337
+ "riviera.coloursKicker": "By colour",
338
+ "riviera.colours": "The colours of summer",
339
+ "riviera.all": "The whole collection",
340
+ "riviera.step1": "Choose",
341
+ "riviera.step1Sub": "One piece, one colour, your size.",
342
+ "riviera.step2": "Receive",
343
+ "riviera.step2Sub": "Carefully packed, tracked to your door.",
344
+ "riviera.step3": "Enjoy",
345
+ "riviera.step3Sub": "Free returns within 30 days.",
346
+ "sunset.postcardsKicker": "Postcards",
347
+ "sunset.checklistKicker": "Before you go",
348
+ "sunset.checklist": "The beach checklist",
349
+ "sunset.checklistSub": "Tick what you're missing, we add it up for you.",
350
+ "sunset.total": "Total",
351
+ "sunset.addAll": "Add all to cart",
352
+ "sunset.added": "Added to cart",
353
+ "sunset.choose": "choose size",
354
+ "sunset.empty": "Tick at least one item",
355
+ "locker.home": "Home",
356
+ "locker.away": "Away",
357
+ "locker.clock": "Full time in",
358
+ "locker.lineupKicker": "The line-up",
359
+ "locker.lineupSub": "Eleven starters in a {formation}. Tap a player to see the product.",
360
+ "locker.all": "The whole locker room",
361
+ "locker.half": "Half-time",
362
+ "training.programKicker": "7 days, 7 goals",
363
+ "training.program": "This week's programme",
364
+ "training.day1": "Mon",
365
+ "training.day2": "Tue",
366
+ "training.day3": "Wed",
367
+ "training.day4": "Thu",
368
+ "training.day5": "Fri",
369
+ "training.day6": "Sat",
370
+ "training.day7": "Sun",
371
+ "training.focus1": "Strength",
372
+ "training.focus2": "Cardio",
373
+ "training.focus3": "Mobility",
374
+ "training.focus4": "Upper body",
375
+ "training.focus5": "Lower body",
376
+ "training.focus6": "Outdoors",
377
+ "training.focus7": "Recovery",
378
+ "training.pack": "The starter pack",
379
+ "training.total": "All 3 together",
380
+ "training.saving": "You save {amount}",
381
+ "training.promise1": "30-day returns",
382
+ "training.promise1Sub": "Tried it, not convinced: refunded",
383
+ "training.promise4": "Tested gear",
384
+ "training.promise4Sub": "Chosen to last",
385
+ "arena.chrono": "Event ends in",
386
+ "arena.podiumKicker": "The biggest discounts",
387
+ "arena.podium": "The podium",
388
+ "arena.place1": "Gold",
389
+ "arena.place2": "Silver",
390
+ "arena.place3": "Bronze",
391
+ "arena.all": "All events",
392
+ "mosaic.left": "Time left",
393
+ "mosaic.offers": "deals in play",
394
+ "mosaic.medalsKicker": "The standings",
395
+ "mosaic.rank": "Rank",
396
+ "mosaic.product": "Product",
397
+ "mosaic.saving": "Saving",
398
+ "mosaic.price": "Price",
399
+ "mosaic.relay": "The relay",
400
+ "mosaic.leg": "Leg {n}",
401
+ "lantern.until": "Until the offer ends",
402
+ "lantern.selectionKicker": "Under the lantern",
403
+ "lantern.giftsKicker": "For everyone",
404
+ "lantern.gifts": "Gift ideas by budget",
405
+ "lantern.tier1": "Little thoughts",
406
+ "lantern.tier2": "Lovely gifts",
407
+ "lantern.tier3": "Grand gestures",
408
+ "lantern.upTo": "Up to {amount}",
409
+ "lantern.from": "From {amount}",
410
+ "lantern.between": "{min} to {max}",
411
+ "souk.perk1": "Free gift wrapping",
412
+ "souk.perk2": "Delivered before the celebration",
413
+ "souk.stallsKicker": "Along the stalls",
414
+ "souk.sign": "With our warmest wishes",
415
+ "souk.all": "The whole souk",
416
+ "shop.results": "Results for “{q}”",
417
+ "shop.clear": "Clear search",
418
+ "shop.noResults": "No product matches “{q}”. Try another word.",
419
+ "souk.see": "View product",
420
+ "checkout.payPaytech": "Wave, Orange Money, Free Money or card",
421
+ "checkout.payPaydunya": "Wave, Orange Money or card",
422
+ "checkout.payNaboopay": "Wave or Orange Money",
423
+ "checkout.payRedirect": "Pay now",
424
+ "checkout.payRedirectHint": "You will be taken to the secure payment page, then brought back here automatically.",
425
+ "checkout.payChecking": "We are confirming your payment…",
426
+ "checkout.payCancelled": "Payment cancelled. You can try again or choose another payment method.",
427
+ "checkout.payRetry": "Check again",
428
+ "checkout.orderLabel": "Online order",
429
+ "checkout.payInitError": "This payment method is temporarily unavailable. Please try again shortly or choose another one.",
430
+ "cookies.title": "Cookies",
431
+ "cookies.text": "This site only uses cookies needed for it to work (cart, sign-in). No advertising tracking.",
432
+ "cookies.textOptional": "We use cookies needed for the site to work and, with your consent, audience measurement cookies.",
433
+ "cookies.more": "Learn more",
434
+ "cookies.ok": "Got it",
435
+ "cookies.accept": "Accept",
436
+ "cookies.refuse": "Decline",
437
+ "legal.privacy.1.title": "Who we are",
438
+ "legal.privacy.1.body": "{storeName} is responsible for the personal data collected on this site. Any question: {email}.",
439
+ "legal.privacy.2.title": "What we collect",
440
+ "legal.privacy.2.body": "Only what your order needs: name, shipping and billing address, e-mail, phone, items ordered and your order history. If you create an account: your e-mail and password (stored encrypted, never readable, even by us). If you leave a review: your first name, rating and comment.",
441
+ "legal.privacy.3.title": "Why",
442
+ "legal.privacy.3.body": "To prepare, ship and track your order; send you order e-mails (confirmation, shipping, delivery, refund); answer your messages; meet our accounting obligations. We never sell or rent your data, and we do not send you advertising without your consent.",
443
+ "legal.privacy.4.title": "Who receives it",
444
+ "legal.privacy.4.body": "Only the providers we need, and only what they need: the carrier (name, address, phone), our payment partner (card, Wave, Orange Money…), our e-mail service and our hosting provider. No other third party.",
445
+ "legal.privacy.5.title": "Payment",
446
+ "legal.privacy.5.body": "Payment happens on our payment partner's secure page. We never see, receive or store your card number or your Wave or Orange Money codes. The amount charged is always calculated by our server, never by your browser.",
447
+ "legal.privacy.6.title": "Security",
448
+ "legal.privacy.6.body": "The site is encrypted (HTTPS): information exchanged cannot be read in transit. Passwords are stored encrypted. Access to the store's administration is protected by login and password and reserved for the {storeName} team. Data is backed up regularly.",
449
+ "legal.privacy.7.title": "How long",
450
+ "legal.privacy.7.body": "Order data is kept as long as needed to handle the order, then for the period required by law for invoices (usually 10 years). A customer account with no order for 3 years may be deleted. You can ask us to delete your account at any time.",
451
+ "legal.privacy.8.title": "Cookies",
452
+ "legal.privacy.8.body": "We only use cookies needed for the site to work: your cart, your sign-in and the store of your cart. No advertising cookies, no cross-site tracking, no resale.",
453
+ "legal.privacy.9.title": "Your rights",
454
+ "legal.privacy.9.body": "You can access, correct, delete or export your data, and object to its use, at any time. Write to {email}: we reply within 30 days. If you are not satisfied with our answer, you can contact the data protection authority of your country.",
455
+ "legal.terms.1.title": "Purpose",
456
+ "legal.terms.1.body": "These terms apply to any order placed on the {storeName} site. Placing an order means you accept them.",
457
+ "legal.terms.2.title": "Prices",
458
+ "legal.terms.2.body": "Prices are shown in the store's currency, including discounts at the time of ordering. The amount charged is the one shown at the payment step, shipping included. In case of an obvious pricing error, {storeName} may cancel the order: you are then fully refunded.",
459
+ "legal.terms.3.title": "Orders",
460
+ "legal.terms.3.body": "Your order is confirmed by a summary e-mail. {storeName} may refuse an order in case of a payment dispute or if an item is out of stock; you are then informed and refunded.",
461
+ "legal.terms.4.title": "Payment",
462
+ "legal.terms.4.body": "By card, Wave, Orange Money or any other method shown, on our payment partner's secure page. The order is prepared as soon as payment is confirmed.",
463
+ "legal.terms.5.title": "Shipping",
464
+ "legal.terms.5.body": "Methods, prices and times are shown before payment. An e-mail lets you know when the order ships, with the tracking number when there is one. See the Shipping page.",
465
+ "legal.terms.6.title": "Returns and refunds",
466
+ "legal.terms.6.body": "You have 30 days after delivery to return an unused item in its original packaging. Refunds go back to the original payment method. See the Returns page.",
467
+ "legal.terms.7.title": "Warranty",
468
+ "legal.terms.7.body": "Products are covered by the legal conformity warranty. An item damaged or not as described on arrival? Write to {email} with a photo: we replace or refund it.",
469
+ "legal.terms.8.title": "Complaints",
470
+ "legal.terms.8.body": "For any complaint, contact us first at {email}: we always look for an amicable solution. Failing that, the dispute falls under the competent courts.",
471
+ "legal.shipping.1.title": "Preparation",
472
+ "legal.shipping.1.body": "Orders are prepared within 1 to 2 business days after payment is confirmed.",
473
+ "legal.shipping.2.title": "Methods and prices",
474
+ "legal.shipping.2.body": "The shipping methods available for your address, their prices and estimated times are shown before payment. Shipping is included in the total you pay: no hidden fees on delivery.",
475
+ "legal.shipping.3.title": "Tracking",
476
+ "legal.shipping.3.body": "An e-mail lets you know when your parcel ships, with the tracking number and link when the carrier provides one, and another on delivery. You can also track your order from the « Order tracking » page.",
477
+ "legal.shipping.4.title": "Damaged or late parcel",
478
+ "legal.shipping.4.body": "Parcel damaged on arrival or seriously late? Write to {email} with your order number: we will take care of it.",
479
+ "legal.returns.1.title": "Time limit",
480
+ "legal.returns.1.body": "You can return an item within 30 days after delivery.",
481
+ "legal.returns.2.title": "Conditions",
482
+ "legal.returns.2.body": "The item must be unused, complete and in its original packaging. For hygiene reasons, some items cannot be taken back once opened (cosmetics, underwear, food).",
483
+ "legal.returns.3.title": "How to",
484
+ "legal.returns.3.body": "Write to {email} with your order number and the item concerned: we will tell you how to send it back.",
485
+ "legal.returns.4.title": "Refund",
486
+ "legal.returns.4.body": "Once the item is received and checked, we refund you on the original payment method (card, Wave, Orange Money…) and you receive a confirmation e-mail. An item received damaged or not as described is fully refunded, return costs included.",
487
+ "legal.updated": "Last updated: {date}",
488
+ "legal.emailFallback": "the Contact page",
489
+ "reviews.outOf": "Rating: {value} out of 5",
490
+ "reviews.title": "Customer reviews",
491
+ "reviews.none": "No reviews for this product yet. Every buyer gets a link to rate it after delivery.",
492
+ "reviews.countOne": "{count} review",
493
+ "reviews.countMany": "{count} reviews",
494
+ "reviews.how": "Verified buyer reviews: only customers who ordered this product can rate it, and every review is checked before it goes live.",
495
+ "reviews.verified": "Verified purchase",
496
+ "reviews.homeKicker": "They ordered",
497
+ "reviews.homeTitle": "What our customers say",
498
+ "reviews.pageTitle": "Leave a review",
499
+ "reviews.pageLead": "Thank you for order #{number}! Rate your items: your review helps other customers.",
500
+ "reviews.invalidLink": "This link is no longer valid. Review links are sent by e-mail on delivery and stay valid for 6 months.",
501
+ "reviews.backHome": "Back to the store",
502
+ "reviews.already": "Thank you, you have already rated this product.",
503
+ "reviews.yourRating": "Your rating",
504
+ "reviews.rating1": "Disappointing",
505
+ "reviews.rating2": "Average",
506
+ "reviews.rating3": "Good",
507
+ "reviews.rating4": "Very good",
508
+ "reviews.rating5": "Excellent",
509
+ "reviews.name": "Your first name (shown with the review)",
510
+ "reviews.titleField": "Title",
511
+ "reviews.optional": "(optional)",
512
+ "reviews.comment": "Your review",
513
+ "reviews.commentHint": "Quality, size, delivery… anything that will help the next customers (10 characters minimum).",
514
+ "reviews.send": "Post my review",
515
+ "reviews.sending": "Sending…",
516
+ "reviews.thanks": "Thank you! Your review will show after a quick check.",
517
+ "reviews.error.invalid": "Pick a rating and write at least 10 characters (no < or >).",
518
+ "reviews.error.duplicate": "You have already rated this product for this order.",
519
+ "reviews.error.expired": "This link is no longer valid.",
520
+ "reviews.error.tooMany": "Too many attempts. Please try again later.",
521
+ "reviews.error.failed": "Sending failed. Please try again shortly."
335
522
  }