@salifbiaye/create-boutique 0.3.2 → 0.3.4
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/cli/dist/create.js
CHANGED
|
@@ -90,6 +90,18 @@ async function ask(a, dirName, yes) {
|
|
|
90
90
|
}
|
|
91
91
|
const stripePk = a.stripePk ?? (cancelled(await p.text({ message: "Clé Stripe publique (vide = paiement manuel)", placeholder: "pk_test_…", defaultValue: "" })) || undefined);
|
|
92
92
|
const stripeSk = stripePk ? (a.stripeSk ?? (cancelled(await p.password({ message: "Clé Stripe secrète" })) || undefined)) : a.stripeSk;
|
|
93
|
+
// E-mails clients (confirmation, expédition, mot de passe oublié…) via Resend ; vide = aucun e-mail envoyé.
|
|
94
|
+
const resendKey = a.resendKey ??
|
|
95
|
+
(cancelled(await p.password({ message: "Clé API Resend (vide = aucun e-mail envoyé)", validate: (v) => (!v || v.startsWith("re_") ? undefined : "une clé Resend commence par re_") })) ||
|
|
96
|
+
undefined);
|
|
97
|
+
const emailFrom = resendKey
|
|
98
|
+
? (a.emailFrom ??
|
|
99
|
+
cancelled(await p.text({
|
|
100
|
+
message: "Adresse d'expédition des e-mails (domaine vérifié chez Resend ; test : onboarding@resend.dev)",
|
|
101
|
+
placeholder: "commandes@votredomaine.com",
|
|
102
|
+
validate: (v) => (z.email().safeParse(v).success ? undefined : "adresse e-mail invalide"),
|
|
103
|
+
})))
|
|
104
|
+
: a.emailFrom;
|
|
93
105
|
const exists = (kind) => (v) => {
|
|
94
106
|
if (!v?.trim())
|
|
95
107
|
return undefined;
|
|
@@ -100,7 +112,7 @@ async function ask(a, dirName, yes) {
|
|
|
100
112
|
};
|
|
101
113
|
const products = a.products ?? (cancelled(await p.text({ message: "Fichier produits (CSV, optionnel)", defaultValue: "", validate: exists("file") })).trim() || undefined);
|
|
102
114
|
const images = a.images ?? (cancelled(await p.text({ message: "Dossier images (optionnel)", defaultValue: "", validate: exists("dir") })).trim() || undefined);
|
|
103
|
-
return { ...a, name, email, currency, country, language, themes: chosen, boutiques: extra, stripePk, stripeSk, products, images };
|
|
115
|
+
return { ...a, name, email, currency, country, language, themes: chosen, boutiques: extra, stripePk, stripeSk, resendKey, emailFrom, products, images };
|
|
104
116
|
}
|
|
105
117
|
export async function create(dir, input, opts) {
|
|
106
118
|
const target = path.resolve(dir);
|
|
@@ -163,6 +175,7 @@ export async function create(dir, input, opts) {
|
|
|
163
175
|
`${"Backend / admin".padEnd(width + 16)}→ http://localhost:${proj.apiPort}/app`,
|
|
164
176
|
`Devise ${a.currency.toUpperCase()} · pays ${a.country.toUpperCase()} · langue ${a.language}`,
|
|
165
177
|
`Paiement : ${a.stripeSk ? "Stripe + manuel" : "manuel (Stripe : non configuré)"}`,
|
|
178
|
+
`E-mails : ${a.resendKey ? `Resend, depuis ${a.emailFrom ?? "(adresse manquante)"}` : "désactivés (pas de clé Resend)"}`,
|
|
166
179
|
`Catalogue : ${a.products ?? "aucun (à ajouter dans l'admin)"}`,
|
|
167
180
|
];
|
|
168
181
|
if (opts.yes)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salifbiaye/create-boutique",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Usine à Boutiques : génère un projet complet (backend Medusa + une boutique Next.js par campagne) prêt pour docker compose",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": { "type": "git", "url": "git+https://github.com/salifbiaye/create-boutique.git" },
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { forwardRef, useImperativeHandle, useMemo, useRef } from "react"
|
|
2
2
|
|
|
3
|
+
import { useLocale, useT } from "@lib/boutique/i18n-client"
|
|
3
4
|
import NativeSelect, {
|
|
4
5
|
NativeSelectProps,
|
|
5
6
|
} from "@modules/common/components/native-select"
|
|
6
7
|
import { HttpTypes } from "@medusajs/types"
|
|
7
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Liste des pays de la région : noms dans la langue du site (« Sénégal », « Côte d'Ivoire »), triés par ordre
|
|
11
|
+
* alphabétique, pays de la boutique en tête. (Le starter affichait les noms anglais de Medusa, non triés.)
|
|
12
|
+
*/
|
|
8
13
|
const CountrySelect = forwardRef<
|
|
9
14
|
HTMLSelectElement,
|
|
10
15
|
NativeSelectProps & {
|
|
11
16
|
region?: HttpTypes.StoreRegion
|
|
12
17
|
}
|
|
13
|
-
>(({ placeholder = "
|
|
18
|
+
>(({ placeholder = "form.country", region, defaultValue, ...props }, ref) => {
|
|
14
19
|
const innerRef = useRef<HTMLSelectElement>(null)
|
|
20
|
+
const t = useT()
|
|
21
|
+
const locale = useLocale()
|
|
15
22
|
|
|
16
23
|
useImperativeHandle<HTMLSelectElement | null, HTMLSelectElement | null>(
|
|
17
24
|
ref,
|
|
@@ -19,25 +26,36 @@ const CountrySelect = forwardRef<
|
|
|
19
26
|
)
|
|
20
27
|
|
|
21
28
|
const countryOptions = useMemo(() => {
|
|
22
|
-
if (!region) {
|
|
29
|
+
if (!region?.countries) {
|
|
23
30
|
return []
|
|
24
31
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
let names: Intl.DisplayNames | undefined
|
|
33
|
+
try {
|
|
34
|
+
names = new Intl.DisplayNames([locale], { type: "region" })
|
|
35
|
+
} catch {
|
|
36
|
+
names = undefined
|
|
37
|
+
}
|
|
38
|
+
const home = (locale.split("-")[1] ?? "").toLowerCase()
|
|
39
|
+
const options = region.countries
|
|
40
|
+
.filter((c) => c.iso_2)
|
|
41
|
+
.map((c) => ({
|
|
42
|
+
value: c.iso_2!,
|
|
43
|
+
label: names?.of(c.iso_2!.toUpperCase()) ?? c.display_name ?? c.iso_2!,
|
|
44
|
+
}))
|
|
45
|
+
.sort((a, b) => a.label.localeCompare(b.label, locale, { sensitivity: "base" }))
|
|
46
|
+
const first = options.find((o) => o.value === home)
|
|
47
|
+
return first ? [first, ...options.filter((o) => o !== first)] : options
|
|
48
|
+
}, [region, locale])
|
|
31
49
|
|
|
32
50
|
return (
|
|
33
51
|
<NativeSelect
|
|
34
52
|
ref={innerRef}
|
|
35
|
-
placeholder={placeholder}
|
|
53
|
+
placeholder={t(placeholder)}
|
|
36
54
|
defaultValue={defaultValue}
|
|
37
55
|
{...props}
|
|
38
56
|
>
|
|
39
|
-
{countryOptions
|
|
40
|
-
<option key={
|
|
57
|
+
{countryOptions.map(({ value, label }) => (
|
|
58
|
+
<option key={value} value={value}>
|
|
41
59
|
{label}
|
|
42
60
|
</option>
|
|
43
61
|
))}
|