feat: complete Phase 3 — advanced features for Casera web app
Adds sharing (residence share codes, join, user management, .casera file export/import), subscription status with feature comparison, notification preferences with bell icon, profile settings (edit info, change password, theme picker, delete account), onboarding wizard with create/join paths, enhanced dashboard with stats cards, Recharts completion chart, recent activity feed, and task report PDF download. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
# Phase 3 — Advanced Features
|
||||
|
||||
Build sharing, subscriptions, notifications, profile, onboarding, and summary metrics.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Residence sharing: generate/display share code, join residence, manage users, .casera file export/import
|
||||
- [ ] Contractor sharing: .casera file export/import
|
||||
- [ ] Subscription: status display, feature comparison, upgrade prompt, usage tracking
|
||||
- [ ] Notification preferences: toggle + time picker per notification type
|
||||
- [ ] Profile: edit name/email, change password, delete account
|
||||
- [ ] Onboarding: multi-step wizard (fresh vs join paths)
|
||||
- [ ] Summary metrics: dashboard cards with Recharts
|
||||
- [ ] Task report: PDF generation + download
|
||||
|
||||
---
|
||||
|
||||
## 1. Residence Sharing
|
||||
|
||||
### Screens
|
||||
|
||||
| Route | Screen | Description |
|
||||
|-------|--------|-------------|
|
||||
| `/app/residences/[id]/share` | Share Residence | Generate/display share code, manage users |
|
||||
| `/app/residences/join` | Join Residence | Enter share code or import .casera file |
|
||||
|
||||
### Share Code Flow
|
||||
|
||||
```
|
||||
Owner opens Share screen
|
||||
→ If no active share code: "Generate Share Code" button
|
||||
→ POST /api/residences/:id/share/ → returns { code: "ABC123", expires_at: "..." }
|
||||
→ Display code with copy button + expiry countdown
|
||||
→ "Revoke" button to disable code
|
||||
|
||||
Invitee opens Join screen
|
||||
→ Enter share code manually, OR
|
||||
→ Upload .casera file (drag-and-drop zone)
|
||||
→ POST /api/residences/join/ { code: "ABC123" }
|
||||
→ On success: redirect to residence detail
|
||||
```
|
||||
|
||||
### .casera File Handling
|
||||
|
||||
**Export** (owner):
|
||||
- Button on residence detail: "Export as .casera"
|
||||
- Generates JSON file with `{ type: "residence", code: "ABC123", ... }`
|
||||
- Browser downloads the file
|
||||
|
||||
**Import** (invitee):
|
||||
- Drag-and-drop zone on join page
|
||||
- Or file picker button
|
||||
- Read JSON, extract code, auto-submit join request
|
||||
|
||||
### Manage Users
|
||||
|
||||
| Action | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| List users | `GET /api/residences/:id/users/` | Show all users with roles |
|
||||
| Remove user | `DELETE /api/residences/:id/users/:userId/` | Owner removes a member |
|
||||
|
||||
### API Endpoints
|
||||
|
||||
| Method | Endpoint | Purpose |
|
||||
|--------|----------|---------|
|
||||
| POST | `/api/residences/:id/share/` | Generate share code |
|
||||
| DELETE | `/api/residences/:id/share/` | Revoke share code |
|
||||
| POST | `/api/residences/join/` | Join with share code |
|
||||
| GET | `/api/residences/:id/users/` | List users |
|
||||
| DELETE | `/api/residences/:id/users/:userId/` | Remove user |
|
||||
|
||||
---
|
||||
|
||||
## 2. Contractor Sharing
|
||||
|
||||
### .casera File Export/Import
|
||||
|
||||
**Export**:
|
||||
- Button on contractor detail: "Share Contractor"
|
||||
- Generates JSON file with `{ type: "contractor", name: "...", phone: "...", ... }`
|
||||
- Browser downloads the file
|
||||
|
||||
**Import**:
|
||||
- Button on contractor list: "Import Contractor"
|
||||
- File picker or drag-and-drop for .casera file
|
||||
- Read JSON, show confirmation dialog, create contractor
|
||||
- `POST /api/contractors/import/`
|
||||
|
||||
---
|
||||
|
||||
## 3. Subscription
|
||||
|
||||
### Screens
|
||||
|
||||
| Route | Screen | Description |
|
||||
|-------|--------|-------------|
|
||||
| `/app/settings/subscription` | Subscription Status | Current plan, usage, upgrade CTA |
|
||||
|
||||
### Status Display
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Current Plan: Free │
|
||||
│ Residences: 1/1 Tasks: 5/5 │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ Upgrade to Premium │ │
|
||||
│ │ • Unlimited residences │ │
|
||||
│ │ • Unlimited tasks │ │
|
||||
│ │ • Document storage │ │
|
||||
│ │ • Priority support │ │
|
||||
│ │ [Upgrade on App Store] │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Feature Gating
|
||||
|
||||
Check tier limits before allowing creation:
|
||||
- If at limit → show upgrade prompt dialog instead of create form
|
||||
- Limits come from `GET /api/subscription/status/` response
|
||||
|
||||
### Upgrade Path (Phase 1)
|
||||
|
||||
Web users are directed to the mobile app for purchases:
|
||||
- "Download Casera on the App Store to upgrade"
|
||||
- Link to App Store listing
|
||||
|
||||
### Upgrade Path (Future — Phase 2)
|
||||
|
||||
Add Stripe Checkout for web-only subscription purchases. Requires backend work to support Stripe webhooks alongside StoreKit/Play Store.
|
||||
|
||||
### API Endpoints
|
||||
|
||||
| Method | Endpoint | Purpose |
|
||||
|--------|----------|---------|
|
||||
| GET | `/api/subscription/status/` | Current subscription + limits |
|
||||
| GET | `/api/upgrade-triggers/` | Feature comparison data |
|
||||
|
||||
---
|
||||
|
||||
## 4. Notification Preferences
|
||||
|
||||
### Screen
|
||||
|
||||
| Route | Screen | Description |
|
||||
|-------|--------|-------------|
|
||||
| `/app/settings/notifications` | Notification Preferences | Toggle + time picker per type |
|
||||
|
||||
### Preference Types
|
||||
|
||||
| Preference | Description | Controls |
|
||||
|------------|-------------|----------|
|
||||
| Task Reminders | Reminders for upcoming due dates | Toggle on/off + time of day |
|
||||
| Overdue Alerts | Alerts when tasks become overdue | Toggle on/off |
|
||||
| Completion Confirmations | Notifications when tasks are completed | Toggle on/off |
|
||||
| Residence Updates | When someone else modifies your residence | Toggle on/off |
|
||||
|
||||
### API Endpoints
|
||||
|
||||
| Method | Endpoint | Purpose |
|
||||
|--------|----------|---------|
|
||||
| GET | `/api/notifications/preferences/` | Get all preferences |
|
||||
| PUT | `/api/notifications/preferences/:id/` | Update a preference |
|
||||
| GET | `/api/notifications/` | List notifications (in-app inbox) |
|
||||
| POST | `/api/notifications/:id/read/` | Mark notification as read |
|
||||
|
||||
### In-App Notification Inbox
|
||||
|
||||
- Bell icon in top bar with unread count badge
|
||||
- Dropdown panel showing recent notifications
|
||||
- Click to navigate to related item
|
||||
- "Mark all as read" action
|
||||
|
||||
---
|
||||
|
||||
## 5. Profile
|
||||
|
||||
### Screen
|
||||
|
||||
| Route | Screen | Description |
|
||||
|-------|--------|-------------|
|
||||
| `/app/settings/profile` | Profile Settings | Edit name, email, password, delete account |
|
||||
|
||||
### Sections
|
||||
|
||||
**Personal Info:**
|
||||
- First name, Last name, Email
|
||||
- `PUT /api/auth/profile/`
|
||||
|
||||
**Change Password:**
|
||||
- Current password, New password, Confirm new password
|
||||
- `POST /api/auth/change-password/`
|
||||
|
||||
**Danger Zone:**
|
||||
- Delete account button with confirmation dialog
|
||||
- `DELETE /api/auth/account/`
|
||||
|
||||
**Theme:**
|
||||
- Theme picker (11 options, preview swatches)
|
||||
- Dark/light mode toggle
|
||||
- Persisted to localStorage
|
||||
|
||||
---
|
||||
|
||||
## 6. Onboarding
|
||||
|
||||
### Screen
|
||||
|
||||
| Route | Screen | Description |
|
||||
|-------|--------|-------------|
|
||||
| `/onboarding` | Onboarding Wizard | Multi-step flow after first registration |
|
||||
|
||||
### Flow
|
||||
|
||||
```
|
||||
Step 1: Welcome
|
||||
→ "Welcome to Casera! Let's set up your first property."
|
||||
|
||||
Step 2: Choose Path
|
||||
→ "Create a new residence" OR "Join an existing residence"
|
||||
|
||||
Path A: Create Residence
|
||||
Step 3a: Residence form (name, address, type)
|
||||
Step 4a: "Add your first task?" (optional quick-add)
|
||||
Step 5a: Done → redirect to residence detail
|
||||
|
||||
Path B: Join Residence
|
||||
Step 3b: Enter share code
|
||||
Step 4b: Success → redirect to residence detail
|
||||
```
|
||||
|
||||
### State Management
|
||||
|
||||
Use Zustand store to track onboarding progress:
|
||||
```typescript
|
||||
interface OnboardingState {
|
||||
currentStep: number;
|
||||
path: 'create' | 'join' | null;
|
||||
residenceData: Partial<CreateResidenceRequest>;
|
||||
isComplete: boolean;
|
||||
nextStep: () => void;
|
||||
prevStep: () => void;
|
||||
setPath: (path: 'create' | 'join') => void;
|
||||
complete: () => void;
|
||||
}
|
||||
```
|
||||
|
||||
After completion, set a flag so onboarding isn't shown again:
|
||||
- `POST /api/auth/profile/` with `onboarding_complete: true`
|
||||
- Or store in localStorage as fallback
|
||||
|
||||
---
|
||||
|
||||
## 7. Summary Metrics
|
||||
|
||||
### Dashboard (Home Page)
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ Welcome back, Trey │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐│
|
||||
│ │ 3 │ │ 2 │ │ 12 │ │ 5 ││
|
||||
│ │ Overdue │ │ Due Today│ │ Active │ │ Done ││
|
||||
│ │ 🔴 │ │ 🟠 │ │ 🔵 │ │ ✅ ││
|
||||
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘│
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────┐│
|
||||
│ │ Task Completion Trend (last 30 days) ││
|
||||
│ │ [Area chart via Recharts] ││
|
||||
│ └─────────────────────────────────────────────────┘│
|
||||
│ │
|
||||
│ Recent Activity │
|
||||
│ • Task "Fix leak" completed 2h ago │
|
||||
│ • New contractor "Bob's Plumbing" added yesterday │
|
||||
│ • Residence "Main House" updated 3d ago │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Data sources:
|
||||
- Task counts from `GET /api/tasks/` response (column counts)
|
||||
- Summary calculated client-side from kanban data (same as mobile)
|
||||
- Charts via Recharts library
|
||||
|
||||
---
|
||||
|
||||
## 8. Task Reports
|
||||
|
||||
### Feature
|
||||
|
||||
- Button on residence detail: "Download Task Report"
|
||||
- `GET /api/residences/:id/report/` → returns PDF
|
||||
- Browser triggers download
|
||||
|
||||
---
|
||||
|
||||
## Deliverables
|
||||
|
||||
At the end of Phase 3, you should have:
|
||||
1. Residence sharing with code generation, join flow, and user management
|
||||
2. Contractor sharing via .casera files
|
||||
3. Subscription status with tier limits and upgrade prompts
|
||||
4. Notification preferences with toggles
|
||||
5. Profile editing (name, email, password, delete account)
|
||||
6. Onboarding wizard for new users
|
||||
7. Home dashboard with summary metrics and charts
|
||||
8. Task report PDF download
|
||||
Reference in New Issue
Block a user