Where teams get sh*t done.
A team management platform built to solve the chaos of organizing events across classes and organizations in college.
In college, students juggle memberships across multiple organizations, classes, and committees. Event schedules are scattered across group chats, emails, and word of mouth. Leaders waste time manually coordinating announcements, and members miss important events because there's no single source of truth.
Taskboard fixes this by giving every team a shared workspace with a calendar, member roster, and announcement system β all synced directly to Google Calendar.
- Create, edit, and delete events per team
- Two-way sync with Google Calendar β events appear on members' personal calendars automatically
- Month/week/day views powered by
react-big-calendar
- Add members individually or bulk import via CSV
- Inline validation and duplicate detection
- Searchable, sortable data tables powered by TanStack Table
- Compose rich-text announcements with a Tiptap editor (bold, italic, lists)
- Batch email delivery to all team members via Resend API
- Real-time delivery tracking with webhook status updates (Sent, Delivered, Failed)
- Supports batches of 100+ recipients with automatic splitting
- Google OAuth via Supabase Auth
- Automatic profile creation on first login
- Secure session management with
@supabase/ssrmiddleware
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack) |
| Language | TypeScript |
| Styling | Tailwind CSS 4 |
| UI Components | Radix UI, Lucide Icons, Class Variance Authority |
| Database | PostgreSQL via Supabase |
| ORM | Prisma with @prisma/adapter-pg |
| Auth | Supabase Auth + Google OAuth 2.0 |
| Resend + React Email + Svix webhooks | |
| Calendar | Google Calendar API via googleapis |
| Rich Text | Tiptap |
| Tables | TanStack React Table |
| Forms | React Hook Form + Zod validation |
| Error Tracking | Sentry |
| Hosting | Vercel |
| Domain | taskboard.page |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Vercel (Next.js 16) β
β β
β βββββββββββ ββββββββββββ ββββββββββββββ ββββββββββ β
β β Login β βDashboard β βTeam Workspaceβ βLegal β β
β β Page β β (Teams) β βCal/Members/ β βPages β β
β β β β β βAnnouncements β β β β
β ββββββ¬βββββ ββββββ¬ββββββ ββββββββ¬ββββββββ ββββββββββ β
β β β β β
β ββββββΌβββββββββββββΌββββββββββββββββΌβββββββββββββββββββ β
β β Supabase Auth Middleware (proxy.ts) β β
β ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββ β
β β Server Actions (actions/) β β
β β teams.ts Β· members.ts Β· announcements.ts β β
β ββββ¬βββββββββββ¬βββββββββββββββ¬ββββββββββββββββββββββββ β
β β β β β
β βΌ βΌ βΌ β
β Prisma Google API Resend β
β β β β β
βββββββΌβββββββββββΌβββββββββββββββΌβββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
Supabase Google Resend API
PostgreSQL Calendar + Webhooks
erDiagram
profiles {
uuid id PK
string email
string full_name
string avatar_url
string google_refresh_token
}
teams {
uuid id PK
uuid leader_id FK
string name
string google_calendar_id
}
members {
uuid id PK
string email UK
string full_name
}
team_members {
uuid id PK
uuid team_id FK
uuid member_id FK
}
events {
uuid id PK
uuid team_id FK
string title
string google_event_id UK
timestamp event_start
timestamp event_end
}
announcements {
bigint id PK
uuid team_id FK
string title
string content
string resend_batch_id
enum email_status
int recipient_count
int delivered_count
}
profiles ||--o{ teams : "leads"
teams ||--o{ team_members : "has"
members ||--o{ team_members : "belongs to"
teams ||--o{ events : "has"
teams ||--o{ announcements : "has"
- Node.js 18+
- A Supabase project
- A Google Cloud project with Calendar API enabled
- A Resend account
git clone https://github.com/your-username/taskboard.git
cd taskboard
npm installCreate a .env file in the project root:
# App
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your_supabase_anon_key
DATABASE_URL=your_pooled_connection_string
DIRECT_URL=your_direct_connection_string
# Google OAuth
NEXT_PUBLIC_GOOGLE_CLIENT_ID=your_google_client_id
SUPABASE_AUTH_EXTERNAL_GOOGLE_CLIENT_SECRET=your_google_client_secret
# Resend
RESEND_API_KEY=your_resend_api_key
RESEND_WEBHOOK_SECRET=your_resend_webhook_secretnpx prisma generate
npx prisma migrate devnpm run devVisit http://localhost:3000
| Command | Description |
|---|---|
npm run dev |
Start development server (Turbopack) |
npm run build |
Production build |
npm run start |
Start production server |
npm run lint |
Run ESLint |
npm run test |
Run Jest tests |
npm run test:watch |
Run tests in watch mode |
npm run test:coverage |
Generate test coverage report |
Taskboard/
βββ app/
β βββ (auth)/login/ # Login page + Google OAuth
β βββ dashboard/ # Team selection dashboard
β β βββ components/ # Dashboard UI components
β β βββ teams/[teamsId]/ # Team workspace
β β βββ (calendar)/ # Calendar tab
β β βββ (members)/ # Members tab
β β βββ (announcements)/ # Announcements tab
β βββ privacy/ # Privacy Policy
β βββ terms/ # Terms of Service
β βββ auth/callback/ # OAuth callback handler
βββ actions/ # Server actions
β βββ teams.ts
β βββ members.ts
β βββ (announcements)/
βββ components/ # Shared UI components
βββ lib/ # Utilities (Resend, Google Calendar)
βββ prisma/ # Schema & migrations
βββ utils/ # Supabase clients, Prisma client
βββ supabase/functions/ # Edge Functions
Taskboard is deployed on Vercel with automatic deploys from the main branch.
- Connect your GitHub repo to Vercel
- Set all environment variables in the Vercel dashboard
- Set
NEXT_PUBLIC_APP_URLto your production domain - Push to
mainβ Vercel handles the rest
This project is open-source under the MIT License.
Built with β for college students who are tired of missing org events.
