FormFlow is a full-stack form builder built with Next.js, React, TypeScript, Tailwind CSS, and Supabase.
It allows users to:
- Register and sign in
- Create forms with auto-generated 6-character share codes
- Add/edit/delete questions (short answer, paragraph, multiple choice)
- Share forms via code or direct URL
- Collect one response per user per form
- Review submitted responses (form owner)
- View personal response history (form participant)
- Next.js 16 (App Router)
- React 19
- TypeScript
- Tailwind CSS 4
- Supabase JS + @supabase/ssr
- Node.js 20+ (recommended)
- npm 10+ (or compatible package manager)
- A Supabase project
Create .env.local in the project root:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_keyThese are required by utils/supabase.ts.
- Open your Supabase project.
- Go to SQL Editor.
- Run the SQL in
schema.sql.
This creates the core tables:
usersformsquestionsresponsesanswers
And supporting indexes for query performance.
npm install
npm run devApp runs at:
npm run dev: Start development servernpm run build: Create production buildnpm run start: Run production servernpm run lint: Run ESLint
/: Landing page/login: Login page/login/register: Registration page/dashboard: User dashboard (owned forms + stats)/dashboard/history: Attempted forms history/dashboard/forms/[code]/edit: Form builder/editor (owner only)/dashboard/forms/[code]/responses: View form responses (owner only)/forms/[code]: Public form answer page (requires login)
Current authentication/session model is custom and app-level:
- User data is stored in the
userstable - Login writes local storage entry
formdb_user - Session/identity cookies are used:
formdb_sessionformdb_user_id
- Route protection for dashboard/auth pages is handled in
proxy.ts
app/page.tsx: Landing pageapp/login/*: Sign in/sign up UI and flowsapp/dashboard/*: Dashboard, history, owner workflowsapp/components/FormBuilderClient.tsx: Form editor clientapp/components/CreateFormModal.tsx: Form creation modalapp/forms/[code]/page.tsx: Form submission flowutils/supabase.ts: Supabase client factoryutils/generateCode.ts: 6-character form code generatorschema.sql: Database schema
- Passwords are currently compared/stored directly from app logic (no hashing layer in this codebase yet).
- Authorization is cookie/local-storage based; it is not using Supabase Auth.
- Form code generation is random 6-character uppercase alphanumeric and does not currently include collision retry logic.
- Migrate auth to Supabase Auth (or another managed auth provider).
- Hash passwords with a strong algorithm (Argon2/bcrypt) if custom auth is retained.
- Add form code collision checks before insert.
- Add automated tests for critical flows (auth, creation, submission).
- Add DB-level RLS policies and tighten data access guarantees.