This PR introduces a robust, drag-and-drop widget layout engine for the Vero Guardian dashboard. This enables users to seamlessly reorganize their dashboard widgets based on their specific monitoring priorities, significantly improving the customizability and UX of the core dashboard application.
Users have varying monitoring priorities depending on their roles and current tasks. Previously, the dashboard had a static, hardcoded grid layout. This rigid design prevented users from optimizing their workflow (e.g., prioritizing "Admin Management" over "PR Feed" for admin-specific days).
- Replaced the static CSS grid layout in
src/app/page.tsxwith a dynamicWidgetGridcomponent. - Implemented
@dnd-kit(specifically@dnd-kit/core,@dnd-kit/sortable, and@dnd-kit/utilities) over older alternatives likereact-beautiful-dnddue to its superior accessibility, performance, and modern hook-based API. - Developed
SortableWidget.tsx, which serves as a draggable container wrapping individual widgets. It features a clean grip-handle that appears on hover, ensuring that interactive content inside the widgets (buttons, links) remains fully clickable.
src/components/DashboardLayout/SortableWidget.tsx: New component handling drag behaviors and styles.src/components/DashboardLayout/WidgetGrid.tsx: New component managing theDndContext, sensors (pointer & keyboard), and sorting context using arectSortingStrategyfor grid support.src/app/page.tsx: Replaced static dashboard sections with the dynamicWidgetGrid.
- Local State & Persistence: Integrated
localStorage(vero-dashboard-layout) to persist the widget ordering across sessions. - Hydration Safety: Engineered the
WidgetGridto prevent React hydration mismatch errors by deferringlocalStorageresolution until post-mount, ensuring seamless SSR/SSG compatibility.
- Layout Persistence: Layout perfectly persists across page reloads and browser sessions.
- Layout State Safety: The component ensures state safety by gracefully handling missing or new widgets. Only valid widget IDs are allowed in the state array, and conditionally rendered widgets (like
Admin Managementusing role-based access control) are supported without breaking layout indexes.
Verified via extensive UX testing:
- Pointer sensor successfully configured with an activation constraint (8px threshold) to allow interacting with the widget content without triggering unintended drags.
- Keyboard accessible drag-and-drop integrated.
- Successfully built and passed Next.js linting checks.
closes #43