@ollaid/native-sso 1.0.7 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +427 -66
- package/dist/components/LoginModal.d.ts +3 -1
- package/dist/components/PhoneInput.d.ts +1 -1
- package/dist/components/SignupModal.d.ts +3 -1
- package/dist/components/ui.d.ts +10 -0
- package/dist/hooks/useLogout.d.ts +41 -0
- package/dist/hooks/useMobileRegistration.d.ts +1 -1
- package/dist/hooks/useTokenHealthCheck.d.ts +11 -5
- package/dist/index.cjs +711 -407
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +711 -407
- package/dist/index.js.map +1 -1
- package/dist/services/api.d.ts +26 -0
- package/dist/services/nativeAuth.d.ts +1 -1
- package/dist/types/native.d.ts +5 -3
- package/dist/utils/countries.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -125,8 +125,13 @@ function DialogContent({ children, className = "" }) {
|
|
|
125
125
|
/* @__PURE__ */ jsx(
|
|
126
126
|
"div",
|
|
127
127
|
{
|
|
128
|
-
style: {
|
|
129
|
-
|
|
128
|
+
style: {
|
|
129
|
+
position: "fixed",
|
|
130
|
+
inset: 0,
|
|
131
|
+
backgroundColor: "rgba(0,0,0,0.5)",
|
|
132
|
+
backdropFilter: "blur(4px)",
|
|
133
|
+
animation: "ollaid-overlay-in 0.25s ease-out"
|
|
134
|
+
}
|
|
130
135
|
}
|
|
131
136
|
),
|
|
132
137
|
/* @__PURE__ */ jsxs(
|
|
@@ -139,19 +144,21 @@ function DialogContent({ children, className = "" }) {
|
|
|
139
144
|
width: "100%",
|
|
140
145
|
maxWidth: "28rem",
|
|
141
146
|
margin: "1rem",
|
|
142
|
-
padding: "
|
|
147
|
+
padding: "1rem",
|
|
143
148
|
borderRadius: "0.75rem",
|
|
144
149
|
backgroundColor: "white",
|
|
145
150
|
boxShadow: "0 25px 50px -12px rgba(0,0,0,0.25)",
|
|
146
151
|
maxHeight: "90vh",
|
|
147
|
-
|
|
152
|
+
display: "flex",
|
|
153
|
+
flexDirection: "column",
|
|
154
|
+
animation: "ollaid-modal-in 0.3s ease-out"
|
|
148
155
|
},
|
|
149
156
|
children: [
|
|
150
157
|
/* @__PURE__ */ jsx(
|
|
151
158
|
"button",
|
|
152
159
|
{
|
|
153
160
|
onClick: () => onOpenChange(false),
|
|
154
|
-
style: { position: "absolute", right: "
|
|
161
|
+
style: { position: "absolute", right: "0.75rem", top: "0.75rem", background: "none", border: "none", cursor: "pointer", fontSize: "1.25rem", color: "#9ca3af", lineHeight: 1, zIndex: 2 },
|
|
155
162
|
"aria-label": "Close",
|
|
156
163
|
children: "✕"
|
|
157
164
|
}
|
|
@@ -162,8 +169,14 @@ function DialogContent({ children, className = "" }) {
|
|
|
162
169
|
)
|
|
163
170
|
] });
|
|
164
171
|
}
|
|
172
|
+
function DialogBody({ children, className = "", style }) {
|
|
173
|
+
return /* @__PURE__ */ jsx("div", { className, style: { flex: 1, overflowY: "auto", paddingBottom: "0.5rem", minHeight: 0, ...style }, children });
|
|
174
|
+
}
|
|
175
|
+
function DialogFooter({ children, className = "", style }) {
|
|
176
|
+
return /* @__PURE__ */ jsx("div", { className, style: { flexShrink: 0, paddingTop: "0.75rem", borderTop: "1px solid #e5e7eb", display: "flex", flexDirection: "column", gap: "0.5rem", ...style }, children });
|
|
177
|
+
}
|
|
165
178
|
function DialogHeader({ children, className = "", style }) {
|
|
166
|
-
return /* @__PURE__ */ jsx("div", { className, style: { marginBottom: "0.5rem", ...style }, children });
|
|
179
|
+
return /* @__PURE__ */ jsx("div", { className, style: { marginBottom: "0.5rem", flexShrink: 0, ...style }, children });
|
|
167
180
|
}
|
|
168
181
|
function DialogTitle({ children, className = "" }) {
|
|
169
182
|
return /* @__PURE__ */ jsx("h2", { className, style: { fontSize: "1.25rem", fontWeight: 600, color: "#111827" }, children });
|
|
@@ -263,7 +276,7 @@ if (typeof document !== "undefined") {
|
|
|
263
276
|
if (!document.getElementById(styleId)) {
|
|
264
277
|
const style = document.createElement("style");
|
|
265
278
|
style.id = styleId;
|
|
266
|
-
style.textContent = `@keyframes spin { to { transform: rotate(360deg); } }`;
|
|
279
|
+
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); } }`;
|
|
267
280
|
document.head.appendChild(style);
|
|
268
281
|
}
|
|
269
282
|
}
|
|
@@ -481,7 +494,8 @@ const STORAGE = {
|
|
|
481
494
|
TOKEN: "token",
|
|
482
495
|
USER: "user",
|
|
483
496
|
ACCOUNT_TYPE: "account_type",
|
|
484
|
-
ALIAS_REFERENCE: "alias_reference"
|
|
497
|
+
ALIAS_REFERENCE: "alias_reference",
|
|
498
|
+
APP_ACCESS_TOKEN_REF: "app_access_token_ref"
|
|
485
499
|
};
|
|
486
500
|
const setAuthToken = (token) => {
|
|
487
501
|
if (typeof localStorage !== "undefined") {
|
|
@@ -500,8 +514,14 @@ const clearAuthToken = () => {
|
|
|
500
514
|
localStorage.removeItem(STORAGE.USER);
|
|
501
515
|
localStorage.removeItem(STORAGE.ACCOUNT_TYPE);
|
|
502
516
|
localStorage.removeItem(STORAGE.ALIAS_REFERENCE);
|
|
517
|
+
localStorage.removeItem(STORAGE.APP_ACCESS_TOKEN_REF);
|
|
503
518
|
}
|
|
504
519
|
};
|
|
520
|
+
const logout = async () => {
|
|
521
|
+
const { nativeAuthService: nativeAuthService2 } = await Promise.resolve().then(() => nativeAuth);
|
|
522
|
+
const token = getAuthToken();
|
|
523
|
+
return nativeAuthService2.logout(token || void 0);
|
|
524
|
+
};
|
|
505
525
|
const setAuthUser = (user) => {
|
|
506
526
|
if (typeof localStorage !== "undefined") {
|
|
507
527
|
localStorage.setItem(STORAGE.USER, JSON.stringify(user));
|
|
@@ -795,7 +815,7 @@ const nativeAuthService = {
|
|
|
795
815
|
);
|
|
796
816
|
},
|
|
797
817
|
async exchange(callbackToken) {
|
|
798
|
-
var _a;
|
|
818
|
+
var _a, _b;
|
|
799
819
|
const config2 = getNativeAuthConfig();
|
|
800
820
|
if (!config2.saasApiUrl) {
|
|
801
821
|
throw new ApiError("saasApiUrl non configurée", "unknown");
|
|
@@ -817,9 +837,16 @@ const nativeAuthService = {
|
|
|
817
837
|
if (response.user) {
|
|
818
838
|
setAuthUser(response.user);
|
|
819
839
|
}
|
|
840
|
+
if (response.app_access_token_ref && typeof localStorage !== "undefined") {
|
|
841
|
+
localStorage.setItem(STORAGE.APP_ACCESS_TOKEN_REF, response.app_access_token_ref);
|
|
842
|
+
}
|
|
843
|
+
const aliasRef = ((_a = response.user) == null ? void 0 : _a.alias_reference) || response.alias_reference;
|
|
844
|
+
if (aliasRef && typeof localStorage !== "undefined") {
|
|
845
|
+
localStorage.setItem(STORAGE.ALIAS_REFERENCE, aliasRef);
|
|
846
|
+
}
|
|
820
847
|
}
|
|
821
848
|
if (isDebugMode()) {
|
|
822
|
-
console.log("✅ [SaaS] Session établie:", { user: (
|
|
849
|
+
console.log("✅ [SaaS] Session établie:", { user: (_b = response.user) == null ? void 0 : _b.name });
|
|
823
850
|
}
|
|
824
851
|
return response;
|
|
825
852
|
},
|
|
@@ -840,7 +867,13 @@ const nativeAuthService = {
|
|
|
840
867
|
},
|
|
841
868
|
1e4
|
|
842
869
|
);
|
|
843
|
-
|
|
870
|
+
if (response.status === "connected" && response.user) {
|
|
871
|
+
return { valid: true, user: response.user };
|
|
872
|
+
}
|
|
873
|
+
if (response.success !== false) {
|
|
874
|
+
return { valid: true, user: response.user };
|
|
875
|
+
}
|
|
876
|
+
return { valid: false };
|
|
844
877
|
} catch (err) {
|
|
845
878
|
if (err instanceof ApiError && err.statusCode === 401) {
|
|
846
879
|
return { valid: false };
|
|
@@ -850,28 +883,53 @@ const nativeAuthService = {
|
|
|
850
883
|
},
|
|
851
884
|
async logout(token) {
|
|
852
885
|
const config2 = getNativeAuthConfig();
|
|
853
|
-
|
|
854
|
-
|
|
886
|
+
const iamToken = typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE.AUTH_TOKEN) || localStorage.getItem(STORAGE.TOKEN) : null;
|
|
887
|
+
const appAccessTokenRef = typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE.APP_ACCESS_TOKEN_REF) : null;
|
|
888
|
+
const promises = [];
|
|
889
|
+
if (config2.saasApiUrl && token) {
|
|
890
|
+
promises.push(
|
|
891
|
+
fetchWithTimeout(
|
|
892
|
+
`${config2.saasApiUrl}/native/logout`,
|
|
893
|
+
{
|
|
894
|
+
method: "POST",
|
|
895
|
+
headers: getHeaders(token, true)
|
|
896
|
+
},
|
|
897
|
+
config2.timeout || 3e4
|
|
898
|
+
).catch((err) => {
|
|
899
|
+
if (isDebugMode()) {
|
|
900
|
+
console.warn("⚠️ [SaaS] Échec logout (non-bloquant):", err instanceof Error ? err.message : err);
|
|
901
|
+
}
|
|
902
|
+
})
|
|
903
|
+
);
|
|
855
904
|
}
|
|
856
|
-
|
|
857
|
-
const
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
905
|
+
if (config2.iamApiUrl && (iamToken || appAccessTokenRef)) {
|
|
906
|
+
const payload = {};
|
|
907
|
+
if (iamToken) payload.sanctum_token = iamToken;
|
|
908
|
+
if (appAccessTokenRef) payload.app_access_token_ref = appAccessTokenRef;
|
|
909
|
+
promises.push(
|
|
910
|
+
fetchWithTimeout(
|
|
911
|
+
`${config2.iamApiUrl}/iam/disconnect`,
|
|
912
|
+
{
|
|
913
|
+
method: "POST",
|
|
914
|
+
headers: { "Content-Type": "application/json", "Accept": "application/json" },
|
|
915
|
+
body: JSON.stringify(payload)
|
|
916
|
+
},
|
|
917
|
+
5e3
|
|
918
|
+
).catch((err) => {
|
|
919
|
+
if (isDebugMode()) {
|
|
920
|
+
console.warn("⚠️ [IAM] Échec disconnect (non-bloquant):", err instanceof Error ? err.message : err);
|
|
921
|
+
}
|
|
922
|
+
})
|
|
864
923
|
);
|
|
865
|
-
clearAuthToken();
|
|
866
|
-
credentials = null;
|
|
867
|
-
credentialsLoadedAt = 0;
|
|
868
|
-
return response;
|
|
869
|
-
} catch {
|
|
870
|
-
clearAuthToken();
|
|
871
|
-
credentials = null;
|
|
872
|
-
credentialsLoadedAt = 0;
|
|
873
|
-
return { success: true };
|
|
874
924
|
}
|
|
925
|
+
await Promise.allSettled(promises);
|
|
926
|
+
if (isDebugMode()) {
|
|
927
|
+
console.log("✅ [Logout] Double revocation terminée — nettoyage local");
|
|
928
|
+
}
|
|
929
|
+
clearAuthToken();
|
|
930
|
+
credentials = null;
|
|
931
|
+
credentialsLoadedAt = 0;
|
|
932
|
+
return { success: true };
|
|
875
933
|
},
|
|
876
934
|
clearCredentials() {
|
|
877
935
|
credentials = null;
|
|
@@ -932,6 +990,10 @@ const nativeAuthService = {
|
|
|
932
990
|
return this.init(native_token);
|
|
933
991
|
}
|
|
934
992
|
};
|
|
993
|
+
const nativeAuth = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
994
|
+
__proto__: null,
|
|
995
|
+
nativeAuthService
|
|
996
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
935
997
|
function getIAMHeaders() {
|
|
936
998
|
const creds = nativeAuthService.getCredentials();
|
|
937
999
|
if (!creds) {
|
|
@@ -939,7 +1001,8 @@ function getIAMHeaders() {
|
|
|
939
1001
|
}
|
|
940
1002
|
return {
|
|
941
1003
|
"Content-Type": "application/json",
|
|
942
|
-
"Accept": "application/json"
|
|
1004
|
+
"Accept": "application/json",
|
|
1005
|
+
"X-IAM-App-Key": creds.appKey
|
|
943
1006
|
};
|
|
944
1007
|
}
|
|
945
1008
|
const mobilePasswordService = {
|
|
@@ -1427,7 +1490,7 @@ function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamA
|
|
|
1427
1490
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Mot de passe modifié !" }),
|
|
1428
1491
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Votre mot de passe a été changé avec succès." })
|
|
1429
1492
|
] }),
|
|
1430
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleBackToLogin, style: { width: "100%"
|
|
1493
|
+
/* @__PURE__ */ jsx(DialogFooter, { style: { borderTop: "none" }, children: /* @__PURE__ */ jsx(Button, { onClick: handleBackToLogin, style: { width: "100%" }, children: "Retour à la connexion" }) })
|
|
1431
1494
|
] }) });
|
|
1432
1495
|
}
|
|
1433
1496
|
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(DialogContent, { children: [
|
|
@@ -1447,49 +1510,35 @@ function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamA
|
|
|
1447
1510
|
step === "password" && "Définissez votre nouveau mot de passe"
|
|
1448
1511
|
] })
|
|
1449
1512
|
] }),
|
|
1450
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
1513
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
1451
1514
|
error && /* @__PURE__ */ jsx("div", { style: { padding: "0.75rem", borderRadius: "0.375rem", backgroundColor: C$3.redBg, color: C$3.red, fontSize: "0.875rem" }, children: error }),
|
|
1452
|
-
step === "email" && /* @__PURE__ */ jsxs(
|
|
1453
|
-
/* @__PURE__ */
|
|
1454
|
-
|
|
1455
|
-
/* @__PURE__ */ jsx(Input, { id: "recovery-email", type: "email", placeholder: "vous@exemple.com", value: email, onChange: (e) => setEmail(e.target.value), disabled: pwLoading })
|
|
1456
|
-
] }),
|
|
1457
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleEmailSubmit, disabled: pwLoading, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
1458
|
-
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
1459
|
-
" Vérification..."
|
|
1460
|
-
] }) : "Continuer" }),
|
|
1461
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleBackToLogin, style: { width: "100%" }, children: "Retour à la connexion" })
|
|
1515
|
+
step === "email" && /* @__PURE__ */ jsxs("div", { children: [
|
|
1516
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "recovery-email", children: "Adresse email" }),
|
|
1517
|
+
/* @__PURE__ */ jsx(Input, { id: "recovery-email", type: "email", placeholder: "vous@exemple.com", value: email, onChange: (e) => setEmail(e.target.value), disabled: pwLoading })
|
|
1462
1518
|
] }),
|
|
1463
|
-
step === "method-choice" && /* @__PURE__ */ jsxs(
|
|
1464
|
-
/* @__PURE__ */
|
|
1465
|
-
/* @__PURE__ */
|
|
1466
|
-
|
|
1467
|
-
/* @__PURE__ */
|
|
1468
|
-
|
|
1469
|
-
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.75rem", color: C$3.gray500 }, children: maskedEmail })
|
|
1470
|
-
] })
|
|
1471
|
-
] }),
|
|
1472
|
-
/* @__PURE__ */ 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: [
|
|
1473
|
-
/* @__PURE__ */ jsx(RadioGroupItem, { value: "phone", id: "method-phone" }),
|
|
1474
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1475
|
-
/* @__PURE__ */ jsx("div", { style: { fontWeight: 500 }, children: "Par SMS" }),
|
|
1476
|
-
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.75rem", color: C$3.gray500 }, children: maskedPhone })
|
|
1477
|
-
] })
|
|
1519
|
+
step === "method-choice" && /* @__PURE__ */ jsx(RadioGroup, { value: selectedMethod, onValueChange: (v) => setSelectedMethod(v), children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
1520
|
+
/* @__PURE__ */ 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: [
|
|
1521
|
+
/* @__PURE__ */ jsx(RadioGroupItem, { value: "email", id: "method-email" }),
|
|
1522
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1523
|
+
/* @__PURE__ */ jsx("div", { style: { fontWeight: 500 }, children: "Par email" }),
|
|
1524
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.75rem", color: C$3.gray500 }, children: maskedEmail })
|
|
1478
1525
|
] })
|
|
1479
|
-
] })
|
|
1480
|
-
/* @__PURE__ */
|
|
1481
|
-
/* @__PURE__ */ jsx(
|
|
1482
|
-
"
|
|
1483
|
-
|
|
1484
|
-
|
|
1526
|
+
] }),
|
|
1527
|
+
/* @__PURE__ */ 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: [
|
|
1528
|
+
/* @__PURE__ */ jsx(RadioGroupItem, { value: "phone", id: "method-phone" }),
|
|
1529
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1530
|
+
/* @__PURE__ */ jsx("div", { style: { fontWeight: 500 }, children: "Par SMS" }),
|
|
1531
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.75rem", color: C$3.gray500 }, children: maskedPhone })
|
|
1532
|
+
] })
|
|
1533
|
+
] })
|
|
1534
|
+
] }) }),
|
|
1485
1535
|
step === "otp" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1486
1536
|
/* @__PURE__ */ jsx(OTPInput, { value: otp, onChange: setOtp, disabled: pwLoading }),
|
|
1487
1537
|
/* @__PURE__ */ jsx("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: resendCooldown > 0 ? /* @__PURE__ */ jsxs("span", { style: { color: C$3.gray500 }, children: [
|
|
1488
1538
|
"Renvoyer dans ",
|
|
1489
1539
|
resendCooldown,
|
|
1490
1540
|
"s"
|
|
1491
|
-
] }) : /* @__PURE__ */ 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" }) })
|
|
1492
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleOTPSubmit, disabled: otp.length !== 6, style: { width: "100%" }, children: "Vérifier" })
|
|
1541
|
+
] }) : /* @__PURE__ */ 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" }) })
|
|
1493
1542
|
] }),
|
|
1494
1543
|
step === "password" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1495
1544
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -1499,17 +1548,31 @@ function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamA
|
|
|
1499
1548
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1500
1549
|
/* @__PURE__ */ jsx(Label, { children: "Confirmer le mot de passe" }),
|
|
1501
1550
|
/* @__PURE__ */ jsx(Input, { type: "password", placeholder: "Retapez votre mot de passe", value: confirmPassword, onChange: (e) => setConfirmPassword(e.target.value), disabled: pwLoading })
|
|
1502
|
-
] })
|
|
1503
|
-
/* @__PURE__ */ jsx(Button, { onClick: handlePasswordSubmit, disabled: pwLoading || !password || !confirmPassword, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
1504
|
-
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
1505
|
-
" Modification..."
|
|
1506
|
-
] }) : "Modifier le mot de passe" })
|
|
1551
|
+
] })
|
|
1507
1552
|
] })
|
|
1553
|
+
] }) }),
|
|
1554
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
1555
|
+
step === "email" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1556
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleEmailSubmit, disabled: pwLoading, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
1557
|
+
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
1558
|
+
" Vérification..."
|
|
1559
|
+
] }) : "Continuer" }),
|
|
1560
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleBackToLogin, style: { width: "100%" }, children: "Retour à la connexion" })
|
|
1561
|
+
] }),
|
|
1562
|
+
step === "method-choice" && /* @__PURE__ */ jsx(Button, { onClick: handleMethodSubmit, disabled: pwLoading, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
1563
|
+
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
1564
|
+
" Envoi..."
|
|
1565
|
+
] }) : "Envoyer le code" }),
|
|
1566
|
+
step === "otp" && /* @__PURE__ */ jsx(Button, { onClick: handleOTPSubmit, disabled: otp.length !== 6, style: { width: "100%" }, children: "Vérifier" }),
|
|
1567
|
+
step === "password" && /* @__PURE__ */ jsx(Button, { onClick: handlePasswordSubmit, disabled: pwLoading || !password || !confirmPassword, style: { width: "100%" }, children: pwLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
1568
|
+
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
1569
|
+
" Modification..."
|
|
1570
|
+
] }) : "Modifier le mot de passe" })
|
|
1508
1571
|
] })
|
|
1509
1572
|
] }) });
|
|
1510
1573
|
}
|
|
1511
|
-
const FIRST_CHECK_DELAY =
|
|
1512
|
-
const INTERVAL_DELAY =
|
|
1574
|
+
const FIRST_CHECK_DELAY = 60 * 1e3;
|
|
1575
|
+
const INTERVAL_DELAY = 2 * 60 * 1e3;
|
|
1513
1576
|
async function checkTokenValidity(saasApiUrl, token, debug) {
|
|
1514
1577
|
if (typeof navigator !== "undefined" && !navigator.onLine) {
|
|
1515
1578
|
if (debug) console.log("🔄 [HealthCheck] Offline — skip");
|
|
@@ -1529,7 +1592,7 @@ async function checkTokenValidity(saasApiUrl, token, debug) {
|
|
|
1529
1592
|
});
|
|
1530
1593
|
clearTimeout(timeoutId);
|
|
1531
1594
|
if (response.status === 401) {
|
|
1532
|
-
if (debug) console.log("🔄 [HealthCheck] Token invalide (401)");
|
|
1595
|
+
if (debug) console.log("🔄 [HealthCheck] Token invalide (401) — déconnexion");
|
|
1533
1596
|
return { valid: false };
|
|
1534
1597
|
}
|
|
1535
1598
|
if (!response.ok) {
|
|
@@ -1537,11 +1600,15 @@ async function checkTokenValidity(saasApiUrl, token, debug) {
|
|
|
1537
1600
|
throw new Error(`server_error_${response.status}`);
|
|
1538
1601
|
}
|
|
1539
1602
|
const data = await response.json();
|
|
1540
|
-
if (
|
|
1541
|
-
|
|
1542
|
-
valid: data.
|
|
1543
|
-
|
|
1544
|
-
|
|
1603
|
+
if (data.status === "connected" && data.user) {
|
|
1604
|
+
if (debug) console.log("🔄 [HealthCheck] Token valide ✅ — user_infos mis à jour");
|
|
1605
|
+
return { valid: true, user: data.user };
|
|
1606
|
+
}
|
|
1607
|
+
if (data.success !== false) {
|
|
1608
|
+
if (debug) console.log("🔄 [HealthCheck] Token valide ✅");
|
|
1609
|
+
return { valid: true, user: data.user };
|
|
1610
|
+
}
|
|
1611
|
+
return { valid: false };
|
|
1545
1612
|
} catch (error) {
|
|
1546
1613
|
clearTimeout(timeoutId);
|
|
1547
1614
|
if (error instanceof Error && error.message === "offline") {
|
|
@@ -1554,8 +1621,34 @@ async function checkTokenValidity(saasApiUrl, token, debug) {
|
|
|
1554
1621
|
throw error;
|
|
1555
1622
|
}
|
|
1556
1623
|
}
|
|
1624
|
+
function revokeOnIam(iamApiUrl, sanctumToken, debug) {
|
|
1625
|
+
try {
|
|
1626
|
+
const controller = new AbortController();
|
|
1627
|
+
setTimeout(() => controller.abort(), 5e3);
|
|
1628
|
+
const appAccessTokenRef = typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE.APP_ACCESS_TOKEN_REF) : null;
|
|
1629
|
+
const payload = { sanctum_token: sanctumToken };
|
|
1630
|
+
if (appAccessTokenRef) {
|
|
1631
|
+
payload.app_access_token_ref = appAccessTokenRef;
|
|
1632
|
+
}
|
|
1633
|
+
if (debug) {
|
|
1634
|
+
console.log("🔄 [HealthCheck] Revocation IAM:", { hasRef: !!appAccessTokenRef });
|
|
1635
|
+
}
|
|
1636
|
+
fetch(`${iamApiUrl}/iam/disconnect`, {
|
|
1637
|
+
method: "POST",
|
|
1638
|
+
headers: {
|
|
1639
|
+
"Content-Type": "application/json",
|
|
1640
|
+
"Accept": "application/json"
|
|
1641
|
+
},
|
|
1642
|
+
body: JSON.stringify(payload),
|
|
1643
|
+
signal: controller.signal
|
|
1644
|
+
}).catch(() => {
|
|
1645
|
+
if (debug) console.log("🔄 [HealthCheck] Échec revocation IAM (non-bloquant)");
|
|
1646
|
+
});
|
|
1647
|
+
} catch {
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1557
1650
|
function useTokenHealthCheck(options) {
|
|
1558
|
-
const { enabled, saasApiUrl, onTokenInvalid, onUserUpdated, debug = false } = options;
|
|
1651
|
+
const { enabled, saasApiUrl, iamApiUrl, onTokenInvalid, onUserUpdated, debug = false } = options;
|
|
1559
1652
|
const timerRef = useRef(null);
|
|
1560
1653
|
const intervalRef = useRef(null);
|
|
1561
1654
|
const enabledRef = useRef(enabled);
|
|
@@ -1572,15 +1665,19 @@ function useTokenHealthCheck(options) {
|
|
|
1572
1665
|
try {
|
|
1573
1666
|
const result = await checkTokenValidity(saasApiUrl, token, debug);
|
|
1574
1667
|
if (!result.valid) {
|
|
1668
|
+
if (iamApiUrl) {
|
|
1669
|
+
if (debug) console.log("🔄 [HealthCheck] Revocation IAM avec sanctum_token...");
|
|
1670
|
+
revokeOnIam(iamApiUrl, token, debug);
|
|
1671
|
+
}
|
|
1575
1672
|
callbacksRef.current.onTokenInvalid();
|
|
1576
1673
|
return;
|
|
1577
1674
|
}
|
|
1578
|
-
if (result.
|
|
1579
|
-
callbacksRef.current.onUserUpdated(result.
|
|
1675
|
+
if (result.user && callbacksRef.current.onUserUpdated) {
|
|
1676
|
+
callbacksRef.current.onUserUpdated(result.user);
|
|
1580
1677
|
}
|
|
1581
1678
|
} catch {
|
|
1582
1679
|
}
|
|
1583
|
-
}, [saasApiUrl, debug]);
|
|
1680
|
+
}, [saasApiUrl, iamApiUrl, debug]);
|
|
1584
1681
|
useEffect(() => {
|
|
1585
1682
|
if (timerRef.current) {
|
|
1586
1683
|
clearTimeout(timerRef.current);
|
|
@@ -1591,7 +1688,7 @@ function useTokenHealthCheck(options) {
|
|
|
1591
1688
|
intervalRef.current = null;
|
|
1592
1689
|
}
|
|
1593
1690
|
if (!enabled || !saasApiUrl) return;
|
|
1594
|
-
if (debug) console.log("🔄 [HealthCheck] Activé — premier check dans 2 min");
|
|
1691
|
+
if (debug) console.log("🔄 [HealthCheck] Activé — premier check dans 60s, puis toutes les 2 min");
|
|
1595
1692
|
timerRef.current = setTimeout(() => {
|
|
1596
1693
|
performCheck();
|
|
1597
1694
|
intervalRef.current = setInterval(performCheck, INTERVAL_DELAY);
|
|
@@ -1618,6 +1715,9 @@ function saveSession(exchangeResult, accountType) {
|
|
|
1618
1715
|
if (aliasRef) {
|
|
1619
1716
|
localStorage.setItem(STORAGE.ALIAS_REFERENCE, aliasRef);
|
|
1620
1717
|
}
|
|
1718
|
+
if (exchangeResult.app_access_token_ref) {
|
|
1719
|
+
localStorage.setItem(STORAGE.APP_ACCESS_TOKEN_REF, exchangeResult.app_access_token_ref);
|
|
1720
|
+
}
|
|
1621
1721
|
const acctType = typeof accountType === "string" ? accountType : "user";
|
|
1622
1722
|
localStorage.setItem(STORAGE.USER, JSON.stringify(userToStore));
|
|
1623
1723
|
localStorage.setItem(STORAGE.ACCOUNT_TYPE, acctType);
|
|
@@ -1629,6 +1729,7 @@ function clearSession() {
|
|
|
1629
1729
|
localStorage.removeItem(STORAGE.USER);
|
|
1630
1730
|
localStorage.removeItem(STORAGE.ACCOUNT_TYPE);
|
|
1631
1731
|
localStorage.removeItem(STORAGE.ALIAS_REFERENCE);
|
|
1732
|
+
localStorage.removeItem(STORAGE.APP_ACCESS_TOKEN_REF);
|
|
1632
1733
|
}
|
|
1633
1734
|
function getErrorMessage$1(err, context) {
|
|
1634
1735
|
if (err instanceof Error) {
|
|
@@ -1702,6 +1803,7 @@ function useNativeAuth(options) {
|
|
|
1702
1803
|
useTokenHealthCheck({
|
|
1703
1804
|
enabled: state.status === "completed" && state.user !== null,
|
|
1704
1805
|
saasApiUrl,
|
|
1806
|
+
iamApiUrl,
|
|
1705
1807
|
onTokenInvalid: handleTokenInvalid,
|
|
1706
1808
|
onUserUpdated: handleUserUpdated,
|
|
1707
1809
|
debug: isDebug
|
|
@@ -1871,7 +1973,7 @@ function useNativeAuth(options) {
|
|
|
1871
1973
|
await nativeAuthService.loadCredentials();
|
|
1872
1974
|
}
|
|
1873
1975
|
const response = await nativeAuthService.loginAccessOtp(otpCode);
|
|
1874
|
-
if (response.
|
|
1976
|
+
if ((response.needs_access || response.status === "needs_access") && response.process_token) {
|
|
1875
1977
|
setState((prev) => ({
|
|
1876
1978
|
...prev,
|
|
1877
1979
|
processToken: response.process_token,
|
|
@@ -2178,7 +2280,7 @@ function useNativeAuth(options) {
|
|
|
2178
2280
|
processToken: null
|
|
2179
2281
|
}));
|
|
2180
2282
|
}, [defaultAccountType]);
|
|
2181
|
-
const
|
|
2283
|
+
const logout2 = useCallback(async () => {
|
|
2182
2284
|
const token = localStorage.getItem(STORAGE.AUTH_TOKEN) || localStorage.getItem(STORAGE.TOKEN);
|
|
2183
2285
|
try {
|
|
2184
2286
|
if (token) {
|
|
@@ -2250,7 +2352,7 @@ function useNativeAuth(options) {
|
|
|
2250
2352
|
grantAccess,
|
|
2251
2353
|
resendOtp,
|
|
2252
2354
|
setSession,
|
|
2253
|
-
logout,
|
|
2355
|
+
logout: logout2,
|
|
2254
2356
|
reset,
|
|
2255
2357
|
clearError,
|
|
2256
2358
|
register,
|
|
@@ -2339,7 +2441,8 @@ function LoginModal({
|
|
|
2339
2441
|
iamApiUrl,
|
|
2340
2442
|
loading,
|
|
2341
2443
|
showSwitchToSignup = true,
|
|
2342
|
-
defaultAccountType
|
|
2444
|
+
defaultAccountType,
|
|
2445
|
+
initialPhone
|
|
2343
2446
|
}) {
|
|
2344
2447
|
const {
|
|
2345
2448
|
status,
|
|
@@ -2418,6 +2521,12 @@ function LoginModal({
|
|
|
2418
2521
|
useEffect(() => {
|
|
2419
2522
|
if (!open) resetState();
|
|
2420
2523
|
}, [open]);
|
|
2524
|
+
useEffect(() => {
|
|
2525
|
+
if (open && initialPhone) {
|
|
2526
|
+
setStep("phone-input");
|
|
2527
|
+
setPhone(initialPhone);
|
|
2528
|
+
}
|
|
2529
|
+
}, [open, initialPhone]);
|
|
2421
2530
|
const exchangeCallbackToken = async (callbackToken) => {
|
|
2422
2531
|
try {
|
|
2423
2532
|
const response = await nativeAuthService.exchange(callbackToken);
|
|
@@ -2574,23 +2683,25 @@ function LoginModal({
|
|
|
2574
2683
|
"."
|
|
2575
2684
|
] })
|
|
2576
2685
|
] }),
|
|
2577
|
-
/* @__PURE__ */ jsxs(
|
|
2578
|
-
/* @__PURE__ */ jsxs("div", { style: { padding: "1rem", backgroundColor: C$2.gray100, borderRadius: "0.5rem",
|
|
2686
|
+
/* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
2687
|
+
/* @__PURE__ */ jsxs("div", { style: { padding: "1rem", backgroundColor: C$2.gray100, borderRadius: "0.5rem", fontSize: "0.875rem", color: C$2.gray500 }, children: [
|
|
2579
2688
|
"Votre compte ",
|
|
2580
2689
|
/* @__PURE__ */ jsx("strong", { style: { color: C$2.primary }, children: "iam.ollaid.com" }),
|
|
2581
2690
|
" existe déjà. Cliquez sur Confirmer pour créer votre accès à ",
|
|
2582
2691
|
/* @__PURE__ */ jsx("strong", { style: { color: C$2.gray900 }, children: application.name }),
|
|
2583
2692
|
"."
|
|
2584
2693
|
] }),
|
|
2585
|
-
renderError()
|
|
2586
|
-
|
|
2694
|
+
renderError()
|
|
2695
|
+
] }),
|
|
2696
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
2697
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleGrantAccess, disabled: isSubmitting, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
2587
2698
|
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
2588
2699
|
"Création en cours..."
|
|
2589
2700
|
] }) : "Confirmer la création de mon compte" }),
|
|
2590
2701
|
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => {
|
|
2591
2702
|
resetAuth();
|
|
2592
2703
|
setStep("choice");
|
|
2593
|
-
}, disabled: isSubmitting, style: { width: "100%"
|
|
2704
|
+
}, disabled: isSubmitting, style: { width: "100%" }, children: "Annuler" })
|
|
2594
2705
|
] })
|
|
2595
2706
|
] }) : alternativeMethod ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2596
2707
|
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
@@ -2598,21 +2709,21 @@ function LoginModal({
|
|
|
2598
2709
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Moyen de connexion désactivé" }),
|
|
2599
2710
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Vos identifiants sont corrects, mais vous avez désactivé ce moyen de connexion depuis votre compte IAM." })
|
|
2600
2711
|
] }),
|
|
2601
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
/* @__PURE__ */
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2712
|
+
/* @__PURE__ */ jsx(DialogBody, { children: alternativeMethod.value && /* @__PURE__ */ jsxs("div", { style: { padding: "1rem", backgroundColor: C$2.gray100, borderRadius: "0.5rem" }, children: [
|
|
2713
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem", color: C$2.gray500, marginBottom: "0.75rem" }, children: "Vous pouvez vous connecter avec :" }),
|
|
2714
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", fontSize: "0.875rem", fontWeight: 500, color: C$2.gray900 }, children: [
|
|
2715
|
+
alternativeMethod.type === "phone" ? /* @__PURE__ */ jsx(IconPhone, { style: { width: "1rem", height: "1rem", color: C$2.primary } }) : /* @__PURE__ */ jsx(IconMail, { style: { width: "1rem", height: "1rem", color: C$2.primary } }),
|
|
2716
|
+
/* @__PURE__ */ jsx("span", { children: alternativeMethod.value })
|
|
2717
|
+
] })
|
|
2718
|
+
] }) }),
|
|
2719
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
2609
2720
|
/* @__PURE__ */ jsx(Button, { onClick: () => {
|
|
2610
2721
|
if (alternativeMethod.type === "phone") setStep("phone-input");
|
|
2611
2722
|
else setStep("email-check");
|
|
2612
2723
|
resetAuth();
|
|
2613
2724
|
}, style: { width: "100%" }, children: alternativeMethod.type === "phone" ? "Se connecter par téléphone" : "Se connecter par email" }),
|
|
2614
|
-
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => window.open("https://iam.ollaid.com", "_blank"), style: { width: "100%"
|
|
2615
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => onOpenChange(false), style: { width: "100%"
|
|
2725
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => window.open("https://iam.ollaid.com", "_blank"), style: { width: "100%" }, children: "Réactiver depuis iam.ollaid.com" }),
|
|
2726
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => onOpenChange(false), style: { width: "100%" }, children: "Annuler" })
|
|
2616
2727
|
] })
|
|
2617
2728
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2618
2729
|
step !== "choice" && renderBackBtn(),
|
|
@@ -2622,7 +2733,7 @@ function LoginModal({
|
|
|
2622
2733
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Connexion" }),
|
|
2623
2734
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Choisissez votre méthode de connexion" })
|
|
2624
2735
|
] }),
|
|
2625
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
2736
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
2626
2737
|
renderError(),
|
|
2627
2738
|
/* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: () => setStep("email-check"), style: methodBtnStyle, children: [
|
|
2628
2739
|
/* @__PURE__ */ jsx("div", { style: methodIconStyle(C$2.accent), children: /* @__PURE__ */ jsx(IconMail, { style: { width: "1.25rem", height: "1.25rem", color: C$2.white } }) }),
|
|
@@ -2657,7 +2768,7 @@ function LoginModal({
|
|
|
2657
2768
|
/* @__PURE__ */ jsx("span", { style: { color: C$2.gray500 }, children: "Pas encore de compte ? " }),
|
|
2658
2769
|
/* @__PURE__ */ jsx("button", { type: "button", style: linkStyle$1, onClick: onSwitchToSignup, children: "Inscrivez-vous" })
|
|
2659
2770
|
] })
|
|
2660
|
-
] })
|
|
2771
|
+
] }) })
|
|
2661
2772
|
] }),
|
|
2662
2773
|
step === "email-check" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2663
2774
|
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
@@ -2665,7 +2776,7 @@ function LoginModal({
|
|
|
2665
2776
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Connexion par email" }),
|
|
2666
2777
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Entrez votre adresse email" })
|
|
2667
2778
|
] }),
|
|
2668
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
2779
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
2669
2780
|
renderError(),
|
|
2670
2781
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
2671
2782
|
/* @__PURE__ */ jsx(Label, { htmlFor: "email", children: "Adresse email" }),
|
|
@@ -2687,7 +2798,9 @@ function LoginModal({
|
|
|
2687
2798
|
}
|
|
2688
2799
|
)
|
|
2689
2800
|
] }),
|
|
2690
|
-
/* @__PURE__ */ jsx("div", { style: { textAlign: "right" }, children: /* @__PURE__ */ jsx("button", { type: "button", style: { ...linkStyle$1, fontSize: "0.75rem" }, onClick: () => setShowPasswordRecovery(true), children: "Mot de passe oublié ?" }) })
|
|
2801
|
+
/* @__PURE__ */ jsx("div", { style: { textAlign: "right" }, children: /* @__PURE__ */ jsx("button", { type: "button", style: { ...linkStyle$1, fontSize: "0.75rem" }, onClick: () => setShowPasswordRecovery(true), children: "Mot de passe oublié ?" }) })
|
|
2802
|
+
] }) }),
|
|
2803
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
2691
2804
|
renderLoaderBtn("Continuer", "Vérification...", handleEmailCheck, !email.trim()),
|
|
2692
2805
|
showSwitchToSignup && /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: [
|
|
2693
2806
|
/* @__PURE__ */ jsx("span", { style: { color: C$2.gray500 }, children: "Pas encore de compte ? " }),
|
|
@@ -2705,41 +2818,43 @@ function LoginModal({
|
|
|
2705
2818
|
] }),
|
|
2706
2819
|
/* @__PURE__ */ jsx(DialogDescription, { children: email })
|
|
2707
2820
|
] }),
|
|
2708
|
-
/* @__PURE__ */ jsxs("form", { onSubmit: handleEmailPasswordSubmit, style: {
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex",
|
|
2712
|
-
/* @__PURE__ */
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
/* @__PURE__ */
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2821
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleEmailPasswordSubmit, style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
|
|
2822
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
2823
|
+
renderError(),
|
|
2824
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
2825
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
|
|
2826
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "password", children: "Mot de passe" }),
|
|
2827
|
+
/* @__PURE__ */ jsx("button", { type: "button", style: { ...linkStyle$1, fontSize: "0.75rem" }, onClick: () => setShowPasswordRecovery(true), children: "Mot de passe oublié ?" })
|
|
2828
|
+
] }),
|
|
2829
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
2830
|
+
/* @__PURE__ */ jsx(
|
|
2831
|
+
Input,
|
|
2832
|
+
{
|
|
2833
|
+
id: "password",
|
|
2834
|
+
type: showPassword ? "text" : "password",
|
|
2835
|
+
placeholder: "••••••••",
|
|
2836
|
+
value: password,
|
|
2837
|
+
onChange: (e) => setPassword(e.target.value),
|
|
2838
|
+
disabled: isSubmitting,
|
|
2839
|
+
style: { paddingRight: "2.5rem" }
|
|
2840
|
+
}
|
|
2841
|
+
),
|
|
2842
|
+
/* @__PURE__ */ jsx(
|
|
2843
|
+
"button",
|
|
2844
|
+
{
|
|
2845
|
+
type: "button",
|
|
2846
|
+
onClick: () => setShowPassword(!showPassword),
|
|
2847
|
+
style: { position: "absolute", right: 0, top: 0, height: "100%", padding: "0 0.75rem", background: "none", border: "none", cursor: "pointer" },
|
|
2848
|
+
children: showPassword ? /* @__PURE__ */ jsx(IconEyeOff, { style: { width: "1rem", height: "1rem", color: C$2.gray500 } }) : /* @__PURE__ */ jsx(IconEye, { style: { width: "1rem", height: "1rem", color: C$2.gray500 } })
|
|
2849
|
+
}
|
|
2850
|
+
)
|
|
2851
|
+
] })
|
|
2737
2852
|
] })
|
|
2738
|
-
] }),
|
|
2739
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting || !password, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
2853
|
+
] }) }),
|
|
2854
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting || !password, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
2740
2855
|
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
2741
2856
|
"Connexion..."
|
|
2742
|
-
] }) : "Se connecter" })
|
|
2857
|
+
] }) : "Se connecter" }) })
|
|
2743
2858
|
] })
|
|
2744
2859
|
] }),
|
|
2745
2860
|
step === "email-otp" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -2752,12 +2867,12 @@ function LoginModal({
|
|
|
2752
2867
|
/* @__PURE__ */ jsx("strong", { style: { color: C$2.gray900 }, children: email })
|
|
2753
2868
|
] })
|
|
2754
2869
|
] }),
|
|
2755
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
2870
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
2756
2871
|
renderError(),
|
|
2757
2872
|
/* @__PURE__ */ jsx(OTPInput, { value: emailOtpCode, onChange: setEmailOtpCode, disabled: isSubmitting }),
|
|
2758
|
-
renderResendLink()
|
|
2759
|
-
|
|
2760
|
-
|
|
2873
|
+
renderResendLink()
|
|
2874
|
+
] }) }),
|
|
2875
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: renderLoaderBtn("Vérifier", "Vérification...", handleEmailOtpVerify, emailOtpCode.length !== 6) })
|
|
2761
2876
|
] }),
|
|
2762
2877
|
step === "phone-input" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2763
2878
|
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
@@ -2765,7 +2880,7 @@ function LoginModal({
|
|
|
2765
2880
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Connexion par téléphone" }),
|
|
2766
2881
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Entrez votre numéro pour recevoir un code SMS" })
|
|
2767
2882
|
] }),
|
|
2768
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
2883
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
2769
2884
|
renderError(),
|
|
2770
2885
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
2771
2886
|
/* @__PURE__ */ jsx(Label, { children: "Indicatif" }),
|
|
@@ -2802,7 +2917,9 @@ function LoginModal({
|
|
|
2802
2917
|
phone.replace(/\D/g, "").length,
|
|
2803
2918
|
"/9)"
|
|
2804
2919
|
] })
|
|
2805
|
-
] })
|
|
2920
|
+
] })
|
|
2921
|
+
] }) }),
|
|
2922
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
2806
2923
|
renderLoaderBtn("Recevoir le code SMS", "Envoi en cours...", handlePhoneInit, phone.replace(/\D/g, "").length !== 9),
|
|
2807
2924
|
showSwitchToSignup && /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: [
|
|
2808
2925
|
/* @__PURE__ */ jsx("span", { style: { color: C$2.gray500 }, children: "Pas encore de compte ? " }),
|
|
@@ -2825,12 +2942,12 @@ function LoginModal({
|
|
|
2825
2942
|
] })
|
|
2826
2943
|
] })
|
|
2827
2944
|
] }),
|
|
2828
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
2945
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
2829
2946
|
renderError(),
|
|
2830
2947
|
/* @__PURE__ */ jsx(OTPInput, { value: phoneOtpCode, onChange: setPhoneOtpCode, disabled: isSubmitting }),
|
|
2831
|
-
renderResendLink()
|
|
2832
|
-
|
|
2833
|
-
|
|
2948
|
+
renderResendLink()
|
|
2949
|
+
] }) }),
|
|
2950
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: renderLoaderBtn("Se connecter", "Vérification...", handlePhoneVerify, phoneOtpCode.length !== 6) })
|
|
2834
2951
|
] }),
|
|
2835
2952
|
step === "access-otp" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2836
2953
|
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
@@ -2838,7 +2955,7 @@ function LoginModal({
|
|
|
2838
2955
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Code d'accès" }),
|
|
2839
2956
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Entrez le code d'accès à 8 chiffres" })
|
|
2840
2957
|
] }),
|
|
2841
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
2958
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
2842
2959
|
renderError(),
|
|
2843
2960
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
2844
2961
|
/* @__PURE__ */ jsx(Label, { children: "Code d'accès (8 chiffres)" }),
|
|
@@ -2855,9 +2972,9 @@ function LoginModal({
|
|
|
2855
2972
|
maxLength: 8
|
|
2856
2973
|
}
|
|
2857
2974
|
)
|
|
2858
|
-
] })
|
|
2859
|
-
|
|
2860
|
-
|
|
2975
|
+
] })
|
|
2976
|
+
] }) }),
|
|
2977
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: renderLoaderBtn("Se connecter", "Vérification...", handleAccessOtpSubmit, accessOtpCode.length !== 8) })
|
|
2861
2978
|
] })
|
|
2862
2979
|
] }) }) }),
|
|
2863
2980
|
/* @__PURE__ */ jsx(
|
|
@@ -3054,6 +3171,7 @@ const COUNTRIES = [
|
|
|
3054
3171
|
];
|
|
3055
3172
|
const DEFAULT_COUNTRY_CODE = "SN";
|
|
3056
3173
|
const DEFAULT_DIAL_CODE = "+221";
|
|
3174
|
+
const COUNTRIES_SORTED_BY_CODE = [...COUNTRIES].sort((a, b) => a.code.localeCompare(b.code));
|
|
3057
3175
|
const getCountryByCode = (code) => COUNTRIES.find((c) => c.code.toLowerCase() === code.toLowerCase());
|
|
3058
3176
|
const getCountryByDialCode = (dialCode) => COUNTRIES.find((c) => c.dialCode === dialCode);
|
|
3059
3177
|
const getDefaultCountry = () => COUNTRIES.find((c) => c.code === DEFAULT_COUNTRY_CODE);
|
|
@@ -3074,7 +3192,17 @@ function PhoneInput({
|
|
|
3074
3192
|
placeholder = "77 123 45 67",
|
|
3075
3193
|
lockCcphone = false
|
|
3076
3194
|
}) {
|
|
3077
|
-
const selectedCountry = getCountryByDialCode(ccphone) ||
|
|
3195
|
+
const selectedCountry = getCountryByDialCode(ccphone) || COUNTRIES_SORTED_BY_CODE[0];
|
|
3196
|
+
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
3197
|
+
const dropdownRef = useRef(null);
|
|
3198
|
+
useEffect(() => {
|
|
3199
|
+
if (!dropdownOpen) return;
|
|
3200
|
+
const handler = (e) => {
|
|
3201
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) setDropdownOpen(false);
|
|
3202
|
+
};
|
|
3203
|
+
document.addEventListener("mousedown", handler);
|
|
3204
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
3205
|
+
}, [dropdownOpen]);
|
|
3078
3206
|
const handleChange = (e) => {
|
|
3079
3207
|
const cleaned = e.target.value.replace(/\D/g, "");
|
|
3080
3208
|
onChange(cleaned.slice(0, selectedCountry.digits));
|
|
@@ -3085,33 +3213,96 @@ function PhoneInput({
|
|
|
3085
3213
|
if (phone.length <= 7) return `${phone.slice(0, 2)} ${phone.slice(2, 5)} ${phone.slice(5)}`;
|
|
3086
3214
|
return `${phone.slice(0, 2)} ${phone.slice(2, 5)} ${phone.slice(5, 7)} ${phone.slice(7)}`;
|
|
3087
3215
|
};
|
|
3216
|
+
const handleSelect = (dialCode) => {
|
|
3217
|
+
if (onCcphoneChange) onCcphoneChange(dialCode);
|
|
3218
|
+
setDropdownOpen(false);
|
|
3219
|
+
};
|
|
3088
3220
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
3089
3221
|
/* @__PURE__ */ jsxs("div", { style: {
|
|
3090
3222
|
display: "flex",
|
|
3091
3223
|
alignItems: "center",
|
|
3092
3224
|
border: `2px solid ${error ? "#ef4444" : "#d1d5db"}`,
|
|
3093
3225
|
borderRadius: "0.5rem",
|
|
3094
|
-
overflow: "
|
|
3226
|
+
overflow: "visible",
|
|
3095
3227
|
opacity: disabled ? 0.5 : 1,
|
|
3096
|
-
backgroundColor: disabled ? "#f3f4f6" : "white"
|
|
3228
|
+
backgroundColor: disabled ? "#f3f4f6" : "white",
|
|
3229
|
+
position: "relative"
|
|
3097
3230
|
}, children: [
|
|
3098
|
-
onCcphoneChange && !lockCcphone ? /* @__PURE__ */
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3231
|
+
onCcphoneChange && !lockCcphone ? /* @__PURE__ */ jsxs("div", { ref: dropdownRef, style: { position: "relative" }, children: [
|
|
3232
|
+
/* @__PURE__ */ jsxs(
|
|
3233
|
+
"button",
|
|
3234
|
+
{
|
|
3235
|
+
type: "button",
|
|
3236
|
+
onClick: () => !disabled && setDropdownOpen(!dropdownOpen),
|
|
3237
|
+
disabled,
|
|
3238
|
+
style: {
|
|
3239
|
+
display: "flex",
|
|
3240
|
+
alignItems: "center",
|
|
3241
|
+
gap: "0.375rem",
|
|
3242
|
+
padding: "0.75rem",
|
|
3243
|
+
backgroundColor: "#f9fafb",
|
|
3244
|
+
borderRight: "1px solid #e5e7eb",
|
|
3245
|
+
border: "none",
|
|
3246
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
3247
|
+
fontWeight: 500,
|
|
3248
|
+
color: "#374151",
|
|
3249
|
+
fontSize: "0.9375rem",
|
|
3250
|
+
whiteSpace: "nowrap"
|
|
3251
|
+
},
|
|
3252
|
+
children: [
|
|
3253
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "1.125rem" }, children: selectedCountry.flag }),
|
|
3254
|
+
/* @__PURE__ */ jsx("span", { children: selectedCountry.dialCode }),
|
|
3255
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.625rem", marginLeft: "0.125rem" }, children: "▼" })
|
|
3256
|
+
]
|
|
3257
|
+
}
|
|
3258
|
+
),
|
|
3259
|
+
dropdownOpen && /* @__PURE__ */ jsx("div", { style: {
|
|
3260
|
+
position: "absolute",
|
|
3261
|
+
top: "100%",
|
|
3262
|
+
left: 0,
|
|
3263
|
+
zIndex: 50,
|
|
3264
|
+
backgroundColor: "white",
|
|
3265
|
+
border: "1px solid #d1d5db",
|
|
3266
|
+
borderRadius: "0.375rem",
|
|
3267
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
|
3268
|
+
maxHeight: "15rem",
|
|
3269
|
+
overflowY: "auto",
|
|
3270
|
+
minWidth: "12rem",
|
|
3271
|
+
marginTop: "0.25rem"
|
|
3272
|
+
}, children: COUNTRIES_SORTED_BY_CODE.map((c) => /* @__PURE__ */ jsxs(
|
|
3273
|
+
"button",
|
|
3274
|
+
{
|
|
3275
|
+
type: "button",
|
|
3276
|
+
onClick: () => handleSelect(c.dialCode),
|
|
3277
|
+
style: {
|
|
3278
|
+
display: "flex",
|
|
3279
|
+
alignItems: "center",
|
|
3280
|
+
gap: "0.5rem",
|
|
3281
|
+
width: "100%",
|
|
3282
|
+
padding: "0.5rem 0.75rem",
|
|
3283
|
+
border: "none",
|
|
3284
|
+
cursor: "pointer",
|
|
3285
|
+
fontSize: "0.875rem",
|
|
3286
|
+
backgroundColor: c.dialCode === ccphone ? "#f3f4f6" : "transparent",
|
|
3287
|
+
textAlign: "left"
|
|
3288
|
+
},
|
|
3289
|
+
onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "#f3f4f6",
|
|
3290
|
+
onMouseLeave: (e) => e.currentTarget.style.backgroundColor = c.dialCode === ccphone ? "#f3f4f6" : "transparent",
|
|
3291
|
+
children: [
|
|
3292
|
+
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: "#374151", minWidth: "1.75rem" }, children: c.code }),
|
|
3293
|
+
/* @__PURE__ */ jsx("span", { children: c.flag }),
|
|
3294
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#6b7280" }, children: c.dialCode })
|
|
3295
|
+
]
|
|
3296
|
+
},
|
|
3297
|
+
`${c.code}-${c.dialCode}`
|
|
3298
|
+
)) })
|
|
3299
|
+
] }) : (
|
|
3300
|
+
/* Locked view: only flag + dialCode */
|
|
3301
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.375rem", padding: "0.75rem", backgroundColor: "#f9fafb", borderRight: "1px solid #e5e7eb" }, children: [
|
|
3302
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "1.125rem" }, children: selectedCountry.flag }),
|
|
3303
|
+
/* @__PURE__ */ jsx("span", { style: { fontWeight: 500, color: "#374151" }, children: selectedCountry.dialCode })
|
|
3304
|
+
] })
|
|
3305
|
+
),
|
|
3115
3306
|
/* @__PURE__ */ jsx(
|
|
3116
3307
|
"input",
|
|
3117
3308
|
{
|
|
@@ -3414,6 +3605,18 @@ function useMobileRegistration(options) {
|
|
|
3414
3605
|
}));
|
|
3415
3606
|
return { success: false, error_type: response.error_type };
|
|
3416
3607
|
} catch (err) {
|
|
3608
|
+
if (err instanceof ApiError && err.statusCode === 409 && err.response) {
|
|
3609
|
+
const resp = err.response;
|
|
3610
|
+
if (resp.conflict) {
|
|
3611
|
+
setState((prev) => ({
|
|
3612
|
+
...prev,
|
|
3613
|
+
loading: false,
|
|
3614
|
+
error: resp.message || "Ce compte existe déjà",
|
|
3615
|
+
conflict: resp.conflict
|
|
3616
|
+
}));
|
|
3617
|
+
return { success: false, error_type: resp.error_type };
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3417
3620
|
const message = getErrorMessage(err, "l'inscription");
|
|
3418
3621
|
setState((prev) => ({ ...prev, loading: false, error: message, conflict: null }));
|
|
3419
3622
|
return { success: false };
|
|
@@ -3559,6 +3762,7 @@ const C$1 = {
|
|
|
3559
3762
|
gray900: "#111827",
|
|
3560
3763
|
red: "#dc2626",
|
|
3561
3764
|
redBg: "#fef2f2",
|
|
3765
|
+
amber: "#f59e0b",
|
|
3562
3766
|
amberBg: "#fef3c7",
|
|
3563
3767
|
white: "#ffffff"
|
|
3564
3768
|
};
|
|
@@ -3651,12 +3855,14 @@ function SuccessOrbit() {
|
|
|
3651
3855
|
})
|
|
3652
3856
|
] });
|
|
3653
3857
|
}
|
|
3654
|
-
function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saasApiUrl, iamApiUrl, defaultAccountType }) {
|
|
3858
|
+
function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saasApiUrl, iamApiUrl, defaultAccountType, onSwitchToLoginWithPhone }) {
|
|
3859
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3655
3860
|
const {
|
|
3656
3861
|
status,
|
|
3657
3862
|
formData,
|
|
3658
3863
|
loading: regLoading,
|
|
3659
3864
|
error: regError,
|
|
3865
|
+
conflict,
|
|
3660
3866
|
accountType,
|
|
3661
3867
|
setAccountType,
|
|
3662
3868
|
isPhoneOnly,
|
|
@@ -3668,6 +3874,7 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
|
|
|
3668
3874
|
reset: resetReg,
|
|
3669
3875
|
clearError
|
|
3670
3876
|
} = useMobileRegistration({ saasApiUrl, iamApiUrl });
|
|
3877
|
+
const [showPasswordRecovery, setShowPasswordRecovery] = useState(false);
|
|
3671
3878
|
const [step, setStep] = useState("intro");
|
|
3672
3879
|
const [otpCode, setOtpCode] = useState("");
|
|
3673
3880
|
const [password, setPassword] = useState("");
|
|
@@ -3720,31 +3927,35 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
|
|
|
3720
3927
|
}
|
|
3721
3928
|
};
|
|
3722
3929
|
const handleInfoSubmit = async (e) => {
|
|
3723
|
-
var
|
|
3930
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g;
|
|
3724
3931
|
e.preventDefault();
|
|
3725
3932
|
setLocalError(null);
|
|
3726
3933
|
clearError();
|
|
3727
|
-
if (!((
|
|
3934
|
+
if (!((_a2 = formData.name) == null ? void 0 : _a2.trim())) {
|
|
3728
3935
|
setLocalError("Le nom est requis");
|
|
3729
3936
|
return;
|
|
3730
3937
|
}
|
|
3731
|
-
if (!isPhoneOnly && !((
|
|
3938
|
+
if (!isPhoneOnly && !((_b2 = formData.email) == null ? void 0 : _b2.trim())) {
|
|
3732
3939
|
setLocalError("L'adresse email est requise");
|
|
3733
3940
|
return;
|
|
3734
3941
|
}
|
|
3735
|
-
if (!((
|
|
3942
|
+
if (!((_c2 = formData.phone) == null ? void 0 : _c2.trim()) || (((_d2 = formData.phone) == null ? void 0 : _d2.length) || 0) < 6) {
|
|
3736
3943
|
setLocalError("Numéro de téléphone invalide");
|
|
3737
3944
|
return;
|
|
3738
3945
|
}
|
|
3946
|
+
if (formData.ccphone === "+221" && ((_e2 = formData.phone) == null ? void 0 : _e2.length) !== 9) {
|
|
3947
|
+
setLocalError("Le numéro sénégalais doit contenir exactement 9 chiffres");
|
|
3948
|
+
return;
|
|
3949
|
+
}
|
|
3739
3950
|
if (isPhoneOnly && formData.ccphone !== "+221") {
|
|
3740
3951
|
setLocalError("L'inscription par téléphone est réservée aux numéros sénégalais (+221)");
|
|
3741
3952
|
return;
|
|
3742
3953
|
}
|
|
3743
|
-
if (!((
|
|
3954
|
+
if (!((_f2 = formData.town) == null ? void 0 : _f2.trim())) {
|
|
3744
3955
|
setLocalError("La ville est requise");
|
|
3745
3956
|
return;
|
|
3746
3957
|
}
|
|
3747
|
-
if (!((
|
|
3958
|
+
if (!((_g = formData.country) == null ? void 0 : _g.trim())) {
|
|
3748
3959
|
setLocalError("Le pays est requis");
|
|
3749
3960
|
return;
|
|
3750
3961
|
}
|
|
@@ -3796,197 +4007,281 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
|
|
|
3796
4007
|
goToStep("info");
|
|
3797
4008
|
};
|
|
3798
4009
|
const renderError = () => error ? /* @__PURE__ */ jsx("div", { style: { padding: "0.75rem", borderRadius: "0.375rem", backgroundColor: C$1.redBg, color: C$1.red, fontSize: "0.875rem" }, children: error }) : null;
|
|
3799
|
-
return /* @__PURE__ */
|
|
3800
|
-
/* @__PURE__ */ jsx(
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem", fontSize: "0.875rem", color: C$1.gray500, marginTop: "1rem" }, children: [
|
|
3808
|
-
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
3809
|
-
"Connexion automatique en cours..."
|
|
3810
|
-
] })
|
|
3811
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3812
|
-
step === "intro" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3813
|
-
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
3814
|
-
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.accent + "1a", "4rem"), children: /* @__PURE__ */ jsx(IconShieldCheck, { style: { width: "2rem", height: "2rem", color: C$1.accent } }) }),
|
|
3815
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "Ouvrez un compte Ollaid" }),
|
|
3816
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: "Un compte unique qui vous donne accès à toutes les applications" })
|
|
4010
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4011
|
+
/* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx(DialogContent, { children: signupSuccess && signupData ? /* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
4012
|
+
/* @__PURE__ */ jsx(SuccessOrbit, {}),
|
|
4013
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Félicitations !" }),
|
|
4014
|
+
/* @__PURE__ */ jsxs(DialogDescription, { children: [
|
|
4015
|
+
"Votre compte a été créé avec succès. Bienvenue ",
|
|
4016
|
+
formData.name,
|
|
4017
|
+
" !"
|
|
3817
4018
|
] }),
|
|
3818
|
-
/* @__PURE__ */
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
text
|
|
3822
|
-
] }, text)) }),
|
|
3823
|
-
/* @__PURE__ */ jsx(StepIndicator, { current: 1 }),
|
|
3824
|
-
/* @__PURE__ */ jsx(Button, { onClick: () => goToStep("account-type"), style: { width: "100%", marginTop: "1rem" }, children: "Suivant →" }),
|
|
3825
|
-
/* @__PURE__ */ jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem", marginTop: "1rem" }, children: [
|
|
3826
|
-
/* @__PURE__ */ jsx("span", { style: { color: C$1.gray500 }, children: "Déjà un compte ? " }),
|
|
3827
|
-
/* @__PURE__ */ jsx("button", { type: "button", style: linkStyle, onClick: onSwitchToLogin, children: "Connectez-vous" })
|
|
4019
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem", fontSize: "0.875rem", color: C$1.gray500, marginTop: "1rem" }, children: [
|
|
4020
|
+
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
4021
|
+
"Connexion automatique en cours..."
|
|
3828
4022
|
] })
|
|
3829
|
-
] }),
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
] }),
|
|
3836
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem", marginTop: "1rem" }, children: [
|
|
3837
|
-
/* @__PURE__ */ jsxs(
|
|
3838
|
-
"button",
|
|
3839
|
-
{
|
|
3840
|
-
type: "button",
|
|
3841
|
-
onClick: () => handleAccountTypeSelect("email"),
|
|
3842
|
-
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" },
|
|
3843
|
-
children: [
|
|
3844
|
-
/* @__PURE__ */ 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__ */ jsx(IconMail, { style: { width: "1.25rem", height: "1.25rem", color: C$1.white } }) }),
|
|
3845
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3846
|
-
/* @__PURE__ */ jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Email + Téléphone" }),
|
|
3847
|
-
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "Compte complet" })
|
|
3848
|
-
] })
|
|
3849
|
-
]
|
|
3850
|
-
}
|
|
3851
|
-
),
|
|
3852
|
-
/* @__PURE__ */ jsxs(
|
|
3853
|
-
"button",
|
|
3854
|
-
{
|
|
3855
|
-
type: "button",
|
|
3856
|
-
onClick: () => handleAccountTypeSelect("phone-only"),
|
|
3857
|
-
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" },
|
|
3858
|
-
children: [
|
|
3859
|
-
/* @__PURE__ */ 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__ */ jsx(IconSmartphone, { style: { width: "1.25rem", height: "1.25rem", color: C$1.white } }) }),
|
|
3860
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3861
|
-
/* @__PURE__ */ jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Téléphone uniquement" }),
|
|
3862
|
-
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "🇸🇳 Sénégal uniquement" })
|
|
3863
|
-
] })
|
|
3864
|
-
]
|
|
3865
|
-
}
|
|
3866
|
-
)
|
|
3867
|
-
] }),
|
|
3868
|
-
/* @__PURE__ */ jsx(StepIndicator, { current: 2 })
|
|
3869
|
-
] }),
|
|
3870
|
-
step === "info" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3871
|
-
/* @__PURE__ */ jsx("button", { onClick: () => goToStep("account-type"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
|
|
3872
|
-
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
3873
|
-
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.primary + "1a"), children: /* @__PURE__ */ jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
|
|
3874
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "Créer votre compte" })
|
|
3875
|
-
] }),
|
|
3876
|
-
isPhoneOnly && /* @__PURE__ */ 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" }),
|
|
3877
|
-
!isPhoneOnly && /* @__PURE__ */ 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" }),
|
|
3878
|
-
/* @__PURE__ */ jsxs("form", { onSubmit: handleInfoSubmit, style: { display: "flex", flexDirection: "column", gap: "0.75rem", marginTop: "0.75rem" }, children: [
|
|
3879
|
-
renderError(),
|
|
3880
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3881
|
-
/* @__PURE__ */ jsx(Label, { children: "Nom complet" }),
|
|
3882
|
-
/* @__PURE__ */ jsx(Input, { placeholder: "Jean Dupont", value: formData.name || "", onChange: (e) => updateFormData({ name: e.target.value }), disabled: regLoading })
|
|
4023
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4024
|
+
step === "intro" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4025
|
+
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
4026
|
+
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.accent + "1a", "4rem"), children: /* @__PURE__ */ jsx(IconShieldCheck, { style: { width: "2rem", height: "2rem", color: C$1.accent } }) }),
|
|
4027
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Ouvrez un compte Ollaid" }),
|
|
4028
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: "Un compte unique qui vous donne accès à toutes les applications" })
|
|
3883
4029
|
] }),
|
|
3884
|
-
|
|
3885
|
-
/* @__PURE__ */ jsx(
|
|
3886
|
-
/* @__PURE__ */ jsx(
|
|
4030
|
+
/* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
4031
|
+
/* @__PURE__ */ jsx(AppsLogoSlider, { iamApiUrl }),
|
|
4032
|
+
/* @__PURE__ */ 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__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem" }, children: [
|
|
4033
|
+
/* @__PURE__ */ jsx(IconCheckCircle2, { style: { width: "1.25rem", height: "1.25rem", color: C$1.green, flexShrink: 0 } }),
|
|
4034
|
+
text
|
|
4035
|
+
] }, text)) }),
|
|
4036
|
+
/* @__PURE__ */ jsx(StepIndicator, { current: 1 })
|
|
3887
4037
|
] }),
|
|
3888
|
-
/* @__PURE__ */ jsxs(
|
|
3889
|
-
/* @__PURE__ */ jsx(
|
|
3890
|
-
/* @__PURE__ */
|
|
4038
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
4039
|
+
/* @__PURE__ */ jsx(Button, { onClick: () => goToStep("account-type"), style: { width: "100%" }, children: "Suivant →" }),
|
|
4040
|
+
/* @__PURE__ */ jsxs("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: [
|
|
4041
|
+
/* @__PURE__ */ jsx("span", { style: { color: C$1.gray500 }, children: "Déjà un compte ? " }),
|
|
4042
|
+
/* @__PURE__ */ jsx("button", { type: "button", style: linkStyle, onClick: onSwitchToLogin, children: "Connectez-vous" })
|
|
4043
|
+
] })
|
|
4044
|
+
] })
|
|
4045
|
+
] }),
|
|
4046
|
+
step === "account-type" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4047
|
+
/* @__PURE__ */ jsx("button", { onClick: () => goToStep("intro"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
|
|
4048
|
+
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
4049
|
+
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.gray100), children: /* @__PURE__ */ jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
|
|
4050
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Choisissez votre type de compte" })
|
|
3891
4051
|
] }),
|
|
3892
|
-
/* @__PURE__ */ jsxs(
|
|
3893
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3894
|
-
/* @__PURE__ */
|
|
3895
|
-
|
|
4052
|
+
/* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
4053
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
4054
|
+
/* @__PURE__ */ jsxs(
|
|
4055
|
+
"button",
|
|
4056
|
+
{
|
|
4057
|
+
type: "button",
|
|
4058
|
+
onClick: () => handleAccountTypeSelect("email"),
|
|
4059
|
+
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" },
|
|
4060
|
+
children: [
|
|
4061
|
+
/* @__PURE__ */ 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__ */ jsx(IconMail, { style: { width: "1.25rem", height: "1.25rem", color: C$1.white } }) }),
|
|
4062
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4063
|
+
/* @__PURE__ */ jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Email + Téléphone" }),
|
|
4064
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "Compte complet" })
|
|
4065
|
+
] })
|
|
4066
|
+
]
|
|
4067
|
+
}
|
|
4068
|
+
),
|
|
4069
|
+
/* @__PURE__ */ jsxs(
|
|
4070
|
+
"button",
|
|
4071
|
+
{
|
|
4072
|
+
type: "button",
|
|
4073
|
+
onClick: () => handleAccountTypeSelect("phone-only"),
|
|
4074
|
+
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" },
|
|
4075
|
+
children: [
|
|
4076
|
+
/* @__PURE__ */ 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__ */ jsx(IconSmartphone, { style: { width: "1.25rem", height: "1.25rem", color: C$1.white } }) }),
|
|
4077
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4078
|
+
/* @__PURE__ */ jsx("div", { style: { fontWeight: 600, color: C$1.gray900 }, children: "Téléphone uniquement" }),
|
|
4079
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: "🇸🇳 Sénégal uniquement" })
|
|
4080
|
+
] })
|
|
4081
|
+
]
|
|
4082
|
+
}
|
|
4083
|
+
)
|
|
3896
4084
|
] }),
|
|
3897
|
-
/* @__PURE__ */
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
4085
|
+
/* @__PURE__ */ jsx(StepIndicator, { current: 2 })
|
|
4086
|
+
] })
|
|
4087
|
+
] }),
|
|
4088
|
+
step === "info" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4089
|
+
/* @__PURE__ */ jsx("button", { onClick: () => goToStep("account-type"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
|
|
4090
|
+
conflict ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4091
|
+
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
4092
|
+
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.amberBg), children: /* @__PURE__ */ jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.amber } }) }),
|
|
4093
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: conflict.type === "phone" ? "Numéro déjà utilisé" : "Email déjà utilisé" }),
|
|
4094
|
+
/* @__PURE__ */ jsxs(DialogDescription, { children: [
|
|
4095
|
+
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.`,
|
|
4096
|
+
" ",
|
|
4097
|
+
"S'il s'agit du vôtre, connectez-vous."
|
|
4098
|
+
] })
|
|
4099
|
+
] }),
|
|
4100
|
+
/* @__PURE__ */ jsxs(DialogFooter, { style: { borderTop: "none" }, children: [
|
|
4101
|
+
conflict.type === "phone" && formData.ccphone === "+221" && ((_a = conflict.options) == null ? void 0 : _a.can_login) && /* @__PURE__ */ jsxs(
|
|
4102
|
+
Button,
|
|
3901
4103
|
{
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
4104
|
+
onClick: () => {
|
|
4105
|
+
const fullPhone = formData.phone || "";
|
|
4106
|
+
if (onSwitchToLoginWithPhone) onSwitchToLoginWithPhone(fullPhone);
|
|
4107
|
+
else onSwitchToLogin();
|
|
3906
4108
|
},
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
c.name
|
|
3913
|
-
] }, c.code))
|
|
4109
|
+
style: { width: "100%" },
|
|
4110
|
+
children: [
|
|
4111
|
+
/* @__PURE__ */ jsx(IconSmartphone, { style: { width: "1rem", height: "1rem" } }),
|
|
4112
|
+
"Se connecter par téléphone"
|
|
4113
|
+
]
|
|
3914
4114
|
}
|
|
3915
|
-
)
|
|
4115
|
+
),
|
|
4116
|
+
(conflict.type === "email" || conflict.type === "phone" && formData.ccphone !== "+221") && ((_b = conflict.options) == null ? void 0 : _b.can_login) && /* @__PURE__ */ jsx(Button, { onClick: onSwitchToLogin, style: { width: "100%" }, children: "Se connecter" }),
|
|
4117
|
+
!isPhoneOnly && (((_c = conflict.options) == null ? void 0 : _c.can_recover_by_email) || ((_d = conflict.options) == null ? void 0 : _d.can_recover_by_sms)) && /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setShowPasswordRecovery(true), style: { width: "100%" }, children: "Récupérer mon compte" }),
|
|
4118
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => clearError(), style: { width: "100%" }, children: conflict.type === "phone" ? "Changer le numéro" : "Changer l'email" }),
|
|
4119
|
+
((_e = conflict.options) == null ? void 0 : _e.masked_email) && /* @__PURE__ */ jsxs("div", { style: { padding: "0.75rem", backgroundColor: C$1.gray100, borderRadius: "0.375rem", fontSize: "0.8125rem", color: C$1.gray500, textAlign: "center" }, children: [
|
|
4120
|
+
"Email lié : ",
|
|
4121
|
+
/* @__PURE__ */ jsx("strong", { style: { color: C$1.gray900 }, children: conflict.options.masked_email })
|
|
4122
|
+
] }),
|
|
4123
|
+
((_f = conflict.options) == null ? void 0 : _f.masked_phone) && /* @__PURE__ */ jsxs("div", { style: { padding: "0.75rem", backgroundColor: C$1.gray100, borderRadius: "0.375rem", fontSize: "0.8125rem", color: C$1.gray500, textAlign: "center" }, children: [
|
|
4124
|
+
"Téléphone lié : ",
|
|
4125
|
+
/* @__PURE__ */ jsx("strong", { style: { color: C$1.gray900 }, children: conflict.options.masked_phone })
|
|
4126
|
+
] })
|
|
3916
4127
|
] })
|
|
3917
|
-
] })
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
4128
|
+
] }) : (
|
|
4129
|
+
/* ---- NORMAL INFO FORM ---- */
|
|
4130
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4131
|
+
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
4132
|
+
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.primary + "1a"), children: /* @__PURE__ */ jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
|
|
4133
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Créer votre compte" })
|
|
4134
|
+
] }),
|
|
4135
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleInfoSubmit, style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
|
|
4136
|
+
/* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
4137
|
+
isPhoneOnly && /* @__PURE__ */ 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" }),
|
|
4138
|
+
!isPhoneOnly && /* @__PURE__ */ 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" }),
|
|
4139
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
4140
|
+
renderError(),
|
|
4141
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4142
|
+
/* @__PURE__ */ jsxs(Label, { children: [
|
|
4143
|
+
"Nom complet ",
|
|
4144
|
+
/* @__PURE__ */ jsx("span", { style: { color: C$1.red }, children: "*" })
|
|
4145
|
+
] }),
|
|
4146
|
+
/* @__PURE__ */ jsx(Input, { placeholder: "Jean Dupont", value: formData.name || "", onChange: (e) => updateFormData({ name: e.target.value }), disabled: regLoading })
|
|
4147
|
+
] }),
|
|
4148
|
+
!isPhoneOnly && /* @__PURE__ */ jsxs("div", { children: [
|
|
4149
|
+
/* @__PURE__ */ jsxs(Label, { children: [
|
|
4150
|
+
"Adresse email ",
|
|
4151
|
+
/* @__PURE__ */ jsx("span", { style: { color: C$1.red }, children: "*" })
|
|
4152
|
+
] }),
|
|
4153
|
+
/* @__PURE__ */ jsx(Input, { type: "email", placeholder: "vous@exemple.com", value: formData.email || "", onChange: (e) => updateFormData({ email: e.target.value }), disabled: regLoading })
|
|
4154
|
+
] }),
|
|
4155
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4156
|
+
/* @__PURE__ */ jsxs(Label, { children: [
|
|
4157
|
+
"Numéro de téléphone ",
|
|
4158
|
+
/* @__PURE__ */ jsx("span", { style: { color: C$1.red }, children: "*" })
|
|
4159
|
+
] }),
|
|
4160
|
+
/* @__PURE__ */ jsx(PhoneInput, { value: formData.phone || "", onChange: (p) => updateFormData({ phone: p }), ccphone: formData.ccphone || "+221", onCcphoneChange: (c) => updateFormData({ ccphone: c }), disabled: regLoading, lockCcphone: isPhoneOnly })
|
|
4161
|
+
] }),
|
|
4162
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.75rem" }, children: [
|
|
4163
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4164
|
+
/* @__PURE__ */ jsxs(Label, { children: [
|
|
4165
|
+
"Ville ",
|
|
4166
|
+
/* @__PURE__ */ jsx("span", { style: { color: C$1.red }, children: "*" })
|
|
4167
|
+
] }),
|
|
4168
|
+
/* @__PURE__ */ jsx(Input, { placeholder: "Dakar", value: formData.town || "", onChange: (e) => updateFormData({ town: e.target.value }), disabled: regLoading })
|
|
4169
|
+
] }),
|
|
4170
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4171
|
+
/* @__PURE__ */ jsxs(Label, { children: [
|
|
4172
|
+
"Pays ",
|
|
4173
|
+
/* @__PURE__ */ jsx("span", { style: { color: C$1.red }, children: "*" })
|
|
4174
|
+
] }),
|
|
4175
|
+
/* @__PURE__ */ jsx(
|
|
4176
|
+
"select",
|
|
4177
|
+
{
|
|
4178
|
+
value: formData.country || DEFAULT_COUNTRY_CODE,
|
|
4179
|
+
onChange: (e) => {
|
|
4180
|
+
const country = getCountryByCode(e.target.value);
|
|
4181
|
+
updateFormData({ country: e.target.value, ccphone: (country == null ? void 0 : country.dialCode) || "+221" });
|
|
4182
|
+
},
|
|
4183
|
+
disabled: regLoading || isPhoneOnly,
|
|
4184
|
+
style: { width: "100%", padding: "0.5rem", borderRadius: "0.375rem", border: "1px solid #d1d5db", backgroundColor: regLoading || isPhoneOnly ? "#f3f4f6" : "white", fontSize: "0.875rem" },
|
|
4185
|
+
children: COUNTRIES_SORTED_BY_CODE.map((c) => /* @__PURE__ */ jsxs("option", { value: c.code, children: [
|
|
4186
|
+
c.code,
|
|
4187
|
+
" ",
|
|
4188
|
+
c.flag,
|
|
4189
|
+
" ",
|
|
4190
|
+
c.name
|
|
4191
|
+
] }, c.code))
|
|
4192
|
+
}
|
|
4193
|
+
)
|
|
4194
|
+
] })
|
|
4195
|
+
] }),
|
|
4196
|
+
/* @__PURE__ */ jsx(StepIndicator, { current: 3 })
|
|
4197
|
+
] })
|
|
4198
|
+
] }),
|
|
4199
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { type: "submit", disabled: regLoading, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
4200
|
+
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
4201
|
+
" Vérification..."
|
|
4202
|
+
] }) : "Continuer" }) })
|
|
4203
|
+
] })
|
|
4204
|
+
] })
|
|
4205
|
+
)
|
|
3934
4206
|
] }),
|
|
3935
|
-
/* @__PURE__ */ jsxs(
|
|
3936
|
-
|
|
3937
|
-
/* @__PURE__ */
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
4207
|
+
step === "otp" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4208
|
+
/* @__PURE__ */ jsx("button", { onClick: () => goToStep("info"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
|
|
4209
|
+
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
4210
|
+
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.accent), children: /* @__PURE__ */ jsx(IconKeyRound, { style: { width: "1.5rem", height: "1.5rem", color: C$1.white } }) }),
|
|
4211
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Vérification" }),
|
|
4212
|
+
/* @__PURE__ */ jsxs(DialogDescription, { children: [
|
|
4213
|
+
"Entrez le code envoyé ",
|
|
4214
|
+
isPhoneOnly ? `au ${formData.ccphone} ${formData.phone}` : `à ${formData.email}`
|
|
4215
|
+
] })
|
|
4216
|
+
] }),
|
|
4217
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
4218
|
+
renderError(),
|
|
4219
|
+
/* @__PURE__ */ jsx(OTPInput, { value: otpCode, onChange: setOtpCode, disabled: regLoading }),
|
|
4220
|
+
/* @__PURE__ */ jsx("div", { style: { textAlign: "center", fontSize: "0.875rem" }, children: resendCooldown > 0 ? /* @__PURE__ */ jsxs("span", { style: { color: C$1.gray500 }, children: [
|
|
4221
|
+
"Renvoyer dans ",
|
|
4222
|
+
resendCooldown,
|
|
4223
|
+
"s"
|
|
4224
|
+
] }) : /* @__PURE__ */ jsx("button", { type: "button", onClick: handleResendOTP, style: linkStyle, children: "Code non reçu ? Renvoyer" }) }),
|
|
4225
|
+
/* @__PURE__ */ jsx(StepIndicator, { current: 4 })
|
|
4226
|
+
] }) }),
|
|
4227
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { onClick: handleOTPSubmit, disabled: regLoading || otpCode.length !== 6, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
3945
4228
|
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
3946
4229
|
" Vérification..."
|
|
3947
|
-
] }) : "Vérifier" })
|
|
3948
|
-
] })
|
|
3949
|
-
] }),
|
|
3950
|
-
step === "password" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3951
|
-
/* @__PURE__ */ jsx("button", { onClick: () => goToStep("otp"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
|
|
3952
|
-
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
3953
|
-
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.accent), children: /* @__PURE__ */ jsx(IconLock, { style: { width: "1.5rem", height: "1.5rem", color: C$1.white } }) }),
|
|
3954
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "Créer un mot de passe" })
|
|
4230
|
+
] }) : "Vérifier" }) })
|
|
3955
4231
|
] }),
|
|
3956
|
-
/* @__PURE__ */ jsxs(
|
|
3957
|
-
|
|
3958
|
-
/* @__PURE__ */ jsxs("
|
|
3959
|
-
/* @__PURE__ */ jsx(
|
|
3960
|
-
/* @__PURE__ */ jsx(
|
|
3961
|
-
] }),
|
|
3962
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3963
|
-
/* @__PURE__ */ jsx(Label, { children: "Confirmer le mot de passe" }),
|
|
3964
|
-
/* @__PURE__ */ jsx(Input, { type: "password", placeholder: "••••••••", value: passwordConfirm, onChange: (e) => setPasswordConfirm(e.target.value), disabled: regLoading })
|
|
4232
|
+
step === "password" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4233
|
+
/* @__PURE__ */ jsx("button", { onClick: () => goToStep("otp"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
|
|
4234
|
+
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
4235
|
+
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.accent), children: /* @__PURE__ */ jsx(IconLock, { style: { width: "1.5rem", height: "1.5rem", color: C$1.white } }) }),
|
|
4236
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Créer un mot de passe" })
|
|
3965
4237
|
] }),
|
|
3966
|
-
/* @__PURE__ */
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
4238
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handlePasswordSubmit, style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }, children: [
|
|
4239
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
4240
|
+
renderError(),
|
|
4241
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4242
|
+
/* @__PURE__ */ jsx(Label, { children: "Mot de passe" }),
|
|
4243
|
+
/* @__PURE__ */ jsx(Input, { type: "password", placeholder: "Minimum 8 caractères", value: password, onChange: (e) => setPassword(e.target.value), disabled: regLoading })
|
|
4244
|
+
] }),
|
|
4245
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4246
|
+
/* @__PURE__ */ jsx(Label, { children: "Confirmer le mot de passe" }),
|
|
4247
|
+
/* @__PURE__ */ jsx(Input, { type: "password", placeholder: "••••••••", value: passwordConfirm, onChange: (e) => setPasswordConfirm(e.target.value), disabled: regLoading })
|
|
4248
|
+
] }),
|
|
4249
|
+
/* @__PURE__ */ jsx(StepIndicator, { current: 5 })
|
|
4250
|
+
] }) }),
|
|
4251
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { type: "submit", disabled: regLoading, style: { width: "100%" }, children: "Continuer" }) })
|
|
4252
|
+
] })
|
|
3975
4253
|
] }),
|
|
3976
|
-
/* @__PURE__ */ jsxs(
|
|
3977
|
-
|
|
3978
|
-
/* @__PURE__ */
|
|
3979
|
-
/* @__PURE__ */ jsx("
|
|
3980
|
-
/* @__PURE__ */ jsx(
|
|
3981
|
-
] }
|
|
3982
|
-
/* @__PURE__ */ jsx(
|
|
3983
|
-
|
|
4254
|
+
step === "confirm" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4255
|
+
/* @__PURE__ */ jsx("button", { onClick: () => goToStep("password"), style: backBtnStyle, type: "button", children: /* @__PURE__ */ jsx(IconArrowLeft, { style: { width: "1rem", height: "1rem" } }) }),
|
|
4256
|
+
/* @__PURE__ */ jsxs(DialogHeader, { style: { textAlign: "center" }, children: [
|
|
4257
|
+
/* @__PURE__ */ jsx("div", { style: iconCircle(C$1.primary + "1a"), children: /* @__PURE__ */ jsx(IconShieldCheck, { style: { width: "1.5rem", height: "1.5rem", color: C$1.primary } }) }),
|
|
4258
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Confirmer votre inscription" })
|
|
4259
|
+
] }),
|
|
4260
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
4261
|
+
renderError(),
|
|
4262
|
+
/* @__PURE__ */ 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__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", padding: "0.375rem 0" }, children: [
|
|
4263
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.875rem", color: C$1.gray500 }, children: label }),
|
|
4264
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.875rem", fontWeight: 500 }, children: value })
|
|
4265
|
+
] }, label)) }),
|
|
4266
|
+
/* @__PURE__ */ jsx(StepIndicator, { current: 6 })
|
|
4267
|
+
] }) }),
|
|
4268
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, disabled: regLoading, style: { width: "100%" }, children: regLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
3984
4269
|
/* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
3985
4270
|
" Création du compte..."
|
|
3986
|
-
] }) : "Créer mon compte" })
|
|
4271
|
+
] }) : "Créer mon compte" }) })
|
|
3987
4272
|
] })
|
|
3988
|
-
] })
|
|
3989
|
-
|
|
4273
|
+
] }) }) }),
|
|
4274
|
+
/* @__PURE__ */ jsx(
|
|
4275
|
+
PasswordRecoveryModal,
|
|
4276
|
+
{
|
|
4277
|
+
open: showPasswordRecovery,
|
|
4278
|
+
onOpenChange: setShowPasswordRecovery,
|
|
4279
|
+
onSuccess: () => setShowPasswordRecovery(false),
|
|
4280
|
+
saasApiUrl,
|
|
4281
|
+
iamApiUrl
|
|
4282
|
+
}
|
|
4283
|
+
)
|
|
4284
|
+
] });
|
|
3990
4285
|
}
|
|
3991
4286
|
const C = {
|
|
3992
4287
|
primary: "#002147",
|
|
@@ -4053,7 +4348,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
|
|
|
4053
4348
|
] }),
|
|
4054
4349
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Ajoutez les informations manquantes pour finaliser votre compte." })
|
|
4055
4350
|
] }),
|
|
4056
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.25rem", marginTop: "
|
|
4351
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.25rem", marginTop: "0.75rem" }, children: [
|
|
4057
4352
|
needsPhoto && /* @__PURE__ */ jsxs("div", { children: [
|
|
4058
4353
|
/* @__PURE__ */ jsx(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: "Photo de profil" }),
|
|
4059
4354
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "1rem" }, children: [
|
|
@@ -4085,15 +4380,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
|
|
|
4085
4380
|
fontWeight: 500
|
|
4086
4381
|
}, children: [
|
|
4087
4382
|
"Choisir une photo",
|
|
4088
|
-
/* @__PURE__ */ jsx(
|
|
4089
|
-
"input",
|
|
4090
|
-
{
|
|
4091
|
-
type: "file",
|
|
4092
|
-
accept: "image/*",
|
|
4093
|
-
onChange: handleFileChange,
|
|
4094
|
-
style: { display: "none" }
|
|
4095
|
-
}
|
|
4096
|
-
)
|
|
4383
|
+
/* @__PURE__ */ jsx("input", { type: "file", accept: "image/*", onChange: handleFileChange, style: { display: "none" } })
|
|
4097
4384
|
] }),
|
|
4098
4385
|
/* @__PURE__ */ jsx("p", { style: { fontSize: "0.75rem", color: fileError ? "#dc2626" : C.gray500, marginTop: "0.25rem" }, children: fileError || "JPG, PNG. Max 2 Mo." })
|
|
4099
4386
|
] })
|
|
@@ -4101,15 +4388,7 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
|
|
|
4101
4388
|
] }),
|
|
4102
4389
|
needsPhone && /* @__PURE__ */ jsxs("div", { children: [
|
|
4103
4390
|
/* @__PURE__ */ jsx(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: "Numéro de téléphone" }),
|
|
4104
|
-
/* @__PURE__ */ jsx(
|
|
4105
|
-
PhoneInput,
|
|
4106
|
-
{
|
|
4107
|
-
value: phone,
|
|
4108
|
-
onChange: setPhone,
|
|
4109
|
-
ccphone,
|
|
4110
|
-
onCcphoneChange: setCcphone
|
|
4111
|
-
}
|
|
4112
|
-
)
|
|
4391
|
+
/* @__PURE__ */ jsx(PhoneInput, { value: phone, onChange: setPhone, ccphone, onCcphoneChange: setCcphone })
|
|
4113
4392
|
] }),
|
|
4114
4393
|
needsEmail && /* @__PURE__ */ jsxs("div", { children: [
|
|
4115
4394
|
/* @__PURE__ */ jsxs(Label, { style: { display: "block", marginBottom: "0.5rem", color: C.gray700, fontWeight: 500 }, children: [
|
|
@@ -4151,38 +4430,32 @@ function OnboardingModal({ open, onOpenChange, user, onComplete, onSkip }) {
|
|
|
4151
4430
|
type: "checkbox",
|
|
4152
4431
|
checked: confirmed,
|
|
4153
4432
|
onChange: (e) => setConfirmed(e.target.checked),
|
|
4154
|
-
style: {
|
|
4155
|
-
width: "1rem",
|
|
4156
|
-
height: "1rem",
|
|
4157
|
-
marginTop: "0.125rem",
|
|
4158
|
-
accentColor: C.primary,
|
|
4159
|
-
cursor: "pointer"
|
|
4160
|
-
}
|
|
4433
|
+
style: { width: "1rem", height: "1rem", marginTop: "0.125rem", accentColor: C.primary, cursor: "pointer" }
|
|
4161
4434
|
}
|
|
4162
4435
|
),
|
|
4163
4436
|
/* @__PURE__ */ jsx("span", { children: "Je confirme que ces informations sont exactes" })
|
|
4164
|
-
] }),
|
|
4165
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
4166
|
-
/* @__PURE__ */ jsx(
|
|
4167
|
-
Button,
|
|
4168
|
-
{
|
|
4169
|
-
onClick: handleSubmit,
|
|
4170
|
-
disabled: !canSubmit || submitting,
|
|
4171
|
-
style: { width: "100%", height: "2.75rem", opacity: canSubmit && !submitting ? 1 : 0.5 },
|
|
4172
|
-
children: submitting ? "Enregistrement..." : "Valider"
|
|
4173
|
-
}
|
|
4174
|
-
),
|
|
4175
|
-
/* @__PURE__ */ jsx(
|
|
4176
|
-
Button,
|
|
4177
|
-
{
|
|
4178
|
-
variant: "outline",
|
|
4179
|
-
onClick: onSkip,
|
|
4180
|
-
disabled: submitting,
|
|
4181
|
-
style: { width: "100%", height: "2.75rem" },
|
|
4182
|
-
children: "Passer pour l'instant"
|
|
4183
|
-
}
|
|
4184
|
-
)
|
|
4185
4437
|
] })
|
|
4438
|
+
] }) }),
|
|
4439
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
4440
|
+
/* @__PURE__ */ jsx(
|
|
4441
|
+
Button,
|
|
4442
|
+
{
|
|
4443
|
+
onClick: handleSubmit,
|
|
4444
|
+
disabled: !canSubmit || submitting,
|
|
4445
|
+
style: { width: "100%", height: "2.75rem", opacity: canSubmit && !submitting ? 1 : 0.5 },
|
|
4446
|
+
children: submitting ? "Enregistrement..." : "Valider"
|
|
4447
|
+
}
|
|
4448
|
+
),
|
|
4449
|
+
/* @__PURE__ */ jsx(
|
|
4450
|
+
Button,
|
|
4451
|
+
{
|
|
4452
|
+
variant: "outline",
|
|
4453
|
+
onClick: onSkip,
|
|
4454
|
+
disabled: submitting,
|
|
4455
|
+
style: { width: "100%", height: "2.75rem" },
|
|
4456
|
+
children: "Passer pour l'instant"
|
|
4457
|
+
}
|
|
4458
|
+
)
|
|
4186
4459
|
] })
|
|
4187
4460
|
] }) });
|
|
4188
4461
|
}
|
|
@@ -4433,6 +4706,7 @@ function NativeSSOPage({
|
|
|
4433
4706
|
redirectAfterLogout
|
|
4434
4707
|
}) {
|
|
4435
4708
|
const [modal, setModal] = useState("none");
|
|
4709
|
+
const [loginInitialPhone, setLoginInitialPhone] = useState();
|
|
4436
4710
|
const [showOnboarding, setShowOnboarding] = useState(false);
|
|
4437
4711
|
const [pendingSession, setPendingSession] = useState(null);
|
|
4438
4712
|
const [session, setSession] = useState(() => {
|
|
@@ -4474,13 +4748,23 @@ function NativeSSOPage({
|
|
|
4474
4748
|
}, []);
|
|
4475
4749
|
const openLogin = useCallback(() => setModal("login"), []);
|
|
4476
4750
|
const openSignup = useCallback(() => setModal("signup"), []);
|
|
4477
|
-
const closeModal = useCallback(() =>
|
|
4751
|
+
const closeModal = useCallback(() => {
|
|
4752
|
+
setModal("none");
|
|
4753
|
+
setLoginInitialPhone(void 0);
|
|
4754
|
+
}, []);
|
|
4478
4755
|
const switchToSignup = useCallback(() => {
|
|
4479
4756
|
setModal("none");
|
|
4757
|
+
setLoginInitialPhone(void 0);
|
|
4480
4758
|
setTimeout(() => setModal("signup"), 150);
|
|
4481
4759
|
}, []);
|
|
4482
4760
|
const switchToLogin = useCallback(() => {
|
|
4483
4761
|
setModal("none");
|
|
4762
|
+
setLoginInitialPhone(void 0);
|
|
4763
|
+
setTimeout(() => setModal("login"), 150);
|
|
4764
|
+
}, []);
|
|
4765
|
+
const switchToLoginWithPhone = useCallback((phone) => {
|
|
4766
|
+
setModal("none");
|
|
4767
|
+
setLoginInitialPhone(phone);
|
|
4484
4768
|
setTimeout(() => setModal("login"), 150);
|
|
4485
4769
|
}, []);
|
|
4486
4770
|
const handleLoginSuccess = useCallback((token, user) => {
|
|
@@ -4522,12 +4806,8 @@ function NativeSSOPage({
|
|
|
4522
4806
|
onLoginSuccess == null ? void 0 : onLoginSuccess(pendingSession.token, pendingSession.user);
|
|
4523
4807
|
if (redirectAfterLogin) window.location.href = redirectAfterLogin;
|
|
4524
4808
|
}, [pendingSession, onLoginSuccess, redirectAfterLogin]);
|
|
4525
|
-
const handleLogout = useCallback(() => {
|
|
4526
|
-
|
|
4527
|
-
localStorage.removeItem(STORAGE.TOKEN);
|
|
4528
|
-
localStorage.removeItem(STORAGE.USER);
|
|
4529
|
-
localStorage.removeItem(STORAGE.ACCOUNT_TYPE);
|
|
4530
|
-
localStorage.removeItem(STORAGE.ALIAS_REFERENCE);
|
|
4809
|
+
const handleLogout = useCallback(async () => {
|
|
4810
|
+
await logout();
|
|
4531
4811
|
setSession(null);
|
|
4532
4812
|
onLogout == null ? void 0 : onLogout();
|
|
4533
4813
|
if (redirectAfterLogout) window.location.href = redirectAfterLogout;
|
|
@@ -4631,7 +4911,8 @@ function NativeSSOPage({
|
|
|
4631
4911
|
onLoginSuccess: handleLoginSuccess,
|
|
4632
4912
|
saasApiUrl,
|
|
4633
4913
|
iamApiUrl,
|
|
4634
|
-
defaultAccountType: accountType
|
|
4914
|
+
defaultAccountType: accountType,
|
|
4915
|
+
initialPhone: loginInitialPhone
|
|
4635
4916
|
}
|
|
4636
4917
|
),
|
|
4637
4918
|
/* @__PURE__ */ jsx(
|
|
@@ -4642,6 +4923,7 @@ function NativeSSOPage({
|
|
|
4642
4923
|
if (!open) closeModal();
|
|
4643
4924
|
},
|
|
4644
4925
|
onSwitchToLogin: switchToLogin,
|
|
4926
|
+
onSwitchToLoginWithPhone: switchToLoginWithPhone,
|
|
4645
4927
|
onSignupSuccess: handleLoginSuccess,
|
|
4646
4928
|
saasApiUrl,
|
|
4647
4929
|
iamApiUrl,
|
|
@@ -4681,6 +4963,26 @@ function useNativeSSOConfig() {
|
|
|
4681
4963
|
}
|
|
4682
4964
|
return ctx;
|
|
4683
4965
|
}
|
|
4966
|
+
const useLogout = (options) => {
|
|
4967
|
+
const [loading, setLoading] = useState(false);
|
|
4968
|
+
const [error, setError] = useState(null);
|
|
4969
|
+
const handleLogout = useCallback(async () => {
|
|
4970
|
+
var _a, _b;
|
|
4971
|
+
setLoading(true);
|
|
4972
|
+
setError(null);
|
|
4973
|
+
try {
|
|
4974
|
+
await logout();
|
|
4975
|
+
(_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options);
|
|
4976
|
+
} catch (err) {
|
|
4977
|
+
const message = err instanceof Error ? err.message : "Erreur de déconnexion";
|
|
4978
|
+
setError(message);
|
|
4979
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, err instanceof Error ? err : new Error(message));
|
|
4980
|
+
} finally {
|
|
4981
|
+
setLoading(false);
|
|
4982
|
+
}
|
|
4983
|
+
}, [options]);
|
|
4984
|
+
return { logout: handleLogout, loading, error };
|
|
4985
|
+
};
|
|
4684
4986
|
function getCredentialsOrThrow(params) {
|
|
4685
4987
|
const app_key = params.app_key;
|
|
4686
4988
|
const secret_key = params.secret_key;
|
|
@@ -4851,10 +5153,12 @@ export {
|
|
|
4851
5153
|
getDefaultCountry,
|
|
4852
5154
|
getNativeAuthConfig,
|
|
4853
5155
|
iamAccountService,
|
|
5156
|
+
logout,
|
|
4854
5157
|
mobilePasswordService,
|
|
4855
5158
|
nativeAuthService,
|
|
4856
5159
|
searchCountries,
|
|
4857
5160
|
setNativeAuthConfig,
|
|
5161
|
+
useLogout,
|
|
4858
5162
|
useMobilePassword,
|
|
4859
5163
|
useMobileRegistration,
|
|
4860
5164
|
useNativeAuth,
|