Skip to content

Latest commit

 

History

History
195 lines (163 loc) · 8.35 KB

File metadata and controls

195 lines (163 loc) · 8.35 KB

DEVSPOT — Plan & Progress

Stack

  • Frontend: Vite + React 19 + TypeScript + Tailwind CSS v4
  • Map: mapcn (MapLibre GL via shadcn/ui) — free CARTO tiles, no API key
  • Routing: OSRM (router.project-osrm.org) — free, no key
  • Theme: Dark/light via CSS variables + ThemeProvider context
  • i18n: react-i18next + i18next-browser-languagedetector (pt default, en fallback)
  • UI: shadcn/ui (Button, Map, MapMarker, MapRoute, etc.)
  • Backend: Supabase (Postgres + Auth + Storage)
  • Data Fetching: TanStack Query (@tanstack/react-query) — caching, mutations, auto-refetch
  • Validation: Zod (zod) — schema-based form validation
  • Icons: Tabler Icons (@tabler/icons-react), lucide-react (shadcn dependency)
  • Font: DotGothic16 (Google Fonts)

Architecture Decisions

Why not Next.js?

User requested Vite instead of Next.js. React Router v7 handles SPA routing.

Map Strategy — mapcn (Maplibre GL)

mapcn shadcn/ui component wrapping Maplibre GL JS:

  • Free CARTO basemaps (dark-matter / positron, theme-synced)
  • Built-in controls (zoom, compass, locate, fullscreen)
  • <MapMarker> with <MarkerContent> and <MarkerTooltip>
  • <MapRoute> for OSRM route overlays
  • <MapClusterLayer> for clustered markers
  • No API key required

Routing — OSRM

Public OSRM API at router.project-osrm.org for driving directions:

  • Route geometry rendered as <MapRoute> on the map
  • Distance/duration displayed in route info panel
  • Browser Geolocation API for user origin

Theme Strategy

  • Dark theme default via class="dark" on <html>
  • .light CSS class overrides shadcn variables + DevSpot custom colors
  • ThemeProvider context with localStorage persistence
  • Map basemap syncs automatically (CARTO dark-matter ↔ positron)

i18n Strategy

  • Portuguese (Angolan) default language, English fallback
  • Language detection via localStorage → navigator
  • All user-facing strings in src/lib/i18n.ts
  • LanguageSwitcher in header toggles pt ↔ en
  • All hardcoded English strings replaced with t() calls

Data Fetching Strategy

  • TanStack Query for all Supabase data operations
  • useQuery for reads (places, reviews, profile)
  • useMutation for writes (createPlace, createReview)
  • Automatic cache invalidation on mutations
  • staleTime: 15-30s for responsive UI

Form Validation Strategy

  • Zod schemas in src/lib/schemas.ts (placeSchema, reviewSchema)
  • Real-time field validation on submit
  • Error messages use i18n t() keys
  • Address field with Nominatim autocomplete geocoding

Address Input

  • Text input with Nominatim OpenStreetMap API autocomplete
  • 500ms debounce, 1 req/sec rate limit respected
  • Country filter: Angola (ao)
  • Lat/lng populated from selected address result
  • Falls back to geolocation toggle for location

State Management

TanStack Query for server state. React context for theme + auth. Local component state for forms and UI.

CSS Strategy

Tailwind v4 for utility classes + custom .ds-* component classes. Shadcn CSS variables for system-level theming.

Command Palette

Ctrl/Cmd+K opens overlay with 18 functional actions:

  • Submit place, toggle language, toggle theme
  • Switch view (split/map/list)
  • Toggle filters (vibe, use case, type)
  • Arrow key navigation, Enter to execute
  • All labels use t() for i18n

Progress Tracking

Infrastructure

  • Project scaffold (Vite + React + TS + Tailwind)
  • Design tokens in Tailwind theme
  • Component CSS classes (ds-pill, ds-tag, ds-card, etc.)
  • TypeScript types (Place, PlaceWithRating, Review, User, Filters, etc.)
  • shadcn/ui + mapcn initialized
  • Supabase project created and linked (brdesbsngyoqixfdnfgd)
  • Database schema deployed (places, reviews, profiles, saves + RLS + storage)

Auth & Data Layer

  • Auth context (signIn/signUp/signOut/Google OAuth)
  • Auth pages (SignInPage, SignUpPage)
  • Supabase data service (fetchPlaces, createPlace, uploadPhoto, etc.)
  • Photo upload to Supabase Storage (place-photos bucket)
  • Auth guard: submit requires login (redirects to /signin)

Map & Routing

  • Map component (DevSpotMap with mapcn/MapLibre GL)
  • OSRM routing integration (route from user location to selected place)
  • Mapbox removed (no references, no types package)
  • Theme-synced map basemap (dark ↔ light CARTO)

i18n

  • i18n setup (react-i18next, pt/en locales)
  • LanguageSwitcher in header
  • All components use useTranslation() — no hardcoded strings
  • Default language set to Portuguese
  • Complete PT ↔ EN translation coverage

Theme

  • Dark theme default (class="dark" on html)
  • Light theme via .light CSS class
  • ThemeProvider with localStorage persistence
  • Map theme sync
  • Theme toggle button in header (sun/moon icon)

Command Palette

  • Ctrl/Cmd+K overlay with keyboard navigation
  • i18n support for all labels and groups
  • Functional: submit, lang, theme toggle
  • Functional: view switch (split/map/list)
  • Functional: filter toggle (vibe, use, type)

TanStack Query Integration

  • @tanstack/react-query installed
  • QueryClientProvider wrapping app
  • useQuery for places, reviews, profile data
  • useMutation for createPlace, createReview, deletePlace, deleteReview
  • Cache invalidation on all mutations for auto-refresh

Form Validation

  • Zod schemas (placeSchema, reviewSchema)
  • Validation errors displayed below fields
  • i18n error messages via t()
  • Submit disabled during mutation (loading state)

Address Input

  • Address text field with Nominatim autocomplete
  • Geolocation toggle (ON/OFF) as alternative
  • Lat/lng populated from selected address
  • Validation: address required when location OFF

Pages

  • Home (TanStack Query, real ratings, cmd palette, auth guard)
  • PlaceDetailPage (TanStack Query, real reviews, photos, reviews CRUD, place delete, route)
  • SignInPage (i18n, email/password + Google OAuth)
  • SignUpPage (i18n, username field, auto-profile creation)
  • ProfilePage (TanStack Query, real places with ratings, inline bio editing, sign-out)

Features

  • WiFi/noise/power badges on review cards
  • Edit/delete own reviews (pre-filled form, confirm dialog)
  • Delete own places (confirm dialog, cached invalidation)
  • Profile auto-creation (DB trigger + client-side upsert)
  • Mobile hamburger menu (theme, K, lang, view, profile, sign-out, submit)
  • Profile icon in navbar (links to /profile/{username})
  • Logout overlay (centered message, fade-out animation)
  • Security audit completed (no service_role, no user_metadata in RLS, no SECURITY DEFINER)
  • Security patches applied (RLS for all tables + storage, CSP headers, file validation, npm audit zero vulns)

Remaining

  • Seed data (sample places/reviews for Luanda)
  • Code splitting for maplibre-gl (large chunk warning)
  • Real-time updates via Supabase subscriptions

Do's

  • Keep component CSS classes matching the HTML prototype exactly
  • Use Tabler Icons for all iconography (lucide-react only for shadcn internals)
  • Follow the dark/light monospace, terminal-like aesthetic
  • Portuguese default for Portuguese-speaking market (Luanda)
  • Write clean, minimal code without comments
  • Commit each file with a comprehensive message
  • Build must pass before committing
  • Use TanStack Query for all server data

Don'ts

  • Don't add comments to code
  • Don't use emojis in code — use Tabler Icons
  • Don't over-engineer state management
  • Don't add features not in the PRD scope
  • Don't hardcode strings — always use t()

Current Status

Production-ready MVP with TanStack Query, Zod validation, real Supabase data, and responsive UI. mapcn/MapLibre GL map with theme-synced basemaps. OSRM routing. Full i18n (Portuguese default, English toggle) with no hardcoded strings. Command palette (Ctrl+K) with 18 actions and i18n labels. Dark/light theme with header toggle button and persistence. Auth with login/signup/Google OAuth. Photo uploads to Supabase Storage. Address input with Nominatim geocoding. Place ratings calculated from real reviews. WiFi/noise/power badges on reviews. Edit/delete own content. Mobile-responsive hamburger menu. Logout animation. Security audited and patched.

Known Issues

  • Chunk size warning for maplibre-gl (needs code splitting)
  • No seed data for Luanda places in the database
  • Supabase Storage buckets need manual creation (migration provided)