A production-style listings platform built with React, TypeScript, Tailwind CSS, React Router, and Supabase.
This application includes:
- Email/password authentication (register, login, logout)
- Public listing discovery with search and pagination
- Listing details with seller contacts and image slider
- Protected dashboard workflows for create, edit, and delete
- Multi-file image uploads to Supabase Storage
- Row Level Security-aware data access patterns
- React 18
- TypeScript 5
- Vite 5
- Tailwind CSS 3
- Supabase (Auth, Postgres, Storage)
src/
components/
layout/ # App shell, navbar, footer
listings/ # Listing card UI
routing/ # Protected route guard
context/ # Authentication context
lib/ # Supabase client + listing data APIs
pages/ # Route pages
types/ # Shared domain types
supabase/
migrations/ # SQL migration files
scripts/
seed-supabase.js # Optional JavaScript seeding script
- Node.js 20+
- npm 10+
- A Supabase project
- Install dependencies:
npm install- Copy the environment template:
Windows PowerShell:
Copy-Item .env.example .envmacOS/Linux:
cp .env.example .env- Fill in
.env:
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-or-publishable-keyThe app expects the following Supabase resources:
public.user_profilespublic.listingspublic.listing_photos- Storage bucket:
listing-photos
These are created by migration:
supabase/migrations/20260414_000001_initial_schema.sql
If this migration has not been applied yet, apply it to your Supabase project before running the app.
Start development server:
npm run devBuild for production:
npm run buildPreview production build:
npm run previewnpm run dev- Start Vite development servernpm run build- Type-check and build production bundlenpm run preview- Preview built app locallynpm run seed:supabase- Run JavaScript seeding script (requires Node + valid.env)
/- Home (welcome + latest 6 listings)/listings- Browse listings (search + pagination)/listing/:id- Listing details (photos slider + seller contact)/login- Login page/register- Register page
/my-listings- My listings (with pagination and actions)/dashboard/create- Create listing + upload photos/dashboard/edit/:id- Edit listing + add/remove photos/dashboard/delete/:id- Confirm deletion of listing and its photos
Compatibility aliases are also supported:
/create/edit/:id/delete/:id
- Ensure all required environment variables are configured in your hosting provider.
- Run
npm run buildin CI to validate TypeScript and production output. - Confirm Supabase URL/key point to the intended project.
- Confirm migration has been applied in the target Supabase environment.
- Ensure dependencies are installed:
npm install - Ensure CI uses Node.js 20+ and npm 10+
- Verify
@supabase/supabase-jsis present inpackage.json - Reinstall dependencies and restart the editor TypeScript server if needed
- Check
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEY - Verify email/password auth is enabled in Supabase Auth providers
- Verify bucket
listing-photosexists - Verify storage RLS policies allow authenticated insert/update/delete
- Never commit service role keys to frontend code or
.envfiles used by the client app. - Keep RLS enabled for all application tables.
- Use publishable/anon keys only in frontend runtime.
This project is intended as an educational and portfolio-ready full-stack example.