Coastal Timesheet v2
A modern, mobile-first time tracking application for Coastal Contracting of FL
✨ Features
- 📱 Mobile-first design — Built for field workers, optimized for phones
- 🔐 JWT authentication — Secure login with access/refresh tokens + rate limiting
- 📅 Weekly timesheets — Monday–Sunday pay period with auto-save
- 🏠 Multiple homeowners per day — Track work at different job sites
- ✅ Submit → Approve workflow — Employees submit, admins approve or reject
- 📄 PDF generation — Professional server-side PDF export
- 📧 Email integration — Send timesheets via email with SMTP
- 👥 Admin panel — Manage employees, homeowners, review timesheets
- 📊 Reporting — Filter by employee, date range, status with summary stats
- 🌙 Dark mode — System-aware with manual toggle
- 🐳 One-command deploy — Single
docker compose up for the entire stack
📸 Screenshots
| Timesheet Entry |
Entry Form |
Dark Mode |
 |
 |
 |
| Admin Panel |
Reports & Filters |
History |
 |
 |
 |
Desktop
🚀 Quick Start
Prerequisites
- Docker and Docker Compose
- That's it. Everything else runs in containers.
Deploy
The app will be available at http://localhost (port 80).
Default Admin Account
| Field |
Value |
| Email |
admin@coastal.com |
| Password |
CoastalAdmin2026! |
⚠️ Change the admin password after first login.
⚙️ Configuration
Copy .env.example to .env and configure:
Email Setup (Gmail)
- Enable 2FA on your Google account
- Go to App Passwords
- Generate a new app password for "Mail"
- Use that as
SMTP_PASS
🏗️ Architecture
Tech Stack
| Layer |
Technology |
| Frontend |
React 18, Vite 6, Tailwind CSS 3, Lucide |
| Backend |
Express 4, Prisma ORM, bcryptjs, jsonwebtoken |
| Database |
PostgreSQL 16 (Alpine) |
| PDF |
@react-pdf/renderer (server-side) |
| Email |
Nodemailer + SMTP |
| Proxy |
Nginx 1.27 (Alpine) |
| Container |
Docker Compose v3.9 |
📁 Project Structure
🔒 Security
- bcrypt password hashing (12 rounds)
- JWT access tokens (15min) + refresh tokens (7 days)
- Helmet security headers
- Rate limiting on auth endpoints (50 req / 15 min)
- Zod input validation on all endpoints
- Prisma ORM — parameterized queries (no SQL injection)
- Non-root Docker containers
- CORS origin whitelist
📡 API Endpoints
Auth
| Method |
Endpoint |
Description |
| POST |
/api/auth/login |
Login, get tokens |
| POST |
/api/auth/refresh |
Refresh access token |
| GET |
/api/auth/me |
Current user info |
Entries
| Method |
Endpoint |
Description |
| GET |
/api/entries |
List entries (by week) |
| POST |
/api/entries |
Create entry |
| PUT |
/api/entries/:id |
Update entry |
| DELETE |
/api/entries/:id |
Delete entry |
Timesheets
| Method |
Endpoint |
Description |
| GET |
/api/timesheets |
Get current week |
| GET |
/api/timesheets/history |
All user timesheets |
| POST |
/api/timesheets/submit |
Submit for approval |
| GET |
/api/timesheets/:id/pdf |
Download PDF |
Admin
| Method |
Endpoint |
Description |
| GET |
/api/admin/timesheets |
All timesheets (filter) |
| GET |
/api/admin/timesheets/:id |
Timesheet detail |
| PUT |
/api/admin/timesheets/:id/approve |
Approve timesheet |
| PUT |
/api/admin/timesheets/:id/reject |
Reject timesheet |
| PUT |
/api/admin/timesheets/:id/reopen |
Reopen for editing |
| GET |
/api/admin/users |
List employees |
| POST |
/api/admin/users |
Create employee |
| GET |
/api/admin/homeowners |
List homeowners |
| POST |
/api/admin/homeowners |
Add homeowner |
| GET |
/api/admin/reports |
Reporting with filters |
🔄 Upgrading from v1
v2 is a complete rewrite. Key differences:
| Feature |
v1 |
v2 |
| Storage |
Browser localStorage |
PostgreSQL database |
| Auth |
None |
JWT with roles |
| Multi-user |
No |
Yes — unlimited employees |
| Approval flow |
No |
Submit → Approve/Reject |
| PDF |
Client-side (jsPDF) |
Server-side (@react-pdf) |
| Email |
mailto: link |
SMTP with PDF attachment |
| Deploy |
Static HTML |
Docker Compose (one command) |
| Admin panel |
No |
Full admin with reporting |
| Dark mode |
No |
System-aware + manual toggle |
📝 License
Private — Coastal Contracting of FL. All rights reserved.
Built with ☀️ in Florida