diff --git a/.env.example b/.env.example index 0c53e43..be1511b 100644 --- a/.env.example +++ b/.env.example @@ -8,3 +8,7 @@ VITE_FIREBASE_PROJECT_ID=your-project-id VITE_FIREBASE_STORAGE_BUCKET=your-project.appspot.com VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id VITE_FIREBASE_APP_ID=your_app_id + +# Claude AI Assistant +# Get your API key from: https://console.anthropic.com/ +VITE_CLAUDE_API_KEY=example_key diff --git a/MOBILE_SUPPORT.md b/MOBILE_SUPPORT.md new file mode 100644 index 0000000..bff5851 --- /dev/null +++ b/MOBILE_SUPPORT.md @@ -0,0 +1,371 @@ +# Mobile Support Improvement Plan + +## Current Issues + +Based on testing, the current mobile implementation has several usability problems: + +1. **Circular chart is not properly centered** - Main feature of the app is hard to use +2. **Horizontal scrolling occurs** - Creates poor UX, elements overflow viewport +3. **Sidebar approach is clunky** - Takes up too much space when open, not intuitive +4. **Elements not optimally sized** - Some elements too small, others too large +5. **Footer visibility** - Footer might be interfering with content + +--- + +## Mobile-First Design Goals + +### Priority 1: Circular Chart (The Core Feature) +- **Must be perfectly centered** on the screen +- **Must never cause horizontal scrolling** +- **Must scale to fit viewport width** with proper padding +- **Must be the dominant visual element** on mobile +- All interactions must work smoothly with touch + +### Priority 2: Navigation +- **Remove sidebar completely on mobile** - not suitable for small screens +- Replace with **bottom navigation bar** (industry standard for mobile apps) + - 3-4 icons at bottom: Schedule Editor, My Schedules, Settings + - Always visible, doesn't take up much space + - Easy thumb access on phones + +### Priority 3: Layout & Viewport +- **No horizontal scrolling anywhere** +- **Vertical scrolling only** for timeline/content areas +- **Sticky header** with minimal height +- **Remove or minimize footer** on mobile (or make it absolutely positioned at bottom) + +### Priority 4: Controls & Actions +- **Compact header controls** - smaller, icon-only where possible +- **Floating Action Button (FAB)** for primary actions like "Save" +- **View toggle** (Linear/Circular) should be compact icons, not text buttons + +--- + +## Detailed Implementation Plan + +### 1. Circular Chart Component (src/components/CircularChart.tsx) + +**Changes:** +``` +- Calculate chart size based on viewport width +- Add horizontal padding: 16px on mobile, 24px on tablet +- Center chart using flex container +- Prevent overflow with: overflow-x: hidden on parent +- Max width: min(100vw - 32px, 500px) for chart container +- Position absolutely within centered container +``` + +**Layout:** +```html +
+
+
+ +
+
+
+``` + +### 2. Timeline Component (src/components/Timeline.tsx) + +**Changes:** +``` +- Full width on mobile (no side padding that causes overflow) +- Vertical scrolling only +- Time labels positioned carefully to not overflow +- Hour markers on left with negative margin: careful sizing +``` + +**Layout:** +```html +
+
+ +
+
+``` + +### 3. Navigation - Bottom Nav Bar (New Approach) + +**Create: src/components/BottomNav.tsx** + +```typescript +// Bottom navigation bar for mobile only +// Shown only on screens < 1024px (lg breakpoint) +// 3 main tabs: Schedule Editor, My Schedules, Settings +// Icons with labels below +// Active state highlighting +// Fixed to bottom of screen +``` + +**Design:** +``` +- Fixed position at bottom +- White background with top border shadow +- Height: 64px +- 3 equal-width buttons +- Icon (24px) + Label (10px text) +- Active: blue color, inactive: gray +- Safe area padding for iOS notch +``` + +**Example:** +```html + +``` + +### 4. Dashboard Layout Restructure (src/components/Dashboard.tsx) + +**Mobile Layout (< 1024px):** +``` +┌─────────────────────┐ +│ Compact Header │ ← Minimal height, essential controls only +├─────────────────────┤ +│ │ +│ Main Content │ ← Chart/Timeline fills space +│ (Scrollable) │ +│ │ +├─────────────────────┤ +│ Bottom Nav Bar │ ← Fixed at bottom (mobile only) +└─────────────────────┘ +``` + +**Desktop Layout (≥ 1024px):** +``` +┌───────┬─────────────────────┐ +│ │ Header │ +│ Side ├─────────────────────┤ +│ bar │ │ +│ │ Main Content │ +│ │ │ +└───────┴─────────────────────┘ +``` + +**Changes:** +``` +- Remove sidebar on mobile entirely (not even hamburger menu) +- Remove mobile sidebar backdrop/overlay +- Remove hamburger button +- Add bottom navigation component +- Header: much more compact on mobile +- Footer: hidden on mobile OR absolutely positioned +- Main content: flex-1 with proper overflow handling +``` + +### 5. Header Improvements (Mobile) + +**Current Issues:** +- Too tall on mobile +- Controls take up too much space +- Schedule dropdown is clunky + +**Mobile Header Design:** +``` +Height: 48px (down from current ~60px) +Layout: + - Left: Page title (small, 16px font) + - Right: Compact controls (icon buttons only) + +View toggle: Icon-only buttons (☰ for linear, ⭕ for circular) +Save button: Icon-only (💾) or FAB instead +Schedule selector: Icon/chevron only, opens bottom sheet +``` + +### 6. Footer Handling + +**Options:** + +**Option A: Hide on Mobile** +```css +.footer { + @apply hidden lg:block; +} +``` + +**Option B: Absolute Position** +```css +.footer { + @apply absolute bottom-0 left-0 right-0 lg:relative; + padding-bottom: env(safe-area-inset-bottom); +} +``` + +**Option C: Above Bottom Nav** +```css +.footer { + @apply mb-16 lg:mb-0; /* 64px for bottom nav */ +} +``` + +**Recommendation: Option A (Hide on mobile)** - Simplest, keeps focus on content + +### 7. Responsive Breakpoints Strategy + +```css +Mobile: < 640px (default styles) + - Bottom nav visible + - Sidebar hidden + - Compact header + - Chart: full width minus 32px padding + - Icon-only controls + +Tablet: 640px - 1023px (sm: to lg:) + - Bottom nav visible + - Sidebar hidden + - Slightly larger header + - Chart: max-width 500px, centered + - Some text labels shown + +Desktop: ≥ 1024px (lg:) + - Bottom nav hidden + - Sidebar visible (always shown) + - Full header with text labels + - Chart: flexible sizing + - All features visible +``` + +### 8. Specific Component Updates + +#### CircularChart.tsx +``` +✓ Container: flex justify-center items-center +✓ Max width constraint +✓ Responsive sizing based on viewport +✓ Prevent horizontal overflow +✓ Center tooltip positioning +``` + +#### Timeline.tsx +``` +✓ Full width within container +✓ Remove side overflow +✓ Time labels: careful positioning +✓ Blocks: proper touch targets (min 44px height) +``` + +#### Dashboard.tsx +``` +✓ Remove sidebar for mobile +✓ Add BottomNav component +✓ Restructure layout with proper flex +✓ Add overflow-x-hidden to main container +✓ Make header compact on mobile +✓ Hide/reposition footer +``` + +#### Header Controls +``` +✓ View toggle: sm:text-xs → icons only on mobile +✓ Save button: Consider FAB instead +✓ Schedule dropdown: Bottom sheet modal on mobile +``` + +--- + +## Implementation Order + +### Phase 1: Layout Foundation (Critical) +1. Add `overflow-x-hidden` to main Dashboard container +2. Remove sidebar/hamburger on mobile (< lg) +3. Restructure Dashboard flex layout +4. Hide footer on mobile + +### Phase 2: Bottom Navigation +1. Create BottomNav.tsx component +2. Add to Dashboard (mobile only) +3. Implement active state logic +4. Test navigation flow + +### Phase 3: Chart Centering +1. Wrap CircularChart in flex centering container +2. Add max-width constraints +3. Calculate responsive sizing +4. Test on various mobile sizes (320px - 768px) + +### Phase 4: Header Optimization +1. Reduce header height on mobile +2. Convert text buttons to icon-only +3. Simplify schedule selector +4. Test touch targets (min 44x44px) + +### Phase 5: Timeline Optimization +1. Ensure no horizontal overflow +2. Improve vertical scrolling +3. Optimize time label positioning +4. Test block creation on mobile + +### Phase 6: Polish & Testing +1. Test on real devices (iPhone, Android) +2. Test in Chrome DevTools mobile mode +3. Check all screen sizes: 320px, 375px, 390px, 414px, 768px +4. Verify no horizontal scrolling anywhere +5. Verify circular chart is perfectly centered +6. Test all touch interactions + +--- + +## Testing Checklist + +### Layout Tests +- [ ] No horizontal scrolling on any page +- [ ] Circular chart is perfectly centered +- [ ] Bottom nav is visible on mobile only +- [ ] Sidebar is hidden on mobile +- [ ] Footer doesn't interfere with content +- [ ] All pages use full viewport height + +### Interaction Tests +- [ ] Tap navigation items in bottom nav +- [ ] Drag to create time blocks (circular) +- [ ] Drag to create time blocks (linear) +- [ ] Toggle between linear/circular views +- [ ] Save schedule +- [ ] Edit time blocks +- [ ] All buttons are tappable (44x44px minimum) + +### Visual Tests +- [ ] Text is readable (min 14px on mobile) +- [ ] Colors have sufficient contrast +- [ ] Touch targets are appropriately sized +- [ ] Spacing feels comfortable +- [ ] No UI elements cut off or hidden +- [ ] Safe area padding on iPhone notch + +### Device Tests +- [ ] iPhone SE (375x667) - smallest modern iPhone +- [ ] iPhone 12/13/14 (390x844) +- [ ] iPhone 14 Pro Max (430x932) +- [ ] Samsung Galaxy S21 (360x800) +- [ ] iPad Mini (768x1024) +- [ ] Test in both portrait and landscape + +--- + +## Success Criteria + +After implementation, mobile experience should have: + +1. ✅ **Circular chart is the hero** - Perfectly centered, no scrolling to see it +2. ✅ **Zero horizontal scrolling** - Anywhere in the app +3. ✅ **Easy navigation** - Bottom nav is intuitive and thumb-friendly +4. ✅ **All features accessible** - Nothing hidden or hard to reach +5. ✅ **Smooth interactions** - Drag-to-create works flawlessly +6. ✅ **Professional feel** - Looks and feels like a native mobile app + +--- + +## Notes + +- **Don't use a hamburger menu** - Bottom nav is much better for mobile apps +- **Keep mobile simple** - Remove features if they clutter the UI +- **Touch targets matter** - Minimum 44x44px for all tappable elements +- **Test on real devices** - Emulators are good, but real devices are better +- **Consider gestures** - Swipe to switch between views could be cool (future) + +This plan prioritizes the circular chart as the centerpiece of the mobile experience and removes friction from navigation and layout. diff --git a/MOBILE_UX_IMPROVEMENTS.md b/MOBILE_UX_IMPROVEMENTS.md new file mode 100644 index 0000000..409679d --- /dev/null +++ b/MOBILE_UX_IMPROVEMENTS.md @@ -0,0 +1,117 @@ +# Mobile UX Improvement Plan + +## Current Status +- Chart is centered and not cut off ✅ +- Bottom action bar implemented ✅ +- Desktop recommendation message added ✅ + +## Issues to Fix + +### 1. **Desktop Scrolling Broken** 🔴 CRITICAL +- Desktop cannot scroll at all, stuck +- Likely caused by `overflow-auto` being conditionally applied in CircularChart +- **Fix**: Ensure desktop keeps `overflow-auto`, only remove on mobile +- **Location**: `src/components/CircularChart.tsx:542` + +### 2. **Make Chart Bigger on Mobile** 🟡 +**Options:** +- **Option A**: Reduce label margins further (from 28px to 24px) +- **Option B**: Move hour labels to inner circle (more complex) +- **Option C**: Show only key times (12 AM, 6 AM, 12 PM, 6 PM) and remove others +- **Recommended**: Option A (quick win) + Option C (better UX) + +**Changes needed**: +- Reduce `baseLabelMargin` from 28px to 24px +- Update `renderHourLabels()` to only show [0, 6, 12, 18] hours on mobile +- This saves ~8px around the circle = ~16px more chart diameter + +### 3. **Contextual Bottom Message** 🟢 +**Current**: "For best experience and to save schedules, use desktop" + +**New (contextual)**: +- **Guest users**: "Sign in on desktop to save schedules" +- **Authenticated users**: "Use desktop to manage multiple schedules" + +**Location**: `src/components/Dashboard.tsx:694` + +### 4. **Add Save Button for Authenticated Mobile Users** 🟢 +**Current**: Only showing "Delete All" for signed-in users + +**New**: Replace layout for authenticated users: +``` +[ Save Schedule ] [ Delete All ] +``` + +**Behavior**: +- Save button triggers `handleSaveSchedule()` +- Works the same as desktop (prompts for name, saves to Firebase) +- Users can save but cannot view/switch schedules on mobile + +**Location**: `src/components/Dashboard.tsx:669-693` + +### 5. **Schedule Dropdown on Mobile** 🔵 OPTIONAL +**Decision needed**: Should we add schedule management to mobile? + +**If YES**: +- Add schedule dropdown button in top section +- Show current schedule name +- Allow switching between schedules +- Keep UI minimal + +**If NO**: +- Just allow saving +- Users must use desktop to switch/manage schedules + +**Recommendation**: Start with just Save button, add dropdown later if needed + +## Implementation Order + +### Phase 1: Critical Fixes +1. ✅ Fix desktop scrolling issue +2. ✅ Add Save button for authenticated users +3. ✅ Make message contextual + +### Phase 2: Polish +4. ✅ Make chart bigger (reduce margins + show fewer time labels) +5. ⏸️ (Optional) Add schedule dropdown on mobile + +## Technical Details + +### Chart Size Calculation (iPhone XR: 414 × 896px) +**Current**: +- Height offset: 190px +- Label margin: 28px each side +- Available width: 414 - 8 - 56 = 350px +- Chart diameter: ~350px + +**Proposed**: +- Height offset: 190px (keep same) +- Label margin: 24px each side (reduced) +- Available width: 414 - 8 - 48 = 358px +- Chart diameter: ~358px (+2.3% bigger) + +### Hour Labels +**Current**: Shows all [0, 3, 6, 9, 12, 15, 18, 21] +**Proposed Mobile**: Show only [0, 6, 12, 18] (cardinal directions) + +This provides cleaner look and more space for the actual chart. + +## Files to Modify + +1. `src/components/CircularChart.tsx` + - Fix desktop scrolling (line 542) + - Reduce mobile label margins (line 56) + - Update renderHourLabels() to show fewer labels on mobile (line 247) + +2. `src/components/Dashboard.tsx` + - Add Save button for authenticated users (line 669-693) + - Make message contextual based on auth status (line 694) + +## Success Criteria + +- [ ] Desktop scrolling works normally +- [ ] Chart is ~8-10px bigger on mobile +- [ ] Authenticated users can save schedules on mobile +- [ ] Bottom message changes based on auth status +- [ ] All changes only affect mobile (<1024px) +- [ ] Desktop experience unchanged diff --git a/SECURITY_TODOS.md b/SECURITY_TODOS.md new file mode 100644 index 0000000..eb13949 --- /dev/null +++ b/SECURITY_TODOS.md @@ -0,0 +1,290 @@ +# Security & Performance TODOs + +## HIGH Priority - Do Before Public Launch + +### 1. Firestore Security Rules 🚨 +**Status:** Not implemented +**Risk:** HIGH - Any authenticated user can access other users' schedules + +**Implementation:** +```javascript +rules_version = '2'; +service cloud.firestore { + match /databases/{database}/documents { + match /schedules/{scheduleId} { + // Only schedule owner can read/write their own schedules + allow read, write: if request.auth != null + && request.auth.uid == resource.data.userId; + + // Only owner can create schedules + allow create: if request.auth != null + && request.auth.uid == request.resource.data.userId; + + // Prevent creating more than 10 schedules per user + allow create: if request.auth != null + && request.auth.uid == request.resource.data.userId + && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.scheduleCount < 10; + } + } +} +``` + +**Steps:** +1. Go to Firebase Console → Firestore Database → Rules +2. Replace rules with the above +3. Test with different users +4. Publish + +--- + +### 2. Email Verification +**Status:** Not implemented +**Risk:** MEDIUM - Fake accounts, spam + +**Implementation:** +```typescript +// In src/auth.ts +import { sendEmailVerification } from 'firebase/auth'; + +export const signUp = async (email: string, password: string) => { + const userCredential = await createUserWithEmailAndPassword(auth, email, password); + await sendEmailVerification(userCredential.user); + return userCredential; +}; +``` + +**Steps:** +1. Add email verification after signup +2. Update UI to show "Check your email" message +3. Block access until email verified (optional but recommended) + +--- + +### 3. Firebase App Check +**Status:** Not implemented +**Risk:** MEDIUM - API abuse, bot attacks + +**Steps:** +1. Go to Firebase Console → App Check +2. Register your app +3. Add reCAPTCHA v3 for web +4. Add enforcement to Firestore + +**Documentation:** https://firebase.google.com/docs/app-check + +--- + +### 4. Rate Limiting Per User +**Status:** Not implemented +**Risk:** MEDIUM - Users creating 1000s of schedules + +**Limit schedules to 10 per person:** +- Prevents database bloat +- 10 is generous for normal use +- Users can delete old schedules to make room + +**Implementation:** +```typescript +// In src/services/scheduleService.ts +export const saveSchedule = async (userId: string, scheduleData: ScheduleData) => { + // Check existing schedule count + const schedulesRef = collection(db, 'schedules'); + const q = query(schedulesRef, where('userId', '==', userId)); + const snapshot = await getDocs(q); + + if (snapshot.size >= 10) { + throw new Error('Maximum 10 schedules per user. Delete old schedules to create new ones.'); + } + + // Continue with save... +}; +``` + +--- + +## MEDIUM Priority - Do Soon + +### 5. Input Sanitization +**Status:** Not implemented +**Risk:** LOW - XSS potential (React escapes by default) + +**Implementation:** +```typescript +// Add to src/utils/validation.ts +export const sanitizeInput = (input: string, maxLength = 100): string => { + return input + .replace(/