📱 Cross-platform mobile app (React Native + Expo) for employers and workers to track work hours, manage projects, and handle attendance — all powered by Supabase.
🎉 Version 1.0 – Official Release
Data (employers, workers, projects, punches) is synced with Supabase, while media files are stored locally on the device sandbox.
- Separate sign-in and registration for employers and workers
- Automatic employer ID assignment (
employer_no) - Worker registration linked to an existing employer
- Password reset flow with clipboard copy
- Prevents duplicate IDs in the cloud (unique per table)
- Employers can punch in/out from anywhere (location always logged)
- Real-time shift timer display
- Stored in Supabase table
punchesvia RPC calls - Location accuracy + haversine validation
- Offline punches queued and synced automatically
- View all workers and their total hours (calculated server-side)
- Each worker has an individual attendance policy:
- “From workplace only” (default)
- “From anywhere”
- Policy changes update instantly in Supabase (
workers.punch_mode) - Floating “Monthly Summary” button on workers page
- Employers can create / view / delete projects
- Stored in Supabase (
projectstable) - Local fallback with offline cache
- Add media (photos, videos, files) — saved locally, not in the cloud
- Project details open in a centered modal card
- Delete confirmation dialog with Supabase policy check
- Auto light/dark mode using
useColorScheme - Manual theme toggle (☀️ / 🌙) on login screen and personal info page
- All buttons styled consistently:
- 🟢 Green → main action (login / clock in)
- 🔵 Blue → secondary actions (register / update)
- 🔴 Red → destructive (delete / logout)
- Expo (React Native runtime)
- expo-router for file-based navigation
- Supabase for backend (Postgres + RLS + RPC)
- AsyncStorage for offline/local data
- expo-file-system for local project media
- expo-clipboard for password recovery
- TypeScript for full type safety
Create a .env file at the root (never commit real keys):
EXPO_PUBLIC_SUPABASE_URL="https://xxxx.supabase.co"
EXPO_PUBLIC_SUPABASE_ANON_KEY="your-anon-key"For CI/CD (EAS build):
Use Expo Secrets or GitHub Actions secrets to inject these values securely.
WorkLog-mobile/
├── app/
│ ├── _layout.tsx # Root layout (theme, router)
│ ├── auth.tsx # Worker login & registration
│ ├── employer-auth.tsx # Employer login, registration, password reset
│ ├── employer-home.tsx # Main employer panel (menu, clock, workers, projects)
│ ├── employer-project.tsx # Project modal view + file/media upload + delete
│ └── employer-workers.tsx # Monthly summary per worker
├── components/
│ └── WLLogo.tsx # Reusable large logo component
├── src/
│ ├── data/
│ │ └── repo.ts # Supabase & offline repository logic
│ ├── lib/
│ │ ├── supabase.ts # Supabase client
│ │ ├── location.ts # GPS + geocode helpers
│ │ └── storage.ts # Local storage for media
├── assets/
│ └── logo.png
└── README.md
-
Install dependencies
npm install
-
Configure environment
cp .env.example .env # fill in real Supabase values -
Start development server
npx expo start
-
Run verification + tests
npm run verify npm run test:cov
Security baseline and release-hardening checklist: docs/SECURITY_CHECKLIST.md.
APK files are published automatically on version tags via:
.github/workflows/release-apk.yml
git tag v1.0.1
git push origin v1.0.1The workflow will attach these artifacts to the GitHub Release:
WorkLog-debug.apkWorkLog-release-unsigned.apk
Note:
release-unsignedis not Play Store-ready by itself. For Play Store production, sign with your release keystore or use EAS signed builds.
eas build --platform ios
eas build --platform androidSecrets are managed via Expo → Project → Secrets.
Ensure your .env is not committed to git.
To allow deleting projects directly from the app, make sure you add this policy:
alter table public.projects enable row level security;
drop policy if exists projects_delete_all on public.projects;
create policy projects_delete_all
on public.projects
for delete
using (true);If you prefer owner-based deletion:
create policy projects_delete_own
on public.projects
for delete
using (auth.role() = 'authenticated' OR true)
with check (true);✅ Register employer → verify appears in Supabase
✅ Register worker → verify linked employer_no
✅ Change punch policy → test from worker app
✅ Clock-in/out → validate GPS stored
✅ Create project → verify in DB
✅ Delete project → ensure removed after SQL policy
✅ Light/dark toggle → persists correctly
✅ Logout → returns to login screen
If Android Studio emulator fails to connect:
- Install Expo Go from Play Store.
- Run
npx expo starton your Mac. - Scan the QR code with the Android device (same Wi-Fi).
✅ Easiest and most reliable.
- Open AVD from Android Studio (API 33+).
- In the Expo CLI window press:
a
- If bundler not loading, run:
or start Expo in tunnel mode:
adb reverse tcp:8081 tcp:8081
npx expo start --tunnel
MIT © 2025 WorkLog Team
