@ollaid/native-sso 1.0.6 → 1.0.8

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/dist/index.cjs CHANGED
@@ -127,8 +127,13 @@ function DialogContent({ children, className = "" }) {
127
127
  /* @__PURE__ */ jsxRuntime.jsx(
128
128
  "div",
129
129
  {
130
- style: { position: "fixed", inset: 0, backgroundColor: "rgba(0,0,0,0.5)" },
131
- onClick: () => onOpenChange(false)
130
+ style: {
131
+ position: "fixed",
132
+ inset: 0,
133
+ backgroundColor: "rgba(0,0,0,0.5)",
134
+ backdropFilter: "blur(4px)",
135
+ animation: "ollaid-overlay-in 0.25s ease-out"
136
+ }
132
137
  }
133
138
  ),
134
139
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -141,19 +146,21 @@ function DialogContent({ children, className = "" }) {
141
146
  width: "100%",
142
147
  maxWidth: "28rem",
143
148
  margin: "1rem",
144
- padding: "1.5rem",
149
+ padding: "1rem",
145
150
  borderRadius: "0.75rem",
146
151
  backgroundColor: "white",
147
152
  boxShadow: "0 25px 50px -12px rgba(0,0,0,0.25)",
148
153
  maxHeight: "90vh",
149
- overflowY: "auto"
154
+ display: "flex",
155
+ flexDirection: "column",
156
+ animation: "ollaid-modal-in 0.3s ease-out"
150
157
  },
151
158
  children: [
152
159
  /* @__PURE__ */ jsxRuntime.jsx(
153
160
  "button",
154
161
  {
155
162
  onClick: () => onOpenChange(false),
156
- style: { position: "absolute", right: "1rem", top: "1rem", background: "none", border: "none", cursor: "pointer", fontSize: "1.25rem", color: "#9ca3af", lineHeight: 1 },
163
+ style: { position: "absolute", right: "0.75rem", top: "0.75rem", background: "none", border: "none", cursor: "pointer", fontSize: "1.25rem", color: "#9ca3af", lineHeight: 1, zIndex: 2 },
157
164
  "aria-label": "Close",
158
165
  children: "✕"
159
166
  }
@@ -164,8 +171,14 @@ function DialogContent({ children, className = "" }) {
164
171
  )
165
172
  ] });
166
173
  }
174
+ function DialogBody({ children, className = "", style }) {
175
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { flex: 1, overflowY: "auto", paddingBottom: "0.5rem", minHeight: 0, ...style }, children });
176
+ }
177
+ function DialogFooter({ children, className = "", style }) {
178
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { flexShrink: 0, paddingTop: "0.75rem", borderTop: "1px solid #e5e7eb", display: "flex", flexDirection: "column", gap: "0.5rem", ...style }, children });
179
+ }
167
180
  function DialogHeader({ children, className = "", style }) {
168
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { marginBottom: "0.5rem", ...style }, children });
181
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { marginBottom: "0.5rem", flexShrink: 0, ...style }, children });
169
182
  }
170
183
  function DialogTitle({ children, className = "" }) {
171
184
  return /* @__PURE__ */ jsxRuntime.jsx("h2", { className, style: { fontSize: "1.25rem", fontWeight: 600, color: "#111827" }, children });
@@ -265,7 +278,7 @@ if (typeof document !== "undefined") {
265
278
  if (!document.getElementById(styleId)) {
266
279
  const style = document.createElement("style");
267
280
  style.id = styleId;
268
- style.textContent = `@keyframes spin { to { transform: rotate(360deg); } }`;
281
+ style.textContent = `@keyframes spin { to { transform: rotate(360deg); } } @keyframes ollaid-overlay-in { from { opacity: 0; } to { opacity: 1; } } @keyframes ollaid-modal-in { from { opacity: 0; transform: translateY(20px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } }`;
269
282
  document.head.appendChild(style);
270
283
  }
271
284
  }
@@ -941,7 +954,8 @@ function getIAMHeaders() {
941
954
  }
942
955
  return {
943
956
  "Content-Type": "application/json",
944
- "Accept": "application/json"
957
+ "Accept": "application/json",
958
+ "X-IAM-App-Key": creds.appKey
945
959
  };
946
960
  }
947
961
  const mobilePasswordService = {
@@ -1429,7 +1443,7 @@ function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamA
1429
1443
  /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Mot de passe modifié !" }),
1430
1444
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Votre mot de passe a été changé avec succès." })
1431
1445
  ] }),
1432
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleBackToLogin, style: { width: "100%", marginTop: "1rem" }, children: "Retour à la connexion" })
1446
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { style: { borderTop: "none" }, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleBackToLogin, style: { width: "100%" }, children: "Retour à la connexion" }) })
1433
1447
  ] }) });
1434
1448
  }
1435
1449
  return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { children: [
@@ -1449,49 +1463,35 @@ function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamA
1449
1463
  step === "password" && "Définissez votre nouveau mot de passe"
1450
1464
  ] })
1451
1465
  ] }),
1452
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
1466
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
1453
1467
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem", borderRadius: "0.375rem", backgroundColor: C$3.redBg, color: C$3.red, fontSize: "0.875rem" }, children: error }),
1454
- step === "email" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1455
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1456
- /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "recovery-email", children: "Adresse email" }),
1457
- /* @__PURE__ */ jsxRuntime.jsx(Input, { id: "recovery-email", type: "email", placeholder: "vous@exemple.com", value: email, onChange: (e) => setEmail(e.target.value), disabled: pwLoading })
1458
- ] }),
1459
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleEmailSubmit, disabled: pwLoading, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1460
- /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
1461
- " Vérification..."
1462
- ] }) : "Continuer" }),
1463
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", onClick: handleBackToLogin, style: { width: "100%" }, children: "Retour à la connexion" })
1468
+ step === "email" && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1469
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "recovery-email", children: "Adresse email" }),
1470
+ /* @__PURE__ */ jsxRuntime.jsx(Input, { id: "recovery-email", type: "email", placeholder: "vous@exemple.com", value: email, onChange: (e) => setEmail(e.target.value), disabled: pwLoading })
1464
1471
  ] }),
1465
- step === "method-choice" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1466
- /* @__PURE__ */ jsxRuntime.jsx(RadioGroup, { value: selectedMethod, onValueChange: (v) => setSelectedMethod(v), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
1467
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem", padding: "1rem", borderRadius: "0.5rem", border: `2px solid ${selectedMethod === "email" ? C$3.primary : C$3.gray200}`, cursor: "pointer" }, onClick: () => setSelectedMethod("email"), children: [
1468
- /* @__PURE__ */ jsxRuntime.jsx(RadioGroupItem, { value: "email", id: "method-email" }),
1469
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1470
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 500 }, children: "Par email" }),
1471
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.75rem", color: C$3.gray500 }, children: maskedEmail })
1472
- ] })
1473
- ] }),
1474
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem", padding: "1rem", borderRadius: "0.5rem", border: `2px solid ${selectedMethod === "phone" ? C$3.primary : C$3.gray200}`, cursor: "pointer" }, onClick: () => setSelectedMethod("phone"), children: [
1475
- /* @__PURE__ */ jsxRuntime.jsx(RadioGroupItem, { value: "phone", id: "method-phone" }),
1476
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1477
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 500 }, children: "Par SMS" }),
1478
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.75rem", color: C$3.gray500 }, children: maskedPhone })
1479
- ] })
1472
+ step === "method-choice" && /* @__PURE__ */ jsxRuntime.jsx(RadioGroup, { value: selectedMethod, onValueChange: (v) => setSelectedMethod(v), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
1473
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem", padding: "1rem", borderRadius: "0.5rem", border: `2px solid ${selectedMethod === "email" ? C$3.primary : C$3.gray200}`, cursor: "pointer" }, onClick: () => setSelectedMethod("email"), children: [
1474
+ /* @__PURE__ */ jsxRuntime.jsx(RadioGroupItem, { value: "email", id: "method-email" }),
1475
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1476
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 500 }, children: "Par email" }),
1477
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.75rem", color: C$3.gray500 }, children: maskedEmail })
1480
1478
  ] })
1481
- ] }) }),
1482
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleMethodSubmit, disabled: pwLoading, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1483
- /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
1484
- " Envoi..."
1485
- ] }) : "Envoyer le code" })
1486
- ] }),
1479
+ ] }),
1480
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem", padding: "1rem", borderRadius: "0.5rem", border: `2px solid ${selectedMethod === "phone" ? C$3.primary : C$3.gray200}`, cursor: "pointer" }, onClick: () => setSelectedMethod("phone"), children: [
1481
+ /* @__PURE__ */ jsxRuntime.jsx(RadioGroupItem, { value: "phone", id: "method-phone" }),
1482
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1483
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 500 }, children: "Par SMS" }),
1484
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.75rem", color: C$3.gray500 }, children: maskedPhone })
1485
+ ] })
1486
+ ] })
1487
+ ] }) }),
1487
1488
  step === "otp" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1488
1489
  /* @__PURE__ */ jsxRuntime.jsx(OTPInput, { value: otp, onChange: setOtp, disabled: pwLoading }),
1489
1490
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: resendCooldown > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: C$3.gray500 }, children: [
1490
1491
  "Renvoyer dans ",
1491
1492
  resendCooldown,
1492
1493
  "s"
1493
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { color: C$3.primary, background: "none", border: "none", cursor: "pointer", textDecoration: "underline" }, onClick: handleResendOTP, children: "Code non reçu ? Renvoyer" }) }),
1494
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleOTPSubmit, disabled: otp.length !== 6, style: { width: "100%" }, children: "Vérifier" })
1494
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { color: C$3.primary, background: "none", border: "none", cursor: "pointer", textDecoration: "underline" }, onClick: handleResendOTP, children: "Code non reçu ? Renvoyer" }) })
1495
1495
  ] }),
1496
1496
  step === "password" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1497
1497
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
@@ -1501,12 +1501,26 @@ function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamA
1501
1501
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1502
1502
  /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Confirmer le mot de passe" }),
1503
1503
  /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "password", placeholder: "Retapez votre mot de passe", value: confirmPassword, onChange: (e) => setConfirmPassword(e.target.value), disabled: pwLoading })
1504
- ] }),
1505
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handlePasswordSubmit, disabled: pwLoading || !password || !confirmPassword, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1506
- /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
1507
- " Modification..."
1508
- ] }) : "Modifier le mot de passe" })
1504
+ ] })
1509
1505
  ] })
1506
+ ] }) }),
1507
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
1508
+ step === "email" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1509
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleEmailSubmit, disabled: pwLoading, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1510
+ /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
1511
+ " Vérification..."
1512
+ ] }) : "Continuer" }),
1513
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", onClick: handleBackToLogin, style: { width: "100%" }, children: "Retour à la connexion" })
1514
+ ] }),
1515
+ step === "method-choice" && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleMethodSubmit, disabled: pwLoading, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1516
+ /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
1517
+ " Envoi..."
1518
+ ] }) : "Envoyer le code" }),
1519
+ step === "otp" && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleOTPSubmit, disabled: otp.length !== 6, style: { width: "100%" }, children: "Vérifier" }),
1520
+ step === "password" && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handlePasswordSubmit, disabled: pwLoading || !password || !confirmPassword, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1521
+ /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
1522
+ " Modification..."
1523
+ ] }) : "Modifier le mot de passe" })
1510
1524
  ] })
1511
1525
  ] }) });
1512
1526
  }
@@ -1873,7 +1887,7 @@ function useNativeAuth(options) {
1873
1887
  await nativeAuthService.loadCredentials();
1874
1888
  }
1875
1889
  const response = await nativeAuthService.loginAccessOtp(otpCode);
1876
- if (response.success && response.needs_access && response.process_token) {
1890
+ if ((response.needs_access || response.status === "needs_access") && response.process_token) {
1877
1891
  setState((prev) => ({
1878
1892
  ...prev,
1879
1893
  processToken: response.process_token,
@@ -2341,7 +2355,8 @@ function LoginModal({
2341
2355
  iamApiUrl,
2342
2356
  loading,
2343
2357
  showSwitchToSignup = true,
2344
- defaultAccountType
2358
+ defaultAccountType,
2359
+ initialPhone
2345
2360
  }) {
2346
2361
  const {
2347
2362
  status,
@@ -2420,6 +2435,12 @@ function LoginModal({
2420
2435
  react.useEffect(() => {
2421
2436
  if (!open) resetState();
2422
2437
  }, [open]);
2438
+ react.useEffect(() => {
2439
+ if (open && initialPhone) {
2440
+ setStep("phone-input");
2441
+ setPhone(initialPhone);
2442
+ }
2443
+ }, [open, initialPhone]);
2423
2444
  const exchangeCallbackToken = async (callbackToken) => {
2424
2445
  try {
2425
2446
  const response = await nativeAuthService.exchange(callbackToken);
@@ -2576,23 +2597,25 @@ function LoginModal({
2576
2597
  "."
2577
2598
  ] })
2578
2599
  ] }),
2579
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem" }, children: [
2580
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "1rem", backgroundColor: C$2.gray100, borderRadius: "0.5rem", marginBottom: "1rem", fontSize: "0.875rem", color: C$2.gray500 }, children: [
2600
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogBody, { children: [
2601
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "1rem", backgroundColor: C$2.gray100, borderRadius: "0.5rem", fontSize: "0.875rem", color: C$2.gray500 }, children: [
2581
2602
  "Votre compte ",
2582
2603
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: C$2.primary }, children: "iam.ollaid.com" }),
2583
2604
  " existe déjà. Cliquez sur Confirmer pour créer votre accès à ",
2584
2605
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: C$2.gray900 }, children: application.name }),
2585
2606
  "."
2586
2607
  ] }),
2587
- renderError(),
2588
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleGrantAccess, disabled: isSubmitting, style: { width: "100%", marginTop: "0.75rem" }, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
2608
+ renderError()
2609
+ ] }),
2610
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
2611
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleGrantAccess, disabled: isSubmitting, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
2589
2612
  /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
2590
2613
  "Création en cours..."
2591
2614
  ] }) : "Confirmer la création de mon compte" }),
2592
2615
  /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
2593
2616
  resetAuth();
2594
2617
  setStep("choice");
2595
- }, disabled: isSubmitting, style: { width: "100%", marginTop: "0.5rem" }, children: "Annuler" })
2618
+ }, disabled: isSubmitting, style: { width: "100%" }, children: "Annuler" })
2596
2619
  ] })
2597
2620
  ] }) : alternativeMethod ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2598
2621
  /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
@@ -2600,21 +2623,21 @@ function LoginModal({
2600
2623
  /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Moyen de connexion désactivé" }),
2601
2624
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Vos identifiants sont corrects, mais vous avez désactivé ce moyen de connexion depuis votre compte IAM." })
2602
2625
  ] }),
2603
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem" }, children: [
2604
- alternativeMethod.value && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "1rem", backgroundColor: C$2.gray100, borderRadius: "0.5rem", marginBottom: "1rem" }, children: [
2605
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: C$2.gray500, marginBottom: "0.75rem" }, children: "Vous pouvez vous connecter avec :" }),
2606
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", fontSize: "0.875rem", fontWeight: 500, color: C$2.gray900 }, children: [
2607
- alternativeMethod.type === "phone" ? /* @__PURE__ */ jsxRuntime.jsx(IconPhone, { style: { width: "1rem", height: "1rem", color: C$2.primary } }) : /* @__PURE__ */ jsxRuntime.jsx(IconMail, { style: { width: "1rem", height: "1rem", color: C$2.primary } }),
2608
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: alternativeMethod.value })
2609
- ] })
2610
- ] }),
2626
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: alternativeMethod.value && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "1rem", backgroundColor: C$2.gray100, borderRadius: "0.5rem" }, children: [
2627
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: C$2.gray500, marginBottom: "0.75rem" }, children: "Vous pouvez vous connecter avec :" }),
2628
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", fontSize: "0.875rem", fontWeight: 500, color: C$2.gray900 }, children: [
2629
+ alternativeMethod.type === "phone" ? /* @__PURE__ */ jsxRuntime.jsx(IconPhone, { style: { width: "1rem", height: "1rem", color: C$2.primary } }) : /* @__PURE__ */ jsxRuntime.jsx(IconMail, { style: { width: "1rem", height: "1rem", color: C$2.primary } }),
2630
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: alternativeMethod.value })
2631
+ ] })
2632
+ ] }) }),
2633
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
2611
2634
  /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => {
2612
2635
  if (alternativeMethod.type === "phone") setStep("phone-input");
2613
2636
  else setStep("email-check");
2614
2637
  resetAuth();
2615
2638
  }, style: { width: "100%" }, children: alternativeMethod.type === "phone" ? "Se connecter par téléphone" : "Se connecter par email" }),
2616
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => window.open("https://iam.ollaid.com", "_blank"), style: { width: "100%", marginTop: "0.5rem" }, children: "Réactiver depuis iam.ollaid.com" }),
2617
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", onClick: () => onOpenChange(false), style: { width: "100%", marginTop: "0.5rem" }, children: "Annuler" })
2639
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => window.open("https://iam.ollaid.com", "_blank"), style: { width: "100%" }, children: "Réactiver depuis iam.ollaid.com" }),
2640
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", onClick: () => onOpenChange(false), style: { width: "100%" }, children: "Annuler" })
2618
2641
  ] })
2619
2642
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2620
2643
  step !== "choice" && renderBackBtn(),
@@ -2624,7 +2647,7 @@ function LoginModal({
2624
2647
  /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Connexion" }),
2625
2648
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Choisissez votre méthode de connexion" })
2626
2649
  ] }),
2627
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
2650
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
2628
2651
  renderError(),
2629
2652
  /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", onClick: () => setStep("email-check"), style: methodBtnStyle, children: [
2630
2653
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: methodIconStyle(C$2.accent), children: /* @__PURE__ */ jsxRuntime.jsx(IconMail, { style: { width: "1.25rem", height: "1.25rem", color: C$2.white } }) }),
@@ -2659,7 +2682,7 @@ function LoginModal({
2659
2682
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$2.gray500 }, children: "Pas encore de compte ? " }),
2660
2683
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: linkStyle$1, onClick: onSwitchToSignup, children: "Inscrivez-vous" })
2661
2684
  ] })
2662
- ] })
2685
+ ] }) })
2663
2686
  ] }),
2664
2687
  step === "email-check" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2665
2688
  /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
@@ -2667,7 +2690,7 @@ function LoginModal({
2667
2690
  /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Connexion par email" }),
2668
2691
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Entrez votre adresse email" })
2669
2692
  ] }),
2670
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2693
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2671
2694
  renderError(),
2672
2695
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
2673
2696
  /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "email", children: "Adresse email" }),
@@ -2689,7 +2712,9 @@ function LoginModal({
2689
2712
  }
2690
2713
  )
2691
2714
  ] }),
2692
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "right" }, children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { ...linkStyle$1, fontSize: "0.75rem" }, onClick: () => setShowPasswordRecovery(true), children: "Mot de passe oublié ?" }) }),
2715
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "right" }, children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { ...linkStyle$1, fontSize: "0.75rem" }, onClick: () => setShowPasswordRecovery(true), children: "Mot de passe oublié ?" }) })
2716
+ ] }) }),
2717
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
2693
2718
  renderLoaderBtn("Continuer", "Vérification...", handleEmailCheck, !email.trim()),
2694
2719
  showSwitchToSignup && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: [
2695
2720
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$2.gray500 }, children: "Pas encore de compte ? " }),
@@ -2707,41 +2732,43 @@ function LoginModal({
2707
2732
  ] }),
2708
2733
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: email })
2709
2734
  ] }),
2710
- /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleEmailPasswordSubmit, style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2711
- renderError(),
2712
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
2713
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
2714
- /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "password", children: "Mot de passe" }),
2715
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { ...linkStyle$1, fontSize: "0.75rem" }, onClick: () => setShowPasswordRecovery(true), children: "Mot de passe oublié ?" })
2716
- ] }),
2717
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
2718
- /* @__PURE__ */ jsxRuntime.jsx(
2719
- Input,
2720
- {
2721
- id: "password",
2722
- type: showPassword ? "text" : "password",
2723
- placeholder: "••••••••",
2724
- value: password,
2725
- onChange: (e) => setPassword(e.target.value),
2726
- disabled: isSubmitting,
2727
- style: { paddingRight: "2.5rem" }
2728
- }
2729
- ),
2730
- /* @__PURE__ */ jsxRuntime.jsx(
2731
- "button",
2732
- {
2733
- type: "button",
2734
- onClick: () => setShowPassword(!showPassword),
2735
- style: { position: "absolute", right: 0, top: 0, height: "100%", padding: "0 0.75rem", background: "none", border: "none", cursor: "pointer" },
2736
- children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx(IconEyeOff, { style: { width: "1rem", height: "1rem", color: C$2.gray500 } }) : /* @__PURE__ */ jsxRuntime.jsx(IconEye, { style: { width: "1rem", height: "1rem", color: C$2.gray500 } })
2737
- }
2738
- )
2735
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleEmailPasswordSubmit, style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
2736
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2737
+ renderError(),
2738
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
2739
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
2740
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "password", children: "Mot de passe" }),
2741
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { ...linkStyle$1, fontSize: "0.75rem" }, onClick: () => setShowPasswordRecovery(true), children: "Mot de passe oublié ?" })
2742
+ ] }),
2743
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
2744
+ /* @__PURE__ */ jsxRuntime.jsx(
2745
+ Input,
2746
+ {
2747
+ id: "password",
2748
+ type: showPassword ? "text" : "password",
2749
+ placeholder: "••••••••",
2750
+ value: password,
2751
+ onChange: (e) => setPassword(e.target.value),
2752
+ disabled: isSubmitting,
2753
+ style: { paddingRight: "2.5rem" }
2754
+ }
2755
+ ),
2756
+ /* @__PURE__ */ jsxRuntime.jsx(
2757
+ "button",
2758
+ {
2759
+ type: "button",
2760
+ onClick: () => setShowPassword(!showPassword),
2761
+ style: { position: "absolute", right: 0, top: 0, height: "100%", padding: "0 0.75rem", background: "none", border: "none", cursor: "pointer" },
2762
+ children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx(IconEyeOff, { style: { width: "1rem", height: "1rem", color: C$2.gray500 } }) : /* @__PURE__ */ jsxRuntime.jsx(IconEye, { style: { width: "1rem", height: "1rem", color: C$2.gray500 } })
2763
+ }
2764
+ )
2765
+ ] })
2739
2766
  ] })
2740
- ] }),
2741
- /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: isSubmitting || !password, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
2767
+ ] }) }),
2768
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: isSubmitting || !password, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
2742
2769
  /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
2743
2770
  "Connexion..."
2744
- ] }) : "Se connecter" })
2771
+ ] }) : "Se connecter" }) })
2745
2772
  ] })
2746
2773
  ] }),
2747
2774
  step === "email-otp" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -2754,12 +2781,12 @@ function LoginModal({
2754
2781
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: C$2.gray900 }, children: email })
2755
2782
  ] })
2756
2783
  ] }),
2757
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2784
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2758
2785
  renderError(),
2759
2786
  /* @__PURE__ */ jsxRuntime.jsx(OTPInput, { value: emailOtpCode, onChange: setEmailOtpCode, disabled: isSubmitting }),
2760
- renderResendLink(),
2761
- renderLoaderBtn("Vérifier", "Vérification...", handleEmailOtpVerify, emailOtpCode.length !== 6)
2762
- ] })
2787
+ renderResendLink()
2788
+ ] }) }),
2789
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: renderLoaderBtn("Vérifier", "Vérification...", handleEmailOtpVerify, emailOtpCode.length !== 6) })
2763
2790
  ] }),
2764
2791
  step === "phone-input" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2765
2792
  /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
@@ -2767,7 +2794,7 @@ function LoginModal({
2767
2794
  /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Connexion par téléphone" }),
2768
2795
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Entrez votre numéro pour recevoir un code SMS" })
2769
2796
  ] }),
2770
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2797
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2771
2798
  renderError(),
2772
2799
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
2773
2800
  /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Indicatif" }),
@@ -2804,7 +2831,9 @@ function LoginModal({
2804
2831
  phone.replace(/\D/g, "").length,
2805
2832
  "/9)"
2806
2833
  ] })
2807
- ] }),
2834
+ ] })
2835
+ ] }) }),
2836
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
2808
2837
  renderLoaderBtn("Recevoir le code SMS", "Envoi en cours...", handlePhoneInit, phone.replace(/\D/g, "").length !== 9),
2809
2838
  showSwitchToSignup && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: [
2810
2839
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$2.gray500 }, children: "Pas encore de compte ? " }),
@@ -2827,12 +2856,12 @@ function LoginModal({
2827
2856
  ] })
2828
2857
  ] })
2829
2858
  ] }),
2830
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2859
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2831
2860
  renderError(),
2832
2861
  /* @__PURE__ */ jsxRuntime.jsx(OTPInput, { value: phoneOtpCode, onChange: setPhoneOtpCode, disabled: isSubmitting }),
2833
- renderResendLink(),
2834
- renderLoaderBtn("Se connecter", "Vérification...", handlePhoneVerify, phoneOtpCode.length !== 6)
2835
- ] })
2862
+ renderResendLink()
2863
+ ] }) }),
2864
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: renderLoaderBtn("Se connecter", "Vérification...", handlePhoneVerify, phoneOtpCode.length !== 6) })
2836
2865
  ] }),
2837
2866
  step === "access-otp" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2838
2867
  /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
@@ -2840,7 +2869,7 @@ function LoginModal({
2840
2869
  /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Code d'accès" }),
2841
2870
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Entrez le code d'accès à 8 chiffres" })
2842
2871
  ] }),
2843
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2872
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
2844
2873
  renderError(),
2845
2874
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
2846
2875
  /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Code d'accès (8 chiffres)" }),
@@ -2857,9 +2886,9 @@ function LoginModal({
2857
2886
  maxLength: 8
2858
2887
  }
2859
2888
  )
2860
- ] }),
2861
- renderLoaderBtn("Se connecter", "Vérification...", handleAccessOtpSubmit, accessOtpCode.length !== 8)
2862
- ] })
2889
+ ] })
2890
+ ] }) }),
2891
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: renderLoaderBtn("Se connecter", "Vérification...", handleAccessOtpSubmit, accessOtpCode.length !== 8) })
2863
2892
  ] })
2864
2893
  ] }) }) }),
2865
2894
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2874,25 +2903,220 @@ function LoginModal({
2874
2903
  )
2875
2904
  ] });
2876
2905
  }
2877
- const SUPPORTED_COUNTRIES = [
2878
- { code: "+221", name: "Sénégal", flag: "🇸🇳", digits: 9 },
2879
- { code: "+229", name: "Bénin", flag: "🇧🇯", digits: 8 },
2880
- { code: "+225", name: "Côte d'Ivoire", flag: "🇨🇮", digits: 10 },
2881
- { code: "+228", name: "Togo", flag: "🇹🇬", digits: 8 },
2882
- { code: "+237", name: "Cameroun", flag: "🇨🇲", digits: 9 },
2883
- { code: "+33", name: "France", flag: "🇫🇷", digits: 9 }
2906
+ const COUNTRIES = [
2907
+ // ── Afrique de l'Ouest (prioritaires) ──
2908
+ { code: "SN", name: "Sénégal", dialCode: "+221", flag: "🇸🇳", digits: 9 },
2909
+ { code: "CI", name: "Côte d'Ivoire", dialCode: "+225", flag: "🇨🇮", digits: 10 },
2910
+ { code: "ML", name: "Mali", dialCode: "+223", flag: "🇲🇱", digits: 8 },
2911
+ { code: "BF", name: "Burkina Faso", dialCode: "+226", flag: "🇧🇫", digits: 8 },
2912
+ { code: "GN", name: "Guinée", dialCode: "+224", flag: "🇬🇳", digits: 9 },
2913
+ { code: "TG", name: "Togo", dialCode: "+228", flag: "🇹🇬", digits: 8 },
2914
+ { code: "BJ", name: "Bénin", dialCode: "+229", flag: "🇧🇯", digits: 8 },
2915
+ { code: "NE", name: "Niger", dialCode: "+227", flag: "🇳🇪", digits: 8 },
2916
+ { code: "MR", name: "Mauritanie", dialCode: "+222", flag: "🇲🇷", digits: 8 },
2917
+ { code: "GW", name: "Guinée-Bissau", dialCode: "+245", flag: "🇬🇼", digits: 7 },
2918
+ { code: "GM", name: "Gambie", dialCode: "+220", flag: "🇬🇲", digits: 7 },
2919
+ { code: "CV", name: "Cap-Vert", dialCode: "+238", flag: "🇨🇻", digits: 7 },
2920
+ { code: "SL", name: "Sierra Leone", dialCode: "+232", flag: "🇸🇱", digits: 8 },
2921
+ { code: "LR", name: "Liberia", dialCode: "+231", flag: "🇱🇷", digits: 7 },
2922
+ { code: "GH", name: "Ghana", dialCode: "+233", flag: "🇬🇭", digits: 9 },
2923
+ { code: "NG", name: "Nigeria", dialCode: "+234", flag: "🇳🇬", digits: 10 },
2924
+ // ── Afrique Centrale ──
2925
+ { code: "CM", name: "Cameroun", dialCode: "+237", flag: "🇨🇲", digits: 9 },
2926
+ { code: "GA", name: "Gabon", dialCode: "+241", flag: "🇬🇦", digits: 7 },
2927
+ { code: "CG", name: "Congo", dialCode: "+242", flag: "🇨🇬", digits: 9 },
2928
+ { code: "CD", name: "RD Congo", dialCode: "+243", flag: "🇨🇩", digits: 9 },
2929
+ { code: "TD", name: "Tchad", dialCode: "+235", flag: "🇹🇩", digits: 8 },
2930
+ { code: "CF", name: "Centrafrique", dialCode: "+236", flag: "🇨🇫", digits: 8 },
2931
+ { code: "GQ", name: "Guinée équatoriale", dialCode: "+240", flag: "🇬🇶", digits: 9 },
2932
+ { code: "ST", name: "São Tomé-et-Príncipe", dialCode: "+239", flag: "🇸🇹", digits: 7 },
2933
+ { code: "BI", name: "Burundi", dialCode: "+257", flag: "🇧🇮", digits: 8 },
2934
+ { code: "RW", name: "Rwanda", dialCode: "+250", flag: "🇷🇼", digits: 9 },
2935
+ // ── Afrique de l'Est ──
2936
+ { code: "KE", name: "Kenya", dialCode: "+254", flag: "🇰🇪", digits: 9 },
2937
+ { code: "TZ", name: "Tanzanie", dialCode: "+255", flag: "🇹🇿", digits: 9 },
2938
+ { code: "UG", name: "Ouganda", dialCode: "+256", flag: "🇺🇬", digits: 9 },
2939
+ { code: "ET", name: "Éthiopie", dialCode: "+251", flag: "🇪🇹", digits: 9 },
2940
+ { code: "SO", name: "Somalie", dialCode: "+252", flag: "🇸🇴", digits: 8 },
2941
+ { code: "DJ", name: "Djibouti", dialCode: "+253", flag: "🇩🇯", digits: 8 },
2942
+ { code: "ER", name: "Érythrée", dialCode: "+291", flag: "🇪🇷", digits: 7 },
2943
+ { code: "SS", name: "Soudan du Sud", dialCode: "+211", flag: "🇸🇸", digits: 9 },
2944
+ { code: "MG", name: "Madagascar", dialCode: "+261", flag: "🇲🇬", digits: 9 },
2945
+ { code: "MU", name: "Maurice", dialCode: "+230", flag: "🇲🇺", digits: 8 },
2946
+ { code: "SC", name: "Seychelles", dialCode: "+248", flag: "🇸🇨", digits: 7 },
2947
+ { code: "KM", name: "Comores", dialCode: "+269", flag: "🇰🇲", digits: 7 },
2948
+ // ── Afrique Australe ──
2949
+ { code: "ZA", name: "Afrique du Sud", dialCode: "+27", flag: "🇿🇦", digits: 9 },
2950
+ { code: "MZ", name: "Mozambique", dialCode: "+258", flag: "🇲🇿", digits: 9 },
2951
+ { code: "ZW", name: "Zimbabwe", dialCode: "+263", flag: "🇿🇼", digits: 9 },
2952
+ { code: "ZM", name: "Zambie", dialCode: "+260", flag: "🇿🇲", digits: 9 },
2953
+ { code: "MW", name: "Malawi", dialCode: "+265", flag: "🇲🇼", digits: 9 },
2954
+ { code: "BW", name: "Botswana", dialCode: "+267", flag: "🇧🇼", digits: 8 },
2955
+ { code: "NA", name: "Namibie", dialCode: "+264", flag: "🇳🇦", digits: 9 },
2956
+ { code: "AO", name: "Angola", dialCode: "+244", flag: "🇦🇴", digits: 9 },
2957
+ { code: "SZ", name: "Eswatini", dialCode: "+268", flag: "🇸🇿", digits: 8 },
2958
+ { code: "LS", name: "Lesotho", dialCode: "+266", flag: "🇱🇸", digits: 8 },
2959
+ // ── Afrique du Nord ──
2960
+ { code: "MA", name: "Maroc", dialCode: "+212", flag: "🇲🇦", digits: 9 },
2961
+ { code: "DZ", name: "Algérie", dialCode: "+213", flag: "🇩🇿", digits: 9 },
2962
+ { code: "TN", name: "Tunisie", dialCode: "+216", flag: "🇹🇳", digits: 8 },
2963
+ { code: "LY", name: "Libye", dialCode: "+218", flag: "🇱🇾", digits: 9 },
2964
+ { code: "EG", name: "Égypte", dialCode: "+20", flag: "🇪🇬", digits: 10 },
2965
+ { code: "SD", name: "Soudan", dialCode: "+249", flag: "🇸🇩", digits: 9 },
2966
+ // ── Europe ──
2967
+ { code: "FR", name: "France", dialCode: "+33", flag: "🇫🇷", digits: 9 },
2968
+ { code: "BE", name: "Belgique", dialCode: "+32", flag: "🇧🇪", digits: 9 },
2969
+ { code: "CH", name: "Suisse", dialCode: "+41", flag: "🇨🇭", digits: 9 },
2970
+ { code: "DE", name: "Allemagne", dialCode: "+49", flag: "🇩🇪", digits: 10 },
2971
+ { code: "GB", name: "Royaume-Uni", dialCode: "+44", flag: "🇬🇧", digits: 10 },
2972
+ { code: "ES", name: "Espagne", dialCode: "+34", flag: "🇪🇸", digits: 9 },
2973
+ { code: "IT", name: "Italie", dialCode: "+39", flag: "🇮🇹", digits: 10 },
2974
+ { code: "PT", name: "Portugal", dialCode: "+351", flag: "🇵🇹", digits: 9 },
2975
+ { code: "NL", name: "Pays-Bas", dialCode: "+31", flag: "🇳🇱", digits: 9 },
2976
+ { code: "SE", name: "Suède", dialCode: "+46", flag: "🇸🇪", digits: 9 },
2977
+ { code: "NO", name: "Norvège", dialCode: "+47", flag: "🇳🇴", digits: 8 },
2978
+ { code: "DK", name: "Danemark", dialCode: "+45", flag: "🇩🇰", digits: 8 },
2979
+ { code: "FI", name: "Finlande", dialCode: "+358", flag: "🇫🇮", digits: 10 },
2980
+ { code: "PL", name: "Pologne", dialCode: "+48", flag: "🇵🇱", digits: 9 },
2981
+ { code: "AT", name: "Autriche", dialCode: "+43", flag: "🇦🇹", digits: 10 },
2982
+ { code: "IE", name: "Irlande", dialCode: "+353", flag: "🇮🇪", digits: 9 },
2983
+ { code: "GR", name: "Grèce", dialCode: "+30", flag: "🇬🇷", digits: 10 },
2984
+ { code: "CZ", name: "Tchéquie", dialCode: "+420", flag: "🇨🇿", digits: 9 },
2985
+ { code: "RO", name: "Roumanie", dialCode: "+40", flag: "🇷🇴", digits: 9 },
2986
+ { code: "HU", name: "Hongrie", dialCode: "+36", flag: "🇭🇺", digits: 9 },
2987
+ { code: "BG", name: "Bulgarie", dialCode: "+359", flag: "🇧🇬", digits: 9 },
2988
+ { code: "HR", name: "Croatie", dialCode: "+385", flag: "🇭🇷", digits: 9 },
2989
+ { code: "SK", name: "Slovaquie", dialCode: "+421", flag: "🇸🇰", digits: 9 },
2990
+ { code: "SI", name: "Slovénie", dialCode: "+386", flag: "🇸🇮", digits: 8 },
2991
+ { code: "RS", name: "Serbie", dialCode: "+381", flag: "🇷🇸", digits: 9 },
2992
+ { code: "UA", name: "Ukraine", dialCode: "+380", flag: "🇺🇦", digits: 9 },
2993
+ { code: "RU", name: "Russie", dialCode: "+7", flag: "🇷🇺", digits: 10 },
2994
+ { code: "TR", name: "Turquie", dialCode: "+90", flag: "🇹🇷", digits: 10 },
2995
+ { code: "LU", name: "Luxembourg", dialCode: "+352", flag: "🇱🇺", digits: 9 },
2996
+ { code: "MC", name: "Monaco", dialCode: "+377", flag: "🇲🇨", digits: 8 },
2997
+ { code: "IS", name: "Islande", dialCode: "+354", flag: "🇮🇸", digits: 7 },
2998
+ { code: "AL", name: "Albanie", dialCode: "+355", flag: "🇦🇱", digits: 9 },
2999
+ { code: "ME", name: "Monténégro", dialCode: "+382", flag: "🇲🇪", digits: 8 },
3000
+ { code: "MK", name: "Macédoine du Nord", dialCode: "+389", flag: "🇲🇰", digits: 8 },
3001
+ { code: "BA", name: "Bosnie-Herzégovine", dialCode: "+387", flag: "🇧🇦", digits: 8 },
3002
+ { code: "LT", name: "Lituanie", dialCode: "+370", flag: "🇱🇹", digits: 8 },
3003
+ { code: "LV", name: "Lettonie", dialCode: "+371", flag: "🇱🇻", digits: 8 },
3004
+ { code: "EE", name: "Estonie", dialCode: "+372", flag: "🇪🇪", digits: 8 },
3005
+ { code: "MT", name: "Malte", dialCode: "+356", flag: "🇲🇹", digits: 8 },
3006
+ { code: "CY", name: "Chypre", dialCode: "+357", flag: "🇨🇾", digits: 8 },
3007
+ { code: "MD", name: "Moldavie", dialCode: "+373", flag: "🇲🇩", digits: 8 },
3008
+ { code: "GE", name: "Géorgie", dialCode: "+995", flag: "🇬🇪", digits: 9 },
3009
+ { code: "AM", name: "Arménie", dialCode: "+374", flag: "🇦🇲", digits: 8 },
3010
+ { code: "AZ", name: "Azerbaïdjan", dialCode: "+994", flag: "🇦🇿", digits: 9 },
3011
+ { code: "BY", name: "Biélorussie", dialCode: "+375", flag: "🇧🇾", digits: 9 },
3012
+ // ── Amérique du Nord ──
3013
+ { code: "US", name: "États-Unis", dialCode: "+1", flag: "🇺🇸", digits: 10 },
3014
+ { code: "CA", name: "Canada", dialCode: "+1", flag: "🇨🇦", digits: 10 },
3015
+ { code: "MX", name: "Mexique", dialCode: "+52", flag: "🇲🇽", digits: 10 },
3016
+ // ── Amérique Centrale & Caraïbes ──
3017
+ { code: "HT", name: "Haïti", dialCode: "+509", flag: "🇭🇹", digits: 8 },
3018
+ { code: "DO", name: "République dominicaine", dialCode: "+1809", flag: "🇩🇴", digits: 10 },
3019
+ { code: "CU", name: "Cuba", dialCode: "+53", flag: "🇨🇺", digits: 8 },
3020
+ { code: "JM", name: "Jamaïque", dialCode: "+1876", flag: "🇯🇲", digits: 7 },
3021
+ { code: "GT", name: "Guatemala", dialCode: "+502", flag: "🇬🇹", digits: 8 },
3022
+ { code: "HN", name: "Honduras", dialCode: "+504", flag: "🇭🇳", digits: 8 },
3023
+ { code: "SV", name: "El Salvador", dialCode: "+503", flag: "🇸🇻", digits: 8 },
3024
+ { code: "NI", name: "Nicaragua", dialCode: "+505", flag: "🇳🇮", digits: 8 },
3025
+ { code: "CR", name: "Costa Rica", dialCode: "+506", flag: "🇨🇷", digits: 8 },
3026
+ { code: "PA", name: "Panama", dialCode: "+507", flag: "🇵🇦", digits: 8 },
3027
+ { code: "TT", name: "Trinité-et-Tobago", dialCode: "+1868", flag: "🇹🇹", digits: 7 },
3028
+ // ── Amérique du Sud ──
3029
+ { code: "BR", name: "Brésil", dialCode: "+55", flag: "🇧🇷", digits: 11 },
3030
+ { code: "AR", name: "Argentine", dialCode: "+54", flag: "🇦🇷", digits: 10 },
3031
+ { code: "CO", name: "Colombie", dialCode: "+57", flag: "🇨🇴", digits: 10 },
3032
+ { code: "CL", name: "Chili", dialCode: "+56", flag: "🇨🇱", digits: 9 },
3033
+ { code: "PE", name: "Pérou", dialCode: "+51", flag: "🇵🇪", digits: 9 },
3034
+ { code: "VE", name: "Venezuela", dialCode: "+58", flag: "🇻🇪", digits: 10 },
3035
+ { code: "EC", name: "Équateur", dialCode: "+593", flag: "🇪🇨", digits: 9 },
3036
+ { code: "BO", name: "Bolivie", dialCode: "+591", flag: "🇧🇴", digits: 8 },
3037
+ { code: "PY", name: "Paraguay", dialCode: "+595", flag: "🇵🇾", digits: 9 },
3038
+ { code: "UY", name: "Uruguay", dialCode: "+598", flag: "🇺🇾", digits: 8 },
3039
+ { code: "GY", name: "Guyana", dialCode: "+592", flag: "🇬🇾", digits: 7 },
3040
+ { code: "SR", name: "Suriname", dialCode: "+597", flag: "🇸🇷", digits: 7 },
3041
+ // ── Moyen-Orient ──
3042
+ { code: "AE", name: "Émirats arabes unis", dialCode: "+971", flag: "🇦🇪", digits: 9 },
3043
+ { code: "SA", name: "Arabie saoudite", dialCode: "+966", flag: "🇸🇦", digits: 9 },
3044
+ { code: "QA", name: "Qatar", dialCode: "+974", flag: "🇶🇦", digits: 8 },
3045
+ { code: "KW", name: "Koweït", dialCode: "+965", flag: "🇰🇼", digits: 8 },
3046
+ { code: "BH", name: "Bahreïn", dialCode: "+973", flag: "🇧🇭", digits: 8 },
3047
+ { code: "OM", name: "Oman", dialCode: "+968", flag: "🇴🇲", digits: 8 },
3048
+ { code: "JO", name: "Jordanie", dialCode: "+962", flag: "🇯🇴", digits: 9 },
3049
+ { code: "LB", name: "Liban", dialCode: "+961", flag: "🇱🇧", digits: 8 },
3050
+ { code: "IQ", name: "Irak", dialCode: "+964", flag: "🇮🇶", digits: 10 },
3051
+ { code: "IR", name: "Iran", dialCode: "+98", flag: "🇮🇷", digits: 10 },
3052
+ { code: "IL", name: "Israël", dialCode: "+972", flag: "🇮🇱", digits: 9 },
3053
+ { code: "PS", name: "Palestine", dialCode: "+970", flag: "🇵🇸", digits: 9 },
3054
+ { code: "YE", name: "Yémen", dialCode: "+967", flag: "🇾🇪", digits: 9 },
3055
+ { code: "SY", name: "Syrie", dialCode: "+963", flag: "🇸🇾", digits: 9 },
3056
+ // ── Asie ──
3057
+ { code: "CN", name: "Chine", dialCode: "+86", flag: "🇨🇳", digits: 11 },
3058
+ { code: "JP", name: "Japon", dialCode: "+81", flag: "🇯🇵", digits: 10 },
3059
+ { code: "KR", name: "Corée du Sud", dialCode: "+82", flag: "🇰🇷", digits: 10 },
3060
+ { code: "IN", name: "Inde", dialCode: "+91", flag: "🇮🇳", digits: 10 },
3061
+ { code: "PK", name: "Pakistan", dialCode: "+92", flag: "🇵🇰", digits: 10 },
3062
+ { code: "BD", name: "Bangladesh", dialCode: "+880", flag: "🇧🇩", digits: 10 },
3063
+ { code: "ID", name: "Indonésie", dialCode: "+62", flag: "🇮🇩", digits: 10 },
3064
+ { code: "MY", name: "Malaisie", dialCode: "+60", flag: "🇲🇾", digits: 10 },
3065
+ { code: "PH", name: "Philippines", dialCode: "+63", flag: "🇵🇭", digits: 10 },
3066
+ { code: "TH", name: "Thaïlande", dialCode: "+66", flag: "🇹🇭", digits: 9 },
3067
+ { code: "VN", name: "Vietnam", dialCode: "+84", flag: "🇻🇳", digits: 9 },
3068
+ { code: "SG", name: "Singapour", dialCode: "+65", flag: "🇸🇬", digits: 8 },
3069
+ { code: "HK", name: "Hong Kong", dialCode: "+852", flag: "🇭🇰", digits: 8 },
3070
+ { code: "TW", name: "Taïwan", dialCode: "+886", flag: "🇹🇼", digits: 9 },
3071
+ { code: "MM", name: "Myanmar", dialCode: "+95", flag: "🇲🇲", digits: 9 },
3072
+ { code: "KH", name: "Cambodge", dialCode: "+855", flag: "🇰🇭", digits: 9 },
3073
+ { code: "LA", name: "Laos", dialCode: "+856", flag: "🇱🇦", digits: 10 },
3074
+ { code: "NP", name: "Népal", dialCode: "+977", flag: "🇳🇵", digits: 10 },
3075
+ { code: "LK", name: "Sri Lanka", dialCode: "+94", flag: "🇱🇰", digits: 9 },
3076
+ { code: "AF", name: "Afghanistan", dialCode: "+93", flag: "🇦🇫", digits: 9 },
3077
+ { code: "UZ", name: "Ouzbékistan", dialCode: "+998", flag: "🇺🇿", digits: 9 },
3078
+ { code: "KZ", name: "Kazakhstan", dialCode: "+7", flag: "🇰🇿", digits: 10 },
3079
+ { code: "MN", name: "Mongolie", dialCode: "+976", flag: "🇲🇳", digits: 8 },
3080
+ // ── Océanie ──
3081
+ { code: "AU", name: "Australie", dialCode: "+61", flag: "🇦🇺", digits: 9 },
3082
+ { code: "NZ", name: "Nouvelle-Zélande", dialCode: "+64", flag: "🇳🇿", digits: 9 },
3083
+ { code: "FJ", name: "Fidji", dialCode: "+679", flag: "🇫🇯", digits: 7 },
3084
+ { code: "PG", name: "Papouasie-Nouvelle-Guinée", dialCode: "+675", flag: "🇵🇬", digits: 8 }
2884
3085
  ];
3086
+ const DEFAULT_COUNTRY_CODE = "SN";
3087
+ const DEFAULT_DIAL_CODE = "+221";
3088
+ const COUNTRIES_SORTED_BY_CODE = [...COUNTRIES].sort((a, b) => a.code.localeCompare(b.code));
3089
+ const getCountryByCode = (code) => COUNTRIES.find((c) => c.code.toLowerCase() === code.toLowerCase());
3090
+ const getCountryByDialCode = (dialCode) => COUNTRIES.find((c) => c.dialCode === dialCode);
3091
+ const getDefaultCountry = () => COUNTRIES.find((c) => c.code === DEFAULT_COUNTRY_CODE);
3092
+ const searchCountries = (query) => {
3093
+ const q = query.toLowerCase().trim();
3094
+ if (!q) return COUNTRIES;
3095
+ return COUNTRIES.filter(
3096
+ (c) => c.name.toLowerCase().includes(q) || c.dialCode.includes(q) || c.code.toLowerCase().includes(q)
3097
+ );
3098
+ };
2885
3099
  function PhoneInput({
2886
3100
  value,
2887
3101
  onChange,
2888
- ccphone = "+221",
3102
+ ccphone = DEFAULT_DIAL_CODE,
2889
3103
  onCcphoneChange,
2890
3104
  disabled = false,
2891
3105
  error,
2892
3106
  placeholder = "77 123 45 67",
2893
3107
  lockCcphone = false
2894
3108
  }) {
2895
- const selectedCountry = SUPPORTED_COUNTRIES.find((c) => c.code === ccphone) || SUPPORTED_COUNTRIES[0];
3109
+ const selectedCountry = getCountryByDialCode(ccphone) || COUNTRIES_SORTED_BY_CODE[0];
3110
+ const [dropdownOpen, setDropdownOpen] = react.useState(false);
3111
+ const dropdownRef = react.useRef(null);
3112
+ react.useEffect(() => {
3113
+ if (!dropdownOpen) return;
3114
+ const handler = (e) => {
3115
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) setDropdownOpen(false);
3116
+ };
3117
+ document.addEventListener("mousedown", handler);
3118
+ return () => document.removeEventListener("mousedown", handler);
3119
+ }, [dropdownOpen]);
2896
3120
  const handleChange = (e) => {
2897
3121
  const cleaned = e.target.value.replace(/\D/g, "");
2898
3122
  onChange(cleaned.slice(0, selectedCountry.digits));
@@ -2903,33 +3127,96 @@ function PhoneInput({
2903
3127
  if (phone.length <= 7) return `${phone.slice(0, 2)} ${phone.slice(2, 5)} ${phone.slice(5)}`;
2904
3128
  return `${phone.slice(0, 2)} ${phone.slice(2, 5)} ${phone.slice(5, 7)} ${phone.slice(7)}`;
2905
3129
  };
3130
+ const handleSelect = (dialCode) => {
3131
+ if (onCcphoneChange) onCcphoneChange(dialCode);
3132
+ setDropdownOpen(false);
3133
+ };
2906
3134
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2907
3135
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
2908
3136
  display: "flex",
2909
3137
  alignItems: "center",
2910
3138
  border: `2px solid ${error ? "#ef4444" : "#d1d5db"}`,
2911
3139
  borderRadius: "0.5rem",
2912
- overflow: "hidden",
3140
+ overflow: "visible",
2913
3141
  opacity: disabled ? 0.5 : 1,
2914
- backgroundColor: disabled ? "#f3f4f6" : "white"
3142
+ backgroundColor: disabled ? "#f3f4f6" : "white",
3143
+ position: "relative"
2915
3144
  }, children: [
2916
- onCcphoneChange && !lockCcphone ? /* @__PURE__ */ jsxRuntime.jsx(
2917
- "select",
2918
- {
2919
- value: ccphone,
2920
- onChange: (e) => onCcphoneChange(e.target.value),
2921
- disabled,
2922
- style: { padding: "0.75rem", backgroundColor: "#f9fafb", borderRight: "1px solid #e5e7eb", fontWeight: 500, color: "#374151", outline: "none", border: "none" },
2923
- children: SUPPORTED_COUNTRIES.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: c.code, children: [
2924
- c.flag,
2925
- " ",
2926
- c.code
2927
- ] }, c.code))
2928
- }
2929
- ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", padding: "0.75rem", backgroundColor: "#f9fafb", borderRight: "1px solid #e5e7eb" }, children: [
2930
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "1.125rem" }, children: selectedCountry.flag }),
2931
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: "#374151" }, children: selectedCountry.code })
2932
- ] }),
3145
+ onCcphoneChange && !lockCcphone ? /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, style: { position: "relative" }, children: [
3146
+ /* @__PURE__ */ jsxRuntime.jsxs(
3147
+ "button",
3148
+ {
3149
+ type: "button",
3150
+ onClick: () => !disabled && setDropdownOpen(!dropdownOpen),
3151
+ disabled,
3152
+ style: {
3153
+ display: "flex",
3154
+ alignItems: "center",
3155
+ gap: "0.375rem",
3156
+ padding: "0.75rem",
3157
+ backgroundColor: "#f9fafb",
3158
+ borderRight: "1px solid #e5e7eb",
3159
+ border: "none",
3160
+ cursor: disabled ? "not-allowed" : "pointer",
3161
+ fontWeight: 500,
3162
+ color: "#374151",
3163
+ fontSize: "0.9375rem",
3164
+ whiteSpace: "nowrap"
3165
+ },
3166
+ children: [
3167
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "1.125rem" }, children: selectedCountry.flag }),
3168
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: selectedCountry.dialCode }),
3169
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.625rem", marginLeft: "0.125rem" }, children: "▼" })
3170
+ ]
3171
+ }
3172
+ ),
3173
+ dropdownOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
3174
+ position: "absolute",
3175
+ top: "100%",
3176
+ left: 0,
3177
+ zIndex: 50,
3178
+ backgroundColor: "white",
3179
+ border: "1px solid #d1d5db",
3180
+ borderRadius: "0.375rem",
3181
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
3182
+ maxHeight: "15rem",
3183
+ overflowY: "auto",
3184
+ minWidth: "12rem",
3185
+ marginTop: "0.25rem"
3186
+ }, children: COUNTRIES_SORTED_BY_CODE.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
3187
+ "button",
3188
+ {
3189
+ type: "button",
3190
+ onClick: () => handleSelect(c.dialCode),
3191
+ style: {
3192
+ display: "flex",
3193
+ alignItems: "center",
3194
+ gap: "0.5rem",
3195
+ width: "100%",
3196
+ padding: "0.5rem 0.75rem",
3197
+ border: "none",
3198
+ cursor: "pointer",
3199
+ fontSize: "0.875rem",
3200
+ backgroundColor: c.dialCode === ccphone ? "#f3f4f6" : "transparent",
3201
+ textAlign: "left"
3202
+ },
3203
+ onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "#f3f4f6",
3204
+ onMouseLeave: (e) => e.currentTarget.style.backgroundColor = c.dialCode === ccphone ? "#f3f4f6" : "transparent",
3205
+ children: [
3206
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600, color: "#374151", minWidth: "1.75rem" }, children: c.code }),
3207
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: c.flag }),
3208
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#6b7280" }, children: c.dialCode })
3209
+ ]
3210
+ },
3211
+ `${c.code}-${c.dialCode}`
3212
+ )) })
3213
+ ] }) : (
3214
+ /* Locked view: only flag + dialCode */
3215
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.375rem", padding: "0.75rem", backgroundColor: "#f9fafb", borderRight: "1px solid #e5e7eb" }, children: [
3216
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "1.125rem" }, children: selectedCountry.flag }),
3217
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: "#374151" }, children: selectedCountry.dialCode })
3218
+ ] })
3219
+ ),
2933
3220
  /* @__PURE__ */ jsxRuntime.jsx(
2934
3221
  "input",
2935
3222
  {
@@ -3232,6 +3519,18 @@ function useMobileRegistration(options) {
3232
3519
  }));
3233
3520
  return { success: false, error_type: response.error_type };
3234
3521
  } catch (err) {
3522
+ if (err instanceof ApiError && err.statusCode === 409 && err.response) {
3523
+ const resp = err.response;
3524
+ if (resp.conflict) {
3525
+ setState((prev) => ({
3526
+ ...prev,
3527
+ loading: false,
3528
+ error: resp.message || "Ce compte existe déjà",
3529
+ conflict: resp.conflict
3530
+ }));
3531
+ return { success: false, error_type: resp.error_type };
3532
+ }
3533
+ }
3235
3534
  const message = getErrorMessage(err, "l'inscription");
3236
3535
  setState((prev) => ({ ...prev, loading: false, error: message, conflict: null }));
3237
3536
  return { success: false };
@@ -3377,6 +3676,7 @@ const C$1 = {
3377
3676
  gray900: "#111827",
3378
3677
  red: "#dc2626",
3379
3678
  redBg: "#fef2f2",
3679
+ amber: "#f59e0b",
3380
3680
  amberBg: "#fef3c7",
3381
3681
  white: "#ffffff"
3382
3682
  };
@@ -3469,12 +3769,14 @@ function SuccessOrbit() {
3469
3769
  })
3470
3770
  ] });
3471
3771
  }
3472
- function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saasApiUrl, iamApiUrl, defaultAccountType }) {
3772
+ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saasApiUrl, iamApiUrl, defaultAccountType, onSwitchToLoginWithPhone }) {
3773
+ var _a, _b, _c, _d, _e, _f;
3473
3774
  const {
3474
3775
  status,
3475
3776
  formData,
3476
3777
  loading: regLoading,
3477
3778
  error: regError,
3779
+ conflict,
3478
3780
  accountType,
3479
3781
  setAccountType,
3480
3782
  isPhoneOnly,
@@ -3486,6 +3788,7 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
3486
3788
  reset: resetReg,
3487
3789
  clearError
3488
3790
  } = useMobileRegistration({ saasApiUrl, iamApiUrl });
3791
+ const [showPasswordRecovery, setShowPasswordRecovery] = react.useState(false);
3489
3792
  const [step, setStep] = react.useState("intro");
3490
3793
  const [otpCode, setOtpCode] = react.useState("");
3491
3794
  const [password, setPassword] = react.useState("");
@@ -3538,31 +3841,35 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
3538
3841
  }
3539
3842
  };
3540
3843
  const handleInfoSubmit = async (e) => {
3541
- var _a, _b, _c, _d, _e, _f;
3844
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g;
3542
3845
  e.preventDefault();
3543
3846
  setLocalError(null);
3544
3847
  clearError();
3545
- if (!((_a = formData.name) == null ? void 0 : _a.trim())) {
3848
+ if (!((_a2 = formData.name) == null ? void 0 : _a2.trim())) {
3546
3849
  setLocalError("Le nom est requis");
3547
3850
  return;
3548
3851
  }
3549
- if (!isPhoneOnly && !((_b = formData.email) == null ? void 0 : _b.trim())) {
3852
+ if (!isPhoneOnly && !((_b2 = formData.email) == null ? void 0 : _b2.trim())) {
3550
3853
  setLocalError("L'adresse email est requise");
3551
3854
  return;
3552
3855
  }
3553
- if (!((_c = formData.phone) == null ? void 0 : _c.trim()) || (((_d = formData.phone) == null ? void 0 : _d.length) || 0) < 6) {
3856
+ if (!((_c2 = formData.phone) == null ? void 0 : _c2.trim()) || (((_d2 = formData.phone) == null ? void 0 : _d2.length) || 0) < 6) {
3554
3857
  setLocalError("Numéro de téléphone invalide");
3555
3858
  return;
3556
3859
  }
3860
+ if (formData.ccphone === "+221" && ((_e2 = formData.phone) == null ? void 0 : _e2.length) !== 9) {
3861
+ setLocalError("Le numéro sénégalais doit contenir exactement 9 chiffres");
3862
+ return;
3863
+ }
3557
3864
  if (isPhoneOnly && formData.ccphone !== "+221") {
3558
3865
  setLocalError("L'inscription par téléphone est réservée aux numéros sénégalais (+221)");
3559
3866
  return;
3560
3867
  }
3561
- if (!((_e = formData.town) == null ? void 0 : _e.trim())) {
3868
+ if (!((_f2 = formData.town) == null ? void 0 : _f2.trim())) {
3562
3869
  setLocalError("La ville est requise");
3563
3870
  return;
3564
3871
  }
3565
- if (!((_f = formData.country) == null ? void 0 : _f.trim())) {
3872
+ if (!((_g = formData.country) == null ? void 0 : _g.trim())) {
3566
3873
  setLocalError("Le pays est requis");
3567
3874
  return;
3568
3875
  }
@@ -3609,185 +3916,286 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
3609
3916
  };
3610
3917
  const handleAccountTypeSelect = (type) => {
3611
3918
  setAccountType(type);
3612
- if (type === "phone-only") updateFormData({ ccphone: "+221", country: "Sénégal", email: "" });
3919
+ if (type === "phone-only") updateFormData({ ccphone: "+221", country: "SN", email: "" });
3920
+ else if (!formData.country) updateFormData({ country: DEFAULT_COUNTRY_CODE });
3613
3921
  goToStep("info");
3614
3922
  };
3615
3923
  const renderError = () => error ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem", borderRadius: "0.375rem", backgroundColor: C$1.redBg, color: C$1.red, fontSize: "0.875rem" }, children: error }) : null;
3616
- return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(DialogContent, { children: signupSuccess && signupData ? /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3617
- /* @__PURE__ */ jsxRuntime.jsx(SuccessOrbit, {}),
3618
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Félicitations !" }),
3619
- /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
3620
- "Votre compte a été créé avec succès. Bienvenue ",
3621
- formData.name,
3622
- " !"
3623
- ] }),
3624
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem", fontSize: "0.875rem", color: C$1.gray500, marginTop: "1rem" }, children: [
3625
- /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3626
- "Connexion automatique en cours..."
3627
- ] })
3628
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3629
- step === "intro" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3630
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3631
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.accent + "1a", "4rem"), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "2rem", height: "2rem", color: C$1.accent } }) }),
3632
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Ouvrez un compte Ollaid" }),
3633
- /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Un compte unique qui vous donne accès à toutes les applications" })
3924
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3925
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(DialogContent, { children: signupSuccess && signupData ? /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3926
+ /* @__PURE__ */ jsxRuntime.jsx(SuccessOrbit, {}),
3927
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Félicitations !" }),
3928
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
3929
+ "Votre compte a été créé avec succès. Bienvenue ",
3930
+ formData.name,
3931
+ " !"
3634
3932
  ] }),
3635
- /* @__PURE__ */ jsxRuntime.jsx(AppsLogoSlider, { iamApiUrl }),
3636
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem", fontSize: "0.875rem", color: C$1.gray500, margin: "1rem 0" }, children: ["Un seul compte pour toutes les applications", "Plus besoin de multiples mots de passe", "Connexion simplifiée et sécurisée"].map((text) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem" }, children: [
3637
- /* @__PURE__ */ jsxRuntime.jsx(IconCheckCircle2, { style: { width: "1.25rem", height: "1.25rem", color: C$1.green, flexShrink: 0 } }),
3638
- text
3639
- ] }, text)) }),
3640
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 1 }),
3641
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => goToStep("account-type"), style: { width: "100%", marginTop: "1rem" }, children: "Suivant →" }),
3642
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem", marginTop: "1rem" }, children: [
3643
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$1.gray500 }, children: "Déjà un compte ? " }),
3644
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: linkStyle, onClick: onSwitchToLogin, children: "Connectez-vous" })
3933
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem", fontSize: "0.875rem", color: C$1.gray500, marginTop: "1rem" }, children: [
3934
+ /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3935
+ "Connexion automatique en cours..."
3645
3936
  ] })
3646
- ] }),
3647
- step === "account-type" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3648
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("intro"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3649
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3650
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.gray100), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
3651
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Choisissez votre type de compte" })
3652
- ] }),
3653
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem", marginTop: "1rem" }, children: [
3654
- /* @__PURE__ */ jsxRuntime.jsxs(
3655
- "button",
3656
- {
3657
- type: "button",
3658
- onClick: () => handleAccountTypeSelect("email"),
3659
- style: { width: "100%", padding: "1rem", border: `2px solid ${C$1.gray200}`, borderRadius: "0.5rem", textAlign: "left", cursor: "pointer", background: C$1.white, display: "flex", alignItems: "center", gap: "0.75rem" },
3660
- children: [
3661
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "2.5rem", height: "2.5rem", backgroundColor: C$1.accent, borderRadius: "0.5rem", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(IconMail, { style: { width: "1.25rem", height: "1.25rem", color: C$1.white } }) }),
3662
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3663
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Email + Téléphone" }),
3664
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "Compte complet" })
3665
- ] })
3666
- ]
3667
- }
3668
- ),
3669
- /* @__PURE__ */ jsxRuntime.jsxs(
3670
- "button",
3671
- {
3672
- type: "button",
3673
- onClick: () => handleAccountTypeSelect("phone-only"),
3674
- style: { width: "100%", padding: "1rem", border: `2px solid ${C$1.gray200}`, borderRadius: "0.5rem", textAlign: "left", cursor: "pointer", background: C$1.white, display: "flex", alignItems: "center", gap: "0.75rem" },
3675
- children: [
3676
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "2.5rem", height: "2.5rem", backgroundColor: C$1.accent, borderRadius: "0.5rem", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(IconSmartphone, { style: { width: "1.25rem", height: "1.25rem", color: C$1.white } }) }),
3677
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3678
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Téléphone uniquement" }),
3679
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "🇸🇳 Sénégal uniquement" })
3680
- ] })
3681
- ]
3682
- }
3683
- )
3684
- ] }),
3685
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 2 })
3686
- ] }),
3687
- step === "info" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3688
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("account-type"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3689
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3690
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.primary + "1a"), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
3691
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Créer votre compte" })
3692
- ] }),
3693
- isPhoneOnly && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem", borderRadius: "0.375rem", backgroundColor: C$1.accent + "1a", color: C$1.accent, fontSize: "0.8125rem", marginTop: "0.5rem", textAlign: "center" }, children: "📱 Inscription par téléphone — 🇸🇳 Sénégal uniquement" }),
3694
- !isPhoneOnly && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem", borderRadius: "0.375rem", backgroundColor: C$1.amberBg, color: "#92400e", fontSize: "0.8125rem", marginTop: "0.5rem", textAlign: "center" }, children: "⚠️ Un code OTP sera envoyé par email pour vérification" }),
3695
- /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleInfoSubmit, style: { display: "flex", flexDirection: "column", gap: "0.75rem", marginTop: "0.75rem" }, children: [
3696
- renderError(),
3697
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3698
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Nom complet" }),
3699
- /* @__PURE__ */ jsxRuntime.jsx(Input, { placeholder: "Jean Dupont", value: formData.name || "", onChange: (e) => updateFormData({ name: e.target.value }), disabled: regLoading })
3700
- ] }),
3701
- !isPhoneOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3702
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Adresse email" }),
3703
- /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "email", placeholder: "vous@exemple.com", value: formData.email || "", onChange: (e) => updateFormData({ email: e.target.value }), disabled: regLoading })
3937
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3938
+ step === "intro" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3939
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3940
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.accent + "1a", "4rem"), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "2rem", height: "2rem", color: C$1.accent } }) }),
3941
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Ouvrez un compte Ollaid" }),
3942
+ /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Un compte unique qui vous donne accès à toutes les applications" })
3704
3943
  ] }),
3705
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3706
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Numéro de téléphone" }),
3707
- /* @__PURE__ */ jsxRuntime.jsx(PhoneInput, { value: formData.phone || "", onChange: (p) => updateFormData({ phone: p }), ccphone: formData.ccphone || "+221", onCcphoneChange: (c) => updateFormData({ ccphone: c }), disabled: regLoading, lockCcphone: isPhoneOnly })
3944
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogBody, { children: [
3945
+ /* @__PURE__ */ jsxRuntime.jsx(AppsLogoSlider, { iamApiUrl }),
3946
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem", fontSize: "0.875rem", color: C$1.gray500, margin: "0.75rem 0" }, children: ["Un seul compte pour toutes les applications", "Plus besoin de multiples mots de passe", "Connexion simplifiée et sécurisée"].map((text) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem" }, children: [
3947
+ /* @__PURE__ */ jsxRuntime.jsx(IconCheckCircle2, { style: { width: "1.25rem", height: "1.25rem", color: C$1.green, flexShrink: 0 } }),
3948
+ text
3949
+ ] }, text)) }),
3950
+ /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 1 })
3708
3951
  ] }),
3709
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }, children: [
3710
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3711
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Ville" }),
3712
- /* @__PURE__ */ jsxRuntime.jsx(Input, { placeholder: "Dakar", value: formData.town || "", onChange: (e) => updateFormData({ town: e.target.value }), disabled: regLoading })
3713
- ] }),
3714
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3715
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Pays" }),
3716
- /* @__PURE__ */ jsxRuntime.jsx(Input, { placeholder: "Sénégal", value: formData.country || "", onChange: (e) => updateFormData({ country: e.target.value }), disabled: regLoading || isPhoneOnly })
3952
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
3953
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => goToStep("account-type"), style: { width: "100%" }, children: "Suivant →" }),
3954
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: [
3955
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$1.gray500 }, children: "Déjà un compte ? " }),
3956
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: linkStyle, onClick: onSwitchToLogin, children: "Connectez-vous" })
3717
3957
  ] })
3958
+ ] })
3959
+ ] }),
3960
+ step === "account-type" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3961
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("intro"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3962
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3963
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.gray100), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
3964
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Choisissez votre type de compte" })
3718
3965
  ] }),
3719
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 3 }),
3720
- /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: regLoading, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
3721
- /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3722
- " Vérification..."
3723
- ] }) : "Continuer" })
3724
- ] })
3725
- ] }),
3726
- step === "otp" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3727
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("info"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3728
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3729
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.accent), children: /* @__PURE__ */ jsxRuntime.jsx(IconKeyRound, { style: { width: "1.5rem", height: "1.5rem", color: C$1.white } }) }),
3730
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Vérification" }),
3731
- /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
3732
- "Entrez le code envoyé ",
3733
- isPhoneOnly ? `au ${formData.ccphone} ${formData.phone}` : `à ${formData.email}`
3966
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogBody, { children: [
3967
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
3968
+ /* @__PURE__ */ jsxRuntime.jsxs(
3969
+ "button",
3970
+ {
3971
+ type: "button",
3972
+ onClick: () => handleAccountTypeSelect("email"),
3973
+ style: { width: "100%", padding: "1rem", border: `2px solid ${C$1.gray200}`, borderRadius: "0.5rem", textAlign: "left", cursor: "pointer", background: C$1.white, display: "flex", alignItems: "center", gap: "0.75rem" },
3974
+ children: [
3975
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "2.5rem", height: "2.5rem", backgroundColor: C$1.accent, borderRadius: "0.5rem", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(IconMail, { style: { width: "1.25rem", height: "1.25rem", color: C$1.white } }) }),
3976
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3977
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Email + Téléphone" }),
3978
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "Compte complet" })
3979
+ ] })
3980
+ ]
3981
+ }
3982
+ ),
3983
+ /* @__PURE__ */ jsxRuntime.jsxs(
3984
+ "button",
3985
+ {
3986
+ type: "button",
3987
+ onClick: () => handleAccountTypeSelect("phone-only"),
3988
+ style: { width: "100%", padding: "1rem", border: `2px solid ${C$1.gray200}`, borderRadius: "0.5rem", textAlign: "left", cursor: "pointer", background: C$1.white, display: "flex", alignItems: "center", gap: "0.75rem" },
3989
+ children: [
3990
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "2.5rem", height: "2.5rem", backgroundColor: C$1.accent, borderRadius: "0.5rem", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(IconSmartphone, { style: { width: "1.25rem", height: "1.25rem", color: C$1.white } }) }),
3991
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3992
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Téléphone uniquement" }),
3993
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "🇸🇳 Sénégal uniquement" })
3994
+ ] })
3995
+ ]
3996
+ }
3997
+ )
3998
+ ] }),
3999
+ /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 2 })
3734
4000
  ] })
3735
4001
  ] }),
3736
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
3737
- renderError(),
3738
- /* @__PURE__ */ jsxRuntime.jsx(OTPInput, { value: otpCode, onChange: setOtpCode, disabled: regLoading }),
3739
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: resendCooldown > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: C$1.gray500 }, children: [
3740
- "Renvoyer dans ",
3741
- resendCooldown,
3742
- "s"
3743
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: handleResendOTP, style: linkStyle, children: "Code non reçu ? Renvoyer" }) }),
3744
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 4 }),
3745
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleOTPSubmit, disabled: regLoading || otpCode.length !== 6, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
4002
+ step === "info" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4003
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("account-type"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
4004
+ conflict ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4005
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
4006
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.amberBg), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.amber } }) }),
4007
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: conflict.type === "phone" ? "Numéro déjà utilisé" : "Email déjà utilisé" }),
4008
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
4009
+ conflict.type === "phone" ? `Le numéro ${formData.ccphone || ""} ${formData.phone || ""} est déjà associé à un compte.` : `L'adresse ${formData.email || ""} est déjà associée à un compte.`,
4010
+ " ",
4011
+ "S'il s'agit du vôtre, connectez-vous."
4012
+ ] })
4013
+ ] }),
4014
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { style: { borderTop: "none" }, children: [
4015
+ conflict.type === "phone" && formData.ccphone === "+221" && ((_a = conflict.options) == null ? void 0 : _a.can_login) && /* @__PURE__ */ jsxRuntime.jsxs(
4016
+ Button,
4017
+ {
4018
+ onClick: () => {
4019
+ const fullPhone = formData.phone || "";
4020
+ if (onSwitchToLoginWithPhone) onSwitchToLoginWithPhone(fullPhone);
4021
+ else onSwitchToLogin();
4022
+ },
4023
+ style: { width: "100%" },
4024
+ children: [
4025
+ /* @__PURE__ */ jsxRuntime.jsx(IconSmartphone, { style: { width: "1rem", height: "1rem" } }),
4026
+ "Se connecter par téléphone"
4027
+ ]
4028
+ }
4029
+ ),
4030
+ (conflict.type === "email" || conflict.type === "phone" && formData.ccphone !== "+221") && ((_b = conflict.options) == null ? void 0 : _b.can_login) && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onSwitchToLogin, style: { width: "100%" }, children: "Se connecter" }),
4031
+ !isPhoneOnly && (((_c = conflict.options) == null ? void 0 : _c.can_recover_by_email) || ((_d = conflict.options) == null ? void 0 : _d.can_recover_by_sms)) && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => setShowPasswordRecovery(true), style: { width: "100%" }, children: "Récupérer mon compte" }),
4032
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => clearError(), style: { width: "100%" }, children: conflict.type === "phone" ? "Changer le numéro" : "Changer l'email" }),
4033
+ ((_e = conflict.options) == null ? void 0 : _e.masked_email) && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "0.75rem", backgroundColor: C$1.gray100, borderRadius: "0.375rem", fontSize: "0.8125rem", color: C$1.gray500, textAlign: "center" }, children: [
4034
+ "Email lié : ",
4035
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: C$1.gray900 }, children: conflict.options.masked_email })
4036
+ ] }),
4037
+ ((_f = conflict.options) == null ? void 0 : _f.masked_phone) && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "0.75rem", backgroundColor: C$1.gray100, borderRadius: "0.375rem", fontSize: "0.8125rem", color: C$1.gray500, textAlign: "center" }, children: [
4038
+ "Téléphone lié : ",
4039
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: C$1.gray900 }, children: conflict.options.masked_phone })
4040
+ ] })
4041
+ ] })
4042
+ ] }) : (
4043
+ /* ---- NORMAL INFO FORM ---- */
4044
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4045
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
4046
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.primary + "1a"), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
4047
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Créer votre compte" })
4048
+ ] }),
4049
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleInfoSubmit, style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
4050
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogBody, { children: [
4051
+ isPhoneOnly && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem", borderRadius: "0.375rem", backgroundColor: C$1.accent + "1a", color: C$1.accent, fontSize: "0.8125rem", marginBottom: "0.5rem", textAlign: "center" }, children: "📱 Inscription par téléphone — 🇸🇳 Sénégal uniquement" }),
4052
+ !isPhoneOnly && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem", borderRadius: "0.375rem", backgroundColor: C$1.amberBg, color: "#92400e", fontSize: "0.8125rem", marginBottom: "0.5rem", textAlign: "center" }, children: "⚠️ Un code OTP sera envoyé par email pour vérification" }),
4053
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
4054
+ renderError(),
4055
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4056
+ /* @__PURE__ */ jsxRuntime.jsxs(Label, { children: [
4057
+ "Nom complet ",
4058
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$1.red }, children: "*" })
4059
+ ] }),
4060
+ /* @__PURE__ */ jsxRuntime.jsx(Input, { placeholder: "Jean Dupont", value: formData.name || "", onChange: (e) => updateFormData({ name: e.target.value }), disabled: regLoading })
4061
+ ] }),
4062
+ !isPhoneOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4063
+ /* @__PURE__ */ jsxRuntime.jsxs(Label, { children: [
4064
+ "Adresse email ",
4065
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$1.red }, children: "*" })
4066
+ ] }),
4067
+ /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "email", placeholder: "vous@exemple.com", value: formData.email || "", onChange: (e) => updateFormData({ email: e.target.value }), disabled: regLoading })
4068
+ ] }),
4069
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4070
+ /* @__PURE__ */ jsxRuntime.jsxs(Label, { children: [
4071
+ "Numéro de téléphone ",
4072
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$1.red }, children: "*" })
4073
+ ] }),
4074
+ /* @__PURE__ */ jsxRuntime.jsx(PhoneInput, { value: formData.phone || "", onChange: (p) => updateFormData({ phone: p }), ccphone: formData.ccphone || "+221", onCcphoneChange: (c) => updateFormData({ ccphone: c }), disabled: regLoading, lockCcphone: isPhoneOnly })
4075
+ ] }),
4076
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }, children: [
4077
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4078
+ /* @__PURE__ */ jsxRuntime.jsxs(Label, { children: [
4079
+ "Ville ",
4080
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$1.red }, children: "*" })
4081
+ ] }),
4082
+ /* @__PURE__ */ jsxRuntime.jsx(Input, { placeholder: "Dakar", value: formData.town || "", onChange: (e) => updateFormData({ town: e.target.value }), disabled: regLoading })
4083
+ ] }),
4084
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4085
+ /* @__PURE__ */ jsxRuntime.jsxs(Label, { children: [
4086
+ "Pays ",
4087
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$1.red }, children: "*" })
4088
+ ] }),
4089
+ /* @__PURE__ */ jsxRuntime.jsx(
4090
+ "select",
4091
+ {
4092
+ value: formData.country || DEFAULT_COUNTRY_CODE,
4093
+ onChange: (e) => {
4094
+ const country = getCountryByCode(e.target.value);
4095
+ updateFormData({ country: e.target.value, ccphone: (country == null ? void 0 : country.dialCode) || "+221" });
4096
+ },
4097
+ disabled: regLoading || isPhoneOnly,
4098
+ style: { width: "100%", padding: "0.5rem", borderRadius: "0.375rem", border: "1px solid #d1d5db", backgroundColor: regLoading || isPhoneOnly ? "#f3f4f6" : "white", fontSize: "0.875rem" },
4099
+ children: COUNTRIES_SORTED_BY_CODE.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: c.code, children: [
4100
+ c.code,
4101
+ " ",
4102
+ c.flag,
4103
+ " ",
4104
+ c.name
4105
+ ] }, c.code))
4106
+ }
4107
+ )
4108
+ ] })
4109
+ ] }),
4110
+ /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 3 })
4111
+ ] })
4112
+ ] }),
4113
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: regLoading, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
4114
+ /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
4115
+ " Vérification..."
4116
+ ] }) : "Continuer" }) })
4117
+ ] })
4118
+ ] })
4119
+ )
4120
+ ] }),
4121
+ step === "otp" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4122
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("info"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
4123
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
4124
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.accent), children: /* @__PURE__ */ jsxRuntime.jsx(IconKeyRound, { style: { width: "1.5rem", height: "1.5rem", color: C$1.white } }) }),
4125
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Vérification" }),
4126
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
4127
+ "Entrez le code envoyé ",
4128
+ isPhoneOnly ? `au ${formData.ccphone} ${formData.phone}` : `à ${formData.email}`
4129
+ ] })
4130
+ ] }),
4131
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
4132
+ renderError(),
4133
+ /* @__PURE__ */ jsxRuntime.jsx(OTPInput, { value: otpCode, onChange: setOtpCode, disabled: regLoading }),
4134
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: resendCooldown > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: C$1.gray500 }, children: [
4135
+ "Renvoyer dans ",
4136
+ resendCooldown,
4137
+ "s"
4138
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: handleResendOTP, style: linkStyle, children: "Code non reçu ? Renvoyer" }) }),
4139
+ /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 4 })
4140
+ ] }) }),
4141
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleOTPSubmit, disabled: regLoading || otpCode.length !== 6, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
3746
4142
  /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3747
4143
  " Vérification..."
3748
- ] }) : "Vérifier" })
3749
- ] })
3750
- ] }),
3751
- step === "password" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3752
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("otp"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3753
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3754
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.accent), children: /* @__PURE__ */ jsxRuntime.jsx(IconLock, { style: { width: "1.5rem", height: "1.5rem", color: C$1.white } }) }),
3755
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Créer un mot de passe" })
4144
+ ] }) : "Vérifier" }) })
3756
4145
  ] }),
3757
- /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handlePasswordSubmit, style: { display: "flex", flexDirection: "column", gap: "0.75rem", marginTop: "0.75rem" }, children: [
3758
- renderError(),
3759
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3760
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Mot de passe" }),
3761
- /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "password", placeholder: "Minimum 8 caractères", value: password, onChange: (e) => setPassword(e.target.value), disabled: regLoading })
3762
- ] }),
3763
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3764
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Confirmer le mot de passe" }),
3765
- /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "password", placeholder: "••••••••", value: passwordConfirm, onChange: (e) => setPasswordConfirm(e.target.value), disabled: regLoading })
4146
+ step === "password" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4147
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("otp"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
4148
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
4149
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.accent), children: /* @__PURE__ */ jsxRuntime.jsx(IconLock, { style: { width: "1.5rem", height: "1.5rem", color: C$1.white } }) }),
4150
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Créer un mot de passe" })
3766
4151
  ] }),
3767
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 5 }),
3768
- /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: regLoading, style: { width: "100%" }, children: "Continuer" })
3769
- ] })
3770
- ] }),
3771
- step === "confirm" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3772
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("password"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3773
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3774
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.primary + "1a"), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
3775
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Confirmer votre inscription" })
4152
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handlePasswordSubmit, style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
4153
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
4154
+ renderError(),
4155
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4156
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Mot de passe" }),
4157
+ /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "password", placeholder: "Minimum 8 caractères", value: password, onChange: (e) => setPassword(e.target.value), disabled: regLoading })
4158
+ ] }),
4159
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4160
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Confirmer le mot de passe" }),
4161
+ /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "password", placeholder: "••••••••", value: passwordConfirm, onChange: (e) => setPasswordConfirm(e.target.value), disabled: regLoading })
4162
+ ] }),
4163
+ /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 5 })
4164
+ ] }) }),
4165
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: regLoading, style: { width: "100%" }, children: "Continuer" }) })
4166
+ ] })
3776
4167
  ] }),
3777
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
3778
- renderError(),
3779
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { backgroundColor: C$1.gray100, borderRadius: "0.5rem", padding: "1rem" }, children: [["Nom", formData.name], ...!isPhoneOnly ? [["Email", formData.email]] : [], ["Téléphone", `${formData.ccphone} ${formData.phone}`], ["Ville", formData.town], ["Pays", formData.country]].map(([label, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", padding: "0.375rem 0" }, children: [
3780
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: label }),
3781
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.875rem", fontWeight: 500 }, children: value })
3782
- ] }, label)) }),
3783
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 6 }),
3784
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleConfirm, disabled: regLoading, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
4168
+ step === "confirm" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4169
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("password"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
4170
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
4171
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconCircle(C$1.primary + "1a"), children: /* @__PURE__ */ jsxRuntime.jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
4172
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Confirmer votre inscription" })
4173
+ ] }),
4174
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
4175
+ renderError(),
4176
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { backgroundColor: C$1.gray100, borderRadius: "0.5rem", padding: "1rem" }, children: [["Nom", formData.name], ...!isPhoneOnly ? [["Email", formData.email]] : [], ["Téléphone", `${formData.ccphone} ${formData.phone}`], ["Ville", formData.town], ["Pays", formData.country]].map(([label, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", padding: "0.375rem 0" }, children: [
4177
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: label }),
4178
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.875rem", fontWeight: 500 }, children: value })
4179
+ ] }, label)) }),
4180
+ /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 6 })
4181
+ ] }) }),
4182
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleConfirm, disabled: regLoading, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
3785
4183
  /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3786
4184
  " Création du compte..."
3787
- ] }) : "Créer mon compte" })
4185
+ ] }) : "Créer mon compte" }) })
3788
4186
  ] })
3789
- ] })
3790
- ] }) }) });
4187
+ ] }) }) }),
4188
+ /* @__PURE__ */ jsxRuntime.jsx(
4189
+ PasswordRecoveryModal,
4190
+ {
4191
+ open: showPasswordRecovery,
4192
+ onOpenChange: setShowPasswordRecovery,
4193
+ onSuccess: () => setShowPasswordRecovery(false),
4194
+ saasApiUrl,
4195
+ iamApiUrl
4196
+ }
4197
+ )
4198
+ ] });
3791
4199
  }
3792
4200
  const C = {
3793
4201
  primary: "#002147",
@@ -3854,7 +4262,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
3854
4262
  ] }),
3855
4263
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Ajoutez les informations manquantes pour finaliser votre compte." })
3856
4264
  ] }),
3857
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.25rem", marginTop: "1rem" }, children: [
4265
+ /* @__PURE__ */ jsxRuntime.jsx(DialogBody, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.25rem", marginTop: "0.75rem" }, children: [
3858
4266
  needsPhoto && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3859
4267
  /* @__PURE__ */ jsxRuntime.jsx(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: "Photo de profil" }),
3860
4268
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "1rem" }, children: [
@@ -3886,15 +4294,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
3886
4294
  fontWeight: 500
3887
4295
  }, children: [
3888
4296
  "Choisir une photo",
3889
- /* @__PURE__ */ jsxRuntime.jsx(
3890
- "input",
3891
- {
3892
- type: "file",
3893
- accept: "image/*",
3894
- onChange: handleFileChange,
3895
- style: { display: "none" }
3896
- }
3897
- )
4297
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "file", accept: "image/*", onChange: handleFileChange, style: { display: "none" } })
3898
4298
  ] }),
3899
4299
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.75rem", color: fileError ? "#dc2626" : C.gray500, marginTop: "0.25rem" }, children: fileError || "JPG, PNG. Max 2 Mo." })
3900
4300
  ] })
@@ -3902,15 +4302,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
3902
4302
  ] }),
3903
4303
  needsPhone && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3904
4304
  /* @__PURE__ */ jsxRuntime.jsx(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: "Numéro de téléphone" }),
3905
- /* @__PURE__ */ jsxRuntime.jsx(
3906
- PhoneInput,
3907
- {
3908
- value: phone,
3909
- onChange: setPhone,
3910
- ccphone,
3911
- onCcphoneChange: setCcphone
3912
- }
3913
- )
4305
+ /* @__PURE__ */ jsxRuntime.jsx(PhoneInput, { value: phone, onChange: setPhone, ccphone, onCcphoneChange: setCcphone })
3914
4306
  ] }),
3915
4307
  needsEmail && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3916
4308
  /* @__PURE__ */ jsxRuntime.jsxs(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: [
@@ -3952,38 +4344,32 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
3952
4344
  type: "checkbox",
3953
4345
  checked: confirmed,
3954
4346
  onChange: (e) => setConfirmed(e.target.checked),
3955
- style: {
3956
- width: "1rem",
3957
- height: "1rem",
3958
- marginTop: "0.125rem",
3959
- accentColor: C.primary,
3960
- cursor: "pointer"
3961
- }
4347
+ style: { width: "1rem", height: "1rem", marginTop: "0.125rem", accentColor: C.primary, cursor: "pointer" }
3962
4348
  }
3963
4349
  ),
3964
4350
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Je confirme que ces informations sont exactes" })
3965
- ] }),
3966
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
3967
- /* @__PURE__ */ jsxRuntime.jsx(
3968
- Button,
3969
- {
3970
- onClick: handleSubmit,
3971
- disabled: !canSubmit || submitting,
3972
- style: { width: "100%", height: "2.75rem", opacity: canSubmit && !submitting ? 1 : 0.5 },
3973
- children: submitting ? "Enregistrement..." : "Valider"
3974
- }
3975
- ),
3976
- /* @__PURE__ */ jsxRuntime.jsx(
3977
- Button,
3978
- {
3979
- variant: "outline",
3980
- onClick: onSkip,
3981
- disabled: submitting,
3982
- style: { width: "100%", height: "2.75rem" },
3983
- children: "Passer pour l'instant"
3984
- }
3985
- )
3986
4351
  ] })
4352
+ ] }) }),
4353
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
4354
+ /* @__PURE__ */ jsxRuntime.jsx(
4355
+ Button,
4356
+ {
4357
+ onClick: handleSubmit,
4358
+ disabled: !canSubmit || submitting,
4359
+ style: { width: "100%", height: "2.75rem", opacity: canSubmit && !submitting ? 1 : 0.5 },
4360
+ children: submitting ? "Enregistrement..." : "Valider"
4361
+ }
4362
+ ),
4363
+ /* @__PURE__ */ jsxRuntime.jsx(
4364
+ Button,
4365
+ {
4366
+ variant: "outline",
4367
+ onClick: onSkip,
4368
+ disabled: submitting,
4369
+ style: { width: "100%", height: "2.75rem" },
4370
+ children: "Passer pour l'instant"
4371
+ }
4372
+ )
3987
4373
  ] })
3988
4374
  ] }) });
3989
4375
  }
@@ -4234,6 +4620,7 @@ function NativeSSOPage({
4234
4620
  redirectAfterLogout
4235
4621
  }) {
4236
4622
  const [modal, setModal] = react.useState("none");
4623
+ const [loginInitialPhone, setLoginInitialPhone] = react.useState();
4237
4624
  const [showOnboarding, setShowOnboarding] = react.useState(false);
4238
4625
  const [pendingSession, setPendingSession] = react.useState(null);
4239
4626
  const [session, setSession] = react.useState(() => {
@@ -4275,13 +4662,23 @@ function NativeSSOPage({
4275
4662
  }, []);
4276
4663
  const openLogin = react.useCallback(() => setModal("login"), []);
4277
4664
  const openSignup = react.useCallback(() => setModal("signup"), []);
4278
- const closeModal = react.useCallback(() => setModal("none"), []);
4665
+ const closeModal = react.useCallback(() => {
4666
+ setModal("none");
4667
+ setLoginInitialPhone(void 0);
4668
+ }, []);
4279
4669
  const switchToSignup = react.useCallback(() => {
4280
4670
  setModal("none");
4671
+ setLoginInitialPhone(void 0);
4281
4672
  setTimeout(() => setModal("signup"), 150);
4282
4673
  }, []);
4283
4674
  const switchToLogin = react.useCallback(() => {
4284
4675
  setModal("none");
4676
+ setLoginInitialPhone(void 0);
4677
+ setTimeout(() => setModal("login"), 150);
4678
+ }, []);
4679
+ const switchToLoginWithPhone = react.useCallback((phone) => {
4680
+ setModal("none");
4681
+ setLoginInitialPhone(phone);
4285
4682
  setTimeout(() => setModal("login"), 150);
4286
4683
  }, []);
4287
4684
  const handleLoginSuccess = react.useCallback((token, user) => {
@@ -4381,6 +4778,13 @@ function NativeSSOPage({
4381
4778
  }, children: /* @__PURE__ */ jsxRuntime.jsx(AppsLogoSlider, { iamApiUrl, speed: "normal" }) }) })
4382
4779
  ] }) });
4383
4780
  if (session) {
4781
+ if (redirectAfterLogin) {
4782
+ window.location.href = redirectAfterLogin;
4783
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
4784
+ /* @__PURE__ */ jsxRuntime.jsx(TopBranding, { subtitle: title }),
4785
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "rgba(255,255,255,0.7)", fontSize: "0.875rem" }, children: "Redirection en cours..." })
4786
+ ] });
4787
+ }
4384
4788
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
4385
4789
  /* @__PURE__ */ jsxRuntime.jsx(TopBranding, { subtitle: title }),
4386
4790
  /* @__PURE__ */ jsxRuntime.jsx(SliderBadge, {}),
@@ -4425,7 +4829,8 @@ function NativeSSOPage({
4425
4829
  onLoginSuccess: handleLoginSuccess,
4426
4830
  saasApiUrl,
4427
4831
  iamApiUrl,
4428
- defaultAccountType: accountType
4832
+ defaultAccountType: accountType,
4833
+ initialPhone: loginInitialPhone
4429
4834
  }
4430
4835
  ),
4431
4836
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4436,6 +4841,7 @@ function NativeSSOPage({
4436
4841
  if (!open) closeModal();
4437
4842
  },
4438
4843
  onSwitchToLogin: switchToLogin,
4844
+ onSwitchToLoginWithPhone: switchToLoginWithPhone,
4439
4845
  onSignupSuccess: handleLoginSuccess,
4440
4846
  saasApiUrl,
4441
4847
  iamApiUrl,
@@ -4624,6 +5030,9 @@ const iamAccountService = {
4624
5030
  };
4625
5031
  exports.ApiError = ApiError;
4626
5032
  exports.AppsLogoSlider = AppsLogoSlider;
5033
+ exports.COUNTRIES = COUNTRIES;
5034
+ exports.DEFAULT_COUNTRY_CODE = DEFAULT_COUNTRY_CODE;
5035
+ exports.DEFAULT_DIAL_CODE = DEFAULT_DIAL_CODE;
4627
5036
  exports.LoginModal = LoginModal;
4628
5037
  exports.NativeSSOPage = NativeSSOPage;
4629
5038
  exports.NativeSSOProvider = NativeSSOProvider;
@@ -4636,10 +5045,14 @@ exports.clearAuthToken = clearAuthToken;
4636
5045
  exports.getAccountType = getAccountType;
4637
5046
  exports.getAuthToken = getAuthToken;
4638
5047
  exports.getAuthUser = getAuthUser;
5048
+ exports.getCountryByCode = getCountryByCode;
5049
+ exports.getCountryByDialCode = getCountryByDialCode;
5050
+ exports.getDefaultCountry = getDefaultCountry;
4639
5051
  exports.getNativeAuthConfig = getNativeAuthConfig;
4640
5052
  exports.iamAccountService = iamAccountService;
4641
5053
  exports.mobilePasswordService = mobilePasswordService;
4642
5054
  exports.nativeAuthService = nativeAuthService;
5055
+ exports.searchCountries = searchCountries;
4643
5056
  exports.setNativeAuthConfig = setNativeAuthConfig;
4644
5057
  exports.useMobilePassword = useMobilePassword;
4645
5058
  exports.useMobileRegistration = useMobileRegistration;