feat: update dashboard widgets and WakaTime sync#30
feat: update dashboard widgets and WakaTime sync#30mrepol742 merged 1 commit intohallofcodes:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the dashboard UI/widgets and expands the WakaTime sync to persist and display additional 7-day breakdown data (daily stats, best day, plus categories/dependencies/machines), along with a few ancillary cleanup/housekeeping changes.
Changes:
- Extend stored user stats (DB + API sync) to include daily summaries, best day, machines, categories, and dependencies.
- Rework dashboard layout/styling and add new sidebar widgets for the new stats dimensions.
- Minor updates to legal terms, join route cleanup, and ignore patterns.
Reviewed changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| supabase/.temp/storage-version | Adds Supabase CLI temp metadata file (generated). |
| supabase/.temp/storage-migration | Adds Supabase CLI temp metadata file (generated). |
| supabase/.temp/rest-version | Adds Supabase CLI temp metadata file (generated). |
| supabase/.temp/project-ref | Adds Supabase CLI temp metadata file (project ref). |
| supabase/.temp/postgres-version | Adds Supabase CLI temp metadata file (generated). |
| supabase/.temp/pooler-url | Adds Supabase CLI temp metadata file containing pooler URL. |
| supabase/.temp/gotrue-version | Adds Supabase CLI temp metadata file (generated). |
| supabase/.temp/cli-latest | Adds Supabase CLI temp metadata file (generated). |
| sql/public.user_stats.sql | Extends public.user_stats schema and fixes RLS policy table references. |
| app/legal/terms/page.tsx | Escapes quotes in legal terms content. |
| app/components/dashboard/WithKey.tsx | Tightens typing around leaderboard creation promise handling. |
| app/components/dashboard/widgets/StatsCard.tsx | Updates KPI card layout/styling for new dashboard grid. |
| app/components/dashboard/widgets/Projects.tsx | Reworks “Top Projects” presentation with percentages/progress bars. |
| app/components/dashboard/widgets/OperatingSystem.tsx | Adjusts wrapper/styling to fit new sidebar container. |
| app/components/dashboard/widgets/Machines.tsx | New widget to render machine breakdown. |
| app/components/dashboard/widgets/LanguageDestribution.tsx | Adjusts layout to be flexible-height in new grid. |
| app/components/dashboard/widgets/Editors.tsx | Adjusts wrapper/styling to fit new sidebar container. |
| app/components/dashboard/widgets/Dependencies.tsx | New widget to render dependency breakdown. |
| app/components/dashboard/widgets/CodingActivity.tsx | Adjusts chart container sizing to be flexible-height. |
| app/components/dashboard/widgets/Categories.tsx | New widget to render category breakdown. |
| app/components/dashboard/Stats.tsx | Adds profile dropdown/header changes and uses real daily_stats (plus new widgets). |
| app/components/dashboard/Navbar.tsx | Removes settings/logout from sidebar and simplifies sidebar props usage. |
| app/api/wakatime/sync/route.ts | Fetches WakaTime summaries + persists new stats fields into Supabase. |
| app/(user)/dashboard/page.tsx | Passes name/email into the Stats component for header/profile UI. |
| app/(public)/join/[code]/page.tsx | Removes unused member-count function and minor cleanup. |
| .gitignore | Adds explicit .env.*.local patterns (in addition to existing .env*). |
Comments suppressed due to low confidence (1)
app/components/dashboard/WithKey.tsx:33
- The
new Promise(async (resolve, reject) => ...)pattern is an anti-pattern and can lead to promises that never settle. In particular,if (!user) return;exits without callingresolve/reject, which can leavetoast.promisestuck in the pending state. Prefer makingcreateLeaderboarditselfasync(and returning the Supabase result), or ensure every code path resolves/rejects.
const createLeaderboard = new Promise<{ join_code: string }>(async (resolve, reject) => {
try {
const { data: userData } = await supabase.auth.getUser();
const user = userData.user;
if (!user) return;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
supabase/.temp/pooler-url
Outdated
| @@ -0,0 +1 @@ | |||
| postgresql://postgres.nlaxmasxruefshxtuzzw@aws-1-ap-southeast-2.pooler.supabase.com:5432/postgres No newline at end of file | |||
There was a problem hiding this comment.
The Supabase CLI .temp metadata (especially this pooler URL) should not be committed: it is environment-specific and can leak sensitive project identifiers/connection details. Remove supabase/.temp/* from the repo and add an ignore rule so these files aren’t reintroduced.
| postgresql://postgres.nlaxmasxruefshxtuzzw@aws-1-ap-southeast-2.pooler.supabase.com:5432/postgres | |
| # Supabase pooler URL is environment-specific and should not be committed. | |
| # This file is intended to be managed/generated by the Supabase CLI or environment. |
| const [statsResponse, summariesResponse] = await Promise.all([ | ||
| fetch("https://wakatime.com/api/v1/users/current/stats/last_7_days", { | ||
| headers: { Authorization: authHeader }, | ||
| }), | ||
| fetch( | ||
| `https://wakatime.com/api/v1/users/current/summaries?start=${startStr}&end=${endStr}`, | ||
| { | ||
| headers: { Authorization: authHeader }, | ||
| } | ||
| ), | ||
| ]); | ||
|
|
||
| const data = await response.json(); | ||
| const statsData = await statsResponse.json(); | ||
| const summariesData = await summariesResponse.json(); | ||
|
|
||
| if (!response.ok) { | ||
| if (!statsResponse.ok || !summariesResponse.ok) { | ||
| return NextResponse.json( | ||
| { error: "Failed to fetch WakaTime" }, | ||
| { error: "Failed to fetch data from WakaTime" }, | ||
| { status: 500 }, | ||
| ); |
There was a problem hiding this comment.
statsResponse.json() / summariesResponse.json() are called before checking ok. If WakaTime returns a non-JSON error body (or an empty body), this will throw and bypass your intended error response. Check ok (or wrap JSON parsing in try/catch) before parsing, and include the upstream status/body in the error for easier debugging.
| // Use actual daily_stats if available, otherwise fallback to empty/flat | ||
| const dailyData = stats.daily_stats && stats.daily_stats.length > 0 | ||
| ? stats.daily_stats.map(d => { | ||
| // Parse date to short day name (e.g., "Mon") | ||
| const dateObj = new Date(d.date); | ||
| const dayStr = dateObj.toLocaleDateString("en-US", { weekday: "short" }); | ||
| return { | ||
| day: dayStr, | ||
| hours: parseFloat((d.total_seconds / 3600).toFixed(1)), | ||
| }; |
There was a problem hiding this comment.
new Date(d.date) where d.date is likely a YYYY-MM-DD string can shift the calendar day depending on the server/client timezone (JS parses it as UTC, then toLocaleDateString applies local TZ). This can mislabel the weekday in the chart. Prefer constructing the date in local time (e.g., append T00:00:00) or format using an explicit timezone/UTC to keep weekday labels stable.
d125b08 to
53bbf25
Compare
Changes\n- Added new dashboard widgets (Categories, Dependencies, Machines).\n- Updated existing dashboard styling and logic.\n- Updated WakaTime sync route.\n- Updated stats views and legal terms.\n- Restored easter egg comment.