diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 5bc0631..6ddc626 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,20 +1,22 @@ // App shell — loads the session, applies the entry-routing rule (SD-0001 §6.5), and renders -// the matching screen. SLICE-2 covers the unauthenticated doors (Landing/SignIn) and a -// signed-in placeholder; the real create-storefront/admin screens land in SLICE-3. +// the matching screen. The rule is exhaustive: no state lands nowhere (BUC-4). The verify +// response carries the same shape as /me, so onAuthed feeds the session directly. import { useEffect, useState } from "react"; -import { getMe, type VerifyResult } from "./api"; +import { getMe, type StorefrontResult, type VerifyResult } from "./api"; import { routeFor, type SessionState } from "./routing"; +import Admin from "./screens/Admin"; +import CreateStorefront from "./screens/CreateStorefront"; import Landing from "./screens/Landing"; import SignIn from "./screens/SignIn"; -import SignedIn from "./screens/SignedIn"; type Door = "signup" | "login"; +type Welcome = "new" | "back" | null; export default function App() { const [session, setSession] = useState(null); const [loading, setLoading] = useState(true); const [door, setDoor] = useState(null); - const [justCreated, setJustCreated] = useState(false); + const [welcome, setWelcome] = useState(null); async function reload() { setLoading(true); @@ -26,7 +28,15 @@ export default function App() { void reload(); }, []); - if (loading) return
Loading…
; + if (loading) { + return ( +
+
+

Loading…

+
+
+ ); + } const route = routeFor(session ?? { account: null, storefront: null }); @@ -35,13 +45,11 @@ export default function App() { return ( { - setDoor(null); - }} + onBack={() => setDoor(null)} onAuthed={(result: VerifyResult) => { - setJustCreated(result.created); + setWelcome(result.created ? "new" : "back"); setDoor(null); - void reload(); + setSession({ account: result.account, storefront: result.storefront }); }} /> ); @@ -49,16 +57,35 @@ export default function App() { return setDoor("signup")} onLogIn={() => setDoor("login")} />; } - // route is "create-storefront" or "admin" — both are SLICE-3 screens; SLICE-2 shows the - // signed-in placeholder so sign-out (PUC-9) is reachable. + const email = session!.account!.email; + + function signedOut() { + setWelcome(null); + setDoor(null); + setSession(null); + } + + if (route === "create-storefront") { + return ( + { + setWelcome(null); + setSession({ account: { email }, storefront: sf }); + }} + onAlreadyOwns={() => void reload()} + onSignedOut={signedOut} + /> + ); + } + return ( - { - setJustCreated(false); - void reload(); - }} + ); } diff --git a/frontend/src/screens/Admin.tsx b/frontend/src/screens/Admin.tsx new file mode 100644 index 0000000..aac9afb --- /dev/null +++ b/frontend/src/screens/Admin.tsx @@ -0,0 +1,59 @@ +// Admin shell (SD-0001 §5.4) — the storefront's stable home; honestly empty this release +// (PUC-8; PUC-9 sign-out). Renders from /me alone: storefront name + signed-in email. No +// zeroed metric tiles, no locked-feature teasers (OHM: Agency & Anti-Manipulation). +// Visuals per the ui/designs export (hf-admin). +import { logout } from "../api"; +import { AccountChip, Banner, Eyebrow, Screen, TopBar } from "../ui/kit"; + +interface Props { + storefrontName: string; + email: string; + welcome: "new" | "back" | null; + onSignedOut: () => void; +} + +export default function Admin({ storefrontName, email, welcome, onSignedOut }: Props) { + async function signOut() { + await logout(); + onSignedOut(); + } + + return ( + + + + + {storefrontName} + ecomm storefront + + + } + right={} + /> +
+
+ {welcome && ( +
+ + {welcome === "new" + ? "A new account was created for this email." + : "Signed in to your existing account."} + +
+ )} + + Your storefront +

{storefrontName}

+

+ There's nothing to manage yet — and that's a finished state, not a missing one. + Catalog, orders, and settings will appear here as ecomm grows. +

+
+
+
+ ); +} diff --git a/frontend/src/screens/SignedIn.tsx b/frontend/src/screens/SignedIn.tsx deleted file mode 100644 index af3b8bd..0000000 --- a/frontend/src/screens/SignedIn.tsx +++ /dev/null @@ -1,34 +0,0 @@ -// SLICE-2 placeholder for the signed-in surfaces (create-storefront, admin) that land in -// SLICE-3. It honestly states what's next and makes PUC-9 sign-out reachable now. No -// fabricated capability (INV-9). -import { logout } from "../api"; - -interface Props { - email: string; - created: boolean; - onSignedOut: () => void; -} - -export default function SignedIn({ email, created, onSignedOut }: Props) { - async function signOut() { - await logout(); - onSignedOut(); - } - - return ( -
-
- ecomm - {email} - -
-
-

{created ? "Welcome to ecomm" : "Welcome back"}

-

You're signed in as {email}.

-

Creating your storefront arrives in the next slice. Nothing else is needed yet.

-
-
- ); -}