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.
For Users:
For Developers:
- Development Setup
- Technical Architecture
- Authentication & Storage
- Development Workflow
- Documentation
Screenshots:
Additional:
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:
- Start your day - Click one button to begin tracking
- Create tasks - Add tasks as you work on different projects
- End your day - Review your summary and archive the day
- 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
- Daily Time Tracking - Start/stop your workday with clear boundaries
- Task Management - Create, edit, and delete tasks with real-time duration tracking
- 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
- 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
- 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
- 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
- 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
Option 1: Use Online (No installation required)
- Visit the hosted version (if available) or run locally
- Click "Start Day" to begin tracking
- Add tasks throughout your day
- Click "End Day" and archive when finished
Option 2: Install Locally
# 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 devThe application will be available at http://localhost:8080
First Time Setup:
- Open the app in your browser
- Click "Start Day" to begin tracking time
- (Optional) Click "Sign In" to enable cloud sync across devices
- (Optional) Set up projects and categories for better organization
That's it! No complex configuration required.
Morning:
- Click "Start Day" button to begin tracking
- 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
- Task duration calculates automatically
- 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
Setting Up Projects:
- Navigate to Archive page
- Click Projects button
- Click Add Project
- Enter project details:
- Project name
- Client name
- Hourly rate
- Mark as billable/non-billable
- 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
Customizing Categories:
- Navigate to Categories page from the main menu
- View default categories or create new ones
- Click Add Category to create custom categories
- 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
Exporting Data:
- Navigate to Archive page
- Click Export button
- Choose export format:
- CSV - For Excel, Google Sheets, or accounting software
- JSON - For programmatic access or backup
- Invoice - Client-ready invoice format
- Filter by date range, project, or client
- Download the file
Importing Data:
-
Prepare a CSV file using the template format (see CSV Templates)
-
Use the import functionality (coming soon) or test scripts:
npm run test-csv-import
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:
## 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-15This renders beautifully in the task view with proper formatting and styling.
Desktop (Chrome/Edge/Firefox):
- Open TimeTracker Pro in your browser
- Look for the install icon (⊕) in the address bar
- Click "Install" when prompted
- The app opens in its own window
- Find it in your Applications folder or Start menu
iOS (Safari):
- Open TimeTracker Pro in Safari
- Tap the Share button (□↑)
- Scroll and tap "Add to Home Screen"
- Tap "Add" to confirm
- Toggle "Open as Web App" to "On"
- Find the app icon on your home screen
Android (Chrome):
- Open TimeTracker Pro in Chrome
- Tap the menu (⋮) in the top-right
- Tap "Install app" or "Add to Home screen"
- Follow the prompts
- Find the app in your app drawer
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
- Node.js 18+ and npm
- Git for version control
- (Optional) Supabase account for cloud sync features
# Clone the repository
git clone https://github.com/AdamJ/TimeTrackerPro.git
# Navigate to project directory
cd TimeTrackerPro
# Install dependencies
npm installCloud sync and authentication require Supabase credentials:
# 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_hereGetting Supabase Credentials:
- Create a free account at supabase.com
- Create a new project
- Go to Settings → API
- Copy the Project URL and anon/public key
- Paste into your
.envfile
.env to version control!
# Start development server
npm run dev
# Open in browser
# http://localhost:8080# 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 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
# 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 handlingCore 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
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
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:
interface DataService {
loadCurrentDay(): Promise<DayData>
saveCurrentDay(data: DayData): Promise<void>
loadArchivedDays(): Promise<ArchivedDay[]>
saveArchivedDays(days: ArchivedDay[]): Promise<void>
// ... other methods
}
// Factory pattern selects implementation
const service = createDataService(isAuthenticated)
// Returns: LocalStorageService OR SupabaseServiceBenefits:
- 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 methodsuseTimeTracking()- Time tracking operationsuseOffline()- 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
Standard Operation Flow:
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
Service Worker Strategy:
// 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
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
│ │ ├── Settings.tsx # App settings
│ │ └── NotFound.tsx # 404 page
│ ├── services/ # Data Layer
│ │ └── dataService.ts # Persistence abstraction
│ ├── utils/ # Utilities
│ │ └── timeUtil.ts # Time formatting
│ ├── 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
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
useprefix (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 for comprehensive development guidelines.
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
Data Persistence Strategy:
TimeTracker Pro uses a manual sync approach optimized for single-device usage:
- In-Memory First - All changes update React state immediately
- 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)
- 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
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.
1. Create Supabase Project:
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:
1. Go to Project Settings → API
2. Copy Project URL
3. Copy anon/public key3. Configure Environment:
# Copy template
cp .env.example .env
# Edit .env file
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key_here4. Set Up Database:
# Database schema is in supabase/migrations/
# See docs/SCHEMA_COMPATIBILITY.md for details5. Restart Development Server:
npm run devSign Up:
- Click "Sign In" in user menu (top-right)
- Click "Sign Up" tab
- Enter email and password
- Verify email (check inbox)
- Sign in with credentials
Sign In:
- Click "Sign In" in user menu
- Enter email and password
- Data automatically migrates from localStorage
Sign Out:
- Click user menu (top-right)
- Click "Sign Out"
- Data syncs back to localStorage
- Continue using in guest mode
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
.envfile to version control - Keep Supabase keys secure
- Use strong passwords
- Enable MFA on Supabase account (recommended)
See docs/AUTHENTICATION.md for detailed setup. See docs/SECURITY.md for security guidelines.
# Install dependencies
npm install
# Start development server
npm run devBefore Making Changes:
- Read relevant context file (
TimeTrackingContext.tsxorAuthContext.tsx) - Check existing patterns in similar components
- Review CLAUDE.md for conventions
Making Changes:
- Follow existing patterns (don't reinvent)
- Use tabs and double quotes (enforced)
- Use
@/import alias - Test in both guest and authenticated modes
Before Committing:
# Run linter (must pass)
npm run lint
# Run build (must succeed)
npm run build
# Manual testing required
# Test your changes in browserBranch Naming:
feature/your-feature-name
fix/bug-description
refactor/area-nameCommit Messages:
# Format: <type>: <description>
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, chorePull Requests:
- Title:
[TimeTrackerPro] Descriptive Title - Clear description of changes
- Wait for CI checks to pass
- See agents/pull_requests.md for full guidelines
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:
# 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 screenshotsTimeTracker Pro uses @tailwindcss/typography for markdown rendering. Three ways to customize:
1. Utility Classes (Recommended):
<MarkdownDisplay
content={text}
className="prose-p:text-blue-500 prose-headings:underline"
/>2. Global Theme Overrides:
// tailwind.config.ts
export default {
theme: {
extend: {
typography: {
DEFAULT: {
css: {
color: '#333',
a: {
color: '#3182ce',
'&:hover': { color: '#2c5282' },
},
},
},
},
},
},
}3. Component-Specific Overrides:
// src/components/MarkdownDisplay.tsx
<ReactMarkdown
components={{
a: ({ href, children }) => (
<a href={href} className="custom-link-style">
{children}
</a>
),
}}
>
{content}
</ReactMarkdown>Adding a New Component:
// 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:
// 1. Create page in src/pages/
// 2. Add lazy load in App.tsx
const MyPage = lazy(() => import("./pages/MyPage"));
// 3. Add route
<Route path="/mypage" element={<MyPage />} />
// 4. Add navigation link in Navigation.tsxAdding Context Method:
// 1. Define in context interface
// 2. Implement in provider
// 3. Export in context value
// 4. Use in components via hook- This README - Complete user and developer guide
- CSV Templates - Import/export format documentation
- Screenshots - PWA screenshot documentation
Essential Reading:
- CLAUDE.md - START HERE - Comprehensive codebase guide
- AGENTS.md - Quick agent instructions and workflows
- Styles - UI/UX style guidelines
- Pull Requests - PR creation and review rules
Technical Documentation:
- Authentication - Auth setup and configuration
- Data Persistence - Persistence implementation
- Schema Compatibility - Database schema history
- Migration Guide - Supabase data migration
- Security - Security configuration and practices
Additional Resources:
- Features - Feature requests and improvement notes
- Chatbot Notes - AI interaction development records
- Lovable README - Project origin and history
- Radix UI - Component primitives and design system
- shadcn/ui - Component library documentation
- Tailwind CSS - CSS framework documentation
- React Router - Routing documentation
- Supabase Docs - Backend documentation
- Vite - Build tool documentation
| View | Image |
|---|---|
| Dashboard | |
| Time Entry - Markdown | |
| Time Entry - Preview | |
| Active Tasks | |
| Day Ended | |
| Archive |
This project is open source and available under the MIT License.
- This project originally began as a Lovable prompt - Learn more
- Badges from markdown-badges
- UI components from shadcn/ui built on Radix UI
- Icons from Radix Icons and Lucide
- Built with React, Vite, and Supabase
For Users:
- Clone the repository or visit the hosted version
- Click "Start Day" to begin tracking
- Add tasks throughout your day
- Review and archive when finished
For Developers:
- Clone the repository:
git clone https://github.com/AdamJ/TimeTrackerPro.git - Install dependencies:
npm install - Start developing:
npm run dev - Read CLAUDE.md for comprehensive guidelines
See where your hours really go with TimeTracker Pro.