Compare commits
2 Commits
619ec4c9b1
...
10141806dc
| Author | SHA1 | Date | |
|---|---|---|---|
| 10141806dc | |||
| 08ef85869f |
@@ -41,3 +41,4 @@ yarn-error.log*
|
|||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
.vercel
|
.vercel
|
||||||
|
.env*.local
|
||||||
|
|||||||
Generated
+780
-20
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
"lint": "eslint"
|
"lint": "eslint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@abe-kap/appshell-sdk": "^0.2.3",
|
"@abe-kap/appshell-sdk": "^0.2.4",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"lucide-react": "^1.21.0",
|
"lucide-react": "^1.21.0",
|
||||||
"next": "16.2.9",
|
"next": "16.2.9",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|||||||
|
|
||||||
export function LoginFlow() {
|
export function LoginFlow() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { login, loginWithOAuth, completeOAuthLogin } = useAuth();
|
const { login, loginWithOAuth, completeOAuthLogin, getUserEmail } = useAuth();
|
||||||
const { ready, sdk } = useAppShell();
|
const { ready, sdk } = useAppShell();
|
||||||
const [step, setStep] = useState<Step>("identify");
|
const [step, setStep] = useState<Step>("identify");
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
@@ -86,13 +86,16 @@ export function LoginFlow() {
|
|||||||
registered = !!st?.registered;
|
registered = !!st?.registered;
|
||||||
} catch { registered = false; }
|
} catch { registered = false; }
|
||||||
window.history.replaceState({}, "", "/portal/login");
|
window.history.replaceState({}, "", "/portal/login");
|
||||||
router.replace(registered ? "/dashboard" : "/portal/onboarding");
|
if (registered) { router.replace("/dashboard"); return; }
|
||||||
|
// Capture the verified email now (session is fresh) so onboarding prefills it.
|
||||||
|
try { const em = await getUserEmail(); if (em) sessionStorage.setItem("onboard_email", em); } catch { /* ignore */ }
|
||||||
|
router.replace("/portal/onboarding");
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setFlash("Google sign-in didn't complete. Please try again.");
|
setFlash("Google sign-in didn't complete. Please try again.");
|
||||||
replace("identify");
|
replace("identify");
|
||||||
});
|
});
|
||||||
}, [ready, completeOAuthLogin, router, sdk]);
|
}, [ready, completeOAuthLogin, router, sdk, getUserEmail]);
|
||||||
|
|
||||||
/* ---- auth resolution ---- */
|
/* ---- auth resolution ---- */
|
||||||
function afterAuth(factor: "password" | "passkey" | "otp" | "totp" | "push" | "social") {
|
function afterAuth(factor: "password" | "passkey" | "otp" | "totp" | "push" | "social") {
|
||||||
|
|||||||
@@ -54,9 +54,11 @@ export function RegisterFlow({ mode = "register" }: { mode?: "register" | "onboa
|
|||||||
const [emailVerified, setEmailVerified] = useState(false);
|
const [emailVerified, setEmailVerified] = useState(false);
|
||||||
const [phoneVerified, setPhoneVerified] = useState(false);
|
const [phoneVerified, setPhoneVerified] = useState(false);
|
||||||
|
|
||||||
// Onboarding: prefill the verified email from the Google session (the ACE omits it).
|
// Onboarding: prefill the verified email — from the session-storage hint the login
|
||||||
|
// page stashed at OAuth time, then confirmed via the live Supabase session.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!onboard) return;
|
if (!onboard) return;
|
||||||
|
try { const cached = sessionStorage.getItem("onboard_email"); if (cached) setEmail(cached); } catch { /* ignore */ }
|
||||||
getUserEmail().then((e) => { if (e) setEmail(e); }).catch(() => { /* ignore */ });
|
getUserEmail().then((e) => { if (e) setEmail(e); }).catch(() => { /* ignore */ });
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [onboard]);
|
}, [onboard]);
|
||||||
@@ -205,12 +207,13 @@ function StepAccount(p: {
|
|||||||
<h1>Complete your profile</h1>
|
<h1>Complete your profile</h1>
|
||||||
<p className="sub">Tell us a bit about you to set up your account.</p>
|
<p className="sub">Tell us a bit about you to set up your account.</p>
|
||||||
|
|
||||||
<div style={{ marginTop: 16 }}>
|
<div className="field" style={{ marginTop: 16 }}>
|
||||||
{p.sso ? (
|
<label className="label">Email address</label>
|
||||||
<div className="conn-banner conn-green"><Icon name="check" size={16} /> Connected with {cap(p.sso.provider)} · {p.sso.email}</div>
|
<div className="input-wrap">
|
||||||
) : (
|
<span className="input-ico"><Icon name="mail" size={17} /></span>
|
||||||
<div className="conn-banner conn-blue"><Icon name="mail" size={16} /> {p.onboard ? "Signed in as" : "Creating account for"} {p.email}</div>
|
<input className="input" type="email" value={p.email} disabled readOnly aria-label="Email address" />
|
||||||
)}
|
</div>
|
||||||
|
<span className="faint" style={{ fontSize: 12 }}>{p.onboard ? "Verified with Google — this can't be changed." : "The email you're registering with."}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="row gap-3" style={{ marginTop: 18, alignItems: "center" }}>
|
<div className="row gap-3" style={{ marginTop: 18, alignItems: "center" }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user