@ollaid/native-sso 1.0.7 → 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(
@@ -3056,6 +3085,7 @@ const COUNTRIES = [
3056
3085
  ];
3057
3086
  const DEFAULT_COUNTRY_CODE = "SN";
3058
3087
  const DEFAULT_DIAL_CODE = "+221";
3088
+ const COUNTRIES_SORTED_BY_CODE = [...COUNTRIES].sort((a, b) => a.code.localeCompare(b.code));
3059
3089
  const getCountryByCode = (code) => COUNTRIES.find((c) => c.code.toLowerCase() === code.toLowerCase());
3060
3090
  const getCountryByDialCode = (dialCode) => COUNTRIES.find((c) => c.dialCode === dialCode);
3061
3091
  const getDefaultCountry = () => COUNTRIES.find((c) => c.code === DEFAULT_COUNTRY_CODE);
@@ -3076,7 +3106,17 @@ function PhoneInput({
3076
3106
  placeholder = "77 123 45 67",
3077
3107
  lockCcphone = false
3078
3108
  }) {
3079
- const selectedCountry = getCountryByDialCode(ccphone) || 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]);
3080
3120
  const handleChange = (e) => {
3081
3121
  const cleaned = e.target.value.replace(/\D/g, "");
3082
3122
  onChange(cleaned.slice(0, selectedCountry.digits));
@@ -3087,33 +3127,96 @@ function PhoneInput({
3087
3127
  if (phone.length <= 7) return `${phone.slice(0, 2)} ${phone.slice(2, 5)} ${phone.slice(5)}`;
3088
3128
  return `${phone.slice(0, 2)} ${phone.slice(2, 5)} ${phone.slice(5, 7)} ${phone.slice(7)}`;
3089
3129
  };
3130
+ const handleSelect = (dialCode) => {
3131
+ if (onCcphoneChange) onCcphoneChange(dialCode);
3132
+ setDropdownOpen(false);
3133
+ };
3090
3134
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3091
3135
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
3092
3136
  display: "flex",
3093
3137
  alignItems: "center",
3094
3138
  border: `2px solid ${error ? "#ef4444" : "#d1d5db"}`,
3095
3139
  borderRadius: "0.5rem",
3096
- overflow: "hidden",
3140
+ overflow: "visible",
3097
3141
  opacity: disabled ? 0.5 : 1,
3098
- backgroundColor: disabled ? "#f3f4f6" : "white"
3142
+ backgroundColor: disabled ? "#f3f4f6" : "white",
3143
+ position: "relative"
3099
3144
  }, children: [
3100
- onCcphoneChange && !lockCcphone ? /* @__PURE__ */ jsxRuntime.jsx(
3101
- "select",
3102
- {
3103
- value: ccphone,
3104
- onChange: (e) => onCcphoneChange(e.target.value),
3105
- disabled,
3106
- style: { padding: "0.75rem", backgroundColor: "#f9fafb", borderRight: "1px solid #e5e7eb", fontWeight: 500, color: "#374151", outline: "none", border: "none", maxWidth: "7rem" },
3107
- children: COUNTRIES.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: c.dialCode, children: [
3108
- c.flag,
3109
- " ",
3110
- c.dialCode
3111
- ] }, `${c.code}-${c.dialCode}`))
3112
- }
3113
- ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", padding: "0.75rem", backgroundColor: "#f9fafb", borderRight: "1px solid #e5e7eb" }, children: [
3114
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "1.125rem" }, children: selectedCountry.flag }),
3115
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: "#374151" }, children: selectedCountry.dialCode })
3116
- ] }),
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
+ ),
3117
3220
  /* @__PURE__ */ jsxRuntime.jsx(
3118
3221
  "input",
3119
3222
  {
@@ -3416,6 +3519,18 @@ function useMobileRegistration(options) {
3416
3519
  }));
3417
3520
  return { success: false, error_type: response.error_type };
3418
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
+ }
3419
3534
  const message = getErrorMessage(err, "l'inscription");
3420
3535
  setState((prev) => ({ ...prev, loading: false, error: message, conflict: null }));
3421
3536
  return { success: false };
@@ -3561,6 +3676,7 @@ const C$1 = {
3561
3676
  gray900: "#111827",
3562
3677
  red: "#dc2626",
3563
3678
  redBg: "#fef2f2",
3679
+ amber: "#f59e0b",
3564
3680
  amberBg: "#fef3c7",
3565
3681
  white: "#ffffff"
3566
3682
  };
@@ -3653,12 +3769,14 @@ function SuccessOrbit() {
3653
3769
  })
3654
3770
  ] });
3655
3771
  }
3656
- 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;
3657
3774
  const {
3658
3775
  status,
3659
3776
  formData,
3660
3777
  loading: regLoading,
3661
3778
  error: regError,
3779
+ conflict,
3662
3780
  accountType,
3663
3781
  setAccountType,
3664
3782
  isPhoneOnly,
@@ -3670,6 +3788,7 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
3670
3788
  reset: resetReg,
3671
3789
  clearError
3672
3790
  } = useMobileRegistration({ saasApiUrl, iamApiUrl });
3791
+ const [showPasswordRecovery, setShowPasswordRecovery] = react.useState(false);
3673
3792
  const [step, setStep] = react.useState("intro");
3674
3793
  const [otpCode, setOtpCode] = react.useState("");
3675
3794
  const [password, setPassword] = react.useState("");
@@ -3722,31 +3841,35 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
3722
3841
  }
3723
3842
  };
3724
3843
  const handleInfoSubmit = async (e) => {
3725
- var _a, _b, _c, _d, _e, _f;
3844
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g;
3726
3845
  e.preventDefault();
3727
3846
  setLocalError(null);
3728
3847
  clearError();
3729
- if (!((_a = formData.name) == null ? void 0 : _a.trim())) {
3848
+ if (!((_a2 = formData.name) == null ? void 0 : _a2.trim())) {
3730
3849
  setLocalError("Le nom est requis");
3731
3850
  return;
3732
3851
  }
3733
- if (!isPhoneOnly && !((_b = formData.email) == null ? void 0 : _b.trim())) {
3852
+ if (!isPhoneOnly && !((_b2 = formData.email) == null ? void 0 : _b2.trim())) {
3734
3853
  setLocalError("L'adresse email est requise");
3735
3854
  return;
3736
3855
  }
3737
- 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) {
3738
3857
  setLocalError("Numéro de téléphone invalide");
3739
3858
  return;
3740
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
+ }
3741
3864
  if (isPhoneOnly && formData.ccphone !== "+221") {
3742
3865
  setLocalError("L'inscription par téléphone est réservée aux numéros sénégalais (+221)");
3743
3866
  return;
3744
3867
  }
3745
- if (!((_e = formData.town) == null ? void 0 : _e.trim())) {
3868
+ if (!((_f2 = formData.town) == null ? void 0 : _f2.trim())) {
3746
3869
  setLocalError("La ville est requise");
3747
3870
  return;
3748
3871
  }
3749
- if (!((_f = formData.country) == null ? void 0 : _f.trim())) {
3872
+ if (!((_g = formData.country) == null ? void 0 : _g.trim())) {
3750
3873
  setLocalError("Le pays est requis");
3751
3874
  return;
3752
3875
  }
@@ -3798,197 +3921,281 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
3798
3921
  goToStep("info");
3799
3922
  };
3800
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;
3801
- return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(DialogContent, { children: signupSuccess && signupData ? /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3802
- /* @__PURE__ */ jsxRuntime.jsx(SuccessOrbit, {}),
3803
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Félicitations !" }),
3804
- /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
3805
- "Votre compte a été créé avec succès. Bienvenue ",
3806
- formData.name,
3807
- " !"
3808
- ] }),
3809
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem", fontSize: "0.875rem", color: C$1.gray500, marginTop: "1rem" }, children: [
3810
- /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3811
- "Connexion automatique en cours..."
3812
- ] })
3813
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3814
- step === "intro" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3815
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3816
- /* @__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 } }) }),
3817
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Ouvrez un compte Ollaid" }),
3818
- /* @__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
+ " !"
3819
3932
  ] }),
3820
- /* @__PURE__ */ jsxRuntime.jsx(AppsLogoSlider, { iamApiUrl }),
3821
- /* @__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: [
3822
- /* @__PURE__ */ jsxRuntime.jsx(IconCheckCircle2, { style: { width: "1.25rem", height: "1.25rem", color: C$1.green, flexShrink: 0 } }),
3823
- text
3824
- ] }, text)) }),
3825
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 1 }),
3826
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => goToStep("account-type"), style: { width: "100%", marginTop: "1rem" }, children: "Suivant →" }),
3827
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem", marginTop: "1rem" }, children: [
3828
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C$1.gray500 }, children: "Déjà un compte ? " }),
3829
- /* @__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..."
3830
3936
  ] })
3831
- ] }),
3832
- step === "account-type" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3833
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("intro"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3834
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3835
- /* @__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 } }) }),
3836
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Choisissez votre type de compte" })
3837
- ] }),
3838
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem", marginTop: "1rem" }, children: [
3839
- /* @__PURE__ */ jsxRuntime.jsxs(
3840
- "button",
3841
- {
3842
- type: "button",
3843
- onClick: () => handleAccountTypeSelect("email"),
3844
- 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" },
3845
- children: [
3846
- /* @__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 } }) }),
3847
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3848
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Email + Téléphone" }),
3849
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "Compte complet" })
3850
- ] })
3851
- ]
3852
- }
3853
- ),
3854
- /* @__PURE__ */ jsxRuntime.jsxs(
3855
- "button",
3856
- {
3857
- type: "button",
3858
- onClick: () => handleAccountTypeSelect("phone-only"),
3859
- 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" },
3860
- children: [
3861
- /* @__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 } }) }),
3862
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3863
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Téléphone uniquement" }),
3864
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "🇸🇳 Sénégal uniquement" })
3865
- ] })
3866
- ]
3867
- }
3868
- )
3869
- ] }),
3870
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 2 })
3871
- ] }),
3872
- step === "info" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3873
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("account-type"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3874
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3875
- /* @__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 } }) }),
3876
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Créer votre compte" })
3877
- ] }),
3878
- 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" }),
3879
- !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" }),
3880
- /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleInfoSubmit, style: { display: "flex", flexDirection: "column", gap: "0.75rem", marginTop: "0.75rem" }, children: [
3881
- renderError(),
3882
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3883
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Nom complet" }),
3884
- /* @__PURE__ */ jsxRuntime.jsx(Input, { placeholder: "Jean Dupont", value: formData.name || "", onChange: (e) => updateFormData({ name: 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" })
3885
3943
  ] }),
3886
- !isPhoneOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3887
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Adresse email" }),
3888
- /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "email", placeholder: "vous@exemple.com", value: formData.email || "", onChange: (e) => updateFormData({ email: e.target.value }), disabled: regLoading })
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 })
3889
3951
  ] }),
3890
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3891
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Numéro de téléphone" }),
3892
- /* @__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 })
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" })
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" })
3893
3965
  ] }),
3894
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }, children: [
3895
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3896
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Ville" }),
3897
- /* @__PURE__ */ jsxRuntime.jsx(Input, { placeholder: "Dakar", value: formData.town || "", onChange: (e) => updateFormData({ town: e.target.value }), disabled: regLoading })
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
+ )
3898
3998
  ] }),
3899
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3900
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Pays" }),
3901
- /* @__PURE__ */ jsxRuntime.jsx(
3902
- "select",
3999
+ /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 2 })
4000
+ ] })
4001
+ ] }),
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,
3903
4017
  {
3904
- value: formData.country || DEFAULT_COUNTRY_CODE,
3905
- onChange: (e) => {
3906
- const country = getCountryByCode(e.target.value);
3907
- updateFormData({ country: e.target.value, ccphone: (country == null ? void 0 : country.dialCode) || "+221" });
4018
+ onClick: () => {
4019
+ const fullPhone = formData.phone || "";
4020
+ if (onSwitchToLoginWithPhone) onSwitchToLoginWithPhone(fullPhone);
4021
+ else onSwitchToLogin();
3908
4022
  },
3909
- disabled: regLoading || isPhoneOnly,
3910
- style: { width: "100%", padding: "0.5rem", borderRadius: "0.375rem", border: "1px solid #d1d5db", backgroundColor: regLoading || isPhoneOnly ? "#f3f4f6" : "white", fontSize: "0.875rem" },
3911
- children: COUNTRIES.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: c.code, children: [
3912
- c.flag,
3913
- " ",
3914
- c.name
3915
- ] }, c.code))
4023
+ style: { width: "100%" },
4024
+ children: [
4025
+ /* @__PURE__ */ jsxRuntime.jsx(IconSmartphone, { style: { width: "1rem", height: "1rem" } }),
4026
+ "Se connecter par téléphone"
4027
+ ]
3916
4028
  }
3917
- )
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
+ ] })
3918
4041
  ] })
3919
- ] }),
3920
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 3 }),
3921
- /* @__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: [
3922
- /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3923
- " Vérification..."
3924
- ] }) : "Continuer" })
3925
- ] })
3926
- ] }),
3927
- step === "otp" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3928
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("info"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3929
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3930
- /* @__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 } }) }),
3931
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Vérification" }),
3932
- /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
3933
- "Entrez le code envoyé ",
3934
- isPhoneOnly ? `au ${formData.ccphone} ${formData.phone}` : `à ${formData.email}`
3935
- ] })
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
+ )
3936
4120
  ] }),
3937
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "1rem" }, children: [
3938
- renderError(),
3939
- /* @__PURE__ */ jsxRuntime.jsx(OTPInput, { value: otpCode, onChange: setOtpCode, disabled: regLoading }),
3940
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: resendCooldown > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: C$1.gray500 }, children: [
3941
- "Renvoyer dans ",
3942
- resendCooldown,
3943
- "s"
3944
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: handleResendOTP, style: linkStyle, children: "Code non reçu ? Renvoyer" }) }),
3945
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 4 }),
3946
- /* @__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: [
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: [
3947
4142
  /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3948
4143
  " Vérification..."
3949
- ] }) : "Vérifier" })
3950
- ] })
3951
- ] }),
3952
- step === "password" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3953
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("otp"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3954
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3955
- /* @__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 } }) }),
3956
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Créer un mot de passe" })
4144
+ ] }) : "Vérifier" }) })
3957
4145
  ] }),
3958
- /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handlePasswordSubmit, style: { display: "flex", flexDirection: "column", gap: "0.75rem", marginTop: "0.75rem" }, children: [
3959
- renderError(),
3960
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3961
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Mot de passe" }),
3962
- /* @__PURE__ */ jsxRuntime.jsx(Input, { type: "password", placeholder: "Minimum 8 caractères", value: password, onChange: (e) => setPassword(e.target.value), disabled: regLoading })
3963
- ] }),
3964
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3965
- /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Confirmer le mot de passe" }),
3966
- /* @__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" })
3967
4151
  ] }),
3968
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 5 }),
3969
- /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: regLoading, style: { width: "100%" }, children: "Continuer" })
3970
- ] })
3971
- ] }),
3972
- step === "confirm" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3973
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => goToStep("password"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
3974
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
3975
- /* @__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 } }) }),
3976
- /* @__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
+ ] })
3977
4167
  ] }),
3978
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
3979
- renderError(),
3980
- /* @__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: [
3981
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: label }),
3982
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.875rem", fontWeight: 500 }, children: value })
3983
- ] }, label)) }),
3984
- /* @__PURE__ */ jsxRuntime.jsx(StepIndicator, { current: 6 }),
3985
- /* @__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: [
3986
4183
  /* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
3987
4184
  " Création du compte..."
3988
- ] }) : "Créer mon compte" })
4185
+ ] }) : "Créer mon compte" }) })
3989
4186
  ] })
3990
- ] })
3991
- ] }) }) });
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
+ ] });
3992
4199
  }
3993
4200
  const C = {
3994
4201
  primary: "#002147",
@@ -4055,7 +4262,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
4055
4262
  ] }),
4056
4263
  /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Ajoutez les informations manquantes pour finaliser votre compte." })
4057
4264
  ] }),
4058
- /* @__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: [
4059
4266
  needsPhoto && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4060
4267
  /* @__PURE__ */ jsxRuntime.jsx(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: "Photo de profil" }),
4061
4268
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "1rem" }, children: [
@@ -4087,15 +4294,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
4087
4294
  fontWeight: 500
4088
4295
  }, children: [
4089
4296
  "Choisir une photo",
4090
- /* @__PURE__ */ jsxRuntime.jsx(
4091
- "input",
4092
- {
4093
- type: "file",
4094
- accept: "image/*",
4095
- onChange: handleFileChange,
4096
- style: { display: "none" }
4097
- }
4098
- )
4297
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "file", accept: "image/*", onChange: handleFileChange, style: { display: "none" } })
4099
4298
  ] }),
4100
4299
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.75rem", color: fileError ? "#dc2626" : C.gray500, marginTop: "0.25rem" }, children: fileError || "JPG, PNG. Max 2 Mo." })
4101
4300
  ] })
@@ -4103,15 +4302,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
4103
4302
  ] }),
4104
4303
  needsPhone && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4105
4304
  /* @__PURE__ */ jsxRuntime.jsx(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: "Numéro de téléphone" }),
4106
- /* @__PURE__ */ jsxRuntime.jsx(
4107
- PhoneInput,
4108
- {
4109
- value: phone,
4110
- onChange: setPhone,
4111
- ccphone,
4112
- onCcphoneChange: setCcphone
4113
- }
4114
- )
4305
+ /* @__PURE__ */ jsxRuntime.jsx(PhoneInput, { value: phone, onChange: setPhone, ccphone, onCcphoneChange: setCcphone })
4115
4306
  ] }),
4116
4307
  needsEmail && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4117
4308
  /* @__PURE__ */ jsxRuntime.jsxs(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: [
@@ -4153,38 +4344,32 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
4153
4344
  type: "checkbox",
4154
4345
  checked: confirmed,
4155
4346
  onChange: (e) => setConfirmed(e.target.checked),
4156
- style: {
4157
- width: "1rem",
4158
- height: "1rem",
4159
- marginTop: "0.125rem",
4160
- accentColor: C.primary,
4161
- cursor: "pointer"
4162
- }
4347
+ style: { width: "1rem", height: "1rem", marginTop: "0.125rem", accentColor: C.primary, cursor: "pointer" }
4163
4348
  }
4164
4349
  ),
4165
4350
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Je confirme que ces informations sont exactes" })
4166
- ] }),
4167
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
4168
- /* @__PURE__ */ jsxRuntime.jsx(
4169
- Button,
4170
- {
4171
- onClick: handleSubmit,
4172
- disabled: !canSubmit || submitting,
4173
- style: { width: "100%", height: "2.75rem", opacity: canSubmit && !submitting ? 1 : 0.5 },
4174
- children: submitting ? "Enregistrement..." : "Valider"
4175
- }
4176
- ),
4177
- /* @__PURE__ */ jsxRuntime.jsx(
4178
- Button,
4179
- {
4180
- variant: "outline",
4181
- onClick: onSkip,
4182
- disabled: submitting,
4183
- style: { width: "100%", height: "2.75rem" },
4184
- children: "Passer pour l'instant"
4185
- }
4186
- )
4187
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
+ )
4188
4373
  ] })
4189
4374
  ] }) });
4190
4375
  }
@@ -4435,6 +4620,7 @@ function NativeSSOPage({
4435
4620
  redirectAfterLogout
4436
4621
  }) {
4437
4622
  const [modal, setModal] = react.useState("none");
4623
+ const [loginInitialPhone, setLoginInitialPhone] = react.useState();
4438
4624
  const [showOnboarding, setShowOnboarding] = react.useState(false);
4439
4625
  const [pendingSession, setPendingSession] = react.useState(null);
4440
4626
  const [session, setSession] = react.useState(() => {
@@ -4476,13 +4662,23 @@ function NativeSSOPage({
4476
4662
  }, []);
4477
4663
  const openLogin = react.useCallback(() => setModal("login"), []);
4478
4664
  const openSignup = react.useCallback(() => setModal("signup"), []);
4479
- const closeModal = react.useCallback(() => setModal("none"), []);
4665
+ const closeModal = react.useCallback(() => {
4666
+ setModal("none");
4667
+ setLoginInitialPhone(void 0);
4668
+ }, []);
4480
4669
  const switchToSignup = react.useCallback(() => {
4481
4670
  setModal("none");
4671
+ setLoginInitialPhone(void 0);
4482
4672
  setTimeout(() => setModal("signup"), 150);
4483
4673
  }, []);
4484
4674
  const switchToLogin = react.useCallback(() => {
4485
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);
4486
4682
  setTimeout(() => setModal("login"), 150);
4487
4683
  }, []);
4488
4684
  const handleLoginSuccess = react.useCallback((token, user) => {
@@ -4633,7 +4829,8 @@ function NativeSSOPage({
4633
4829
  onLoginSuccess: handleLoginSuccess,
4634
4830
  saasApiUrl,
4635
4831
  iamApiUrl,
4636
- defaultAccountType: accountType
4832
+ defaultAccountType: accountType,
4833
+ initialPhone: loginInitialPhone
4637
4834
  }
4638
4835
  ),
4639
4836
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4644,6 +4841,7 @@ function NativeSSOPage({
4644
4841
  if (!open) closeModal();
4645
4842
  },
4646
4843
  onSwitchToLogin: switchToLogin,
4844
+ onSwitchToLoginWithPhone: switchToLoginWithPhone,
4647
4845
  onSignupSuccess: handleLoginSuccess,
4648
4846
  saasApiUrl,
4649
4847
  iamApiUrl,