@ollaid/native-sso 2.7.7 → 2.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/LoginModal.d.ts +1 -1
- package/dist/components/NativeSSOPage.d.ts +1 -1
- package/dist/components/OnboardingModal.d.ts +7 -2
- package/dist/components/SignupModal.d.ts +1 -1
- package/dist/index.cjs +199 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +199 -70
- package/dist/index.js.map +1 -1
- package/dist/services/profile.d.ts +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* NativeSSOPage — Page autonome complète pour @ollaid/native-sso
|
|
3
3
|
* Design aligné sur le parcours Native SSO (fond primary, card blanche, ShieldCheck branding)
|
|
4
4
|
*
|
|
5
|
-
* @version 2.7.
|
|
5
|
+
* @version 2.7.8
|
|
6
6
|
*/
|
|
7
7
|
import type { UserInfos } from '../types/native';
|
|
8
8
|
import type { NativeStorageAdapter } from '../services/api';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Mode `missing` : champs absents uniquement
|
|
4
4
|
* Mode `edit` : édition complète du profil depuis le SaaS
|
|
5
5
|
*
|
|
6
|
-
* @version 2.7.
|
|
6
|
+
* @version 2.7.8
|
|
7
7
|
*/
|
|
8
8
|
import type { NativeUser, UserInfos } from '../types/native';
|
|
9
9
|
export interface OnboardingModalProps {
|
|
@@ -13,6 +13,11 @@ export interface OnboardingModalProps {
|
|
|
13
13
|
user: NativeUser;
|
|
14
14
|
variant?: 'missing' | 'edit';
|
|
15
15
|
profileHydrating?: boolean;
|
|
16
|
+
hydrateProfile?: boolean;
|
|
17
|
+
onUserInfosSync?: (payload: {
|
|
18
|
+
source: 'hydration' | 'update' | 'avatar' | 'contact';
|
|
19
|
+
user_infos: UserInfos;
|
|
20
|
+
}) => void;
|
|
16
21
|
onComplete: (data: {
|
|
17
22
|
name?: string;
|
|
18
23
|
image_url?: string;
|
|
@@ -26,5 +31,5 @@ export interface OnboardingModalProps {
|
|
|
26
31
|
}) => void;
|
|
27
32
|
onSkip: () => void;
|
|
28
33
|
}
|
|
29
|
-
export declare function OnboardingModal({ open, onOpenChange, onDismiss, user, variant, profileHydrating, onComplete, onSkip }: OnboardingModalProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export declare function OnboardingModal({ open, onOpenChange, onDismiss, user, variant, profileHydrating, hydrateProfile, onUserInfosSync, onComplete, onSkip, }: OnboardingModalProps): import("react/jsx-runtime").JSX.Element;
|
|
30
35
|
export default OnboardingModal;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Signup Modal for @ollaid/native-sso — Design aligned with web SSO
|
|
3
3
|
* Full signup flow: intro → account-type → info → OTP → password → confirm → success
|
|
4
4
|
*
|
|
5
|
-
* @version 2.7.
|
|
5
|
+
* @version 2.7.8
|
|
6
6
|
*/
|
|
7
7
|
import type { UserInfos } from '../types/native';
|
|
8
8
|
export interface SignupModalProps {
|
package/dist/index.cjs
CHANGED
|
@@ -12146,26 +12146,41 @@ const C = {
|
|
|
12146
12146
|
gray700: "#374151",
|
|
12147
12147
|
white: "#ffffff"
|
|
12148
12148
|
};
|
|
12149
|
-
function OnboardingModal({
|
|
12149
|
+
function OnboardingModal({
|
|
12150
|
+
open,
|
|
12151
|
+
onOpenChange,
|
|
12152
|
+
onDismiss,
|
|
12153
|
+
user,
|
|
12154
|
+
variant = "missing",
|
|
12155
|
+
profileHydrating = false,
|
|
12156
|
+
hydrateProfile = true,
|
|
12157
|
+
onUserInfosSync,
|
|
12158
|
+
onComplete,
|
|
12159
|
+
onSkip
|
|
12160
|
+
}) {
|
|
12150
12161
|
var _a;
|
|
12151
12162
|
const isEditMode = variant === "edit";
|
|
12152
|
-
const
|
|
12153
|
-
const
|
|
12163
|
+
const [hydratedUser, setHydratedUser] = react.useState(null);
|
|
12164
|
+
const [internalHydrating, setInternalHydrating] = react.useState(false);
|
|
12165
|
+
const hydrationKeyRef = react.useRef(null);
|
|
12166
|
+
const profileUser = hydratedUser ?? user;
|
|
12167
|
+
const hasCurrentPhone = Boolean(profileUser.phone);
|
|
12168
|
+
const hasCurrentEmail = Boolean(profileUser.email);
|
|
12154
12169
|
const directPhoneEdit = !isEditMode || !hasCurrentPhone;
|
|
12155
12170
|
const directEmailEdit = !isEditMode || !hasCurrentEmail;
|
|
12156
|
-
!isEditMode ? !((_a =
|
|
12157
|
-
const [name, setName] = react.useState(
|
|
12171
|
+
!isEditMode ? !((_a = profileUser.name) == null ? void 0 : _a.trim()) : true;
|
|
12172
|
+
const [name, setName] = react.useState(profileUser.name || "");
|
|
12158
12173
|
const [photoPreview, setPhotoPreview] = react.useState("");
|
|
12159
12174
|
const [avatarPickerOpen, setAvatarPickerOpen] = react.useState(false);
|
|
12160
12175
|
const [pendingAvatarSrc, setPendingAvatarSrc] = react.useState(null);
|
|
12161
12176
|
const [avatarUploading, setAvatarUploading] = react.useState(false);
|
|
12162
12177
|
const avatarFileInputRef = react.useRef(null);
|
|
12163
|
-
const [ccphone, setCcphone] = react.useState(
|
|
12164
|
-
const [phone, setPhone] = react.useState(
|
|
12165
|
-
const [email, setEmail] = react.useState(
|
|
12166
|
-
const [address, setAddress] = react.useState(
|
|
12167
|
-
const [town, setTown] = react.useState(
|
|
12168
|
-
const [country, setCountry] = react.useState(
|
|
12178
|
+
const [ccphone, setCcphone] = react.useState(profileUser.ccphone || "+221");
|
|
12179
|
+
const [phone, setPhone] = react.useState(profileUser.phone || "");
|
|
12180
|
+
const [email, setEmail] = react.useState(profileUser.email || "");
|
|
12181
|
+
const [address, setAddress] = react.useState(profileUser.address || "");
|
|
12182
|
+
const [town, setTown] = react.useState(profileUser.town || "");
|
|
12183
|
+
const [country, setCountry] = react.useState(profileUser.country || DEFAULT_COUNTRY_CODE);
|
|
12169
12184
|
const [submitting, setSubmitting] = react.useState(false);
|
|
12170
12185
|
const [fileError, setFileError] = react.useState("");
|
|
12171
12186
|
const [contactFlow, setContactFlow] = react.useState(null);
|
|
@@ -12175,34 +12190,54 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12175
12190
|
const [confirmAction, setConfirmAction] = react.useState(null);
|
|
12176
12191
|
const [nowTick, setNowTick] = react.useState(Date.now());
|
|
12177
12192
|
const userHydrationKey = [
|
|
12178
|
-
|
|
12179
|
-
|
|
12180
|
-
|
|
12181
|
-
|
|
12182
|
-
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12193
|
+
profileUser.reference || "",
|
|
12194
|
+
profileUser.name || "",
|
|
12195
|
+
profileUser.email || "",
|
|
12196
|
+
profileUser.ccphone || "",
|
|
12197
|
+
profileUser.phone || "",
|
|
12198
|
+
profileUser.address || "",
|
|
12199
|
+
profileUser.town || "",
|
|
12200
|
+
profileUser.country || "",
|
|
12201
|
+
profileUser.image_url || "",
|
|
12202
|
+
profileUser.auth_2fa ? "1" : "0"
|
|
12188
12203
|
].join("|");
|
|
12189
|
-
const currentDialCode = (
|
|
12204
|
+
const currentDialCode = (profileUser.ccphone || ccphone || "+221").trim();
|
|
12190
12205
|
const baseSmsAllowed = currentDialCode === "+221";
|
|
12191
12206
|
const contactSmsAllowed = contactFlow ? contactFlow.kind === "phone" ? contactFlow.newCcphone.trim() === "+221" : baseSmsAllowed : baseSmsAllowed;
|
|
12192
12207
|
const lockModalClose = profileHydrating || submitting || submitState === "success" || avatarUploading || Boolean(contactFlow == null ? void 0 : contactFlow.loading);
|
|
12208
|
+
const syncFormFromUser = react.useCallback((nextUser) => {
|
|
12209
|
+
setName(nextUser.name || "");
|
|
12210
|
+
setPhotoPreview(isEditMode ? nextUser.image_url || "" : "");
|
|
12211
|
+
setCcphone(nextUser.ccphone || "+221");
|
|
12212
|
+
setPhone(nextUser.phone || "");
|
|
12213
|
+
setEmail(nextUser.email || "");
|
|
12214
|
+
setAddress(nextUser.address || "");
|
|
12215
|
+
setTown(nextUser.town || "");
|
|
12216
|
+
setCountry(nextUser.country || DEFAULT_COUNTRY_CODE);
|
|
12217
|
+
}, [isEditMode]);
|
|
12218
|
+
const toUserInfos = react.useCallback((nextUser) => ({
|
|
12219
|
+
reference: nextUser.reference,
|
|
12220
|
+
name: nextUser.name,
|
|
12221
|
+
email: nextUser.email || null,
|
|
12222
|
+
ccphone: nextUser.ccphone,
|
|
12223
|
+
phone: nextUser.phone,
|
|
12224
|
+
address: nextUser.address,
|
|
12225
|
+
town: nextUser.town,
|
|
12226
|
+
country: nextUser.country,
|
|
12227
|
+
image_url: nextUser.image_url,
|
|
12228
|
+
auth_2fa: nextUser.auth_2fa,
|
|
12229
|
+
alias_reference: nextUser.alias_reference,
|
|
12230
|
+
iam_reference: nextUser.iam_reference
|
|
12231
|
+
}), []);
|
|
12193
12232
|
react.useEffect(() => {
|
|
12194
|
-
if (!open)
|
|
12195
|
-
|
|
12196
|
-
|
|
12233
|
+
if (!open) {
|
|
12234
|
+
setHydratedUser(null);
|
|
12235
|
+
hydrationKeyRef.current = null;
|
|
12236
|
+
return;
|
|
12237
|
+
}
|
|
12197
12238
|
setPendingAvatarSrc(null);
|
|
12198
12239
|
setAvatarPickerOpen(false);
|
|
12199
12240
|
setAvatarUploading(false);
|
|
12200
|
-
setCcphone(user.ccphone || "+221");
|
|
12201
|
-
setPhone(user.phone || "");
|
|
12202
|
-
setEmail(user.email || "");
|
|
12203
|
-
setAddress(user.address || "");
|
|
12204
|
-
setTown(user.town || "");
|
|
12205
|
-
setCountry(user.country || DEFAULT_COUNTRY_CODE);
|
|
12206
12241
|
setSubmitting(false);
|
|
12207
12242
|
setFileError("");
|
|
12208
12243
|
setContactFlow(null);
|
|
@@ -12210,7 +12245,54 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12210
12245
|
setSubmitMessage("");
|
|
12211
12246
|
setSubmitError("");
|
|
12212
12247
|
setConfirmAction(null);
|
|
12213
|
-
|
|
12248
|
+
syncFormFromUser(profileUser);
|
|
12249
|
+
}, [open, userHydrationKey, profileUser, syncFormFromUser]);
|
|
12250
|
+
react.useEffect(() => {
|
|
12251
|
+
if (!open || !hydratedUser) return;
|
|
12252
|
+
if (contactFlow || submitting || submitState !== "idle") return;
|
|
12253
|
+
syncFormFromUser(hydratedUser);
|
|
12254
|
+
}, [open, hydratedUser, contactFlow, submitting, submitState, syncFormFromUser]);
|
|
12255
|
+
react.useEffect(() => {
|
|
12256
|
+
if (!open || !hydrateProfile || profileHydrating || internalHydrating || hydratedUser) return;
|
|
12257
|
+
const key = userHydrationKey;
|
|
12258
|
+
if (hydrationKeyRef.current === key) return;
|
|
12259
|
+
hydrationKeyRef.current = key;
|
|
12260
|
+
let cancelled = false;
|
|
12261
|
+
setInternalHydrating(true);
|
|
12262
|
+
(async () => {
|
|
12263
|
+
try {
|
|
12264
|
+
const response = await profileService.getProfile();
|
|
12265
|
+
const payload = response.user_infos || response.user || {};
|
|
12266
|
+
const nextUser = {
|
|
12267
|
+
...profileUser,
|
|
12268
|
+
name: payload.name || profileUser.name,
|
|
12269
|
+
email: payload.email ?? profileUser.email ?? null,
|
|
12270
|
+
ccphone: payload.ccphone || profileUser.ccphone,
|
|
12271
|
+
phone: payload.phone || profileUser.phone,
|
|
12272
|
+
address: payload.address || profileUser.address,
|
|
12273
|
+
town: payload.town || profileUser.town,
|
|
12274
|
+
country: payload.country || profileUser.country,
|
|
12275
|
+
image_url: payload.image_url || profileUser.image_url,
|
|
12276
|
+
auth_2fa: payload.auth_2fa ?? profileUser.auth_2fa,
|
|
12277
|
+
alias_reference: payload.alias_reference || profileUser.alias_reference,
|
|
12278
|
+
iam_reference: payload.iam_reference || profileUser.iam_reference
|
|
12279
|
+
};
|
|
12280
|
+
if (cancelled) return;
|
|
12281
|
+
setHydratedUser(nextUser);
|
|
12282
|
+
syncFormFromUser(nextUser);
|
|
12283
|
+
onUserInfosSync == null ? void 0 : onUserInfosSync({ source: "hydration", user_infos: toUserInfos(nextUser) });
|
|
12284
|
+
} catch {
|
|
12285
|
+
if (cancelled) return;
|
|
12286
|
+
} finally {
|
|
12287
|
+
if (!cancelled) {
|
|
12288
|
+
setInternalHydrating(false);
|
|
12289
|
+
}
|
|
12290
|
+
}
|
|
12291
|
+
})();
|
|
12292
|
+
return () => {
|
|
12293
|
+
cancelled = true;
|
|
12294
|
+
};
|
|
12295
|
+
}, [open, hydrateProfile, profileHydrating, internalHydrating, userHydrationKey, profileUser, onUserInfosSync, syncFormFromUser, toUserInfos]);
|
|
12214
12296
|
react.useEffect(() => {
|
|
12215
12297
|
if (!(contactFlow == null ? void 0 : contactFlow.resendAvailableAt)) return;
|
|
12216
12298
|
const timer = window.setInterval(() => {
|
|
@@ -12246,9 +12328,9 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12246
12328
|
setSubmitError("");
|
|
12247
12329
|
const data = {
|
|
12248
12330
|
name: name.trim(),
|
|
12249
|
-
ccphone: directPhoneEdit ? ccphone :
|
|
12250
|
-
phone: directPhoneEdit ? phone :
|
|
12251
|
-
email: directEmailEdit ? email.trim() :
|
|
12331
|
+
ccphone: directPhoneEdit ? ccphone : profileUser.ccphone || void 0,
|
|
12332
|
+
phone: directPhoneEdit ? phone : profileUser.phone || void 0,
|
|
12333
|
+
email: directEmailEdit ? email.trim() : profileUser.email || void 0,
|
|
12252
12334
|
...address.trim() ? { address: address.trim() } : {},
|
|
12253
12335
|
...town.trim() ? { town: town.trim() } : {},
|
|
12254
12336
|
...country ? { country } : {}
|
|
@@ -12257,19 +12339,21 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12257
12339
|
const response = await profileService.updateProfile(data);
|
|
12258
12340
|
const payload = response.user_infos || response.user || {};
|
|
12259
12341
|
const updatedUser = {
|
|
12260
|
-
...
|
|
12261
|
-
name: payload.name || data.name ||
|
|
12262
|
-
email: payload.email ?? data.email ??
|
|
12263
|
-
ccphone: payload.ccphone || data.ccphone ||
|
|
12264
|
-
phone: payload.phone || data.phone ||
|
|
12265
|
-
address: payload.address || data.address ||
|
|
12266
|
-
town: payload.town || data.town ||
|
|
12267
|
-
country: payload.country || data.country ||
|
|
12268
|
-
image_url: payload.image_url ||
|
|
12269
|
-
auth_2fa: payload.auth_2fa ??
|
|
12270
|
-
alias_reference: payload.alias_reference ||
|
|
12271
|
-
iam_reference: payload.iam_reference ||
|
|
12342
|
+
...profileUser,
|
|
12343
|
+
name: payload.name || data.name || profileUser.name,
|
|
12344
|
+
email: payload.email ?? data.email ?? profileUser.email,
|
|
12345
|
+
ccphone: payload.ccphone || data.ccphone || profileUser.ccphone,
|
|
12346
|
+
phone: payload.phone || data.phone || profileUser.phone,
|
|
12347
|
+
address: payload.address || data.address || profileUser.address,
|
|
12348
|
+
town: payload.town || data.town || profileUser.town,
|
|
12349
|
+
country: payload.country || data.country || profileUser.country,
|
|
12350
|
+
image_url: payload.image_url || profileUser.image_url,
|
|
12351
|
+
auth_2fa: payload.auth_2fa ?? profileUser.auth_2fa,
|
|
12352
|
+
alias_reference: payload.alias_reference || profileUser.alias_reference,
|
|
12353
|
+
iam_reference: payload.iam_reference || profileUser.iam_reference
|
|
12272
12354
|
};
|
|
12355
|
+
setHydratedUser(updatedUser);
|
|
12356
|
+
onUserInfosSync == null ? void 0 : onUserInfosSync({ source: "update", user_infos: toUserInfos(updatedUser) });
|
|
12273
12357
|
onComplete({
|
|
12274
12358
|
name: updatedUser.name,
|
|
12275
12359
|
image_url: updatedUser.image_url,
|
|
@@ -12300,7 +12384,7 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12300
12384
|
setSubmitState("error");
|
|
12301
12385
|
setSubmitError(error instanceof Error ? error.message : "Erreur lors de l’enregistrement");
|
|
12302
12386
|
}
|
|
12303
|
-
}, [canSubmit,
|
|
12387
|
+
}, [canSubmit, profileUser, name, directPhoneEdit, directEmailEdit, ccphone, phone, email, address, town, country, onComplete, onUserInfosSync, toUserInfos, markSuccess]);
|
|
12304
12388
|
const openAvatarPicker = react.useCallback(() => {
|
|
12305
12389
|
var _a2;
|
|
12306
12390
|
(_a2 = avatarFileInputRef.current) == null ? void 0 : _a2.click();
|
|
@@ -12330,6 +12414,23 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12330
12414
|
setPhotoPreview(URL.createObjectURL(blob));
|
|
12331
12415
|
}
|
|
12332
12416
|
if (Object.keys(payload).length > 0) {
|
|
12417
|
+
const updatedUser = {
|
|
12418
|
+
...profileUser,
|
|
12419
|
+
reference: payload.reference || profileUser.reference,
|
|
12420
|
+
name: payload.name || profileUser.name,
|
|
12421
|
+
email: payload.email ?? profileUser.email ?? null,
|
|
12422
|
+
ccphone: payload.ccphone || profileUser.ccphone,
|
|
12423
|
+
phone: payload.phone || profileUser.phone,
|
|
12424
|
+
address: payload.address || profileUser.address,
|
|
12425
|
+
town: payload.town || profileUser.town,
|
|
12426
|
+
country: payload.country || profileUser.country,
|
|
12427
|
+
image_url: nextImage || profileUser.image_url,
|
|
12428
|
+
auth_2fa: payload.auth_2fa ?? profileUser.auth_2fa,
|
|
12429
|
+
alias_reference: payload.alias_reference || profileUser.alias_reference,
|
|
12430
|
+
iam_reference: payload.iam_reference || profileUser.iam_reference
|
|
12431
|
+
};
|
|
12432
|
+
setHydratedUser(updatedUser);
|
|
12433
|
+
onUserInfosSync == null ? void 0 : onUserInfosSync({ source: "avatar", user_infos: toUserInfos(updatedUser) });
|
|
12333
12434
|
onComplete({
|
|
12334
12435
|
name: payload.name,
|
|
12335
12436
|
image_url: nextImage || void 0,
|
|
@@ -12340,18 +12441,18 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12340
12441
|
town: payload.town || void 0,
|
|
12341
12442
|
country: payload.country || void 0,
|
|
12342
12443
|
user_infos: {
|
|
12343
|
-
reference: payload.reference ||
|
|
12344
|
-
name: payload.name ||
|
|
12345
|
-
email: payload.email ??
|
|
12346
|
-
ccphone: payload.ccphone ||
|
|
12347
|
-
phone: payload.phone ||
|
|
12348
|
-
address: payload.address ||
|
|
12349
|
-
town: payload.town ||
|
|
12350
|
-
country: payload.country ||
|
|
12351
|
-
image_url: nextImage ||
|
|
12352
|
-
auth_2fa: payload.auth_2fa ??
|
|
12353
|
-
alias_reference: payload.alias_reference ||
|
|
12354
|
-
iam_reference: payload.iam_reference ||
|
|
12444
|
+
reference: payload.reference || profileUser.reference,
|
|
12445
|
+
name: payload.name || profileUser.name,
|
|
12446
|
+
email: payload.email ?? profileUser.email ?? null,
|
|
12447
|
+
ccphone: payload.ccphone || profileUser.ccphone,
|
|
12448
|
+
phone: payload.phone || profileUser.phone,
|
|
12449
|
+
address: payload.address || profileUser.address,
|
|
12450
|
+
town: payload.town || profileUser.town,
|
|
12451
|
+
country: payload.country || profileUser.country,
|
|
12452
|
+
image_url: nextImage || profileUser.image_url,
|
|
12453
|
+
auth_2fa: payload.auth_2fa ?? profileUser.auth_2fa,
|
|
12454
|
+
alias_reference: payload.alias_reference || profileUser.alias_reference,
|
|
12455
|
+
iam_reference: payload.iam_reference || profileUser.iam_reference
|
|
12355
12456
|
}
|
|
12356
12457
|
});
|
|
12357
12458
|
}
|
|
@@ -12361,7 +12462,7 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12361
12462
|
} finally {
|
|
12362
12463
|
setAvatarUploading(false);
|
|
12363
12464
|
}
|
|
12364
|
-
}, [onComplete, markSuccess,
|
|
12465
|
+
}, [onComplete, onUserInfosSync, toUserInfos, markSuccess, profileUser.reference, profileUser.name, profileUser.email, profileUser.ccphone, profileUser.phone, profileUser.address, profileUser.town, profileUser.country, profileUser.image_url, profileUser.auth_2fa, profileUser.alias_reference, profileUser.iam_reference]);
|
|
12365
12466
|
const openContactFlow = react.useCallback((kind) => {
|
|
12366
12467
|
setContactFlow({
|
|
12367
12468
|
kind,
|
|
@@ -12369,7 +12470,7 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12369
12470
|
requestId: null,
|
|
12370
12471
|
method: kind === "email" ? "email" : currentDialCode === "+221" ? "phone" : "email",
|
|
12371
12472
|
newEmail: "",
|
|
12372
|
-
newCcphone: kind === "phone" ?
|
|
12473
|
+
newCcphone: kind === "phone" ? profileUser.ccphone || "+221" : "+221",
|
|
12373
12474
|
newPhone: "",
|
|
12374
12475
|
oldOtp: "",
|
|
12375
12476
|
newOtp: "",
|
|
@@ -12377,18 +12478,18 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12377
12478
|
error: "",
|
|
12378
12479
|
resendAvailableAt: null
|
|
12379
12480
|
});
|
|
12380
|
-
}, [currentDialCode,
|
|
12481
|
+
}, [currentDialCode, profileUser.ccphone]);
|
|
12381
12482
|
const closeContactFlow = react.useCallback(() => {
|
|
12382
12483
|
setContactFlow(null);
|
|
12383
12484
|
}, []);
|
|
12384
12485
|
const updateFlow = react.useCallback((patch) => {
|
|
12385
12486
|
setContactFlow((prev) => prev ? { ...prev, ...patch } : prev);
|
|
12386
12487
|
}, []);
|
|
12387
|
-
const currentPhoneDialDisplay =
|
|
12388
|
-
const currentPhoneNumberDisplay =
|
|
12389
|
-
const currentEmailLabel =
|
|
12488
|
+
const currentPhoneDialDisplay = profileUser.ccphone || ccphone || "+221";
|
|
12489
|
+
const currentPhoneNumberDisplay = profileUser.phone || phone || "";
|
|
12490
|
+
const currentEmailLabel = profileUser.email || email || "";
|
|
12390
12491
|
const currentPhoneDialCode = currentPhoneDialDisplay.trim() || "+221";
|
|
12391
|
-
const currentPhoneDigits = (
|
|
12492
|
+
const currentPhoneDigits = (profileUser.phone || phone || "").replace(/\D/g, "");
|
|
12392
12493
|
const formatPhoneDisplay = react.useCallback((dial, digits) => {
|
|
12393
12494
|
const cleanDial = (dial || "+221").trim() || "+221";
|
|
12394
12495
|
const cleanDigits = (digits || "").replace(/\D/g, "");
|
|
@@ -12444,13 +12545,15 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12444
12545
|
const response = await profileChangeService.verifyNewOTP(contactFlow.requestId, contactFlow.newOtp);
|
|
12445
12546
|
if (!response.success) throw new Error(response.message || "Code OTP incorrect");
|
|
12446
12547
|
const updatedUser = {
|
|
12447
|
-
...
|
|
12548
|
+
...profileUser,
|
|
12448
12549
|
...contactFlow.kind === "email" ? { email: contactFlow.newEmail.trim() } : { ccphone: contactFlow.newCcphone, phone: contactFlow.newPhone.trim() }
|
|
12449
12550
|
};
|
|
12450
12551
|
if (response.user && typeof response.user === "object") {
|
|
12451
12552
|
Object.assign(updatedUser, response.user);
|
|
12452
12553
|
}
|
|
12554
|
+
setHydratedUser(updatedUser);
|
|
12453
12555
|
setContactFlow(null);
|
|
12556
|
+
onUserInfosSync == null ? void 0 : onUserInfosSync({ source: "contact", user_infos: toUserInfos(updatedUser) });
|
|
12454
12557
|
onComplete({
|
|
12455
12558
|
name: updatedUser.name,
|
|
12456
12559
|
image_url: updatedUser.image_url,
|
|
@@ -12476,7 +12579,7 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12476
12579
|
} catch (error) {
|
|
12477
12580
|
updateFlow({ loading: false, error: error instanceof Error ? error.message : "Code OTP incorrect" });
|
|
12478
12581
|
}
|
|
12479
|
-
}, [contactFlow, onComplete, updateFlow,
|
|
12582
|
+
}, [contactFlow, onComplete, onUserInfosSync, updateFlow, profileUser, toUserInfos, markSuccess]);
|
|
12480
12583
|
const resendFlowOtp = react.useCallback(async () => {
|
|
12481
12584
|
if (!(contactFlow == null ? void 0 : contactFlow.requestId) || contactFlow.loading) return;
|
|
12482
12585
|
updateFlow({ loading: true, error: "" });
|
|
@@ -12629,7 +12732,7 @@ function OnboardingModal({ open, onOpenChange, onDismiss, user, variant = "missi
|
|
|
12629
12732
|
cursor: avatarUploading ? "not-allowed" : "pointer"
|
|
12630
12733
|
},
|
|
12631
12734
|
children: [
|
|
12632
|
-
photoPreview ||
|
|
12735
|
+
photoPreview || profileUser.image_url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: photoPreview || profileUser.image_url, alt: "Photo de profil", style: { width: "100%", height: "100%", objectFit: "cover" } }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", color: C.gray500 }, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
12633
12736
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "8", r: "4" }),
|
|
12634
12737
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.5 21a8.38 8.38 0 0 1 13 0" })
|
|
12635
12738
|
] }) }),
|
|
@@ -13806,6 +13909,28 @@ function NativeSSOPage({
|
|
|
13806
13909
|
}
|
|
13807
13910
|
void refreshSessionProfile(true);
|
|
13808
13911
|
}, [pendingSession, debugOnboardingState, onOnboardingComplete, persistSessionUser, refreshSessionProfile]);
|
|
13912
|
+
const handleOnboardingUserInfosSync = react.useCallback((payload) => {
|
|
13913
|
+
const activeSession = debugOnboardingState || pendingSession;
|
|
13914
|
+
if (!activeSession) return;
|
|
13915
|
+
const syncedUser = {
|
|
13916
|
+
...activeSession.sourceUser,
|
|
13917
|
+
...payload.user_infos
|
|
13918
|
+
};
|
|
13919
|
+
persistSessionUser(activeSession.token, syncedUser);
|
|
13920
|
+
if (debugOnboardingState) {
|
|
13921
|
+
setDebugOnboardingState((prev) => prev ? {
|
|
13922
|
+
...prev,
|
|
13923
|
+
user: syncedUser,
|
|
13924
|
+
sourceUser: syncedUser
|
|
13925
|
+
} : prev);
|
|
13926
|
+
} else {
|
|
13927
|
+
setPendingSession((prev) => prev ? {
|
|
13928
|
+
...prev,
|
|
13929
|
+
user: syncedUser,
|
|
13930
|
+
sourceUser: syncedUser
|
|
13931
|
+
} : prev);
|
|
13932
|
+
}
|
|
13933
|
+
}, [debugOnboardingState, pendingSession, persistSessionUser]);
|
|
13809
13934
|
const handleOnboardingSkip = react.useCallback(() => {
|
|
13810
13935
|
const activeSession = debugOnboardingState || pendingSession;
|
|
13811
13936
|
if (!activeSession) return;
|
|
@@ -14013,6 +14138,8 @@ function NativeSSOPage({
|
|
|
14013
14138
|
user: (debugOnboardingState || pendingSession).user,
|
|
14014
14139
|
variant: debugOnboardingState ? "edit" : "missing",
|
|
14015
14140
|
profileHydrating,
|
|
14141
|
+
hydrateProfile: false,
|
|
14142
|
+
onUserInfosSync: handleOnboardingUserInfosSync,
|
|
14016
14143
|
onComplete: handleOnboardingComplete,
|
|
14017
14144
|
onSkip: handleOnboardingSkip
|
|
14018
14145
|
}
|
|
@@ -14092,6 +14219,8 @@ function NativeSSOPage({
|
|
|
14092
14219
|
user: (debugOnboardingState || pendingSession).user,
|
|
14093
14220
|
variant: debugOnboardingState ? "edit" : "missing",
|
|
14094
14221
|
profileHydrating,
|
|
14222
|
+
hydrateProfile: false,
|
|
14223
|
+
onUserInfosSync: handleOnboardingUserInfosSync,
|
|
14095
14224
|
onComplete: handleOnboardingComplete,
|
|
14096
14225
|
onSkip: handleOnboardingSkip
|
|
14097
14226
|
}
|