diff --git a/CHANGELOG.md b/CHANGELOG.md index 470b984..dc8e588 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -209,5 +209,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Links -- [Unreleased Changes](https://github.com/AdamJ/TimeTrackerPro/compare/v0.21.1...HEAD) +- [Unreleased Changes](https://github.com/AdamJ/TimeTrackerPro/compare/v0.54.0...HEAD) +- [Version 0.54.0](https://github.com/AdamJ/TimeTrackerPro/releases/tag/v0.54.0) - [Version 0.21.1](https://github.com/AdamJ/TimeTrackerPro/releases/tag/v0.21.1) diff --git a/CLAUDE.md b/CLAUDE.md index 4a8dbc6..c018a1c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,7 +1,7 @@ # CLAUDE.md - AI Assistant Codebase Guide -**Last Updated:** 2026-05-14 -**Version:** 2.3.0 +**Last Updated:** 2026-05-26 +**Version:** 2.4.0 Timetraked is a React 18 + TypeScript time tracking PWA for freelancers and consultants, with dual storage (localStorage guest mode and optional Supabase cloud sync). A native iOS app is also available via Capacitor. @@ -23,7 +23,7 @@ After implementing changes, run lint and tests before considering a task complet | Layer | Technology | | ------------ | ------------------------------------------- | -| UI Framework | React 18 + TypeScript 5.8 | +| UI Framework | React 18 + TypeScript 5.9 | | Build | Vite 5 + SWC | | Routing | React Router 6 | | Styling | Tailwind CSS 3 + Radix UI + shadcn/ui | @@ -64,8 +64,10 @@ export const MyComponent = () => { | File | Purpose | | -------------------------------------- | ------------------------------------------------ | -| `src/contexts/TimeTrackingContext.tsx` | Main application state and logic (1400+ lines) | -| `src/services/dataService.ts` | Data persistence abstraction layer (1100+ lines) | +| `src/contexts/TimeTrackingContext.tsx` | Main application state and logic (1200+ lines) | +| `src/services/dataService.ts` | Data persistence factory — returns `LocalStorageService` or `SupabaseService` | +| `src/services/supabaseService.ts` | Supabase data persistence implementation (1100+ lines) | +| `src/services/localStorageService/` | localStorage data persistence implementation (split into per-entity modules) | | `src/contexts/AuthContext.tsx` | Authentication state management | | `src/lib/supabase.ts` | Supabase client configuration and caching | | `src/config/categories.ts` | Default category definitions | @@ -74,9 +76,7 @@ export const MyComponent = () => { | `src/components/IosPageHeader.tsx` | iOS-only sticky nav bar with safe-area-inset-top, back chevron, and action slot | | `src/components/ui/adaptive-dialog.tsx` | Renders vaul `Drawer` on iOS, Radix `Dialog` on web | | `src/hooks/useHaptics.ts` | `@capacitor/haptics` wrapper (light/medium/heavy, success/error) | -| `src/hooks/useStatusBar.ts` | `@capacitor/status-bar` wrapper — syncs bar style with dark/light mode | | `src/hooks/useAppLifecycle.ts` | `@capacitor/app` appStateChange hook for reliable background persistence | -| `src/hooks/useKeyboardHeight.ts` | `@capacitor/keyboard` reactive height for bottom-sheet form padding | | `src/hooks/useLongPress.ts` | 500 ms hold detector for context menu trigger on touch | | `capacitor.config.ts` | Capacitor iOS configuration (Keyboard resize plugin configured here) | | `.env.ios` | iOS build env (VITE_IOS_BUILD=true, no Supabase) | @@ -104,7 +104,7 @@ The app ships as both a PWA and a native iOS app via Capacitor 8. - Haptic feedback fires on every meaningful interaction via `useHaptics` - `@capacitor/app` `appStateChange` event used for emergency data persistence (more reliable than `visibilitychange`) - `@capacitor/status-bar` syncs status bar text colour with system dark/light mode -- `@capacitor/keyboard` configured with `resize: body`; `useKeyboardHeight` lifts bottom-sheet content above the keyboard +- `@capacitor/keyboard` configured with `resize: body`; viewport shrinks above the keyboard so bottom-sheet form fields stay accessible - Long-press on task cards opens a context menu (Edit / Delete); on-card action buttons are hidden **Installed Capacitor plugins** (all v8.x): diff --git a/README-EXT.md b/README-EXT.md index eac1af5..00ba365 100644 --- a/README-EXT.md +++ b/README-EXT.md @@ -246,7 +246,7 @@ See [docs/AUTHENTICATION.md](docs/AUTHENTICATION.md) and [docs/SECURITY.md](docs | Category | Technology | | ------------ | ------------------------------------------- | -| UI Framework | React 18 + TypeScript 5.8 | +| UI Framework | React 18 + TypeScript 5.9 | | Build | Vite 5 + SWC | | Routing | React Router 6 | | Styling | Tailwind CSS 3 + Radix UI + shadcn/ui | @@ -287,8 +287,12 @@ const service = createDataService(isAuthenticated); #### 3. Custom Hooks Pattern - `useAuth()` — authentication state and methods -- `useTimeTracking()` — time tracking operations -- `useOffline()` — offline queue management +- `useTimeTracking()` — time tracking state and operations +- `useHaptics()` — Capacitor haptic feedback (no-op on web) +- `useAppLifecycle()` — Capacitor app background/foreground events +- `useLongPress()` — 500 ms hold detector for touch context menus +- `useReportStorage()` — persists and restores generated AI report summaries +- `useReportSummary()` — calls Gemini API to generate weekly summaries ### Data Flow @@ -325,7 +329,7 @@ Precache: App shell (HTML, CSS, JS, icons) ```text src/ ├── components/ -│ ├── ui/ # Base components (49 files) +│ ├── ui/ # Base components (49+ files, including adaptive-dialog) │ ├── ArchiveEditDialog.tsx │ ├── ArchiveFilter.tsx │ ├── ArchiveItem.tsx @@ -335,46 +339,65 @@ src/ │ ├── DeleteConfirmationDialog.tsx │ ├── ExportDialog.tsx │ ├── InstallPrompt.tsx +│ ├── IosPageHeader.tsx # iOS-only sticky nav bar +│ ├── KanbanBoard.tsx # Kanban planning board +│ ├── KanbanColumn.tsx │ ├── MarkdownDisplay.tsx │ ├── MobileNav.tsx │ ├── Navigation.tsx │ ├── NewTaskForm.tsx +│ ├── PageLayout.tsx # Shared page chrome +│ ├── PlannedTaskCard.tsx +│ ├── PlannedTaskDialog.tsx │ ├── ProjectManagement.tsx +│ ├── StaleDayDialog.tsx │ ├── StartDayDialog.tsx +│ ├── SummaryOutput.tsx │ ├── SyncStatus.tsx │ ├── TaskEditDialog.tsx │ ├── TaskItem.tsx +│ ├── TaskTrackingPanel.tsx │ ├── UpdateNotification.tsx │ └── UserMenu.tsx ├── config/ -│ ├── categories.ts # Default categories -│ └── projects.ts # Default projects +│ ├── categories.ts # Default categories +│ └── projects.ts # Default projects ├── contexts/ │ ├── AuthContext.tsx -│ ├── TimeTrackingContext.tsx -│ └── OfflineContext.tsx +│ ├── OfflineContext.tsx # Online/offline detection and toasts +│ └── TimeTrackingContext.tsx ├── hooks/ +│ ├── use-mobile.tsx +│ ├── use-toast.tsx +│ ├── useAppLifecycle.ts # @capacitor/app background persistence │ ├── useAuth.tsx -│ ├── useTimeTracking.tsx -│ ├── useOffline.tsx -│ └── use-toast.tsx +│ ├── useHaptics.ts # @capacitor/haptics wrapper +│ ├── useLongPress.ts # 500 ms hold detector +│ ├── useReportStorage.ts # Persist generated report summaries +│ ├── useReportSummary.ts # Gemini AI summary generation +│ └── useTimeTracking.tsx ├── lib/ -│ ├── supabase.ts # Supabase client -│ └── utils.ts # Helper functions +│ ├── supabase.ts # Supabase client and call telemetry +│ └── utils.ts # Helper functions ├── pages/ -│ ├── Index.tsx # Dashboard (start/end day, stats) -│ ├── TaskList.tsx # Active task list and NewTaskForm -│ ├── Archive.tsx # Archived days -│ ├── ProjectList.tsx # Project management -│ ├── Categories.tsx # Category management -│ ├── Report.tsx # AI weekly summary -│ ├── Settings.tsx # App settings -│ └── NotFound.tsx # 404 page +│ ├── Archive.tsx # Archived days +│ ├── Categories.tsx # Category management +│ ├── Index.tsx # Dashboard (start/end day, stats) +│ ├── NotFound.tsx # 404 page +│ ├── ProjectList.tsx # Project management +│ ├── Report.tsx # AI weekly summary +│ ├── Settings.tsx # App settings +│ └── TaskList.tsx # Active task list and NewTaskForm ├── services/ -│ └── dataService.ts # Persistence abstraction +│ ├── dataService.ts # Factory — returns LocalStorage or Supabase impl +│ ├── localStorageService/ # localStorage implementation (per-entity modules) +│ └── supabaseService.ts # Supabase implementation (1100+ lines) ├── utils/ -│ ├── timeUtil.ts # Time formatting -│ └── reportUtils.ts # Report grouping and formatting +│ ├── calculationUtils.ts # Revenue and hours calculations +│ ├── checklistUtils.ts # GFM checklist extraction +│ ├── exportUtils.ts # CSV import/export +│ ├── reportUtils.ts # Report grouping and formatting +│ └── timeUtil.ts # Time formatting ├── App.tsx └── main.tsx ``` diff --git a/README.md b/README.md index 905ba2c..41154e7 100644 --- a/README.md +++ b/README.md @@ -119,10 +119,11 @@ See [CHANGELOG.md](CHANGELOG.md) for the full history of changes. **Recent highlights:** -- `PageLayout` shared component standardizes page chrome across all pages -- Incomplete checklist items carry over as todo tasks when archiving a day +- **Kanban planning board** — drag-and-drop task planning view (`KanbanBoard`, `KanbanColumn`, `PlannedTaskCard`) +- Apple HIG pass for native iOS: bottom sheets, haptic feedback, status bar theming, page transitions, and long-press context menus +- Persistent report summaries saved to localStorage; markdown preview/export in the report output panel - Weekly Report distinguishes Gemini API failure modes (rate limit, quota, overload, key issues) -- Fixed Weekly Report for authenticated users (data sourced from Supabase) +- `PageLayout` shared component standardizes page chrome across all pages ---