A time-tracking and invoicing application built for freelancers to manage billable hours across multiple clients.
Worklog helps freelancers track their time, manage client information, and generate professional invoices. The app provides a simple interface for starting and stopping timers per client, viewing time entries, and calculating billable hours.
- Authentication — Secure GitHub OAuth login with NextAuth
- Client Management — Add, view, edit, and delete client information
- Time Tracking — Start/stop timers for specific clients to track billable hours
- Dashboard — View recent activity and time summaries
- Invoice Generation — Generate and download invoices based on tracked hours
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS v4
- Authentication: NextAuth v4 (GitHub OAuth)
- Database: PostgreSQL (Prisma Cloud) + Prisma ORM v7
- PDF Generation: jsPDF
- Deployment: Vercel (planned)
- Node.js 18+
- npm or yarn
- GitHub OAuth App credentials
- Clone the repository:
git clone https://github.com/grmbyrn/worklog.git
cd worklog- Install dependencies:
npm install- Set up environment variables:
Create a .env.local file in the root directory:
DATABASE_URL=your-postgresql-connection-string
AUTH_SECRET=your-auth-secret
AUTH_GITHUB_ID=your-github-oauth-client-id
AUTH_GITHUB_SECRET=your-github-oauth-client-secretTo generate AUTH_SECRET:
npx auth secretTo get GitHub OAuth credentials:
- Go to GitHub Settings → Developer Settings → OAuth Apps
- Create a new OAuth App
- Set Homepage URL to
http://localhost:3000 - Set Authorization callback URL to
http://localhost:3000/api/auth/callback/github
- Run the development server:
npm run devworklog/
├── app/
│ ├── api/auth/[...nextauth]/ # NextAuth API routes
│ ├── components/ # React components
│ ├── clients/ # Client management page
│ ├── dashboard/ # Dashboard page
│ ├── invoices/ # Invoice management page
│ ├── timer/ # Time tracking page
│ └── login/ # Login page
├── auth.ts # NextAuth configuration
├── middleware.ts # Route protection middleware
└── .env.local # Environment variables (not committed)
GET/POST /api/clients- List and create clientsPUT/DELETE /api/clients/[id]- Update and delete clientsPOST /api/timer- Save time entriesGET /api/dashboard- Fetch earnings analytics (total, weekly, monthly, by client)GET/POST /api/invoices- List and generate invoicesGET /api/invoices/[id]- Fetch invoice details for PDF generation
All routes are protected with session-based authentication via middleware.
- Authentication with NextAuth
- Landing page and navigation
- Database setup with Prisma
- Client CRUD operations
- Timer functionality
- Dashboard with time summaries
- Invoice generation and PDF export
- Deployment to Vercel
This project demonstrates:
- Modern Next.js patterns (App Router, Server Components)
- OAuth authentication flow
- Protected routes with middleware
- Type-safe development with TypeScript
- Responsive UI with Tailwind CSS
- Full-stack application architecture
Built as a portfolio piece to showcase production-ready code and best practices.
Authentication & Security:
- Implemented OAuth flow with GitHub and NextAuth
- Protected routes using Next.js middleware
- Session management with server-side validation
Database & Backend:
- Designed relational schema with proper foreign keys and cascade deletes
- Used Prisma ORM with PostgreSQL adapter pattern (v7)
- Handled user upsert pattern (session exists before User record)
Full-Stack Patterns:
- RESTful API design with proper HTTP methods
- Server components vs client components in Next.js App Router
- Type-safe development with TypeScript and Prisma
UI/UX:
- Responsive design with Tailwind CSS v4
- Mobile-first navigation with hamburger menu
- Client-side PDF generation with jsPDF
Challenges Solved:
- Next.js 16 async params breaking Prisma queries (awaited params)
- Prisma Client regeneration after schema changes
- Temporal dead zone errors in React hooks
- Calculating time-based earnings across multiple models