diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c1d688a --- /dev/null +++ b/.gitignore @@ -0,0 +1,62 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +**/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage +**/coverage + +# next.js +/.next/ +**/.next/ +/out/ + +# production +/build +/dist + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# local env files +.env*.local +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +# IDE / Editor +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +Thumbs.db + +# Supabase +.supabase/ + +# Optional: Docs that might contain sensitive info +# CLAUDE.old.md \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..ddbe2df --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,502 @@ +# Summit Monorepo - AI Assistant Context File + +**Last Updated**: November 30, 2025 +**Version**: 1.0.2 (Clinic Role Feature Added) +**Purpose**: Quick reference for Claude Code or other AI assistants + +--- + +## ๐ŸŽฏ Project Overview + +This monorepo contains two separate FMS-based rehabilitation applications: + +### 1. Summit Clinic App +**Summit** is a gamified rehabilitation exercise management platform for chiropractic clinics. It digitizes the Functional Movement Screen (FMS) assessment and automatically assigns corrective exercises with a mountain-climbing progress metaphor. + +Patients "climb the mountain" through 4 phases (Analyze โ†’ Mobilize โ†’ Stabilize โ†’ Optimize) by completing exercises assigned based on their FMS assessment scores. + +### 2. Fire FMS App +**FireFMS** is a gamified FMS assessment and training platform for fire departments and first responders. It uses a 3-week mini-series program model with department-wide leaderboards and achievement tracking. + +--- + +## ๐Ÿ“‚ Monorepo Structure + +``` +summit/ +โ”œโ”€โ”€ clinic-app/ # Summit Clinic Application +โ”‚ โ”œโ”€โ”€ app/ # Next.js 14 App Router +โ”‚ โ”‚ โ”œโ”€โ”€ page.tsx # โœจ Landing page with animations +โ”‚ โ”‚ โ”œโ”€โ”€ auth/ # โœจ Authentication pages +โ”‚ โ”‚ โ”œโ”€โ”€ patient/ # โœจ Patient dashboard & exercises +โ”‚ โ”‚ โ”œโ”€โ”€ employee/ # โœจ Employee assessment & management +โ”‚ โ”‚ โ””โ”€โ”€ owner/ # โœจ Owner analytics +โ”‚ โ”œโ”€โ”€ components/ # React components +โ”‚ โ”œโ”€โ”€ lib/supabase/ # Supabase client setup +โ”‚ โ”œโ”€โ”€ types/ # TypeScript types +โ”‚ โ”œโ”€โ”€ supabase/ # Database schemas +โ”‚ โ””โ”€โ”€ package.json # Port 3001 +โ”‚ +โ”œโ”€โ”€ fire-app/ # Fire Department FMS Application +โ”‚ โ”œโ”€โ”€ app/ # Next.js 14 App Router +โ”‚ โ”‚ โ”œโ”€โ”€ page.tsx # Landing/demo page +โ”‚ โ”‚ โ”œโ”€โ”€ auth/ # Authentication +โ”‚ โ”‚ โ”œโ”€โ”€ firefighter/ # Firefighter dashboard +โ”‚ โ”‚ โ”œโ”€โ”€ chief/ # Chief dashboard & analytics +โ”‚ โ”‚ โ”œโ”€โ”€ clinic/ # ๐Ÿฅ Clinic dashboard & assessment (NEW) +โ”‚ โ”‚ โ””โ”€โ”€ profile/ # User profile page +โ”‚ โ”œโ”€โ”€ components/ # React components +โ”‚ โ”œโ”€โ”€ lib/supabase/ # Supabase client setup +โ”‚ โ”œโ”€โ”€ types/ # TypeScript types +โ”‚ โ”œโ”€โ”€ supabase/ # Database schemas +โ”‚ โ””โ”€โ”€ package.json # Port 3002 +โ”‚ +โ”œโ”€โ”€ clinic-docs/ # Clinic app documentation +โ”‚ โ”œโ”€โ”€ DATABASE_SCHEMA.md # โญ Database reference +โ”‚ โ”œโ”€โ”€ DEVELOPMENT.md # Development guide +โ”‚ โ”œโ”€โ”€ STYLE_GUIDE.md # Design system +โ”‚ โ””โ”€โ”€ MIGRATION_INSTRUCTIONS.md +โ”‚ +โ”œโ”€โ”€ fire-docs/ # Fire app documentation +โ”‚ โ””โ”€โ”€ DATABASE_SCHEMA.md # Database reference +โ”‚ +โ”œโ”€โ”€ CLAUDE.md # This file - monorepo guide +โ”œโ”€โ”€ ROADMAP.md # Future features & timeline +โ”œโ”€โ”€ README.md # Monorepo overview +โ””โ”€โ”€ .gitignore # Excludes node_modules +``` + +--- + +## ๐Ÿ—„๏ธ Database Schemas + +### Clinic App Database (8 Tables) +**IMPORTANT**: Check `clinic-docs/DATABASE_SCHEMA.md` before making changes! + +Core Tables: +1. **clinics** - Clinic information +2. **users** - User profiles with roles +3. **fms_assessments** - FMS scores (7 patterns, max 21 points) +4. **exercises** - Exercise library (40+ pre-seeded) +5. **exercise_assignments** - Patient exercise assignments with date ranges +6. **exercise_completions** - Daily completion tracking +7. **patient_progress** - Gamification (points, streaks, phase) +8. **achievements** - Earned badges + +### Fire App Database (9 Tables) +**IMPORTANT**: Check `fire-docs/DATABASE_SCHEMA.md` before making changes! + +Core Tables: +1. **stations** - Fire stations/departments +2. **users** - Firefighters, chiefs, admins +3. **fms_scores** - FMS assessment results +4. **series** - 3-week mini-series programs +5. **exercises** - Exercise library +6. **series_exercises** - Exercises in each series week +7. **series_assignments** - User series assignments +8. **exercise_completions** - Completion tracking +9. **achievements** - Badges and milestones + +--- + +## ๐Ÿ”‘ Key Business Logic + +### Clinic App Logic + +**FMS Assessment Flow:** +1. Employee conducts 7-pattern FMS assessment +2. Bilateral movements scored (take lower of L/R) +3. Scores โ‰ค1 trigger **1 exercise per category** (~5-7 total) +4. Redirect to review page for customization +5. Employee adjusts sets/reps/program duration +6. Patient sees exercises immediately + +**Exercise Completion:** +- Patients can complete exercises **multiple times per day** +- **10 points** awarded only on **FIRST daily completion** +- Subsequent completions same day = 0 points (no double-dipping) +- Streak maintained by completing ANY exercise each day + +### Fire App Logic + +**FMS Assessment Flow (Clinic Role):** +1. Clinic staff conducts 7-pattern FMS assessment on firefighter OR chief +2. Assessment stores final scores (lower of L/R for bilateral movements) +3. Clinic assigns appropriate 3-week mini-series based on weak areas +4. Series automatically progresses through weeks +5. Points awarded for completions (10 per exercise) +6. Department leaderboard updates in real-time + +**User Management:** +- **Clinic** can create both chief and firefighter accounts +- **Chiefs** can view their team but CANNOT add firefighters +- Temp passwords displayed on account creation (manual handoff) + +**Mini-Series Model:** +- 3-week progressive programs targeting specific areas +- Week 1: Foundation/Mobility +- Week 2: Strength/Stability +- Week 3: Integration/Advanced +- Auto-progression to next week after completion + +--- + +## ๐Ÿ› ๏ธ Tech Stack + +- **Framework**: Next.js 14 with App Router +- **Language**: TypeScript (strict mode) +- **Database**: Supabase (PostgreSQL with Row Level Security - currently disabled) +- **Authentication**: Supabase Auth +- **Styling**: Tailwind CSS + shadcn/ui components +- **Animations**: Framer Motion โœจ NEW +- **Theme**: next-themes (dark/light mode) โœจ NEW +- **Hosting**: Vercel +- **Package Manager**: npm +- **Dev Server**: `npm run dev` (runs on port 3001) + +### Important Dependencies: +- `@supabase/supabase-js` - Supabase client +- `@supabase/ssr` - Server-side rendering support +- `framer-motion` - โœจ Animation library +- `next-themes` - โœจ Theme switching +- `canvas-confetti` - Celebration animations +- `lucide-react` - Icons +- `class-variance-authority`, `clsx`, `tailwind-merge` - Utility classes + +--- + +## ๐Ÿ“‹ Common Commands + +```bash +# Clinic App Development +cd clinic-app +npm install # Install dependencies +npm run dev # Start dev server (http://localhost:3001) +npm run build # Build for production +npm start # Start production server + +# Fire App Development +cd fire-app +npm install # Install dependencies +npm run dev # Start dev server (http://localhost:3002) +npm run build # Build for production +npm start # Start production server + +# Git Workflow +git checkout -b clinic/feature-name # New clinic feature +git checkout -b fire/feature-name # New fire feature +``` + +--- + +## ๐Ÿšจ Critical Things to Know + +### 1. Database Schema Changes +- **ALWAYS** read `DATABASE_SCHEMA.md` first +- **ALWAYS** update `DATABASE_SCHEMA.md` after schema changes +- Update `types/supabase.ts` to match schema + +### 2. FMS Scoring +- Bilateral movements use `Math.min(left, right)` in frontend +- Database uses `LEAST(left, right)` in generated column +- **Max total score is 21** (not 36!) +- See `app/employee/assessment/page.tsx:100-109` for scoring logic + +### 3. Exercise Assignment +- Only assign **1 exercise per category** (not 2) +- Use date ranges: `start_date` to `end_date` +- Default program duration is 7 days +- See `app/employee/assessment/page.tsx:280-300` for assignment logic + +### 4. Points System +- Check for daily completions FIRST before awarding points +- Use `completion_date` field (not `completed_at`) for daily checks +- See `app/patient/exercise/[id]/page.tsx:150-180` for points logic + +### 5. Authentication +- Password reset requires Supabase redirect URL configuration +- Redirect URLs: `/auth/reset-password` +- See `app/employee/page.tsx:90-120` for patient creation flow + +--- + +## ๐Ÿงช Testing Workflow + +### Quick Test (Employee โ†’ Patient Flow): +1. Create clinic in Supabase (if not exists) +2. Login as employee (set role + clinic_id in Supabase) +3. Add patient via "Add New Patient" +4. Check email for password reset link +5. Conduct FMS assessment (test bilateral scoring) +6. Review exercises on review page (~5-7 exercises) +7. Customize sets/reps/duration +8. Login as patient +9. Verify exercises show immediately +10. Complete exercise twice (verify points only on first) + +### Test FMS Scoring: +Enter: Deep Squat=3, Hurdle(L=3,R=3), Inline(L=2,R=3), Shoulder(L=3,R=3), ASLR(L=2,R=3), Trunk=3, Rotary(L=3,R=3) +**Expected Total**: 19 (not 33) + +--- + +## ๐Ÿ› Known Issues + +1. **Video URLs are placeholders** - Not implemented yet +2. **RLS is disabled** - Need to re-enable for production +3. **Email templates** - Need customization +4. **Phase progression** - Only analyze โ†’ mobilize works +5. **Owner analytics** - Static data (no filtering) + +--- + +## ๐Ÿ“ˆ Current Phase Status + +### โœ… Clinic App - Phase 1 Complete (Oct 30, 2025) +- MVP with all core features + +### โœ… Fire App - Phase 1 Complete (Nov 17, 2025) ๐Ÿ”ฅ NEW +- **Fully functional demo ready for deployment** +- All 10 core features implemented +- Real Supabase database integration +- Mobile responsive design +- Polished animations and loading states + +**Major Accomplishments:** +1. โœ… Supabase client/server setup with TypeScript types +2. โœ… Firefighter dashboard with real-time data +3. โœ… Chief command center with analytics +4. โœ… Complete FMS assessment workflow +5. โœ… Series assignment based on FMS scores +6. โœ… Exercise completion with points/streaks +7. โœ… Achievement system +8. โœ… Mobile-responsive across all pages +9. โœ… Animated cards and loading states +10. โœ… Login with demo account quick-fill + +### โœ… Phase 2 Complete (Oct 31, 2025) +- Fixed exercise visibility +- Fixed FMS scoring +- Exercise review & customization +- Password reset flow +- Daily tracking improvements + +### โœ… Visual Polish Complete (Oct 31, 2025) โœจ NEW +- Global dark/light mode with next-themes +- Framer Motion animations across all pages +- Summit brand colors (#0d3d62, #afa586) +- AnimatedCard, ProgressBar, Skeleton components +- Landing page redesign with hero & features +- STYLE_GUIDE.md for consistent design +- 11+ pages polished with animations + +### ๐Ÿ”„ Clinic App - Phase 3 Next (Recommended): +1. โœ… ~~Framer Motion animations~~ - COMPLETED! +2. Video integration (3-4 hrs) +3. Email notifications (4-5 hrs) +4. Phase progression logic (3-4 hrs) +5. Mobile optimization (2-3 hrs) + +### โœ… Fire App - DEPLOYED (Nov 18, 2025) ๐Ÿš€ +1. โœ… **Deployed to Vercel** - Live at production URL +2. โœ… Production build tested and verified +3. โœ… Environment variables configured +4. โœ… All features working in production +5. โœ… Mobile Safari UI fixes applied + +**Deployment Fixes Applied:** +- TypeScript build errors bypassed (`ignoreBuildErrors: true`) +- Mobile dark mode color inversion fixed (`color-scheme` meta tag) +- Safari UI bars darkened to match app theme +- Removed broken "View Profile" and "Continue Training" buttons +- Automatic Vercel deployment from dev branch configured + +### โœ… Clinic Role Feature (Nov 30, 2025) ๐Ÿฅ +1. โœ… Clinic dashboard (`/clinic`) - Assessment-focused interface +2. โœ… FMS assessment - Can assess both chiefs AND firefighters +3. โœ… Series assignment after assessment +4. โœ… Team roster management (`/clinic/team`) +5. โœ… Add chief/firefighter with temp password display +6. โœ… Chiefs can no longer add firefighters (clinic-only) +7. โœ… Login redirects for clinic role +8. โœ… Database constraint updated for 'clinic' role + +### ๐Ÿ”ฅ Fire App - Remaining Work (Priority Order) + +**High Priority (Before Next Demo):** + +1. **Injury Tracking for Clinic** โฑ๏ธ 4-5 hours + - [ ] Create `/clinic/injuries` page to log and view injuries + - [ ] Log injuries during or after FMS assessment + - [ ] Link injuries to specific users (firefighter or chief) + - [ ] Track: injury type, date, severity, body area, notes + - [ ] View injury history per person + - [ ] Chiefs can view (read-only) injury reports for their station + +2. **FMS Assessment History** โฑ๏ธ 3-4 hours + - [ ] View previous FMS assessments for a user + - [ ] Compare scores over time (score trend chart) + - [ ] Show improvement/decline indicators + - [ ] Add "View History" button on team roster + - [ ] Display last assessment date prominently on user cards + +3. **Password Change Feature** โฑ๏ธ 2-3 hours + - [ ] Add "Change Password" section to profile page + - [ ] First-login password change prompt (optional enhancement) + - [ ] Validate new password requirements + - [ ] Success confirmation message + +**Medium Priority (Post-Demo Enhancements):** + +4. **Reassessment Workflow** โฑ๏ธ 2-3 hours + - [ ] "Due for reassessment" indicator (e.g., 90+ days since last) + - [ ] Filter team roster by assessment status (overdue, recent, never) + - [ ] Quick "reassess" action button from team list + - [ ] Reassessment reminders/notifications (future) + +5. **Clinic Dashboard Analytics** โฑ๏ธ 3-4 hours + - [ ] Assessments completed this week/month count + - [ ] Department-wide average FMS score + - [ ] Score trends over time (improving vs declining firefighters) + - [ ] Personnel needing attention (low scores, overdue assessments) + +6. **Series Management for Clinic** โฑ๏ธ 2-3 hours + - [ ] View all active series assignments across station + - [ ] Ability to reassign or cancel a series + - [ ] Track series completion rates + - [ ] See which series are most effective (completion %) + +**Lower Priority (Future Iterations):** + +7. **Multi-Station Support** + - [ ] Clinic user assigned to multiple stations + - [ ] Station selector dropdown in clinic dashboard + - [ ] Cross-station reporting for clinic admins + - [ ] Separate manager app for multi-station administration + +8. **Email Notifications** + - [ ] Welcome email with credentials on account creation + - [ ] Assessment completion notifications to chief + - [ ] Series assignment notifications to firefighter + - [ ] Weekly progress summary emails + +9. **Advanced Reporting** + - [ ] Export data to CSV/PDF + - [ ] Custom date range reports + - [ ] Injury correlation with FMS scores analysis + - [ ] ROI metrics (cost savings from injury prevention) + +--- + +## ๐Ÿ’ก Quick Tips for AI Assistants + +### Before Making Changes: +1. Read `DATABASE_SCHEMA.md` if touching database +2. Read `DEVELOPMENT.md` for current status +3. Read `ROADMAP.md` for planned features +4. Check if feature already exists (don't duplicate) + +### When Writing Code: +- **FMS Scoring**: Use `Math.min()` for bilateral movements +- **Exercise Queries**: Filter by date ranges, not due_date +- **Points**: Check daily completions first +- **Types**: Import from `@/types/supabase` +- **Client**: Use `createClient()` from `@/lib/supabase/client` or `server` +- **Animations**: Use Framer Motion for all animations โœจ NEW +- **Theme**: Use `useTheme()` from next-themes for dark mode โœจ NEW +- **Components**: Use AnimatedCard instead of Card for polish โœจ NEW +- **Colors**: Use Summit brand colors from tailwind.config.ts โœจ NEW + +### When Updating Database: +1. Update `types/supabase.ts` +2. Update `DATABASE_SCHEMA.md` + +### Common File Paths: + +**Clinic App:** +- FMS scoring logic: `clinic-app/app/employee/assessment/page.tsx:100-109` +- Exercise assignment: `clinic-app/app/employee/assessment/page.tsx:280-300` +- Review page: `clinic-app/app/employee/assessment/review/[assessmentId]/page.tsx` +- Patient dashboard: `clinic-app/app/patient/page.tsx:40-60` +- Exercise completion: `clinic-app/app/patient/exercise/[id]/page.tsx:150-180` +- Add patient flow: `clinic-app/app/employee/page.tsx:90-120` + +**Fire App:** โœจ UPDATED Nov 30 +- Database schema: `fire-app/supabase/schema.sql` โœ… +- Seed data: `fire-app/supabase/seed.sql` โœ… +- UUID sync script: `fire-app/supabase/restore-with-auth-uuids.sql` โœ… +- Firefighter dashboard: `fire-app/app/firefighter/page.tsx` โœ… REAL DATA +- Chief dashboard: `fire-app/app/chief/page.tsx` โœ… FULL FEATURES +- Chief FMS Assessment: `fire-app/app/chief/assessment/page.tsx` โœ… +- Chief Series Assignment: `fire-app/app/chief/assessment/review/[assessmentId]/page.tsx` โœ… +- Exercise Detail: `fire-app/app/firefighter/exercise/[id]/page.tsx` โœ… +- Login page: `fire-app/app/auth/login/page.tsx` โœ… ANIMATED +- TypeScript types: `fire-app/types/database.ts` โœ… +- Supabase client: `fire-app/lib/supabase/client.ts` โœ… +- Supabase server: `fire-app/lib/supabase/server.ts` โœ… +- **Clinic dashboard**: `fire-app/app/clinic/page.tsx` โœ… NEW +- **Clinic FMS assessment**: `fire-app/app/clinic/assessment/page.tsx` โœ… NEW +- **Clinic series assignment**: `fire-app/app/clinic/assessment/review/[assessmentId]/page.tsx` โœ… NEW +- **Clinic team roster**: `fire-app/app/clinic/team/page.tsx` โœ… NEW +- **Clinic add user**: `fire-app/app/clinic/team/new/page.tsx` โœ… NEW +- **Profile page**: `fire-app/app/profile/page.tsx` โœ… UPDATED for clinic + +--- + +## ๐Ÿ”— Related Files + +**Root Level:** +- **Monorepo overview**: `README.md` +- **Future plans**: `ROADMAP.md` +- **This file**: `CLAUDE.md` + +**Clinic App Documentation:** +- **Database reference**: `clinic-docs/DATABASE_SCHEMA.md` โญ +- **Developer guide**: `clinic-docs/DEVELOPMENT.md` +- **Design system**: `clinic-docs/STYLE_GUIDE.md` +- **Migration guide**: `clinic-docs/MIGRATION_INSTRUCTIONS.md` + +**Fire App Documentation:** +- **Database reference**: `fire-docs/DATABASE_SCHEMA.md` +- Additional docs to be created as app develops + +--- + +## ๐Ÿš€ Next Steps + +### Clinic App +- Ready for client demo +- Consider video integration +- Production readiness (RLS, email templates) + +### Fire App โœ… DEPLOYED TO PRODUCTION (Nov 18, 2025) +1. โœ… ~~Create seed data with demo exercises~~ - DONE +2. โœ… ~~Build demo login page~~ - DONE with animations +3. โœ… ~~Implement firefighter dashboard~~ - DONE with real data +4. โœ… ~~Implement chief dashboard with leaderboards~~ - DONE +5. โœ… ~~Build FMS assessment interface~~ - DONE +6. โœ… ~~Build series assignment flow~~ - DONE +7. โœ… ~~Create exercise completion system~~ - DONE +8. โœ… ~~Add mobile responsiveness~~ - DONE +9. โœ… ~~Polish with animations~~ - DONE +10. โœ… **Deployed to Vercel!** ๐Ÿš€ + +**What Works:** +- Full authentication system +- Real-time database integration +- Points and streak tracking +- FMS assessments with 7 patterns +- Series assignment based on weak areas +- Exercise completion with celebrations +- Achievement unlocking +- Mobile-responsive design +- Loading states and animations + +**Demo Accounts:** +- Clinic: `clinic@firestation1.com` / `demo123` +- Chief: `chief@firestation1.com` / `demo123` +- Firefighter: `john@firestation1.com` / `demo123` + +--- + +**Remember**: The apps are completely separate! Different databases, different auth, different deployments. The only shared element is the monorepo structure for code organization. diff --git a/README.md b/README.md index a7307a5..d750e5c 100644 --- a/README.md +++ b/README.md @@ -1 +1,180 @@ -# summit \ No newline at end of file +# Summit Monorepo + +**Last Updated:** November 12, 2025 + +This monorepo contains two independent applications for FMS-based movement screening and rehabilitation. + +## ๐Ÿ“ฑ Applications + +### ๐Ÿฅ Clinic App (`/clinic-app`) +**Summit** - A gamified rehabilitation exercise management platform for chiropractic clinics. It digitizes the Functional Movement Screen (FMS) assessment and automatically assigns corrective exercises with a mountain-climbing progress metaphor. + +- **For:** Chiropractic clinics +- **Users:** Patients, Employees, Clinic Owners +- **Model:** Individual exercise assignments based on FMS scores +- **Features:** FMS assessments, exercise assignments, 4-phase mountain progression, patient progress tracking +- **Status:** โœ… v0.3.0 - Production ready with visual polish +- **Port:** 3001 + +### ๐Ÿš’ Fire App (`/fire-app`) +**FireFMS** - A specialized FMS assessment and training platform for fire departments and first responders. Uses 3-week mini-series programs with department-wide gamification. + +- **For:** Fire departments, Police, EMS, First Responders +- **Users:** Firefighters, Chiefs, Department Admins +- **Model:** 3-week mini-series programs targeting specific weaknesses +- **Features:** FMS scoring, series-based training, leaderboards, achievements, station analytics +- **Status:** ๐Ÿšง v0.1.0 - MVP in development (demo ready) +- **Port:** 3002 + +## ๐Ÿ“‚ Repository Structure + +``` +summit/ +โ”œโ”€โ”€ clinic-app/ # Chiropractic clinic application +โ”‚ โ”œโ”€โ”€ app/ # Next.js App Router +โ”‚ โ”œโ”€โ”€ components/ # React components +โ”‚ โ”œโ”€โ”€ lib/ # Utilities and helpers +โ”‚ โ”œโ”€โ”€ supabase/ # Database files +โ”‚ โ””โ”€โ”€ ...config files +โ”‚ +โ”œโ”€โ”€ fire-app/ # Fire department application +โ”‚ โ”œโ”€โ”€ app/ # Next.js App Router +โ”‚ โ”œโ”€โ”€ components/ # React components +โ”‚ โ”œโ”€โ”€ lib/ # Utilities and helpers +โ”‚ โ”œโ”€โ”€ supabase/ # Database files +โ”‚ โ””โ”€โ”€ ...config files +โ”‚ +โ”œโ”€โ”€ clinic-docs/ # Documentation for clinic app +โ”‚ โ”œโ”€โ”€ README.md +โ”‚ โ”œโ”€โ”€ DATABASE_SCHEMA.md +โ”‚ โ””โ”€โ”€ ...other docs +โ”‚ +โ”œโ”€โ”€ fire-docs/ # Documentation for fire app +โ”‚ โ”œโ”€โ”€ DATABASE_SCHEMA.md +โ”‚ โ””โ”€โ”€ SUPABASE_SETUP.md +โ”‚ +โ”œโ”€โ”€ CLAUDE.md # AI assistant context +โ”œโ”€โ”€ README.md # This file +โ””โ”€โ”€ ROADMAP.md # Future plans for both apps +``` + +## ๐Ÿš€ Getting Started + +### Prerequisites +- Node.js 18+ +- npm or yarn +- Supabase account (for database) + +### Installation + +#### Clinic App +```bash +cd clinic-app +npm install +cp .env.local.example .env.local +# Add your Supabase credentials to .env.local +npm run dev +# Runs on http://localhost:3001 +``` + +#### Fire App +```bash +cd fire-app +npm install +cp .env.local.example .env.local +# Add your Supabase credentials to .env.local +npm run dev +# Runs on http://localhost:3002 +``` + +## ๐ŸŒฟ Git Workflow + +This monorepo uses a branch naming convention to keep work organized: + +- `dev` - Main development branch (default) +- `main` - Production branch +- `clinic/*` - Features for the clinic app +- `fire/*` - Features for the fire app +- `chore/*` - Updates to shared components or documentation + +**Workflow:** +```bash +# Start new feature +git checkout dev +git pull origin dev +git checkout -b clinic/add-video-support # or fire/chief-dashboard + +# After completing work +git add . +git commit -m "feat: description" +git push origin clinic/add-video-support + +# Create PR to merge back to dev +``` + +## ๐Ÿ“š Documentation + +### Quick Links +- **Clinic App Docs:** `/clinic-docs/` + - [README](clinic-docs/README.md) - Overview and features + - [DATABASE_SCHEMA](clinic-docs/DATABASE_SCHEMA.md) - Database structure + - [DEVELOPMENT](clinic-docs/DEVELOPMENT.md) - Development guide + +- **Fire App Docs:** `/fire-docs/` + - [DATABASE_SCHEMA](fire-docs/DATABASE_SCHEMA.md) - Database structure + - [SUPABASE_SETUP](fire-docs/SUPABASE_SETUP.md) - Setup instructions + +- **Root Docs:** + - [CLAUDE.md](CLAUDE.md) - AI assistant context + - [ROADMAP.md](ROADMAP.md) - Future plans + +## ๐Ÿ› ๏ธ Tech Stack + +Both applications share similar technology: + +- **Framework:** Next.js 14 with App Router +- **Language:** TypeScript +- **Database:** Supabase (PostgreSQL) +- **Styling:** Tailwind CSS + shadcn/ui +- **Animations:** Framer Motion +- **Hosting:** Vercel + +## ๐Ÿš€ Deployment + +Each app can be deployed independently to Vercel: + +### Clinic App +- Deploy from `/clinic-app` directory +- Environment variables needed (see `.env.local.example`) +- Production URL: [your-clinic-domain] + +### Fire App +- Deploy from `/fire-app` directory +- Environment variables needed (see `.env.local.example`) +- Production URL: [your-fire-domain] + +## ๐Ÿ“Š Current Status + +| Feature | Clinic App | Fire App | +|---------|------------|----------| +| Database Schema | โœ… Complete | โœ… Complete | +| Authentication | โœ… Working | โœ… Ready (needs setup) | +| Dashboard | โœ… All roles | ๐Ÿšง Firefighter only | +| Exercise System | โœ… Individual | ๐Ÿ“‹ Series planned | +| Gamification | โœ… Points/Streaks | ๐Ÿšง Mock data | +| Production Ready | โœ… Yes | โŒ Demo only | + +## ๐Ÿค Contributing + +1. Create feature branch from `dev` +2. Follow naming convention (`clinic/*` or `fire/*`) +3. Make changes in appropriate app directory +4. Submit PR back to `dev` + +--- + +**Important:** The applications are completely independent with separate: +- Databases (different Supabase projects) +- Authentication systems +- Deployment configurations +- No shared code or infrastructure (except UI components) \ No newline at end of file diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..67056c7 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,453 @@ +# Summit Monorepo - Development Roadmap + +**Last Updated**: November 30, 2025 + +This roadmap covers both applications in the monorepo: the production-ready Clinic App and the Fire App (deployed with clinic role feature). + +## ๐Ÿฅ Clinic App Status: Production Ready (v0.3.0) + +All MVP features plus Phase 2 enhancements and visual polish are complete. The platform has immediate exercise visibility, proper FMS scoring, exercise customization, professional patient onboarding, and comprehensive animations with dark/light mode. + +## ๐Ÿš’ Fire App Status: Deployed with Clinic Feature (v0.2.0) + +Core MVP deployed to Vercel. Clinic role feature implemented allowing clinic staff to: +- Conduct FMS assessments on firefighters AND chiefs +- Create chief and firefighter accounts with temp passwords +- Manage station personnel +- Assign exercise series based on FMS results + +--- + +## โœ… Fire App - Completed Features + +### Phase 1: Core MVP (November 18, 2025) +1. โœ… Supabase client/server setup with TypeScript types +2. โœ… Firefighter dashboard with real-time data +3. โœ… Chief command center with analytics +4. โœ… Complete FMS assessment workflow +5. โœ… Series assignment based on FMS scores +6. โœ… Exercise completion with points/streaks +7. โœ… Achievement system +8. โœ… Mobile-responsive across all pages +9. โœ… Animated cards and loading states +10. โœ… Login with demo account quick-fill +11. โœ… Deployed to Vercel + +### Phase 2: Clinic Role Feature (November 30, 2025) +1. โœ… Clinic dashboard (`/clinic`) - Assessment-focused interface +2. โœ… FMS assessment page - Can assess both chiefs AND firefighters +3. โœ… Series assignment after assessment +4. โœ… Team roster management (`/clinic/team`) +5. โœ… Add chief/firefighter accounts with temp password display +6. โœ… Chiefs can no longer add firefighters (clinic-only) +7. โœ… Login redirects for clinic role +8. โœ… Database constraint updated for 'clinic' role +9. โœ… Profile page updated for clinic role + +--- + +## ๐Ÿ”ฅ Fire App - Remaining Work (Priority Order) + +### High Priority (Before Next Demo) + +#### 1. Injury Tracking for Clinic โฑ๏ธ 4-5 hours +- [ ] Create `/clinic/injuries` page +- [ ] Log injuries during or after FMS assessment +- [ ] Link injuries to specific users +- [ ] Track injury type, date, severity, notes +- [ ] View injury history per firefighter +- [ ] Chiefs can view (read-only) injury reports + +#### 2. FMS Assessment History โฑ๏ธ 3-4 hours +- [ ] View previous FMS assessments for a user +- [ ] Compare scores over time (score trend chart) +- [ ] Show improvement/decline indicators +- [ ] Add "View History" button on team roster +- [ ] Display last assessment date prominently + +#### 3. Password Change Feature โฑ๏ธ 2-3 hours +- [ ] Add "Change Password" to profile page +- [ ] First-login password change prompt (optional) +- [ ] Validate new password requirements +- [ ] Success confirmation + +### Medium Priority (Post-Demo Enhancements) + +#### 4. Reassessment Workflow โฑ๏ธ 2-3 hours +- [ ] "Due for reassessment" indicator (e.g., 90 days since last) +- [ ] Filter team roster by assessment status +- [ ] Quick "reassess" action from team list +- [ ] Reassessment reminders/notifications + +#### 5. Clinic Dashboard Analytics โฑ๏ธ 3-4 hours +- [ ] Assessments completed this week/month +- [ ] Department-wide average FMS score +- [ ] Score trends over time (improving vs declining) +- [ ] Personnel needing attention (low scores, overdue assessments) + +#### 6. Series Management for Clinic โฑ๏ธ 2-3 hours +- [ ] View all active series assignments +- [ ] Reassign or cancel series +- [ ] Track series completion rates +- [ ] See which series are most effective + +### Lower Priority (Future Iterations) + +#### 7. Multi-Station Support +- [ ] Clinic assigned to multiple stations +- [ ] Station selector in clinic dashboard +- [ ] Cross-station reporting +- [ ] Separate manager app for multi-station admin + +#### 8. Email Notifications +- [ ] Welcome email with credentials +- [ ] Assessment completion notifications +- [ ] Series assignment notifications +- [ ] Weekly progress summaries + +#### 9. Advanced Reporting +- [ ] Export data to CSV/PDF +- [ ] Custom date range reports +- [ ] Injury correlation with FMS scores +- [ ] ROI metrics (cost savings from injury prevention) + +--- + +## ๐Ÿ“‹ Demo Accounts + +| Role | Email | Password | +|------|-------|----------| +| Clinic | clinic@firestation1.com | demo123 | +| Chief | chief@firestation1.com | demo123 | +| Firefighter | john@firestation1.com | demo123 | + +--- + +## ๐Ÿ“‹ Clinic App - Next Steps + +### Phase 3: Advanced Features + +#### High Priority +1. **Video Upload/Integration** โฑ๏ธ 3-4 hours + - Supabase Storage setup for videos + - Video upload interface for exercises + - Video player component + - YouTube/Vimeo URL integration option + +2. **Email Notifications** โฑ๏ธ 4-5 hours + - Resend or SendGrid integration + - Welcome email template + - Exercise assignment notifications + - Streak reminder emails + +#### Medium Priority +4. **Phase Progression Logic** โฑ๏ธ 3-4 hours + - Automatic advancement based on completion rate + - Phase requirements (e.g., 80% completion to advance) + - Stabilize โ†’ Optimize progression + - Manual override for employees + +5. **Owner Analytics Enhancements** โฑ๏ธ 3-4 hours + - Date range filters + - Charts and graphs (Chart.js or Recharts) + - Export to CSV/PDF + - Trend analysis + - Comparison metrics (month over month) + +6. **Patient Profile Management** โฑ๏ธ 2 hours + - Edit profile page + - Profile photo upload + - Contact information + - Emergency contact + - Medical history notes + +#### Lower Priority +7. **Exercise History Page** โฑ๏ธ 2 hours + - Patient view of all completed exercises + - Calendar view of activity + - Personal records tracking + - Exercise streaks per category + +8. **Achievement System Expansion** โฑ๏ธ 2-3 hours + - More achievement types + - Milestone badges (10, 25, 50, 100 exercises) + - Category-specific achievements + - Monthly challenges + - Achievement showcase page + +9. **Search & Filters** โฑ๏ธ 2 hours + - Employee dashboard filters (phase, activity status) + - Exercise library search + - Assessment history filters + - Date range selectors + +10. **Mobile App Considerations** โฑ๏ธ Research + - PWA setup + - Push notifications + - Offline support + - Mobile-specific UI improvements + +--- + +## ๐Ÿ”ง Technical Debt & Improvements + +### Code Quality +- [ ] Add comprehensive error handling +- [ ] Implement loading states consistently +- [ ] Add form validation with Zod +- [ ] Write unit tests (Jest + React Testing Library) +- [ ] Add E2E tests (Playwright or Cypress) +- [ ] Implement proper TypeScript types throughout +- [ ] Add JSDoc comments for complex functions + +### Performance +- [ ] Optimize image loading (Next.js Image component) +- [ ] Implement lazy loading for heavy components +- [ ] Add pagination for long lists +- [ ] Optimize database queries (reduce N+1 queries) +- [ ] Implement caching strategy +- [ ] Add service worker for PWA + +### Security +- [ ] Re-enable and refine RLS policies +- [ ] Implement rate limiting +- [ ] Add CSRF protection +- [ ] Sanitize user inputs +- [ ] Implement content security policy +- [ ] Add audit logging + +### UX Improvements +- [ ] Add skeleton loaders +- [ ] Improve error messages +- [ ] Add confirmation dialogs for destructive actions +- [ ] Implement undo functionality +- [ ] Add keyboard shortcuts +- [ ] Improve accessibility (ARIA labels, focus management) + +--- + +--- + +## ๐Ÿš€ Phase 4: Advanced Features + +### Advanced Gamification +- [ ] Leaderboards (clinic-wide, global) +- [ ] Challenges and competitions +- [ ] Reward tiers (Bronze, Silver, Gold) +- [ ] Customizable avatars +- [ ] Virtual rewards/unlockables +- [ ] Social features (share achievements) + +### Clinical Features +- [ ] Custom assessment templates +- [ ] Progress photos tracking +- [ ] Pain scale tracking +- [ ] Range of motion measurements +- [ ] Note-taking for each session +- [ ] Treatment plans beyond FMS + +### Multi-Clinic Support +- [ ] Organization accounts above clinics +- [ ] Clinic branding customization +- [ ] Multi-clinic reporting for franchises +- [ ] Clinic switching for employees + +### Communication +- [ ] In-app messaging between employee and patient +- [ ] Appointment scheduling +- [ ] Reminder system +- [ ] Exercise feedback loop +- [ ] Video call integration for remote sessions + +### Billing & Subscription +- [ ] Stripe integration +- [ ] Per-clinic subscription tiers +- [ ] Per-patient billing +- [ ] Invoice generation +- [ ] Payment history + +--- + +## ๐ŸŽจ UI/UX Enhancements + +### Design Improvements +- [ ] Dark mode support +- [ ] Custom themes per clinic +- [ ] Improved print styles +- [ ] Better mobile navigation +- [ ] Onboarding tour for new users +- [ ] Help tooltips and documentation + +### Data Visualization +- [ ] Progress charts (line/bar graphs) +- [ ] FMS score comparisons over time +- [ ] Exercise completion heatmap +- [ ] Body map for pain/mobility tracking +- [ ] Interactive mountain visualization + +--- + +## ๐Ÿ—๏ธ Infrastructure + +### DevOps +- [ ] Set up CI/CD pipeline +- [ ] Automated testing in CI +- [ ] Staging environment +- [ ] Database backups +- [ ] Monitoring (Sentry, LogRocket) +- [ ] Performance monitoring (Vercel Analytics) + +### Database +- [ ] Database migrations system +- [ ] Backup and restore procedures +- [ ] Data retention policies +- [ ] Archive old data + +### Documentation +- [ ] API documentation +- [ ] Component storybook +- [ ] User manuals for each role +- [ ] Video tutorials +- [ ] Deployment guide + +--- + +## ๐Ÿ“… Suggested Timeline + +### โœ… Phase 1: MVP (Completed Oct 30, 2025) +- Core authentication and dashboards +- FMS assessment tool +- Exercise assignment and completion +- Basic gamification + +### โœ… Phase 2: Critical Fixes (Completed Oct 31, 2025) +- Fixed exercise visibility +- Fixed FMS scoring +- Exercise customization +- Professional onboarding + +### Phase 3: Polish & Enhancements (Next 1-2 weeks) +- Animations (Framer Motion) +- Video integration +- Email notifications +- Phase progression logic + +### Phase 4: Analytics & Advanced Features (Weeks 3-4) +- Enhanced owner analytics +- Patient profile management +- Exercise history +- Achievement expansion + +### Phase 5: Testing & Refinement (Month 2) +- Comprehensive testing +- Security hardening +- Performance optimization +- Bug fixes + +### Phase 6: Advanced Gamification (Month 3) +- Leaderboards +- Challenges +- Enhanced achievement system +- Social features + +### Phase 7: Scale & Growth (Month 4+) +- Multi-clinic support +- Advanced clinical features +- Mobile app +- Billing integration + +--- + +## ๐ŸŽฏ Success Metrics + +### Phase 1 Goals (Achieved โœ…) +- โœ… Functional assessment tool +- โœ… Automated exercise assignment +- โœ… Patient engagement gamification +- โœ… Multi-role system working +- โœ… Data persistence and tracking + +### Phase 2 Goals (Achieved โœ…) +- โœ… Exercise visibility fixed +- โœ… FMS scoring accurate +- โœ… Exercise customization working +- โœ… Professional patient onboarding +- โœ… Complete documentation +- โœ… Ready for client demo + +### Phase 3 Goals (In Progress) +- [ ] 80%+ exercise completion rate +- [ ] Average 5+ day patient streaks +- [ ] Employee time savings (50% faster vs Excel) +- [ ] Positive user feedback from pilot clinic +- [ ] Video content integrated +- [ ] Animations polished + +### Long-term Goals +- [ ] 10+ clinic customers +- [ ] 1000+ active patients +- [ ] 90%+ patient retention +- [ ] Measurable improvement in FMS scores +- [ ] Reduced patient dropout rates + +--- + +## ๐Ÿค” Open Questions / Decisions Needed + +1. **Video Hosting**: Self-host on Supabase or use YouTube/Vimeo? +2. **Email Service**: Resend, SendGrid, or Amazon SES? +3. **Charts Library**: Chart.js, Recharts, or D3? +4. **Mobile Strategy**: PWA first or native app? +5. **Pricing Model**: Per-clinic, per-patient, or per-employee? +6. **Branding**: Allow clinic white-labeling? +7. **Data Export**: What formats needed? (CSV, PDF, XLSX?) + +--- + +## ๐Ÿ“ž Next Session Prep + +### Before You Start Tomorrow: +1. Review `DEVELOPMENT.md` for Phase 2 summary +2. Review `README.md` for complete feature list +3. Check `DATABASE_SCHEMA.md` if working with database +4. Run `npm run dev` to ensure everything still works +5. Decide which feature from Phase 3 to tackle first + - **Recommended**: Start with Framer Motion animations for polish + - **Alternative**: Video integration if you have video content ready + - **Alternative**: Email notifications for production readiness + +### Quick Start Commands: +```bash +# Start development server +npm run dev + +# Check if Supabase is connected +# (Visit http://localhost:3001 and try logging in) + +# Test password reset flow +# (Add a patient via employee dashboard, check email) + +# Verify FMS scoring +# (Create assessment with bilateral movements, check score โ‰ค 21) + +# Test daily tracking +# (Complete same exercise multiple times, verify points only on first) +``` + +### Phase 2 Recap: +- โœ… 10 major features completed +- โœ… 5 critical bugs fixed +- โœ… 3 database migrations applied +- โœ… Complete documentation written +- โœ… Ready for client demo + +### Recommended Next Features (in order): +1. **Framer Motion Animations** - Quick visual polish (2-3 hrs) +2. **Video Integration** - Core functionality enhancement (3-4 hrs) +3. **Email Notifications** - Production readiness (4-5 hrs) +4. **Phase Progression Logic** - Gamification enhancement (3-4 hrs) + +--- + +**Last Updated**: November 30, 2025 (Clinic Role Feature Complete) +**Next Review**: After Fire App High Priority Features \ No newline at end of file diff --git a/clinic-app/app/auth/login/page.tsx b/clinic-app/app/auth/login/page.tsx new file mode 100644 index 0000000..f912f8d --- /dev/null +++ b/clinic-app/app/auth/login/page.tsx @@ -0,0 +1,238 @@ +'use client' + +import { useState } from 'react' +import { useRouter } from 'next/navigation' +import Link from 'next/link' +import { motion } from 'framer-motion' +import { createClient } from '@/lib/supabase/client' +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { AnimatedCard, AnimatedCardContent, AnimatedCardDescription, AnimatedCardFooter, AnimatedCardHeader, AnimatedCardTitle } from '@/components/ui/animated-card' +import { Skeleton } from '@/components/ui/skeleton' +import { Mountain, Mail, Lock, AlertCircle, ArrowRight, Loader2 } from 'lucide-react' +import Image from 'next/image' + +const container = { + hidden: { opacity: 0 }, + show: { + opacity: 1, + transition: { + staggerChildren: 0.1 + } + } +} + +const item = { + hidden: { opacity: 0, y: 20 }, + show: { opacity: 1, y: 0 } +} + +export default function LoginPage() { + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [error, setError] = useState(null) + const [loading, setLoading] = useState(false) + const router = useRouter() + const supabase = createClient() + + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault() + setError(null) + setLoading(true) + + try { + const { error: signInError } = await supabase.auth.signInWithPassword({ + email, + password, + }) + + if (signInError) { + setError(signInError.message) + return + } + + // Get user role and redirect accordingly + const { data: { user } } = await supabase.auth.getUser() + if (user) { + const { data: userData } = await supabase + .from('users') + .select('role') + .eq('id', user.id) + .single() + + if (userData) { + router.push(`/${userData.role}`) + } else { + router.push('/') + } + } + } catch (err) { + setError('An unexpected error occurred') + } finally { + setLoading(false) + } + } + + return ( +
+ {/* Background Pattern */} +
+
+
+
+ + + + + + {/* Logo or Mountain Icon */} +
+ +
+
+ + + Welcome to Summit + + + Begin your journey to recovery + +
+ +
+ + + {error && ( + + + {error} + + )} + + + + setEmail(e.target.value)} + required + disabled={loading} + className="h-12 rounded-xl border-2 focus:border-summit-blue transition-colors" + /> + + + +
+ + + Forgot password? + +
+ setPassword(e.target.value)} + required + disabled={loading} + className="h-12 rounded-xl border-2 focus:border-summit-blue transition-colors" + /> +
+
+
+ + + + +
+
+
+
+
+ Or +
+
+ + + Don't have an account?{' '} + + Create one + + +
+
+
+ + {/* Footer */} + + By signing in, you agree to our Terms of Service and Privacy Policy + +
+
+ ) +} \ No newline at end of file diff --git a/clinic-app/app/auth/reset-password/page.tsx b/clinic-app/app/auth/reset-password/page.tsx new file mode 100644 index 0000000..d95de36 --- /dev/null +++ b/clinic-app/app/auth/reset-password/page.tsx @@ -0,0 +1,296 @@ +'use client' + +import { useState, useEffect } from 'react' +import { useRouter } from 'next/navigation' +import { motion } from 'framer-motion' +import { createClient } from '@/lib/supabase/client' +import { AnimatedCard, AnimatedCardContent, AnimatedCardDescription, AnimatedCardHeader, AnimatedCardTitle } from '@/components/ui/animated-card' +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { Shield, Lock, CheckCircle2, AlertCircle, ArrowLeft, Loader2, KeyRound } from 'lucide-react' + +const container = { + hidden: { opacity: 0 }, + show: { + opacity: 1, + transition: { + staggerChildren: 0.1 + } + } +} + +const item = { + hidden: { opacity: 0, y: 20 }, + show: { opacity: 1, y: 0 } +} + +export default function ResetPasswordPage() { + const router = useRouter() + const supabase = createClient() + + const [password, setPassword] = useState('') + const [confirmPassword, setConfirmPassword] = useState('') + const [loading, setLoading] = useState(false) + const [error, setError] = useState('') + const [success, setSuccess] = useState(false) + + useEffect(() => { + // Check if user is accessing this page via password reset link + supabase.auth.onAuthStateChange(async (event, session) => { + if (event === 'PASSWORD_RECOVERY') { + // User clicked the reset link, ready to set new password + console.log('Password recovery mode activated') + } + }) + }, [supabase.auth]) + + const handleResetPassword = async (e: React.FormEvent) => { + e.preventDefault() + setError('') + setLoading(true) + + // Validation + if (password.length < 6) { + setError('Password must be at least 6 characters long') + setLoading(false) + return + } + + if (password !== confirmPassword) { + setError('Passwords do not match') + setLoading(false) + return + } + + try { + const { error: updateError } = await supabase.auth.updateUser({ + password: password + }) + + if (updateError) { + setError(updateError.message) + } else { + setSuccess(true) + setTimeout(() => { + router.push('/auth/login') + }, 2000) + } + } catch (err) { + setError('An unexpected error occurred') + console.error(err) + } finally { + setLoading(false) + } + } + + if (success) { + return ( +
+ {/* Background Pattern */} +
+
+
+
+ + + + + +
+ + + +
+
+ Password Updated! + + Your password has been successfully changed. Redirecting to login... + +
+
+
+
+ ) + } + + return ( +
+ {/* Background Pattern */} +
+
+
+
+ + + + + +
+ +
+
+ + Set Your Password + + + Create a secure password for your Summit account + +
+ + +
+ + {error && ( + + + {error} + + )} + + + + setPassword(e.target.value)} + required + minLength={6} + className="h-12 rounded-xl border-2 focus:border-summit-blue transition-colors" + /> +

Must be at least 6 characters

+
+ + + + setConfirmPassword(e.target.value)} + required + minLength={6} + className="h-12 rounded-xl border-2 focus:border-summit-blue transition-colors" + /> + {password && confirmPassword && password !== confirmPassword && ( + + Passwords do not match + + )} + {password && confirmPassword && password === confirmPassword && ( + + + Passwords match + + )} + + + + + + + +
+
+
+
+ + {/* Footer */} + + Need help? Contact your clinic administrator + +
+
+ ) +} \ No newline at end of file diff --git a/clinic-app/app/auth/signup/page.tsx b/clinic-app/app/auth/signup/page.tsx new file mode 100644 index 0000000..129f209 --- /dev/null +++ b/clinic-app/app/auth/signup/page.tsx @@ -0,0 +1,311 @@ +'use client' + +import { useState } from 'react' +import { useRouter, useSearchParams } from 'next/navigation' +import Link from 'next/link' +import { motion } from 'framer-motion' +import { createClient } from '@/lib/supabase/client' +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { AnimatedCard, AnimatedCardContent, AnimatedCardDescription, AnimatedCardFooter, AnimatedCardHeader, AnimatedCardTitle } from '@/components/ui/animated-card' +import { Mountain, Mail, Lock, User, AlertCircle, ArrowRight, Loader2, UserPlus, CheckCircle } from 'lucide-react' + +const container = { + hidden: { opacity: 0 }, + show: { + opacity: 1, + transition: { + staggerChildren: 0.1 + } + } +} + +const item = { + hidden: { opacity: 0, y: 20 }, + show: { opacity: 1, y: 0 } +} + +export default function SignupPage() { + const searchParams = useSearchParams() + const inviteCode = searchParams.get('invite') // Invite code from employee + + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [firstName, setFirstName] = useState('') + const [lastName, setLastName] = useState('') + const [error, setError] = useState(null) + const [loading, setLoading] = useState(false) + const router = useRouter() + const supabase = createClient() + + const handleSignup = async (e: React.FormEvent) => { + e.preventDefault() + setError(null) + setLoading(true) + + try { + // For MVP, we'll create a simple patient signup + // In production, this would validate the invite code + const { data: authData, error: signUpError } = await supabase.auth.signUp({ + email, + password, + options: { + data: { + first_name: firstName, + last_name: lastName, + role: 'patient', // Default to patient for now + } + } + }) + + if (signUpError) { + setError(signUpError.message) + return + } + + if (authData.user) { + // Create user profile + const { error: profileError } = await supabase + .from('users') + .insert({ + id: authData.user.id, + email, + first_name: firstName, + last_name: lastName, + role: 'patient', + // clinic_id would be set based on invite code in production + }) + + if (profileError) { + console.error('Profile creation error:', profileError) + setError(`Failed to create user profile: ${profileError.message}`) + return + } + + // Initialize patient progress + await supabase + .from('patient_progress') + .insert({ + patient_id: authData.user.id, + phase: 'analyze', + points: 0, + streak_days: 0, + total_exercises_completed: 0, + }) + + router.push('/patient') + } + } catch (err) { + setError('An unexpected error occurred') + } finally { + setLoading(false) + } + } + + return ( +
+ {/* Background Pattern */} +
+
+
+
+ + + + + + {/* Logo or Mountain Icon */} +
+ +
+
+ + + Join Summit + + + {inviteCode + ? 'Complete your registration to begin your recovery journey' + : 'Create your account to reach new heights' + } + +
+ +
+ + + {error && ( + + + {error} + + )} + + {inviteCode && ( + + + You've been invited by your healthcare provider + + )} + + +
+ + setFirstName(e.target.value)} + required + disabled={loading} + className="h-12 rounded-xl border-2 focus:border-summit-blue transition-colors" + /> +
+
+ + setLastName(e.target.value)} + required + disabled={loading} + className="h-12 rounded-xl border-2 focus:border-summit-blue transition-colors" + /> +
+
+ + + + setEmail(e.target.value)} + required + disabled={loading} + className="h-12 rounded-xl border-2 focus:border-summit-blue transition-colors" + /> + + + + + setPassword(e.target.value)} + required + disabled={loading} + minLength={6} + className="h-12 rounded-xl border-2 focus:border-summit-blue transition-colors" + /> +

+ Must be at least 6 characters +

+
+
+
+ + + + +
+
+
+
+
+ Or +
+
+ + + Already have an account?{' '} + + Sign in instead + + +
+
+
+ + {/* Footer */} + + By creating an account, you agree to our Terms of Service and Privacy Policy + +
+
+ ) +} \ No newline at end of file diff --git a/clinic-app/app/employee/assessment/page.tsx b/clinic-app/app/employee/assessment/page.tsx new file mode 100644 index 0000000..0205424 --- /dev/null +++ b/clinic-app/app/employee/assessment/page.tsx @@ -0,0 +1,714 @@ +'use client' + +import { useState, useEffect } from 'react' +import { useRouter } from 'next/navigation' +import { motion, AnimatePresence } from 'framer-motion' +import { createClient } from '@/lib/supabase/client' +import { AnimatedCard, AnimatedCardContent, AnimatedCardDescription, AnimatedCardHeader, AnimatedCardTitle } from '@/components/ui/animated-card' +import { Button } from '@/components/ui/button' +import { Label } from '@/components/ui/label' +import { Badge } from '@/components/ui/badge' +import { Skeleton } from '@/components/ui/skeleton' +import { ProgressBar } from '@/components/ui/progress-bar' +import { + ArrowLeft, + Save, + AlertCircle, + CheckCircle2, + ClipboardList, + User, + Activity, + ChevronRight, + FileText, + Target, + Loader2, + Info, + Mountain +} from 'lucide-react' + +interface Patient { + id: string + first_name: string + last_name: string + email: string +} + +interface FMSScores { + deep_squat: number + hurdle_step_left: number + hurdle_step_right: number + inline_lunge_left: number + inline_lunge_right: number + shoulder_mobility_left: number + shoulder_mobility_right: number + active_straight_leg_raise_left: number + active_straight_leg_raise_right: number + trunk_stability_push_up: number + rotary_stability_left: number + rotary_stability_right: number +} + +const initialScores: FMSScores = { + deep_squat: 0, + hurdle_step_left: 0, + hurdle_step_right: 0, + inline_lunge_left: 0, + inline_lunge_right: 0, + shoulder_mobility_left: 0, + shoulder_mobility_right: 0, + active_straight_leg_raise_left: 0, + active_straight_leg_raise_right: 0, + trunk_stability_push_up: 0, + rotary_stability_left: 0, + rotary_stability_right: 0, +} + +const container = { + hidden: { opacity: 0 }, + show: { + opacity: 1, + transition: { + staggerChildren: 0.1 + } + } +} + +const item = { + hidden: { opacity: 0, y: 20 }, + show: { opacity: 1, y: 0 } +} + +const movementPatterns = [ + { + id: 'deep_squat', + name: 'Deep Squat', + bilateral: false, + icon: '๐Ÿ‹๏ธ', + description: 'Tests bilateral symmetry and functional mobility' + }, + { + id: 'hurdle_step', + name: 'Hurdle Step', + bilateral: true, + icon: '๐Ÿฆต', + description: 'Assesses stepping and balance' + }, + { + id: 'inline_lunge', + name: 'Inline Lunge', + bilateral: true, + icon: '๐Ÿคธ', + description: 'Tests hip and ankle mobility' + }, + { + id: 'shoulder_mobility', + name: 'Shoulder Mobility', + bilateral: true, + icon: '๐Ÿ’ช', + description: 'Evaluates shoulder range of motion' + }, + { + id: 'active_straight_leg_raise', + name: 'Active Straight Leg Raise', + bilateral: true, + icon: '๐Ÿฆฟ', + description: 'Tests hamstring flexibility' + }, + { + id: 'trunk_stability_push_up', + name: 'Trunk Stability Push-Up', + bilateral: false, + icon: '๐Ÿƒ', + description: 'Assesses core stability' + }, + { + id: 'rotary_stability', + name: 'Rotary Stability', + bilateral: true, + icon: '๐Ÿ”„', + description: 'Tests multi-plane stability' + }, +] + +export default function FMSAssessmentPage() { + const [employee, setEmployee] = useState(null) + const [patients, setPatients] = useState([]) + const [selectedPatient, setSelectedPatient] = useState('') + const [scores, setScores] = useState(initialScores) + const [notes, setNotes] = useState('') + const [loading, setLoading] = useState(false) + const [fetching, setFetching] = useState(true) + const [success, setSuccess] = useState(false) + const [currentSection, setCurrentSection] = useState(0) + const router = useRouter() + const supabase = createClient() + + useEffect(() => { + fetchData() + }, []) + + const fetchData = async () => { + try { + const { data: { user } } = await supabase.auth.getUser() + if (!user) { + router.push('/auth/login') + return + } + + // Get employee data + const { data: employeeData } = await supabase + .from('users') + .select('*') + .eq('id', user.id) + .single() + + if (employeeData?.role !== 'employee' && employeeData?.role !== 'owner') { + router.push('/patient') + return + } + + setEmployee(employeeData) + + // Get patients in the same clinic + const { data: patientsData } = await supabase + .from('users') + .select('id, first_name, last_name, email') + .eq('clinic_id', employeeData.clinic_id) + .eq('role', 'patient') + + if (patientsData) { + setPatients(patientsData) + } + } finally { + setFetching(false) + } + } + + const calculateTotalScore = () => { + // For bilateral movements, take the lower of the two scores + const deepSquat = scores.deep_squat + const hurdleStep = Math.min(scores.hurdle_step_left, scores.hurdle_step_right) + const inlineLunge = Math.min(scores.inline_lunge_left, scores.inline_lunge_right) + const shoulderMobility = Math.min(scores.shoulder_mobility_left, scores.shoulder_mobility_right) + const activeStraightLegRaise = Math.min(scores.active_straight_leg_raise_left, scores.active_straight_leg_raise_right) + const trunkStability = scores.trunk_stability_push_up + const rotaryStability = Math.min(scores.rotary_stability_left, scores.rotary_stability_right) + + // Total score is sum of all 7 movement patterns (max 21) + return deepSquat + hurdleStep + inlineLunge + shoulderMobility + + activeStraightLegRaise + trunkStability + rotaryStability + } + + const getScoreColor = (score: number) => { + if (score === 0) return 'bg-gray-500' + if (score === 1) return 'bg-destructive' + if (score === 2) return 'bg-warning' + return 'bg-success' + } + + const getScoreLabel = (score: number) => { + if (score === 0) return 'Unable' + if (score === 1) return 'Poor' + if (score === 2) return 'Moderate' + return 'Good' + } + + const handleScoreChange = (movement: keyof FMSScores, score: number) => { + setScores(prev => ({ ...prev, [movement]: score })) + } + + const assignExercisesBasedOnScores = async (patientId: string, assessmentScores: FMSScores, assessmentId: string) => { + // Get all exercises + const { data: exercises } = await supabase + .from('exercises') + .select('*') + + if (!exercises) return + + const exercisesToAssign = [] + const today = new Date() + const startDate = new Date(today) + const endDate = new Date(today) + endDate.setDate(endDate.getDate() + 7) // 7-day program + + // Calculate effective scores for each movement pattern (taking lower of bilateral) + const movementScores = { + 'Deep Squat': assessmentScores.deep_squat, + 'Hurdle Step': Math.min(assessmentScores.hurdle_step_left, assessmentScores.hurdle_step_right), + 'Inline Lunge': Math.min(assessmentScores.inline_lunge_left, assessmentScores.inline_lunge_right), + 'Shoulder Mobility': Math.min(assessmentScores.shoulder_mobility_left, assessmentScores.shoulder_mobility_right), + 'ASLR': Math.min(assessmentScores.active_straight_leg_raise_left, assessmentScores.active_straight_leg_raise_right), + 'Trunk Stability': assessmentScores.trunk_stability_push_up, + 'Rotary Stability': Math.min(assessmentScores.rotary_stability_left, assessmentScores.rotary_stability_right), + } + + // Check each movement pattern + for (const [category, score] of Object.entries(movementScores)) { + if (score <= 1) { // Needs corrective exercises + // Get exercises for this category + const categoryExercises = exercises.filter(ex => ex.category === category) + + // Add only 1 exercise per category to reduce total count + categoryExercises.slice(0, 1).forEach(exercise => { + exercisesToAssign.push({ + patient_id: patientId, + exercise_id: exercise.id, + assigned_by: employee.id, + assigned_date: today.toISOString().split('T')[0], + start_date: startDate.toISOString().split('T')[0], + end_date: endDate.toISOString().split('T')[0], + due_date: endDate.toISOString().split('T')[0], // Keep for backward compatibility + daily_target: 1, // One completion per day + custom_sets: exercise.sets, // Initialize with exercise defaults + custom_reps: exercise.reps, // Initialize with exercise defaults + total_completions_required: 7, // Default to daily over 7 days + assessment_id: assessmentId, + phase: 'mobilize', // Start with mobilize phase for corrective work + }) + }) + } + } + + // Insert all exercise assignments + if (exercisesToAssign.length > 0) { + await supabase + .from('exercise_assignments') + .insert(exercisesToAssign) + } + + return { count: exercisesToAssign.length, assessmentId } + } + + const handleSubmit = async () => { + if (!selectedPatient) { + alert('Please select a patient') + return + } + + setLoading(true) + setSuccess(false) + + try { + // Save FMS assessment + const { data: assessment, error } = await supabase + .from('fms_assessments') + .insert({ + patient_id: selectedPatient, + employee_id: employee.id, + ...scores, + notes: notes || null, + }) + .select() + .single() + + if (error) { + console.error('Assessment error:', error) + alert(`Failed to save assessment: ${error.message}`) + return + } + + // Automatically assign exercises based on scores + const result = await assignExercisesBasedOnScores(selectedPatient, scores, assessment.id) + + // Update patient phase to 'mobilize' if they were in 'analyze' + await supabase + .from('patient_progress') + .update({ phase: 'mobilize' }) + .eq('patient_id', selectedPatient) + .eq('phase', 'analyze') + + setSuccess(true) + + // Show success and redirect to review page + setTimeout(() => { + alert(`Assessment saved! ${result?.count || 0} exercises assigned. Redirecting to review...`) + router.push(`/employee/assessment/review/${assessment.id}`) + }, 1500) + + } catch (error) { + console.error('Error:', error) + alert('An error occurred while saving the assessment') + } finally { + setLoading(false) + } + } + + const ScoreButton = ({ + score, + currentScore, + onClick, + size = 'normal' + }: { + score: number + currentScore: number + onClick: () => void + size?: 'normal' | 'large' + }) => ( + + {score} + + ) + + if (fetching) { + return ( +
+
+ +

Loading assessment...

+
+ + +
+
+
+ ) + } + + const selectedPatientData = patients.find(p => p.id === selectedPatient) + + return ( +
+ {/* Header */} +
+
+
+ + +

+ + FMS Assessment +

+

Functional Movement Screen Scoring

+
+ {selectedPatientData && ( + +

Assessing

+

+ {selectedPatientData.first_name} {selectedPatientData.last_name} +

+
+ )} +
+
+
+ +
+ + {/* Patient Selection */} + + + + + + Patient Information + + Select the patient for this assessment + + + + + + + + + {/* Score Legend */} + + + +
+
+ + Scoring Guide: +
+
+ {[0, 1, 2, 3].map(score => ( + + {score} = {getScoreLabel(score)} + + ))} +
+
+
+
+
+ + {/* Movement Patterns */} + + + + + + Movement Pattern Scoring + + + Score each movement from 0-3. Lower scores indicate areas needing correction. + + + {/* Progress Bar */} +
+ +
+
+ + + + {movementPatterns.map((pattern, index) => ( + +
+
+
+ +

{pattern.description}

+
+
+ + {!pattern.bilateral ? ( + // Single scoring +
+ {[0, 1, 2, 3].map(score => ( + handleScoreChange(pattern.id as keyof FMSScores, score)} + size="large" + /> + ))} +
+ ) : ( + // Bilateral scoring +
+
+ +
+ {[0, 1, 2, 3].map(score => ( + handleScoreChange(`${pattern.id}_left` as keyof FMSScores, score)} + /> + ))} +
+
+
+ +
+ {[0, 1, 2, 3].map(score => ( + handleScoreChange(`${pattern.id}_right` as keyof FMSScores, score)} + /> + ))} +
+
+
+ )} +
+
+ ))} +
+
+
+
+ + {/* Notes and Summary */} + + + + + + Assessment Summary + + + +
+ +