AI workflow planner that turns brain-dumped tasks into a conflict-aware weekly schedule, then syncs approved blocks to Google Calendar.
Built with Next.js App Router, Tailwind, and OpenAI.
- AI task analysis:
- effort estimate (
estimatedHours) - urgency and priority scoring
- split vs non-split recommendation
- date gating (
notBeforeISO) when work cannot start yet
- effort estimate (
- Conflict-aware scheduling against Google Calendar busy times
- Per-day scheduling windows (time preferences)
- Google Calendar conflict filters (ignore selected calendars)
- Live calendar week snapshot with overlap visualization
- One-click "Add to Google Calendar" links for planned blocks
- Persistent planner state:
- local storage
- optional cloud sync via Supabase (per Google user)
- Photo-to-task intake:
- upload an image
- AI extracts one or multiple tasks
- auto-adds to queue
- Theme support: light, dark, pink
- Vercel Analytics integrated globally
- Next.js 16 (App Router)
- React 19
- Tailwind CSS 4
- OpenAI Chat Completions API (analysis + image extraction)
- Google OAuth + Google Calendar API
- Supabase REST API (optional persistence)
- Vercel Analytics (
@vercel/analytics)
src/app/page.tsx- landing pagesrc/app/planner/page.tsx- main planner UIsrc/app/api/ai/analyze/route.ts- AI analysis endpointsrc/app/api/ai/extract-task-image/route.ts- photo task extraction endpointsrc/app/api/planner/schedule/route.ts- Google conflict fetch endpointsrc/app/api/google/*- calendar snapshot, calendar list, token helperssrc/lib/planner.ts- scheduling engine + modelssrc/lib/google-auth.ts- OAuth cookie/token handlingsrc/lib/cloud-state.ts- Supabase cloud state helpers
Create .env.local from .env.example:
cp .env.example .env.localRequired:
NEXT_PUBLIC_APP_URLGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGOOGLE_REDIRECT_URIGOOGLE_OAUTH_COOKIE_SECRET(>= 32 chars, random)OPENAI_API_KEY
Optional:
OPENAI_MODEL(default:gpt-4o-mini)SUPABASE_URLSUPABASE_SERVICE_ROLE_KEYSUPABASE_PLANNER_TABLE(default:planner_states)
- Create/select a Google Cloud project.
- Enable APIs:
- Google Calendar API
- Configure OAuth consent screen:
- add test users while in Testing mode
- Create OAuth 2.0 Client ID (Web application).
- Add authorized origins:
http://localhost:3000- your production domain(s)
- Add redirect URIs:
http://localhost:3000/api/auth/google/callbackhttps://<your-domain>/api/auth/google/callback
- Set env vars in
.env.localand your deployment platform.
If you want planner state shared across sessions/devices:
- Create Supabase project.
- Create table (default name
planner_states) with:user_id text primary keystate jsonb not nullupdated_at timestamptz default now()
- Put
SUPABASE_URLandSUPABASE_SERVICE_ROLE_KEYin env.
If Supabase env vars are not set, app runs in local-only persistence mode.
npm install
npm run devOpen http://localhost:3000.
npm run build
npm run start- Push repo to GitHub/GitLab/Bitbucket.
- Import project in Vercel.
- Add all environment variables in Vercel Project Settings.
- Update Google OAuth authorized origin/redirect URI to your deployed domain.
- Redeploy.
- Tasks are analyzed by AI.
- Planner requests Google busy intervals from
/api/planner/schedule. - Final schedule is generated client-side using:
- AI analyses
- busy intervals
- user time preferences
- Suggested blocks are added to Google via prefilled calendar links.
- Live snapshot polling confirms additions and marks synced blocks.
Error 403 access_deniedon Google login:- add your account as OAuth test user or publish app
Google Calendar API has not been used / disabled:- enable Google Calendar API in the same GCP project
- Conflicts not detected:
- ensure calendar is not in ignored filters
- refresh snapshot and rerun Plan My Week
- Cloud sync says
cloud not configured:- set Supabase env vars
- Photo upload extracts weak details:
- use clearer image/crop and rerun upload
- Never commit
.env.local. - Rotate exposed secrets immediately.
GOOGLE_OAUTH_COOKIE_SECRETshould be long random data.- Supabase
SERVICE_ROLEkey must stay server-side only.
Add your preferred license (MIT, Apache-2.0, proprietary, etc.).