diff --git a/.claude/SKILLS/ios-health-check/SKILL.md b/.claude/SKILLS/ios-health-check/SKILL.md new file mode 100644 index 0000000..107ee98 --- /dev/null +++ b/.claude/SKILLS/ios-health-check/SKILL.md @@ -0,0 +1,185 @@ +--- +name: ios-health-check +description: > + Runs a full iOS/Capacitor environment health check and auto-fixes any failures + before proceeding with iOS-related work. Use before making any changes to iOS + code, Capacitor config, or Xcode project files. +--- + +# iOS Environment Health Check — TimeTracker Pro + +## When to Use + +Run this skill **before** making any changes to: + +- `capacitor.config.ts` +- `ios/App/CapApp-SPM/Package.swift` +- `ios/App/App.xcodeproj/project.pbxproj` +- Any file under `ios/` +- Any feature gated by `VITE_IOS_BUILD` + +Do not skip this check. Fix every failure before starting the actual task. + +--- + +## Key File Locations + +| File | Purpose | +|------|---------| +| `ios/App/CapApp-SPM/Package.swift` | SPM manifest — defines swift-tools-version and iOS platform target | +| `ios/App/CapApp-SPM/Package.resolved` | Resolved dependency lockfile | +| `ios/App/App.xcodeproj/project.pbxproj` | Xcode project — contains `IPHONEOS_DEPLOYMENT_TARGET` entries | +| `ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved` | Workspace-level resolved lockfile | +| `capacitor.config.ts` | Capacitor config — `experimental.ios.spm.swiftToolsVersion` must match Package.swift | +| `.env.ios` | iOS build env (`VITE_IOS_BUILD=true`, no Supabase keys) | + +--- + +## Check 1 — swift-tools-version drift + +**Read both values:** + +```bash +head -1 ios/App/CapApp-SPM/Package.swift +# Expected: // swift-tools-version:X.X +``` + +```bash +node -e "const c = require('./capacitor.config.ts'); console.log(c.default?.experimental?.ios?.spm?.swiftToolsVersion ?? 'NOT SET')" +``` + +Or read `capacitor.config.ts` directly and look for: + +```ts +experimental: { + ios: { + spm: { + swiftToolsVersion: "X.X" + } + } +} +``` + +**Pass condition:** Both values are identical. + +**Auto-fix:** Update `swiftToolsVersion` in `capacitor.config.ts` to match the +value in `Package.swift`, then run: + +```bash +npm run sync:ios +``` + +--- + +## Check 2 — Stale Package.resolved + +```bash +cd ios/App/CapApp-SPM +swift package resolve +cd ../../.. +``` + +**Pass condition:** Command exits 0 with no errors or warnings about missing packages. + +**Auto-fix:** Delete the stale lockfile and regenerate: + +```bash +rm ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +cd ios/App/CapApp-SPM +swift package resolve +cd ../../.. +``` + +--- + +## Check 3 — iOS build target mismatch + +Extract the platform version from `Package.swift`: + +```bash +grep -E "\.iOS\(" ios/App/CapApp-SPM/Package.swift +# Expected: .iOS("26.0") or similar +``` + +Extract all `IPHONEOS_DEPLOYMENT_TARGET` values from the Xcode project: + +```bash +grep IPHONEOS_DEPLOYMENT_TARGET ios/App/App.xcodeproj/project.pbxproj | sort -u +``` + +**Pass condition:** All `IPHONEOS_DEPLOYMENT_TARGET` values match the version +declared in the `.iOS("X.X")` platform entry of `Package.swift`. + +**Auto-fix:** Update every `IPHONEOS_DEPLOYMENT_TARGET` entry in +`ios/App/App.xcodeproj/project.pbxproj` to match the Package.swift value. +Use a targeted sed or direct file edit — do not change any other keys. + +> ⚠️ `cap sync` overwrites `Package.swift`. Always make version changes in +> `capacitor.config.ts`, not directly in Xcode project files. + +--- + +## Check 4 — Workspace integrity + +Check for dangling references in the Xcode workspace: + +```bash +grep -rE "path = .*;" ios/App/App.xcodeproj/project.pbxproj \ + | sed 's/.*path = //;s/;//' \ + | sort -u +``` + +For any path that looks like a file (not a directory), verify it exists relative +to `ios/App/`. Flag any reference whose target is missing. + +**Pass condition:** No referenced paths are missing from the filesystem. + +**Auto-fix:** Remove the dangling `PBXFileReference` and any `PBXBuildFile` +entries that reference it from `project.pbxproj`. Do not remove group or +directory entries — only file references. + +--- + +## Check 5 — Build validation + +```bash +npm run build:ios +``` + +**Pass condition:** Exits 0 with no TypeScript errors, no Vite errors. + +**Auto-fix:** Read the full error output carefully. Common causes: + +| Error pattern | Fix | +|---------------|-----| +| `Cannot find module` | Check import alias — must use `@/`, never relative paths | +| `Type error` in iOS-only code | Ensure `VITE_IOS_BUILD` guard uses `import.meta.env.VITE_IOS_BUILD !== "true"` | +| Vite PWA plugin error | Confirm `.env.ios` sets `VITE_IOS_BUILD=true` to disable PWA plugin | +| Missing env variable | Add to `.env.ios` (never add Supabase keys here) | + +--- + +## Reporting + +After all checks, output a table before proceeding with the actual task: + +| Check | Status | Action Taken | +|-------|--------|--------------| +| swift-tools-version drift | ✅ Pass / ❌ Fixed | (describe fix or "none") | +| Stale Package.resolved | ✅ Pass / ❌ Fixed | (describe fix or "none") | +| iOS build target mismatch | ✅ Pass / ❌ Fixed | (describe fix or "none") | +| Workspace integrity | ✅ Pass / ❌ Fixed | (describe fix or "none") | +| Build validation | ✅ Pass / ❌ Fixed | (describe fix or "none") | + +If any check could not be auto-fixed, stop and report the blocker clearly +before touching any other files. + +--- + +## Rules + +- Always run all five checks — do not skip any because a previous one passed. +- Never modify `Package.swift` directly for version changes — always go through `capacitor.config.ts`. +- Never add Supabase credentials to `.env.ios`. +- Never commit `ios/App/App/public/` — it is gitignored and regenerated by `cap sync ios`. +- The minimum iOS deployment target for this project is **iOS 26**. diff --git a/.claude/SKILLS/new-feature/SKILL.md b/.claude/SKILLS/new-feature/SKILL.md new file mode 100644 index 0000000..48c6bb9 --- /dev/null +++ b/.claude/SKILLS/new-feature/SKILL.md @@ -0,0 +1,136 @@ +--- +name: new-feature +description: > + Implements a new feature using a strict TDD workflow: read codebase patterns, write failing tests first, implement iteratively until all tests pass and lint is clean, then summarize decisions. Use when asked to add a feature or when "implement [FEATURE]" is requested. +--- + +# New Feature — TimeTracker Pro + +## Clarification (if needed) + +If the feature has not been stated, ask: + +> "What feature would you like to implement? Please describe what it does and +> any relevant context (which page it lives on, what data it touches, etc.)." + +Do not proceed until the feature is clearly defined. + +--- + +## Autonomous Workflow + +Follow these steps strictly and in order. Do not skip steps or combine them. + +### Step 1 — Read the codebase + +Before writing a single line of code, read: + +1. **Existing tests** for the area you're touching: + - `src/components/*.test.{ts,tsx}` + - `src/contexts/*.test.{ts,tsx}` + - `src/services/*.test.{ts,tsx}` + - `src/utils/*.test.{ts,tsx}` +2. **The component or context closest to the new feature** — understand existing patterns before introducing new ones. +3. **[agents/conventions.md](../../agents/conventions.md)** — naming, TypeScript usage, and styling rules. +4. **[agents/architecture.md](../../agents/architecture.md)** — data flow, context structure, and service layer patterns. +5. **[agents/operations.md](../../agents/operations.md)** — how to add components, pages, context methods, and data service methods. + +Do not proceed until you have enough context to write correct tests. + +### Step 2 — Write failing tests first + +Create or update test files **before implementing the feature**. + +Cover all of the following: + +- **Happy path** — the feature works under normal conditions +- **Edge cases** — empty state, boundary values, loading states, no data +- **Known error patterns** (from this project's history): + - Wrong function signatures passed as props + - State updates triggered during render (causes React warnings) + - Undefined references when context value is not yet initialized + - localStorage read/write failures (mock these explicitly) + - Supabase calls in guest mode (must be no-ops, not errors) + +Run the tests to confirm they fail for the right reason: + +```bash +npm run test -- --run +``` + +All new tests must fail at this point. If a test passes without implementation, the test is too weak — strengthen it. + +### Step 3 — Implement iteratively + +Build the feature in small increments, running tests after each meaningful change: + +```bash +npm run test -- --run +npm run lint +``` + +Follow project code style — **non-negotiable**: + +- Tabs, not spaces (2-space display width) +- Double quotes `""` always +- `@/` import alias — never relative paths like `../../` +- shadcn/ui components — never raw HTML with custom styles +- Radix/theme color variables — never custom Tailwind colors like `bg-blue-500` + +Follow project architecture patterns: + +- New UI → `src/components/` using shadcn/ui primitives +- New page → `src/pages/` with lazy load added in `App.tsx` +- New state/logic → method on `TimeTrackingContext` consumed via `useTimeTracking()` +- New persistence → method on `DataService` interface, implemented in both + `LocalStorageService` and `SupabaseService` +- New utility → `src/utils/` (pure functions, easy to unit-test) + +### Step 4 — Do not stop until green + +Continue iterating until: + +- [ ] All new tests pass +- [ ] All pre-existing tests still pass +- [ ] `npm run lint` exits with no errors +- [ ] `npm run build` succeeds + +**Do not ask for help or report partial progress.** Debug failures yourself: + +1. Read the full error output — do not skim it. +2. Identify the root cause before changing code. +3. Fix one issue at a time, then re-run tests. +4. If stuck after two attempts on the same failure, step back and re-read the relevant context or service file from scratch. + +### Step 5 — Commit the work + +Stage only files related to the feature: + +```bash +git add +git status # verify nothing unintended is staged +git commit -m "feat: " +``` + +Do not use `--no-verify`. Do not commit test artifacts or build output. + +### Step 6 — Write a summary + +After committing, output a brief summary covering: + +1. **What was built** — one-paragraph description of the feature +2. **Files added/changed** — list with one-line purpose for each +3. **Architectural decisions** — any non-obvious choices made (e.g., why state lives in context vs. local, why a new service method was needed) +4. **Known limitations** — anything deferred or out of scope +5. **Next step** — remind to run the `sync-docs` skill before opening a PR + +--- + +## Rules + +- Never implement before tests exist. +- Never declare success while any test or lint failure remains. +- Never bypass linting (`--no-verify`, `eslint-disable` without justification). +- Never introduce new raw HTML elements where a shadcn/ui equivalent exists. +- Never use relative import paths. +- Never commit directly to `main` — always use a feature branch. diff --git a/.claude/SKILLS/sync-docs/SKILL.md b/.claude/SKILLS/sync-docs/SKILL.md new file mode 100644 index 0000000..60d5de8 --- /dev/null +++ b/.claude/SKILLS/sync-docs/SKILL.md @@ -0,0 +1,126 @@ +--- +name: sync-docs +description: > + Syncs CHANGELOG.md, README.md, README-EXT.md, and CLAUDE.md with the current codebase changes after a major feature or fix, then commits the updates. + Use before opening a PR or after completing significant work. +--- + +# Sync Docs — TimeTracker Pro + +## When to Use + +Run this skill after completing a major feature, bug fix, or refactor — **before creating a PR**. +It keeps the four documentation files consistent with the actual codebase state. + +## Files Updated + +| File | Updated when... | +|------|----------------| +| `CHANGELOG.md` | Any user-visible or developer-visible change | +| `README.md` | Features, commands, install steps, or quick-start change | +| `README-EXT.md` | Detailed usage, architecture, stack, conventions, or workflow change | +| `CLAUDE.md` | Tech stack, critical code style rules, key files, or iOS config change | + +## Steps + +### 1 — Gather the diff + +```bash +git diff main...HEAD -- '*.ts' '*.tsx' '*.js' '*.jsx' \ + 'package.json' 'vite.config.ts' 'tailwind.config.ts' \ + 'capacitor.config.ts' 'eslint.config.js' +``` + +If still on the same branch without a comparison target, use: + +```bash +git diff HEAD~1 -- '*.ts' '*.tsx' '*.js' '*.jsx' \ + 'package.json' 'vite.config.ts' 'tailwind.config.ts' \ + 'capacitor.config.ts' 'eslint.config.js' +``` + +Read the diff output carefully before touching any documentation file. + +### 2 — Update CHANGELOG.md + +- Add entries under the `## [Unreleased]` section. +- Use this entry format (from the project's existing pattern): + + ```markdown + - [Brief description of what changed] + — `path/to/file.ts`, `path/to/other.ts` ([context/reason]) + ``` + +- One bullet per **logical change**, not per file. +- Do **not** add an entry if identical wording already exists. +- Do **not** add speculative or future-tense entries. + +### 3 — Update README.md + +Update only if one or more of the following changed: + +- A user-facing feature was added or removed +- An `npm run` command was added, renamed, or removed +- The install/quick-start steps changed +- The "Recent highlights" section in the Changelog block is stale + +Keep the README brief — it links out to README-EXT.md for detail. + +### 4 — Update README-EXT.md + +Update only the section(s) directly affected by the diff: + +- **How to Use** — if task/project/category/export workflows changed +- **Progressive Web App** — if PWA manifest, service worker, or install flow changed +- **Authentication & Storage** — if auth flow, storage strategy, or Supabase setup changed +- **Technical Architecture → Technology Stack** — if a dependency was added or removed +- **Technical Architecture → Project Structure** — if new files/directories were added +- **Technical Architecture → Code Conventions** — if lint rules or style requirements changed +- **Development Workflow → Testing** — if test commands or checklists changed +- **Development Workflow → Adding Features** — if patterns for new components/pages changed +- **Documentation Index** — if a new doc file was added or an existing one renamed + +Do **not** rewrite or reformat sections that are unaffected. + +### 5 — Update CLAUDE.md + +Update only if one or more of the following changed: + +- **Technology Stack table** — new or removed dependency +- **Critical Code Style** — lint rule or formatting convention change +- **Key Files table** — a key file was added, renamed, or its purpose changed +- **iOS Environment / Capacitor** — iOS build config, scripts, or deployment target changed +- **Pre-Commit Checklist** — new required check added + +Do **not** modify the "Agent Sub-Documents" table or general narrative unless the files it references changed. + +### 6 — Verify consistency + +Quickly cross-check that the four files don't contradict each other: + +- CHANGELOG entry matches what README/README-EXT describe +- Any new npm script in CLAUDE.md also appears in README.md's commands table +- Tech stack table in CLAUDE.md and README-EXT.md agree + +### 7 — Commit the updates + +```bash +git add CHANGELOG.md README.md README-EXT.md CLAUDE.md +git diff --staged --stat +``` + +Only commit if there are actual changes: + +```bash +git commit -m "docs: sync documentation with recent changes" +``` + +Do **not** use `--no-verify`. Do **not** stage any source files — documentation only. + +## Rules + +- Modify only the four files listed above. +- Never guess at intent — derive every entry directly from the diff. +- Never add emojis, praise, or filler language. +- Never reformat unchanged sections (no whitespace-only diffs). +- If none of the four files need changes, say so and do nothing. diff --git a/.gitignore b/.gitignore index 171e2a0..653b55e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ dist .env.development.local .env.test.local .env.production.local -.claude +.claude/settings.local.json # Playwright /test-results/ diff --git a/CLAUDE.md b/CLAUDE.md index cf2ed3d..052c5c9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ TimeTracker Pro is a React 18 + TypeScript time tracking PWA for freelancers and ## Documentation -After making changes, always sync documentation files (CHANGELOG.md, README.md, AGENTS.md) to reflect current codebase state. +After making changes, always sync documentation files before opening a PR. Use the **sync-docs** skill (`.claude/skills/sync-docs/SKILL.md`) to update CHANGELOG.md, README.md, README-EXT.md, and CLAUDE.md to reflect the current codebase state, then commit the updates. ## Git Workflow @@ -78,25 +78,7 @@ export const MyComponent = () => { ## iOS Environment Health Check -Before making any changes to iOS-related code or configs, run this health check and auto-fix any failures before proceeding. - -**Checks to run:** - -1. **swift-tools-version drift** — Verify `// swift-tools-version:` in `ios/App/CapApp-SPM/Package.swift` matches `experimental.ios.spm.swiftToolsVersion` in `capacitor.config.ts` -2. **Stale Package.resolved** — Run `swift package resolve` inside `ios/App/CapApp-SPM/` to confirm `Package.resolved` is current -3. **iOS build targets** — Verify all `IPHONEOS_DEPLOYMENT_TARGET` entries in `ios/App/App.xcodeproj/project.pbxproj` match the platform version in `Package.swift` -4. **Workspace integrity** — Confirm no `.xcworkspace` or `.pbxproj` file references paths that no longer exist -5. **Build validation** — Run `npm run build:ios` and capture any errors - -**Auto-fix solutions:** - -| Failure | Fix | -| ------- | --- | -| swift-tools-version drift | Update `experimental.ios.spm.swiftToolsVersion` in `capacitor.config.ts`, then run `npm run sync:ios` | -| Stale Package.resolved | Delete `ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved` and re-run `swift package resolve` | -| Build target mismatch | Update all `IPHONEOS_DEPLOYMENT_TARGET` entries in `project.pbxproj` to match `Package.swift` | - -Report what was found and fixed, then proceed with the actual task. +Before making any changes to iOS-related code or configs, run the **ios-health-check** skill (`.claude/skills/ios-health-check/SKILL.md`). It runs five checks, auto-fixes any failures, and reports results before proceeding with the actual task. --- @@ -148,16 +130,19 @@ When working on iOS/Capacitor projects, remember that `cap sync` overwrites Pack Read these files proactively based on what you're working on: -| When you're working on... | Read this file | -| --------------------------------------------------------------- | ------------------------- | -| Architecture, data flow, auth flow, contexts, DataService | `agents/architecture.md` | -| Naming conventions, TypeScript patterns, UI/styling rules | `agents/conventions.md` | -| Dev setup, npm commands, git workflow, Supabase | `agents/workflow.md` | -| Adding components, pages, context methods, data service methods | `agents/operations.md` | -| Testing, QA checklists, code quality requirements | `agents/testing.md` | -| Debugging, common mistakes, architecture gotchas, Gemini errors | `agents/pitfalls.md` | -| UI/styling rules and Radix component usage | `agents/styles.md` | -| Pull request guidelines | `agents/pull_requests.md` | +| When you're working on... | Read this file | +| --------------------------------------------------------------- | ------------------------------------------- | +| Architecture, data flow, auth flow, contexts, DataService | `agents/architecture.md` | +| Naming conventions, TypeScript patterns, UI/styling rules | `agents/conventions.md` | +| Dev setup, npm commands, git workflow, Supabase | `agents/workflow.md` | +| Adding components, pages, context methods, data service methods | `agents/operations.md` | +| Testing, QA checklists, code quality requirements | `agents/testing.md` | +| Debugging, common mistakes, architecture gotchas, Gemini errors | `agents/pitfalls.md` | +| UI/styling rules and Radix component usage | `agents/styles.md` | +| Pull request guidelines | `agents/pull_requests.md` | +| Adding a new feature (TDD workflow) | `.claude/skills/new-feature/SKILL.md` | +| Syncing docs before a PR | `.claude/skills/sync-docs/SKILL.md` | +| Any iOS/Capacitor changes | `.claude/skills/ios-health-check/SKILL.md` | --- diff --git a/README-EXT.md b/README-EXT.md new file mode 100644 index 0000000..ef8477a --- /dev/null +++ b/README-EXT.md @@ -0,0 +1,526 @@ +# TimeTracker Pro — Extended Reference + +This document contains detailed usage guides, technical architecture, and developer workflow information. +For the main overview, see [README.md](README.md). + +--- + +## Table of Contents + +- [How to Use](#how-to-use) + - [Daily Workflow](#daily-workflow) + - [Project Management](#project-management) + - [Category Management](#category-management) + - [Data Export & Import](#data-export--import) + - [Markdown in Task Descriptions](#markdown-in-task-descriptions) +- [Progressive Web App](#progressive-web-app) + - [Installing as an App](#installing-as-an-app) + - [PWA Features](#pwa-features) +- [Authentication & Storage](#authentication--storage) + - [Storage Modes](#storage-modes) + - [How Data Storage Works](#how-data-storage-works) + - [Setting Up Cloud Sync](#setting-up-cloud-sync) + - [Authentication Flow](#authentication-flow) + - [Security](#security) +- [Technical Architecture](#technical-architecture) + - [Technology Stack](#technology-stack) + - [Architecture Patterns](#architecture-patterns) + - [Data Flow](#data-flow) + - [Project Structure](#project-structure) + - [Code Conventions](#code-conventions) +- [Development Workflow](#development-workflow) + - [Git Workflow](#git-workflow) + - [Testing](#testing) + - [Adding Features](#adding-features) + - [Customizing Markdown Styles](#customizing-markdown-styles) +- [Documentation Index](#documentation-index) +- [iOS Screenshots](#ios-screenshots) + +--- + +## How to Use + +### Daily Workflow + +**Morning:** + +1. Click "Start Day" to begin tracking. The timer starts automatically. + +**Throughout the Day:** + +1. Click "New Task" to create a task. +2. Fill in task details: + - **Title** (required) — brief description of the work + - **Description** (optional) — detailed notes with markdown support + - **Project** (optional) — assign to a client/project + - **Category** (optional) — categorize the work type +3. Task duration calculates automatically. +4. Create new tasks as you switch between work items. + +**Evening:** + +1. Click "End Day" when finished. +2. Review your day summary (total time, revenue, task breakdown). +3. Click "Post Time to Archive" to save permanently. + +**Ongoing:** + +- View archived days on the **Archive** page. +- Manage projects and rates via **Archive → Projects**. +- Customize categories on the **Categories** page. +- Export data via **Archive → Export**. + +### Project Management + +1. Navigate to **Archive → Projects**. +2. Click **Add Project** and enter: + - Project name and client name + - Hourly rate + - Billable / non-billable flag +3. Assign projects to tasks when creating or editing them. + +Projects enable automatic revenue calculation, per-client invoice exports, and archive filtering. + +### Category Management + +1. Navigate to **Categories** from the main menu. +2. Click **Add Category** to create a custom category with a name, color, and billable flag. + +**Default categories:** Meeting, Development, Design, Research, Administration, Testing, Documentation, Client Communication. + +### Data Export & Import + +**Exporting:** + +1. Navigate to **Archive → Export**. +2. Choose a format: + - **CSV** — for spreadsheets or accounting software + - **JSON** — for backup or programmatic access + - **Invoice** — client-ready invoice format +3. Optionally filter by date range, project, or client, then download. + +**Importing:** + +Prepare a CSV using the [template format](docs/CSV_TEMPLATES_README.md), then use the import functionality or run a test script: + +```bash +npm run test-csv-import +``` + +### Markdown in Task Descriptions + +Task descriptions support **GitHub Flavored Markdown (GFM)**: + +- **Bold** and _italic_ text +- Lists (bulleted and numbered), task lists with checkboxes +- Tables and ~~strikethrough~~ +- Links and code blocks +- Headings with automatic line breaks + +**Example:** + +```markdown +## Client Meeting Notes + +**Attendees:** John, Sarah, Mike + +**Action Items:** + +- [ ] Send meeting minutes +- [ ] Update project roadmap +``` + +--- + +## Progressive Web App + +### Installing as an App + +**Desktop (Chrome / Edge / Firefox):** + +1. Open TimeTracker Pro in your browser. +2. Click the install icon (⊕) in the address bar. +3. Click "Install" — the app opens in its own window. + +**iOS (Safari):** + +1. Open TimeTracker Pro in Safari. +2. Tap the Share button (□↑) → "Add to Home Screen" → "Add". +3. Toggle "Open as Web App" to On. + +**Android (Chrome):** + +1. Open TimeTracker Pro in Chrome. +2. Tap the menu (⋮) → "Install app" or "Add to Home screen". + +### PWA Features + +**Offline Capability:** All features work without internet; data syncs automatically when the connection is restored. + +**Mobile Optimized:** Bottom navigation, 44×44 px minimum touch targets, safe-area support for notched devices, responsive layout. + +**Seamless Updates:** New versions install automatically with a refresh prompt; no data is lost. + +**Native-Like Experience:** Standalone window, app icon, splash screen on launch. + +--- + +## Authentication & Storage + +### Storage Modes + +| Mode | Description | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------- | +| **Guest (default)** | No account required. All data in `localStorage`. Full functionality, single-device only. | +| **Authenticated (optional)** | Sign in via Supabase. Data synced to PostgreSQL. Multi-device access with automatic `localStorage` migration. | + +### How Data Storage Works + +TimeTracker Pro uses a **manual sync** approach optimized for single-device usage: + +1. **In-Memory First** — changes update React state immediately. +2. **Critical Event Saves** — data persists only on day end, window close, or manual sync. +3. **No Auto-Save** — prevents unnecessary API calls and rate limiting. + +When you sign in, your `localStorage` data automatically migrates to Supabase (timestamps compared to prevent overwriting newer data, no data loss). When you sign out, Supabase data syncs back to `localStorage`. + +### Setting Up Cloud Sync + +**1. Create a Supabase project** at [supabase.com](https://supabase.com). + +**2. Get API credentials** from Project Settings → API (copy the Project URL and anon/public key). + +**3. Configure your environment:** + +```bash +cp .env.example .env +# Edit .env: +# VITE_SUPABASE_URL=https://your-project.supabase.co +# VITE_SUPABASE_ANON_KEY=your_anon_key_here +``` + +**4. Apply the database schema** from `supabase/migrations/` (see [Schema Compatibility](docs/SCHEMA_COMPATIBILITY.md)). + +**5. Restart the dev server:** `npm run dev` + +> ⚠️ Never commit your `.env` file to version control. + +### Authentication Flow + +**Sign Up:** Click "Sign In" → "Sign Up" tab → enter email and password → verify email → sign in. + +**Sign In:** Click "Sign In" → enter credentials → data migrates from `localStorage`. + +**Sign Out:** Click user menu → "Sign Out" → data syncs back to `localStorage`. + +### Security + +- All API calls over HTTPS. +- Row-level security (RLS) enabled on Supabase — users access only their own data. +- Passwords hashed and salted by Supabase Auth (minimum 8 characters). +- No sensitive data stored in `localStorage`. + +See [docs/AUTHENTICATION.md](docs/AUTHENTICATION.md) and [docs/SECURITY.md](docs/SECURITY.md) for full details. + +--- + +## Technical Architecture + +### Technology Stack + +| Category | Technology | +| ------------ | ------------------------------------------- | +| UI Framework | React 18 + TypeScript 5.8 | +| Build | Vite 5 + SWC | +| Routing | React Router 6 | +| Styling | Tailwind CSS 3 + Radix UI + shadcn/ui | +| Icons | Radix Icons (primary), Lucide (fallback) | +| Forms | React Hook Form + Zod | +| Backend | Supabase (optional) or localStorage | +| PWA | Vite PWA Plugin + Workbox | +| Native iOS | Capacitor 8 | +| Testing | Vitest + React Testing Library + Playwright | + +### Architecture Patterns + +#### 1. Context-Driven Architecture + +```text +App.tsx +└── AuthProvider (authentication state) + └── TimeTrackingProvider (time tracking state) + └── OfflineProvider (offline queue) + └── Pages & Components +``` + +#### 2. Service Layer Pattern + +Data persistence is abstracted through a factory that returns either `LocalStorageService` or `SupabaseService` depending on auth state: + +```typescript +interface DataService { + loadCurrentDay(): Promise; + saveCurrentDay(data: DayData): Promise; + loadArchivedDays(): Promise; + saveArchivedDays(days: ArchivedDay[]): Promise; +} + +const service = createDataService(isAuthenticated); +``` + +#### 3. Custom Hooks Pattern + +- `useAuth()` — authentication state and methods +- `useTimeTracking()` — time tracking operations +- `useOffline()` — offline queue management + +### Data Flow + +```text +User Action + ↓ +Component Event Handler + ↓ +Context Method (useTimeTracking) + ↓ +State Update (React setState) + ↓ +UI Re-render + ↓ +(On critical events only) + ↓ +DataService.save() + ↓ +localStorage OR Supabase +``` + +**Critical save events:** day end (`postDay()`), window close (`beforeunload`), manual sync (`forceSyncToDatabase()`). + +**Service Worker caching:** + +```javascript +NetworkFirst: Supabase API calls (fresh data preferred) +CacheFirst: Google Fonts (static assets) +Precache: App shell (HTML, CSS, JS, icons) +``` + +### Project Structure + +```text +src/ +├── components/ +│ ├── ui/ # Base components (49 files) +│ ├── ArchiveEditDialog.tsx +│ ├── ArchiveFilter.tsx +│ ├── ArchiveItem.tsx +│ ├── AuthDialog.tsx +│ ├── CategoryManagement.tsx +│ ├── DaySummary.tsx +│ ├── DeleteConfirmationDialog.tsx +│ ├── ExportDialog.tsx +│ ├── InstallPrompt.tsx +│ ├── MarkdownDisplay.tsx +│ ├── MobileNav.tsx +│ ├── Navigation.tsx +│ ├── NewTaskForm.tsx +│ ├── ProjectManagement.tsx +│ ├── StartDayDialog.tsx +│ ├── SyncStatus.tsx +│ ├── TaskEditDialog.tsx +│ ├── TaskItem.tsx +│ ├── UpdateNotification.tsx +│ └── UserMenu.tsx +├── config/ +│ ├── categories.ts # Default categories +│ └── projects.ts # Default projects +├── contexts/ +│ ├── AuthContext.tsx +│ ├── TimeTrackingContext.tsx +│ └── OfflineContext.tsx +├── hooks/ +│ ├── useAuth.tsx +│ ├── useTimeTracking.tsx +│ ├── useOffline.tsx +│ └── use-toast.tsx +├── lib/ +│ ├── supabase.ts # Supabase client +│ └── utils.ts # Helper functions +├── pages/ +│ ├── Index.tsx # Home / time tracker +│ ├── 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 +├── services/ +│ └── dataService.ts # Persistence abstraction +├── utils/ +│ ├── timeUtil.ts # Time formatting +│ └── reportUtils.ts # Report grouping and formatting +├── App.tsx +└── main.tsx +``` + +### Code Conventions + +| Rule | Requirement | +| ----------- | ---------------------------------------------------- | +| Indentation | Tabs only, 2-space display width | +| Quotes | Double quotes always (`""`) | +| Imports | `@/` alias — never relative paths (`../../`) | +| Components | PascalCase (`TaskItem.tsx`) | +| Hooks | camelCase with `use` prefix (`useAuth.tsx`) | +| Utilities | camelCase (`timeUtil.ts`) | +| Constants | UPPER_SNAKE_CASE (`STORAGE_KEYS`) | +| Styling | Radix/theme variables — never custom Tailwind colors | + +See [CLAUDE.md](CLAUDE.md) for comprehensive conventions. + +--- + +## Development Workflow + +### Git Workflow + +**Branch naming:** + +```bash +feature/your-feature-name +fix/bug-description +refactor/area-name +``` + +**Commit messages:** + +```bash +# Format: : +git commit -m "feat: add billable category option" +git commit -m "fix: resolve data recovery issue" +# Types: feat, fix, refactor, docs, style, test, chore +``` + +**Pull Requests:** Title format `[TimeTrackerPro] Descriptive Title`. See [agents/pull_requests.md](agents/pull_requests.md) for full guidelines. + +### Testing + +**Manual checklist:** + +- [ ] Guest mode (no auth) +- [ ] Authenticated mode +- [ ] Mobile viewport (DevTools) +- [ ] Data persistence after page refresh +- [ ] Export/import functionality +- [ ] No console errors +- [ ] Responsive design + +**PWA checklist:** + +- [ ] Service worker registers (DevTools → Application → Service Workers) +- [ ] App works offline (DevTools → Network → Offline) +- [ ] Install prompt appears +- [ ] Update notification works + +**Automated tests:** + +```bash +npm run test # Vitest unit tests +npm run test-csv-import # Standard CSV import +npm run test-full-import # Full CSV import +npm run test-error-handling # CSV error handling +npm run screenshots:install # Install Playwright (first time) +npm run screenshots # Capture PWA screenshots +``` + +### Adding Features + +**New component:** + +```typescript +// Create in src/components/ +// Use shadcn/ui components; import via @/ alias +import { MyFeature } from '@/components/MyFeature'; +``` + +**New page:** + +```typescript +// 1. Create in src/pages/ +// 2. Lazy-load in App.tsx +const MyPage = lazy(() => import("./pages/MyPage")); +// 3. Add route +} /> +// 4. Add navigation link in Navigation.tsx +``` + +**New context method:** + +1. Define in context interface. +2. Implement in provider. +3. Export in context value. +4. Consume via the relevant hook. + +### Customizing Markdown Styles + +**Utility classes (recommended):** + +```tsx + +``` + +**Global theme overrides (`tailwind.config.ts`):** + +```typescript +typography: { + DEFAULT: { + css: { + color: "#333", + a: { color: "#3182ce", "&:hover": { color: "#2c5282" } } + } + } +} +``` + +--- + +## Documentation Index + +| Document | Description | +| ---------------------------------------------------------------------- | ----------------------------------------- | +| [CLAUDE.md](CLAUDE.md) | Comprehensive codebase guide — start here | +| [AGENTS.md](AGENTS.md) | Quick agent instructions and workflows | +| [agents/styles.md](agents/styles.md) | UI/UX style guidelines | +| [agents/pull_requests.md](agents/pull_requests.md) | PR creation and review rules | +| [docs/AUTHENTICATION.md](docs/AUTHENTICATION.md) | Auth setup and configuration | +| [docs/AUTH_DATA_PERSISTENCE_FIX.md](docs/AUTH_DATA_PERSISTENCE_FIX.md) | Persistence implementation details | +| [docs/SCHEMA_COMPATIBILITY.md](docs/SCHEMA_COMPATIBILITY.md) | Database schema history | +| [docs/MIGRATION.md](docs/MIGRATION.md) | Supabase data migration guide | +| [docs/SECURITY.md](docs/SECURITY.md) | Security configuration and practices | +| [docs/CSV_TEMPLATES_README.md](docs/CSV_TEMPLATES_README.md) | CSV import/export format | +| [docs/FEATURES.md](docs/FEATURES.md) | Feature requests and improvement notes | +| [info/README-LOVABLE.md](info/README-LOVABLE.md) | Project origin and history | + +**External references:** + +- [Radix UI](https://www.radix-ui.com) — component primitives +- [shadcn/ui](https://ui.shadcn.com) — component library +- [Tailwind CSS](https://tailwindcss.com) — CSS framework +- [React Router](https://reactrouter.com) — routing +- [Supabase Docs](https://supabase.com/docs) — backend +- [Vite](https://vitejs.dev) — build tool + +--- + +## iOS Screenshots + +| View | Image | +| --------------------- | ------------------------------------------------------------------ | +| Dashboard | Timetracker screenshot 01 | +| Time Entry — Markdown | Timetracker screenshot 02 | +| Time Entry — Preview | Timetracker screenshot 03 | +| Active Tasks | Timetracker screenshot 04 | +| Day Ended | Timetracker screenshot 06 | +| Archive | Timetracker screenshot 07 | diff --git a/README.md b/README.md index 9914ee8..5bd8315 100644 --- a/README.md +++ b/README.md @@ -1,1134 +1,129 @@ # TimeTracker Pro -A modern, feature-rich Progressive Web App (PWA) for time tracking built with React, TypeScript, and Tailwind CSS. Installable on desktop and mobile devices with full offline support. Perfect for freelancers, consultants, and professionals who need to track time, manage projects, and generate invoices. +A Progressive Web App (PWA) for time tracking built with React, TypeScript, and Tailwind CSS. Installable on desktop and mobile with full offline support. Built for freelancers, consultants, and professionals who need to track time, manage projects, and generate invoices. ![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB) ![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white) ![Vite](https://img.shields.io/badge/vite-%23646CFF.svg?style=for-the-badge&logo=vite&logoColor=white) ![TailwindCSS](https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white) ![Supabase](https://img.shields.io/badge/Supabase-3ECF8E?style=for-the-badge&logo=supabase&logoColor=white) ![PWA](https://img.shields.io/badge/PWA-Enabled-5A0FC8?style=for-the-badge&logo=pwa&logoColor=white) ![Capacitor](https://img.shields.io/badge/Capacitor-119EFF?style=for-the-badge&logo=capacitor&logoColor=white) -## 📑 Table of Contents - -**For Users:** - -- [What is TimeTracker Pro?](#-what-is-timetracker-pro) -- [Key Features](#-key-features) -- [Perfect For](#-perfect-for) -- [Quick Start](#-quick-start) -- [How to Use](#-how-to-use) -- [Progressive Web App](#-progressive-web-app) - -**For Developers:** - -- [Development Setup](#-development-setup) -- [Technical Architecture](#-technical-architecture) -- [Authentication & Storage](#-authentication--storage) -- [Development Workflow](#-development-workflow) -- [Documentation](#-documentation) - -**Screenshots:** - -- [iOS](#-ios-screenshots)- [Dashboard](screenshots/iOS/01TimeTrackerPro-iOS.png) - -**Additional:** - -- [Changelog](#-changelog) -- [License](#-license) -- [Credits](#-credits) - ---- - -## 🎯 What is TimeTracker Pro? - -TimeTracker Pro is a professional time tracking application that helps you monitor where your time goes throughout the workday. Unlike complex enterprise tools, TimeTracker Pro focuses on simplicity while providing powerful features for freelancers, consultants, and professionals. - -**Core Concept:** - -1. **Start your day** - Click one button to begin tracking -2. **Create tasks** - Add tasks as you work on different projects -3. **End your day** - Review your summary and archive the day -4. **Export data** - Generate invoices, CSV reports, or JSON exports - -**Works Your Way:** - -- **No Account Required** - Start tracking immediately with local storage -- **Optional Cloud Sync** - Sign in to sync across devices -- **Offline First** - Full functionality without internet connection -- **Install as App** - Works like a native app on desktop and mobile - ---- - -## ✨ Key Features - -### Time Tracking Essentials - -- **Daily Time Tracking** - Start/stop your workday with clear boundaries -- **Task Management** - Create, edit, and delete tasks with real-time duration tracking -- **Intuitive Time Selection** - Native browser time inputs for familiar, accessible time entry -- **Rich Text Support** - Add detailed notes with GitHub Flavored Markdown (tables, lists, formatting) -- **Automatic Calculations** - Duration and revenue calculated automatically -- **Archive System** - Permanent record of all completed work days - -### Organization Tools - -- **Projects & Clients** - Organize work by project with hourly rates -- **Custom Categories** - Flexible categorization with custom colors -- **Billable vs Non-Billable** - Track which time can be invoiced -- **Visual Organization** - Color-coded categories for quick identification - -### Professional Features - -- **Revenue Tracking** - Automatic earnings calculation based on hourly rates -- **Invoice Generation** - Export invoice-ready data filtered by client and date range -- **Multiple Export Formats** - CSV, JSON, and invoice formats -- **CSV Import** - Import existing time data from other tools -- **Print Support** - Print-friendly archive views for physical records -- **Weekly Report** - AI-generated work summaries from archived days (standup, client, or retrospective tone); works in both guest and authenticated modes; errors surface specific, actionable guidance (rate limit vs. quota exhaustion vs. overload vs. key issues) - -### Progressive Web App - -- **Install Like Native** - Add to home screen or applications folder -- **Full Offline Support** - Continue working without internet -- **Mobile Optimized** - Touch-friendly with bottom navigation -- **Auto-Updates** - New versions install seamlessly -- **Cross-Platform** - Works on Windows, Mac, Linux, iOS, and Android -- **Native iOS App** - Distributed as a native iOS app via Capacitor (App Store / sideload) - --- -## 🎯 Perfect For +## Features -- **Freelancers** - Track billable hours and generate client invoices -- **Consultants** - Organize time by project and client with revenue tracking -- **Remote Workers** - Submit detailed timesheets to employers -- **Students** - Track study time and project work efficiently -- **Small Businesses** - Monitor project time and profitability -- **Anyone** - Who needs professional time tracking without the complexity +- **Daily Time Tracking** — start/stop your workday with clear daily boundaries +- **Task Management** — create, edit, and delete tasks with real-time duration tracking +- **Projects & Clients** — organize work by project with per-project hourly rates +- **Revenue Tracking** — automatic earnings calculation based on hourly rates +- **Custom Categories** — color-coded, billable/non-billable categorization +- **Rich Text Notes** — GitHub Flavored Markdown in task descriptions +- **Archive & Export** — permanent record with CSV, JSON, and invoice export formats +- **CSV Import** — bring in existing time data from other tools +- **Weekly Report** — AI-generated work summaries (standup, client, or retrospective tone) +- **No Account Required** — full functionality with local storage; optional cloud sync via Supabase +- **PWA + Native iOS** — installable on desktop/mobile; distributed as a native iOS app via Capacitor 8 --- -## 🚀 Quick Start - -**Option 1: Use Online** (No installation required) - -1. Visit the hosted version (if available) or run locally -2. Click "Start Day" to begin tracking -3. Add tasks throughout your day -4. Click "End Day" and archive when finished - -**Option 2: Install Locally** +## Quick Start ```bash -# Clone the repository git clone https://github.com/AdamJ/TimeTrackerPro.git - -# Navigate to project directory cd TimeTrackerPro - -# Install dependencies npm install - -# Start the application npm run dev ``` -The application will be available at **** - -**First Time Setup:** +Open [http://localhost:8080](http://localhost:8080) in your browser. -1. Open the app in your browser -2. Click "Start Day" to begin tracking time -3. (Optional) Click "Sign In" to enable cloud sync across devices -4. (Optional) Set up projects and categories for better organization +**First run:** click "Start Day" to begin tracking. No configuration required. -That's it! No complex configuration required. +**Optional — cloud sync:** copy `.env.example` to `.env` and add your Supabase credentials (see [Authentication & Storage](README-EXT.md#authentication--storage)). --- -## 📱 How to Use - -### Daily Workflow - -**Morning:** - -1. Click "Start Day" button to begin tracking -2. The timer starts automatically - -**Throughout the Day:** 3. Click "New Task" to create a task 4. Fill in task details: - -- **Title** (required) - Brief description of the work -- **Description** (optional) - Detailed notes with markdown support -- **Project** (optional) - Assign to a client/project -- **Category** (optional) - Categorize the work type - -1. Task duration calculates automatically -2. Create new tasks as you switch between different work items - -**Evening:** 7. Click "End Day" when you're finished working 8. Review your day summary (total time, revenue, task breakdown) 9. Click "Post Time to Archive" to save permanently - -**Ongoing:** - -- View archived days in the **Archive** page -- Manage projects and rates in **Archive → Projects** -- Customize categories in the **Categories** page -- Export data via **Archive → Export** - -### Project Management - -**Setting Up Projects:** - -1. Navigate to **Archive** page -2. Click **Projects** button -3. Click **Add Project** -4. Enter project details: - - Project name - - Client name - - Hourly rate - - Mark as billable/non-billable -5. Assign projects to tasks when creating them - -**Benefits:** - -- Automatic revenue calculation based on hourly rates -- Filter archives by project -- Generate client-specific invoices -- Track time and earnings per project - -### Category Management - -**Customizing Categories:** - -1. Navigate to **Categories** page from the main menu -2. View default categories or create new ones -3. Click **Add Category** to create custom categories -4. Customize each category: - - Category name - - Color (for visual identification) - - Billable flag (for invoice generation) - -**Default Categories:** - -- Meeting, Development, Design, Research -- Administration, Testing, Documentation -- Client Communication - -### Data Export & Import - -**Exporting Data:** - -1. Navigate to **Archive** page -2. Click **Export** button -3. Choose export format: - - **CSV** - For Excel, Google Sheets, or accounting software - - **JSON** - For programmatic access or backup - - **Invoice** - Client-ready invoice format -4. Filter by date range, project, or client -5. Download the file - -**Importing Data:** - -1. Prepare a CSV file using the template format (see [CSV Templates](docs/CSV_TEMPLATES_README.md)) -2. Use the import functionality (coming soon) or test scripts: - - ```bash - npm run test-csv-import - ``` - -### Markdown in Task Descriptions - -Task descriptions support **GitHub Flavored Markdown (GFM)** for rich formatting: - -**Supported Features:** - -- **Bold** and _italic_ text -- Lists (bulleted and numbered) -- Task lists with checkboxes -- Tables -- ~~Strikethrough~~ -- Links -- Code blocks -- Headings -- Automatic line breaks - -**Example:** - -```markdown -## Client Meeting Notes - -**Attendees:** John, Sarah, Mike - -**Topics Discussed:** - -1. Q1 project timeline -2. Budget approval -3. Design mockups - -**Action Items:** - -- [ ] Send meeting minutes -- [ ] Update project roadmap -- [ ] Schedule follow-up - -**Next Meeting:** 2024-02-15 -``` - -This renders beautifully in the task view with proper formatting and styling. - ---- - -## 📲 Progressive Web App - -### Installing as an App - -**Desktop (Chrome/Edge/Firefox):** - -1. Open TimeTracker Pro in your browser -2. Look for the install icon (⊕) in the address bar -3. Click "Install" when prompted -4. The app opens in its own window -5. Find it in your Applications folder or Start menu - -**iOS (Safari):** - -1. Open TimeTracker Pro in Safari -2. Tap the Share button (□↑) -3. Scroll and tap "Add to Home Screen" -4. Tap "Add" to confirm - - Toggle "Open as Web App" to "On" -5. Find the app icon on your home screen - -**Android (Chrome):** - -1. Open TimeTracker Pro in Chrome -2. Tap the menu (⋮) in the top-right -3. Tap "Install app" or "Add to Home screen" -4. Follow the prompts -5. Find the app in your app drawer - -### PWA Features - -**Offline Capability:** - -- Continue tracking time without internet -- All features work offline -- Data syncs automatically when connection restored -- Service worker caches app for instant loading - -**Mobile Optimized:** - -- Bottom navigation for easy thumb access -- 44×44px minimum touch targets (accessibility compliant) -- Safe area support for notched devices (iPhone X+) -- Responsive design adapts to any screen size -- Landscape and portrait orientations supported - -**Seamless Updates:** - -- New versions install automatically -- Update notification prompts you to refresh -- No data loss during updates -- Version management handled transparently - -**Native-Like Experience:** - -- Standalone window without browser UI -- Professional app icon -- Splash screen on launch -- Fast, responsive interactions - ---- - -## 🔧 Development Setup - -### Prerequisites - -- **Node.js** 18+ and npm -- **Git** for version control -- (Optional) **Supabase account** for cloud sync features - -### Installation - -```bash -# Clone the repository -git clone https://github.com/AdamJ/TimeTrackerPro.git - -# Navigate to project directory -cd TimeTrackerPro - -# Install dependencies -npm install -``` - -### Environment Setup (Optional) - -Cloud sync and authentication require Supabase credentials: - -```bash -# Copy environment template -cp .env.example .env - -# Edit .env and add your credentials -# VITE_SUPABASE_URL=https://your-project.supabase.co -# VITE_SUPABASE_ANON_KEY=your_anon_key_here -``` - -**Getting Supabase Credentials:** - -1. Create a free account at [supabase.com](https://supabase.com) -2. Create a new project -3. Go to Settings → API -4. Copy the Project URL and anon/public key -5. Paste into your `.env` file - -**⚠️ Security Note:** Never commit `.env` to version control! - -### Development Server - -```bash -# Start development server -npm run dev - -# Open in browser -# http://localhost:8080 -``` - -### Available Commands +## Available Commands ```bash # Development npm run dev # Start dev server (localhost:8080) -npm run build # Build for production -npm run build:dev # Build with development mode +npm run build # Production build npm run preview # Preview production build # Code Quality -npm run lint # Run ESLint for code quality -npm run test # Run Vitest unit tests - -# PWA Screenshots -npm run screenshots:install # Install Playwright browsers (first time) -npm run screenshots # Capture PWA screenshots (headless) -npm run screenshots:headed # Capture screenshots with visible browser +npm run lint # ESLint +npm run test # Vitest unit tests # iOS / Capacitor -npm run build:ios # Build for iOS (vite --mode ios, no PWA/auth UI) -npm run sync:ios # build:ios + cap sync ios (copies dist into Xcode project) - -# CSV Import Testing -npm run test-csv-import # Test standard CSV import -npm run test-full-import # Test full CSV import functionality -npm run test-error-handling # Test CSV error handling -``` - ---- - -## 🏗 Technical Architecture - -### Technology Stack - -**Core Framework:** - -- **React 18** - Modern UI framework with hooks and concurrent features -- **TypeScript 5.8** - Type safety and enhanced developer experience -- **Vite 5** - Lightning-fast build tool with SWC for optimal performance - -**UI & Styling:** - -- **Tailwind CSS 3** - Utility-first CSS framework -- **@tailwindcss/typography** - Beautiful markdown rendering -- **shadcn/ui** - Accessible component library built on Radix UI -- **Radix UI** - Unstyled, accessible component primitives -- **Radix Icons** - Icon library (primary) -- **Lucide React** - Icon library (fallback) - -**State & Data:** - -- **React Context API** - Global state management -- **React Hook Form** - Form state management with validation -- **Zod** - Schema validation for forms and data -- **Local Storage** - Browser storage for offline data persistence -- **Supabase** (optional) - PostgreSQL database and authentication - -**Native Mobile:** - -- **Capacitor 8** - Native iOS app wrapper (appId: `com.adamjolicoeur.timetrackerpro`, iOS 15+ minimum) -- **iOS-only build mode** - `VITE_IOS_BUILD` flag disables PWA/auth UI for native distribution - -**PWA & Performance:** - -- **Vite PWA Plugin** - Service worker and manifest generation -- **Workbox** - Advanced service worker caching strategies -- **React Router 6** - Client-side routing with lazy loading -- **Code Splitting** - All pages lazy loaded for optimal performance - -**Development & Testing:** - -- **Playwright** - Automated screenshot generation and E2E testing -- **Vitest** - Unit testing framework -- **@testing-library/react** - Component testing utilities -- **ESLint 9** - Code quality and style enforcement - -### Architecture Patterns - -**1. Context-Driven Architecture** - -``` -App.tsx -└── AuthProvider (authentication state) - └── TimeTrackingProvider (time tracking state) - └── OfflineProvider (offline queue) - └── Pages & Components -``` - -**2. Service Layer Pattern** - -Data persistence is abstracted through a service interface with two implementations: - -```typescript -interface DataService { - loadCurrentDay(): Promise; - saveCurrentDay(data: DayData): Promise; - loadArchivedDays(): Promise; - saveArchivedDays(days: ArchivedDay[]): Promise; - // ... other methods -} - -// Factory pattern selects implementation -const service = createDataService(isAuthenticated); -// Returns: LocalStorageService OR SupabaseService -``` - -**Benefits:** - -- Seamless switching between localStorage and Supabase -- No code changes when user signs in/out -- Easy to test with mock implementations -- Clean separation of concerns - -**3. Custom Hooks Pattern** - -Complex logic extracted into reusable hooks: - -- `useAuth()` - Authentication state and methods -- `useTimeTracking()` - Time tracking operations -- `useOffline()` - Offline queue management - -**4. Component Architecture** - -``` -src/ -├── components/ -│ ├── ui/ # Base components (49 files) -│ ├── Feature components # Domain-specific components -│ └── Layout components # Navigation, menus -├── pages/ # Route-level components (lazy loaded) -├── contexts/ # Global state providers -├── hooks/ # Custom React hooks -├── services/ # Data persistence layer -└── lib/ # Shared utilities -``` - -### Data Flow - -**Standard Operation Flow:** +npm run build:ios # Vite build for iOS (no PWA/auth UI) +npm run sync:ios # build:ios + cap sync ios -``` -User Action - ↓ -Component Event Handler - ↓ -Context Method (useTimeTracking) - ↓ -State Update (React setState) - ↓ -UI Re-render - ↓ -(On critical events only) - ↓ -DataService.save() - ↓ -localStorage OR Supabase -``` - -**Critical Save Events:** - -- Day end (`postDay()`) -- Window close (`beforeunload`) -- Manual sync button (`forceSyncToDatabase()`) - -**Why Manual Sync?** - -- Optimized for single-device usage -- Reduces unnecessary database calls -- Prevents rate limiting issues -- User controls when data is saved - -### Progressive Web App Implementation - -**Service Worker Strategy:** - -```javascript -// Caching Strategies -NetworkFirst: Supabase API calls (fresh data preferred) -CacheFirst: Google Fonts (static assets) -Precache: App shell (HTML, CSS, JS, icons) -``` - -**Manifest Configuration:** - -- App name, icons, theme colors -- Display mode: standalone -- Orientation: any -- Icons: 8 sizes (72px to 512px) -- Screenshots: Desktop (1920×1080) and Mobile (750×1334) - -**Offline Queue:** - -- Actions queued when offline -- Automatic sync when connection restored -- Conflict resolution for data updates -- User notification of sync status - -### Project Structure +# PWA Screenshots +npm run screenshots:install # Install Playwright (first time) +npm run screenshots # Capture screenshots (headless) -``` -TimeTrackerPro/ -├── src/ -│ ├── components/ # UI Components -│ │ ├── ui/ # Base components (49 files) -│ │ ├── ArchiveEditDialog.tsx -│ │ ├── ArchiveFilter.tsx -│ │ ├── ArchiveItem.tsx -│ │ ├── AuthDialog.tsx -│ │ ├── CategoryManagement.tsx -│ │ ├── DaySummary.tsx -│ │ ├── DeleteConfirmationDialog.tsx -│ │ ├── ExportDialog.tsx -│ │ ├── InstallPrompt.tsx -│ │ ├── MarkdownDisplay.tsx -│ │ ├── MobileNav.tsx -│ │ ├── Navigation.tsx -│ │ ├── NewTaskForm.tsx -│ │ ├── ProjectManagement.tsx -│ │ ├── StartDayDialog.tsx -│ │ ├── SyncStatus.tsx -│ │ ├── TaskEditDialog.tsx -│ │ ├── TaskItem.tsx -│ │ ├── UpdateNotification.tsx -│ │ └── UserMenu.tsx -│ ├── config/ # Configuration -│ │ ├── categories.ts # Default categories -│ │ └── projects.ts # Default projects -│ ├── contexts/ # React Context Providers -│ │ ├── AuthContext.tsx -│ │ ├── TimeTrackingContext.tsx -│ │ └── OfflineContext.tsx -│ ├── hooks/ # Custom Hooks -│ │ ├── useAuth.tsx -│ │ ├── useTimeTracking.tsx -│ │ ├── useOffline.tsx -│ │ └── use-toast.tsx -│ ├── lib/ # Utilities -│ │ ├── supabase.ts # Supabase client -│ │ └── utils.ts # Helper functions -│ ├── pages/ # Route Components -│ │ ├── Index.tsx # Home / Time tracker -│ │ ├── Archive.tsx # Archived days -│ │ ├── ProjectList.tsx # Project management -│ │ ├── Categories.tsx # Category management -│ │ ├── Report.tsx # AI weekly summary generator -│ │ ├── Settings.tsx # App settings -│ │ └── NotFound.tsx # 404 page -│ ├── services/ # Data Layer -│ │ └── dataService.ts # Persistence abstraction -│ ├── utils/ # Utilities -│ │ ├── timeUtil.ts # Time formatting -│ │ └── reportUtils.ts # Report grouping, formatting, and DayRecord adapter -│ ├── App.tsx # Root component -│ └── main.tsx # Entry point -├── public/ -│ ├── icons/ # PWA icons (8 sizes) -│ ├── screenshots/ # PWA screenshots -│ ├── pwa.css # PWA styles -│ └── print.css # Print styles -├── docs/ # Documentation -├── tests/ # Test files -├── supabase/ # Database schema -├── package.json -├── vite.config.ts # Vite + PWA config -├── tailwind.config.ts # Tailwind config -└── tsconfig.json # TypeScript config +# CSV Import Testing +npm run test-csv-import +npm run test-full-import +npm run test-error-handling ``` -### Code Conventions - -**Critical Requirements:** - -- **Indentation**: Tabs only (never spaces), 2-space width display -- **Quotes**: Double quotes (`""`) always, never single quotes -- **Imports**: Use `@/` alias for src imports (never relative paths like `../../`) - -**Naming Conventions:** - -- **Components**: PascalCase (e.g., `TaskItem.tsx`) -- **Hooks**: camelCase with `use` prefix (e.g., `useAuth.tsx`) -- **Utilities**: camelCase (e.g., `timeUtil.ts`) -- **Constants**: UPPER_SNAKE_CASE (e.g., `STORAGE_KEYS`) - -**TypeScript Usage:** - -- Loose type checking enabled (`noImplicitAny: false`) -- Use types where helpful, not strictly enforced -- Interface definitions in context files - -**Styling:** - -- Follow Radix UI design system -- Use shadcn/ui components (don't create custom equivalents) -- Use Tailwind utility classes -- Avoid custom colors (use theme variables) - -**See [CLAUDE.md](CLAUDE.md) for comprehensive development guidelines.** - --- -## 🔐 Authentication & Storage - -### Storage Modes - -**Guest Mode (Default):** - -- No account required -- All data stored in browser localStorage -- Full functionality available -- Data persists between sessions -- Limited to single device - -**Authenticated Mode (Optional):** - -- Sign in with email/password via Supabase -- Data synced to PostgreSQL database -- Access from multiple devices -- Automatic data migration from localStorage -- Cloud backup of all data - -### How Data Storage Works - -**Data Persistence Strategy:** - -TimeTracker Pro uses a **manual sync** approach optimized for single-device usage: - -1. **In-Memory First** - All changes update React state immediately -2. **Critical Event Saves** - Data persists only on: - - Day end (when you archive the day) - - Window close (before you navigate away) - - Manual sync (clicking the sync button) -3. **No Auto-Save** - Prevents unnecessary database calls and rate limiting - -**Why Manual Sync?** - -- Reduces API calls (cost-effective) -- Prevents rate limiting issues -- Optimized for single-device usage -- User controls when data is saved -- Faster UI interactions +## Development Setup -**Data Migration:** - -When you sign in, your localStorage data automatically migrates to Supabase: - -- Compares timestamps to prevent overwriting newer data -- Merges local and cloud data intelligently -- Preserves all archived days and tasks -- No data loss during migration - -When you sign out, Supabase data syncs back to localStorage for offline access. - -### Setting Up Cloud Sync - -**1. Create Supabase Project:** +**Prerequisites:** Node.js 18+ and npm. Supabase account is optional (guest mode works without it). ```bash -1. Visit https://supabase.com -2. Create free account -3. Create new project -4. Wait for project to initialize (~2 minutes) -``` - -**2. Get API Credentials:** - -```bash -1. Go to Project Settings → API -2. Copy Project URL -3. Copy anon/public key -``` - -**3. Configure Environment:** - -```bash -# Copy template -cp .env.example .env - -# Edit .env file -VITE_SUPABASE_URL=https://your-project.supabase.co -VITE_SUPABASE_ANON_KEY=your_anon_key_here -``` - -**4. Set Up Database:** - -```bash -# Database schema is in supabase/migrations/ -# See docs/SCHEMA_COMPATIBILITY.md for details -``` - -**5. Restart Development Server:** - -```bash -npm run dev -``` - -### Authentication Flow - -**Sign Up:** - -1. Click "Sign In" in user menu (top-right) -2. Click "Sign Up" tab -3. Enter email and password -4. Verify email (check inbox) -5. Sign in with credentials - -**Sign In:** - -1. Click "Sign In" in user menu -2. Enter email and password -3. Data automatically migrates from localStorage - -**Sign Out:** - -1. Click user menu (top-right) -2. Click "Sign Out" -3. Data syncs back to localStorage -4. Continue using in guest mode - -### Security - -**Password Requirements:** - -- Minimum 8 characters -- Handled securely by Supabase Auth - -**Data Security:** - -- All API calls over HTTPS -- Row-level security (RLS) enabled on Supabase -- Users can only access their own data -- Passwords hashed and salted by Supabase -- No sensitive data stored in localStorage - -**Best Practices:** - -- Never commit `.env` file to version control -- Keep Supabase keys secure -- Use strong passwords -- Enable MFA on Supabase account (recommended) - -**See [docs/AUTHENTICATION.md](docs/AUTHENTICATION.md) for detailed setup.** -**See [docs/SECURITY.md](docs/SECURITY.md) for security guidelines.** - ---- - -## 🔧 Development Workflow - -### Getting Started - -```bash -# Install dependencies npm install - -# Start development server npm run dev ``` -### Development Process - -**Before Making Changes:** - -1. Read relevant context file (`TimeTrackingContext.tsx` or `AuthContext.tsx`) -2. Check existing patterns in similar components -3. Review [CLAUDE.md](CLAUDE.md) for conventions - -**Making Changes:** - -1. Follow existing patterns (don't reinvent) -2. Use tabs and double quotes (enforced) -3. Use `@/` import alias -4. Test in both guest and authenticated modes - -**Before Committing:** - -```bash -# Run linter (must pass) -npm run lint - -# Run build (must succeed) -npm run build - -# Manual testing required -# Test your changes in browser -``` - -### Git Workflow - -**Branch Naming:** - -```bash -feature/your-feature-name -fix/bug-description -refactor/area-name -``` - -**Commit Messages:** +Before committing: ```bash -# Format: : -git commit -m "feat: add billable category option" -git commit -m "fix: resolve data recovery issue" -git commit -m "refactor: improve data service caching" - -# Types: feat, fix, refactor, docs, style, test, chore -``` - -**Pull Requests:** - -1. Title: `[TimeTrackerPro] Descriptive Title` -2. Clear description of changes -3. Wait for CI checks to pass -4. See [agents/pull_requests.md](agents/pull_requests.md) for full guidelines - -### Testing - -**Manual Testing Checklist:** - -- [ ] Test in guest mode (no authentication) -- [ ] Test in authenticated mode -- [ ] Test on mobile viewport (DevTools) -- [ ] Test data persistence (refresh page) -- [ ] Test export/import functionality -- [ ] Verify no console errors -- [ ] Check responsive design - -**PWA Testing:** - -- [ ] Service worker registers (DevTools → Application → Service Workers) -- [ ] App works offline (DevTools → Network → Offline) -- [ ] Install prompt appears (wait 30 seconds) -- [ ] App installs correctly -- [ ] Bottom navigation on mobile viewports -- [ ] Update notification works - -**Automated Testing:** - -```bash -# Unit tests -npm run test - -# CSV import tests -npm run test-csv-import -npm run test-full-import -npm run test-error-handling - -# PWA screenshots -npm run screenshots:install # First time only -npm run screenshots # Capture screenshots -``` - -### Customizing Markdown Styles - -TimeTracker Pro uses `@tailwindcss/typography` for markdown rendering. Three ways to customize: - -**1. Utility Classes (Recommended):** - -```tsx - -``` - -**2. Global Theme Overrides:** - -```typescript -// tailwind.config.ts -export default { - theme: { - extend: { - typography: { - DEFAULT: { - css: { - color: '#333', - a: { - color: '#3182ce', - '&:hover': { color: '#2c5282' } - } - } - } - } - } - } -}; +npm run lint && npm run build ``` -**3. Component-Specific Overrides:** - -```tsx -// src/components/MarkdownDisplay.tsx - ( - - {children} - - ) - }} -> - {content} - -``` - -### Adding Features - -**Adding a New Component:** - -```typescript -// 1. Create component in src/components/ -// 2. Follow existing patterns -// 3. Use shadcn/ui components -// 4. Import in parent component - -import { MyFeature } from '@/components/MyFeature'; -``` - -**Adding a New Page:** - -```typescript -// 1. Create page in src/pages/ -// 2. Add lazy load in App.tsx -const MyPage = lazy(() => import("./pages/MyPage")); - -// 3. Add route -} /> - -// 4. Add navigation link in Navigation.tsx -``` - -**Adding Context Method:** - -```typescript -// 1. Define in context interface -// 2. Implement in provider -// 3. Export in context value -// 4. Use in components via hook -``` +See [CLAUDE.md](CLAUDE.md) for code style requirements (tabs, double quotes, `@/` imports). See [README-EXT.md](README-EXT.md) for full developer documentation. --- -## 📚 Documentation - -### For Users +## For Developers -- **This README** - Complete user and developer guide -- [CSV Templates](docs/CSV_TEMPLATES_README.md) - Import/export format documentation -- [Screenshots](tests/SCREENSHOTS_README.md) - PWA screenshot documentation +Detailed documentation lives in [README-EXT.md](README-EXT.md): -### For Developers - -**Essential Reading:** - -- [**CLAUDE.md**](CLAUDE.md) - **START HERE** - Comprehensive codebase guide -- [**AGENTS.md**](AGENTS.md) - Quick agent instructions and workflows -- [Styles](agents/styles.md) - UI/UX style guidelines -- [Pull Requests](agents/pull_requests.md) - PR creation and review rules - -**Technical Documentation:** - -- [Authentication](docs/AUTHENTICATION.md) - Auth setup and configuration -- [Data Persistence](docs/AUTH_DATA_PERSISTENCE_FIX.md) - Persistence implementation -- [Schema Compatibility](docs/SCHEMA_COMPATIBILITY.md) - Database schema history -- [Migration Guide](docs/MIGRATION.md) - Supabase data migration -- [Security](docs/SECURITY.md) - Security configuration and practices - -**Additional Resources:** - -- [Features](docs/FEATURES.md) - Feature requests and improvement notes -- [Chatbot Notes](docs/chatbot.md) - AI interaction development records -- [Lovable README](info/README-LOVABLE.md) - Project origin and history - -### External References - -- [Radix UI](https://www.radix-ui.com) - Component primitives and design system -- [shadcn/ui](https://ui.shadcn.com) - Component library documentation -- [Tailwind CSS](https://tailwindcss.com) - CSS framework documentation -- [React Router](https://reactrouter.com) - Routing documentation -- [Supabase Docs](https://supabase.com/docs) - Backend documentation -- [Vite](https://vitejs.dev) - Build tool documentation +- [How to Use](README-EXT.md#how-to-use) — daily workflow, project/category management, export/import, markdown +- [Progressive Web App](README-EXT.md#progressive-web-app) — install instructions and PWA feature details +- [Authentication & Storage](README-EXT.md#authentication--storage) — storage modes, cloud sync setup, auth flow, security +- [Technical Architecture](README-EXT.md#technical-architecture) — stack, patterns, data flow, project structure, conventions +- [Development Workflow](README-EXT.md#development-workflow) — git workflow, testing, adding features +- [Documentation Index](README-EXT.md#documentation-index) — links to all docs +- [iOS Screenshots](README-EXT.md#ios-screenshots) --- -## 📋 Changelog - -For a detailed list of changes, new features, and bug fixes, see [CHANGELOG.md](CHANGELOG.md). - -**Recent Updates:** +## Changelog -- Native iOS app via Capacitor 8 — Xcode project scaffolded, iOS-specific build mode (`build:ios` / `sync:ios`) with auth/PWA UI disabled for native distribution -- `PageLayout` shared component standardizes page chrome (title + actions) across all pages -- Incomplete checklist items in task descriptions are now carried over as todo tasks when a day is archived -- Improved Weekly Report error messages to distinguish Gemini API failure modes (rate limit, quota, overload, key issues) -- Fixed Weekly Report for authenticated users (data now sourced from Supabase, not localStorage only) -- Native HTML5 time inputs for intuitive, accessible time selection +See [CHANGELOG.md](CHANGELOG.md) for the full history of changes. ---- - -## 📱 iOS Screenshots +**Recent highlights:** -| View | Image | -| --------------------- | ------------------------------------------------------------------ | -| Dashboard | | -| Time Entry - Markdown | | -| Time Entry - Preview | | -| Active Tasks | | -| Day Ended | | -| Archive | | +- Native iOS app via Capacitor 8 with iOS-specific build mode (`build:ios` / `sync:ios`) +- `PageLayout` shared component standardizes page chrome across all pages +- Incomplete checklist items carry over as todo tasks when archiving a day +- Weekly Report distinguishes Gemini API failure modes (rate limit, quota, overload, key issues) +- Fixed Weekly Report for authenticated users (data sourced from Supabase) --- -## 📄 License +## License -This project is open source and available under the MIT License. +MIT License — open source and free to use. --- -## 🙏 Credits +## Credits -- This project originally began as a [Lovable](https://lovable.dev) prompt - [Learn more](info/README-LOVABLE.md) +- Originally started with [Lovable](https://lovable.dev) — [learn more](info/README-LOVABLE.md) - Badges from [markdown-badges](https://github.com/Ileriayo/markdown-badges) -- UI components from [shadcn/ui](https://ui.shadcn.com) built on [Radix UI](https://www.radix-ui.com) +- UI components from [shadcn/ui](https://ui.shadcn.com) on [Radix UI](https://www.radix-ui.com) - Icons from [Radix Icons](https://www.radix-ui.com/icons) and [Lucide](https://lucide.dev) - Built with [React](https://react.dev), [Vite](https://vitejs.dev), and [Supabase](https://supabase.com) - ---- - -## 🚀 Ready to Get Started? - -**For Users:** - -1. Clone the repository or visit the hosted version -2. Click "Start Day" to begin tracking -3. Add tasks throughout your day -4. Review and archive when finished - -**For Developers:** - -1. Clone the repository: `git clone https://github.com/AdamJ/TimeTrackerPro.git` -2. Install dependencies: `npm install` -3. Start developing: `npm run dev` -4. Read [CLAUDE.md](CLAUDE.md) for comprehensive guidelines - -See where your hours really go with **TimeTracker Pro**.