The TimeTrackerPro app now supports both authenticated and unauthenticated usage:
- Data synced across devices
- Cloud backup and restore
- Secure user accounts
- Automatic data migration from localStorage
- Works completely offline
- No account required
- Data stored locally in browser
- Full app functionality available
Copy .env.example to .env and add your Supabase credentials:
cp .env.example .envEdit .env:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key_here
Run the SQL commands in supabase/schema.sql in your Supabase dashboard to create the required tables.
npm install
npm run dev- App automatically uses localStorage
- All features work normally
- No authentication required
- Data stays on device
- Users can choose to sign in or continue without account
- Authenticated users get cloud sync
- Unauthenticated users still use localStorage
- Seamless migration when signing in
When a user signs in for the first time, their existing localStorage data is automatically migrated to Supabase, ensuring no data loss.
LocalStorageService: Handles browser storageSupabaseService: Handles cloud storage- Automatic service selection based on auth status
- Manages user authentication state
- Provides sign in/up/out functions
- Handles session management
UserMenu: Shows auth status and optionsAuthDialog: Sign in/up modal- Seamless integration with existing UI
- Environment variables keep credentials secure
- Row Level Security (RLS) in Supabase
- User data isolation
- No sensitive data in client code
- Active tasks with full metadata (title, description, project, client, category)
- Day start/end times
- Current task information
- Real-time duration tracking
- Completed day records with task details
- Individual task records in relational format
- Searchable by project, client, category, date ranges
- User-defined projects with hourly rates
- Custom categories with colors
- Proper relational storage for advanced filtering
The app uses a factory pattern to create the appropriate data service:
const dataService = createDataService(isAuthenticated);This ensures that the same interface is used regardless of storage backend, making the code maintainable and testable.