a7c138add1a5ffaf55571e0c454d74fff50ed3c6
BREAKING: Full rewrite from static HTML to production-grade stack. Features: - React 18 + Vite + Tailwind CSS (mobile-first) - Express + Prisma + PostgreSQL backend - JWT authentication with role-based access - Weekly Mon-Sun timesheets with auto-save - Multiple homeowner entries per day - Submit → Approve/Reject workflow - Server-side PDF generation - SMTP email integration - Admin panel with reporting & filters - Dark mode (system-aware) - Docker Compose one-command deploy - Non-root containers, Helmet, bcrypt, Zod validation
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 upfor 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
# Clone the repo
git clone https://git.bizzle.lol/bizzle/coastal_timesheet.git
cd coastal_timesheet
git checkout v2
# Configure environment
cp .env.example .env
# Edit .env with your secrets (see Configuration below)
# Launch
cd docker
docker compose up -d
The app will be available at http://localhost (port 80).
Default Admin Account
| Field | Value |
|---|---|
admin@coastal.com |
|
| Password | CoastalAdmin2026! |
⚠️ Change the admin password after first login.
⚙️ Configuration
Copy .env.example to .env and configure:
# Database (auto-configured in Docker)
DB_PASSWORD=your-secure-db-password
# JWT Secrets (CHANGE THESE!)
JWT_SECRET=your-jwt-secret-min-32-chars
JWT_REFRESH_SECRET=your-refresh-secret-min-32-chars
# CORS (add your domain)
CORS_ORIGINS=https://timesheets.yourdomain.com
# Email (optional — for sending timesheets)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM=timesheets@yourdomain.com
ADMIN_EMAIL=admin@yourdomain.com
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
┌─────────────────────────────────────────────┐
│ Nginx │
│ (reverse proxy) │
│ /api/* → backend:3001 │
│ /* → static frontend │
├──────────────────┬──────────────────────────┤
│ Frontend │ Backend │
│ React + Vite │ Express + Prisma │
│ Tailwind CSS │ JWT Auth │
│ Lucide Icons │ @react-pdf/renderer │
│ │ Nodemailer │
│ ├──────────────────────────┤
│ │ PostgreSQL 16 │
│ │ (persistent volume) │
└──────────────────┴──────────────────────────┘
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite 6, Tailwind CSS 3, Lucide |
| Backend | Express 4, Prisma ORM, bcryptjs, jsonwebtoken |
| Database | PostgreSQL 16 (Alpine) |
| @react-pdf/renderer (server-side) | |
| Nodemailer + SMTP | |
| Proxy | Nginx 1.27 (Alpine) |
| Container | Docker Compose v3.9 |
📁 Project Structure
.
├── frontend/ # React SPA
│ ├── src/
│ │ ├── api/ # Axios client with token refresh
│ │ ├── components/ # Reusable UI components
│ │ ├── contexts/ # Auth context (JWT)
│ │ ├── hooks/ # Custom hooks (theme, swipe, auto-save)
│ │ └── pages/ # Route pages
│ └── vite.config.js
├── backend/ # Express API
│ ├── prisma/
│ │ ├── schema.prisma # Database schema
│ │ └── seed.js # Seed admin + homeowners
│ └── src/
│ ├── middleware/ # Auth middleware
│ ├── routes/ # API routes
│ └── utils/ # PDF, email, validation
├── docker/ # Deployment
│ ├── docker-compose.yml
│ ├── backend/Dockerfile
│ ├── frontend/Dockerfile
│ └── nginx/default.conf
└── docs/screenshots/ # App screenshots
🔒 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 |
| Client-side (jsPDF) | Server-side (@react-pdf) | |
| 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
Description
Modern, mobile-first time tracking app for Coastal Contracting of FL — React + Express + PostgreSQL + Docker
Readme
6.5 MiB
Languages
JavaScript
95.1%
CSS
2.8%
Dockerfile
1.8%
HTML
0.3%






