Skip to content

Feat/add customizable dashboard widgets with user prefrences persistence [ISSUE: #175]#393

Closed
abdullahxyz85 wants to merge 10 commits into
Priyanshu-byte-coder:mainfrom
abdullahxyz85:feat/add-customizable-dashboard-widgets-with-user-prefrences
Closed

Feat/add customizable dashboard widgets with user prefrences persistence [ISSUE: #175]#393
abdullahxyz85 wants to merge 10 commits into
Priyanshu-byte-coder:mainfrom
abdullahxyz85:feat/add-customizable-dashboard-widgets-with-user-prefrences

Conversation

@abdullahxyz85
Copy link
Copy Markdown
Contributor

Description ISSUE: #175

Implement a comprehensive dashboard widget customization system that allows users to toggle the visibility of dashboard widgets. User preferences are persisted in Supabase and applied immediately without page reload.

Features

User Widget Preferences

  • Users can toggle visibility for 9 dashboard widgets
  • Preferences stored in Supabase as JSONB
  • All widgets default to visible for new users
  • Immediate UI updates without page reload

Database

  • Added user_widget_prefs JSONB column to users table
  • Default values initialized for all 9 widgets
  • RLS policies configured for secure access

Settings UI

  • New "Dashboard Widgets" section in Settings page
  • 9 toggle switches with descriptive labels
  • Real-time save with error handling
  • Shows count of visible widgets
  • Accessible design with proper ARIA labels

Dashboard Integration

  • Dashboard reads user preferences on load
  • Conditionally renders widgets based on preferences
  • Fallback: Shows all widgets if fetch fails (safety default)
  • No page reload required for changes to take effect

API Enhancement

  • Extended /api/user/settings to handle widget preferences
  • Auto-creates user record on first login
  • GET returns current preferences
  • PATCH updates preferences independently

Changes Made

Database

  • File: supabase/migrations/20260519000000_add_widget_preferences.sql

    • New migration file adding user_widget_prefs column
  • File: supabase/schema.sql

    • Updated schema with widget preferences defaults

API Routes

  • File: src/app/api/user/settings/route.ts
    • Added ensureUserExists() call for auto user creation
    • GET endpoint now returns user_widget_prefs
    • PATCH endpoint now accepts user_widget_prefs updates
    • Improved error logging and handling

Pages

  • File: src/app/dashboard/settings/page.tsx

    • Integrated DashboardWidgetSettings component
    • Added handleUpdateWidgetPrefs() handler
    • Improved error reporting
  • File: src/app/dashboard/page.tsx

    • Converted to client component for state management
    • Fetches user preferences on mount
    • Conditionally renders widgets based on preferences
    • Fallback behavior for failed fetches

Widgets Supported

User Experience Flow

  1. First Login: User preferences auto-created with all widgets visible
  2. Settings Page: Navigate to Settings → Dashboard Widgets
  3. Toggle Widgets: Click switches to show/hide widgets
  4. Immediate Updates: Changes apply instantly to dashboard
  5. Persistence: Preferences saved to Supabase and restored on page reload
  6. Safety: If preferences fetch fails, all widgets display by default

Testing Recommendations

  • Test toggling each widget individually
  • Verify preferences persist across page reloads
  • Test with multiple user accounts
  • Verify fallback behavior when API fails
  • Check responsive design on mobile/tablet
  • Test keyboard accessibility (Tab + Space/Enter)
  • Verify all widgets render/hide correctly
  • Test error states and error messages

Related Issues

Closes #175 (Dashboard Widget Customization)

Notes

  • Database migration should be applied to production Supabase before deployment
  • RLS policies configured for secure row-level access
  • All 9 widgets default to visible for new users
  • Feature gracefully degrades if Supabase is unreachable

@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

@abdullahxyz85 is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel.

A member of the Team first needs to authorize it.

@abdullahxyz85
Copy link
Copy Markdown
Contributor Author

@Priyanshu-byte-coder check it now, I close the older PR and create new PRs by spliting from each others, please review and merge and make sure to add the labels, gssoc:approved and level.

Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three issues before merge:

1. Migration timestamp conflict
20260519000000_add_widget_preferences.sql — timestamp 20260519000000 is already used by the merged 20260519000000_add_leaderboard_opt_in.sql. Rename to the next available timestamp, e.g. 20260520000001_add_widget_preferences.sql.

2. Duplicate import in settings/route.ts

import { supabaseAdmin, updateUserPublicFlag, ensureUserExists } from "@/lib/supabase";

import { supabaseAdmin } from "@/lib/supabase"; // ← duplicate — TypeScript error

Delete the second import line.

3. ensureUserExists has a race condition
The find-then-insert pattern:

const existing = await select().eq('github_id', id).single();
if (!existing) await insert([...]);

Two concurrent sign-ins for the same user can both pass the !existing check and then both try to insert → unique constraint violation. Use upsert instead:

const { data } = await supabaseAdmin
  .from('users')
  .upsert({ github_id: githubId, github_login: githubLogin, ... }, { onConflict: 'github_id' })
  .select('id,...').single();

The widget preferences schema, settings UI, and DashboardWidgetSettings.tsx component all look solid. Fix these three and it's ready.

@abdullahxyz85
Copy link
Copy Markdown
Contributor Author

@Priyanshu-byte-coder Done! Please make sure to add the label: gssoc:approved and level:adavanced.

@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

Closing — settings/route.ts has unresolved merge conflict artifacts that will not compile: duplicate imports, fetchError referenced but undeclared, duplicate let body declarations, and two chained .select().single() calls in the same query. Additionally dashboard/page.tsx adds "use client" while keeping server-only imports (cookies, getServerSession, redirect) — Next.js will throw a build error. Please rebase cleanly, resolve all conflicts, and resubmit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Add custom widget visibility settings — show/hide dashboard cards

2 participants