Files
oysqn.app/docs/summaries/handoff-2026-04-12-splash-and-login.md
Patrick Toal c789454810 docs: Update architecture for supabase
test: Add tests for auth workflow
2026-04-12 10:14:44 -04:00

4.6 KiB

Session Handoff: Splash Page & Magic Link Login

Date: 2026-04-12 Session Duration: ~30 minutes Session Focus: Implement unauthenticated splash page with logo and login button; implement magic link login page Context Usage at Handoff: Low

What Was Accomplished

  1. Splash page implementedapp/pages/index.vue — unauthenticated users see centered logo + "Log In" button; authenticated users see home content with header/menu
  2. Login page implementedapp/pages/login.vue — email input, sends magic link via auth.sendMagicLink(), shows confirmation state with mail icon after send
  3. Auth middleware updatedapp/middleware/auth.ts — added / to public routes; unauthenticated users redirected to / (not /login)
  4. Supabase redirect config updatednuxt.config.tslogin redirect changed from /login to /; / added to exclude list

Exact State of Work in Progress

  • Splash + login pages coded but not yet tested end-to-end against local Supabase
  • auth/callback.vue still a skeleton — magic link redirect will land there; not yet implemented

Decisions Made This Session

  • USE / as the unauthenticated landing route INSTEAD OF /login BECAUSE the splash/logo page IS the unauthenticated entry point; /login is a detail page reached from it — STATUS: confirmed
  • MAGIC LINK ONLY on login page (not OTP) BECAUSE user stated "sends a magic link" — STATUS: confirmed; OTP flow (sendOtp + verifyOtp) exists in auth store but unused by login page

Key Numbers Generated or Discovered This Session

  • Logo file: public/oysqn_logo.png (confirmed present)
  • Max logo display width: 280px (CSS)
  • Max login form width: 400px (CSS)

Files Created or Modified

File Path Action Description
app/pages/index.vue Modified Splash (unauthenticated) + home (authenticated) in single page, toggled by useSupabaseUser()
app/pages/login.vue Modified Email input → sendMagicLink() → confirmation state; uses IonBackButton to return to splash
app/middleware/auth.ts Modified Added / to public routes; redirects unauthenticated to /
nuxt.config.ts Modified supabase.redirectOptions.login = /; added / to exclude

What the NEXT Session Should Do

  1. First: Test the auth flow end-to-end: load app → confirm splash shows logo + Login button → tap Login → enter email → check Mailpit (http://127.0.0.1:54324) for magic link → click link → confirm redirect to /auth/callback → confirm redirect to / (home state)
  2. Then: Implement app/pages/auth/callback.vue — handle magic link redirect (Supabase sets session from URL hash; page should show a spinner, then navigate to /)
  3. Then: Verify useAuthStore is auto-imported by Pinia Nuxt module (currently explicitly imported in login.vue with import { useAuthStore } from '~/stores/auth' — check if explicit import is still needed or if auto-import covers it)
  4. Then: Run npx supabase gen types typescript --local > app/types/supabase.ts to replace placeholder types
  5. Then: Implement app/pages/index.vue home content (authenticated state) — boat list or welcome state

Open Questions Requiring User Input

  • Should the login page also support OTP (enter token from email) as a fallback, or magic link only? — sendOtp + verifyOtp exist in auth store but unused — impacts login page UI
  • Should auth/callback.vue redirect to a specific page after login (e.g., boats list) or always to /? — impacts callback implementation

Assumptions That Need Validation

  • ASSUMED: @nuxtjs/ionic + @pinia/nuxt auto-imports useAuthStore — currently explicitly imported; validate by removing explicit import and testing
  • ASSUMED: sendMagicLink() in auth store correctly sets emailRedirectTo to /auth/callback — validate by clicking the email link and checking where it lands
  • ASSUMED: IonRouterOutlet handles router-link on IonButton correctly — validate by tapping Login button in browser

Files to Load Next Session

  • app/pages/auth/callback.vue — primary implementation target
  • app/pages/index.vue — may need home content (authenticated state) built out
  • app/stores/auth.ts — reference for sendMagicLink signature and redirect URL

Dev Environment Reference

# Start local Supabase (if not running):
DOCKER_HOST=unix:///run/user/1000/podman/podman.sock npx supabase start

# Start app:
yarn dev

# Mailpit (view magic link emails):
http://127.0.0.1:54324

# Supabase Studio:
http://127.0.0.1:54323