mirror of
https://github.com/hanzo-apps/magazine.git
synced 2026-10-30 19:11:40 +00:00
Real Hanzo-stack starter: Vite + React 19 + @hanzo/gui + @hanzo/iam + @hanzo/base. Three editorial views (newsstand, issue contents, article read) built from @hanzo/gui primitives; black/white/one-hot-red magazine design in src/press.tsx. schema.sql provisions org-scoped issues + articles collections. tsc + vite build green.
3.8 KiB
3.8 KiB
issue-press — agent notes
Press: an issue-based digital magazine, and a Hanzo app template forked on
hanzo.app. Vite + React 19 + @hanzo/gui (UI) + @hanzo/iam (auth) +
@hanzo/base (data). Keep it minimal and REAL — every surface must build and
run, no fabricated UI.
The app
- Concept — editors curate numbered
issues; each has a cover story and departmentarticles. Readers open an issue and move between its pieces. - Three views (
src/views/):newsstand(issue covers grid + compose) →issue(cover story + department sections + file a piece) →article(feature read: two-column body + hanging pull-quote). The signed-outsigned-out.tsxis the cover. - Navigation is one
Routevalue inshell.tsx(src/nav.ts), no router. - Design lives in
src/press.tsx: the black/white/one-hot-red palette and the editorial primitives (Masthead,Kicker,Rule,Action,Chip,Field,Line,Body). Explicit hex colors, so the look is independent of the gui theme token.
One way, decomplected
- Providers (
src/providers.tsx) mount in the canonical Hanzo order:GuiProvider→IamProvider→BaseProvider.BaseProvidergets aBaseClientcarrying the IAM access token; it is rebuilt when the token changes (src/lib/base.tsbaseAs). That single seam makes everyuseQuery/useMutationorg-scoped to the signed-in user. - Env is one place (
src/env.ts), read fromimport.meta.env.VITE_*. The IAM client id isimport.meta.env.VITE_IAM_CLIENT_ID(fallbackhanzo-app). - UI is one system —
@hanzo/guiprimitives only (no second kit, no Tailwind). Every editorial component inpress.tsxis built fromXStack/YStack/Text/Input.
Gotchas (do not regress)
@hanzo/guiunder Vite needs three things invite.config.ts(it is the Tamagui line): (1) aliasreact-native→react-native-web, (2)defineprocess.env.TAMAGUI_TARGET/NODE_ENV/__DEV__, (3)dedupereact/react-dom/react-native-web. No Tamagui compiler, noone, no Expo.@hanzo/guiprops are Tamagui LONGHAND with this v5 config:alignItems/justifyContent/backgroundColor/padding/borderRadius/textAlign— NOT theitems/justify/bg/p/rounded/textshorthands. Shorthands pass at runtime but FAILtsc.- No
tagprop on stacks, andButtonrejectscolorunder this config (wrap a<Text color>child, or use the pressableActioninpress.tsx).fontSizeaccepts raw numbers on text components — that is what carries the oversized display type. Stacks/TextacceptonPress+hoverStyle. - PKCE storage is
localStorage(not sessionStorage) so the verifier/state survive the round-trip to hanzo.id. schema.sqlis the data contract. It is thedatabaseSchemaDDL the deploy translates into Base collections. Keep it in lockstep with the views (issues↔ newsstand,articles↔ issue/article)."order"is quoted because it is a reserved word.
Deploy contract (Hanzo Cloud)
- Static SPA:
npm run build→dist/, served at<slug>.hanzo.app. No server. - On publish,
schema.sql→provisionBaseFromDDLcreates the collections (org-scoped by@request.auth.org_id = org, IAM-native). Runtime read/write is browser →VITE_HANZO_BASE_URLwith the IAM token. - IAM redirect registration is the one external requirement: the IAM client
(
VITE_IAM_CLIENT_ID, defaulthanzo-app) must allow this origin's/auth/callback(ahttps://*.hanzo.app/auth/callbackwildcard on the shared client, or a per-apphanzo-<app>client).
Proven
tsc --noEmit clean · vite build → dist/. CI (.github/workflows/ci.yml)
runs npm ci && npm run typecheck && npm run build — build-verification only,
NEVER a container image (Hanzo Cloud owns deploys; do not build images locally).