feat(frontend): implement main dashboard page (#48)

Implement the main dashboard / projects list page for Syndarix as the landing
page after login. The implementation includes:

Dashboard Components:
- QuickStats: Overview cards showing active projects, agents, issues, approvals
- ProjectsSection: Grid/list view with filtering and sorting controls
- ProjectCardGrid: Rich project cards for grid view
- ProjectRowList: Compact rows for list view
- ActivityFeed: Real-time activity sidebar with connection status
- PerformanceCard: Performance metrics display
- EmptyState: Call-to-action for new users
- ProjectStatusBadge: Status indicator with icons
- ComplexityIndicator: Visual complexity dots
- ProgressBar: Accessible progress bar component

Features:
- Projects grid/list view with view mode toggle
- Filter by status (all, active, paused, completed, archived)
- Sort by recent, name, progress, or issues
- Quick stats overview with counts
- Real-time activity feed sidebar with live/reconnecting status
- Performance metrics card
- Create project button linking to wizard
- Responsive layout for mobile/desktop
- Loading skeleton states
- Empty state for new users

API Integration:
- useProjects hook for fetching projects (mock data until backend ready)
- useDashboardStats hook for statistics
- TanStack Query for caching and data fetching

Testing:
- 37 unit tests covering all dashboard components
- E2E test suite for dashboard functionality
- Accessibility tests (keyboard nav, aria attributes, heading hierarchy)

Technical:
- TypeScript strict mode compliance
- ESLint passing
- WCAG AA accessibility compliance
- Mobile-first responsive design
- Dark mode support via semantic tokens
- Follows design system guidelines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-30 23:46:50 +01:00
parent e85788f79f
commit 5b1e2852ea
67 changed files with 8879 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
/**
* Issue Management Constants
*
* Configuration for status, priority, and workflow.
*
* @module features/issues/constants
*/
import type {
IssueStatus,
IssuePriority,
StatusConfig,
PriorityConfig,
StatusTransition,
} from './types';
/**
* Status configuration with labels and colors
*/
export const STATUS_CONFIG: Record<IssueStatus, StatusConfig> = {
open: { label: 'Open', color: 'text-blue-500' },
in_progress: { label: 'In Progress', color: 'text-yellow-500' },
in_review: { label: 'In Review', color: 'text-purple-500' },
blocked: { label: 'Blocked', color: 'text-red-500' },
done: { label: 'Done', color: 'text-green-500' },
closed: { label: 'Closed', color: 'text-muted-foreground' },
};
/**
* Priority configuration with labels and colors
*/
export const PRIORITY_CONFIG: Record<IssuePriority, PriorityConfig> = {
high: { label: 'High', color: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200' },
medium: {
label: 'Medium',
color: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
},
low: { label: 'Low', color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' },
};
/**
* Status workflow transitions
* Defines which status transitions are available from each status
*/
export const STATUS_TRANSITIONS: StatusTransition[] = [
{ from: 'open', to: 'in_progress', label: 'Start Work' },
{ from: 'in_progress', to: 'in_review', label: 'Submit for Review' },
{ from: 'in_progress', to: 'blocked', label: 'Mark Blocked' },
{ from: 'in_review', to: 'done', label: 'Mark Done' },
{ from: 'in_review', to: 'in_progress', label: 'Request Changes' },
{ from: 'blocked', to: 'in_progress', label: 'Unblock' },
{ from: 'done', to: 'closed', label: 'Close Issue' },
{ from: 'closed', to: 'open', label: 'Reopen' },
];
/**
* Get available transitions for a given status
*/
export function getAvailableTransitions(currentStatus: IssueStatus): StatusTransition[] {
return STATUS_TRANSITIONS.filter((t) => t.from === currentStatus);
}
/**
* Get primary transition for a given status (the main workflow action)
*/
export function getPrimaryTransition(currentStatus: IssueStatus): StatusTransition | undefined {
const transitions = getAvailableTransitions(currentStatus);
return transitions[0];
}
/**
* All possible statuses in workflow order
*/
export const STATUS_ORDER: IssueStatus[] = [
'open',
'in_progress',
'in_review',
'blocked',
'done',
'closed',
];
/**
* All possible priorities in order
*/
export const PRIORITY_ORDER: IssuePriority[] = ['high', 'medium', 'low'];
/**
* Sync status configuration
*/
export const SYNC_STATUS_CONFIG = {
synced: { label: 'Synced', color: 'text-green-500' },
pending: { label: 'Syncing', color: 'text-yellow-500' },
conflict: { label: 'Conflict', color: 'text-orange-500' },
error: { label: 'Sync Error', color: 'text-red-500' },
} as const;
/**
* Default page size for issue list
*/
export const DEFAULT_PAGE_SIZE = 25;
/**
* Maximum issues for bulk actions
*/
export const MAX_BULK_SELECTION = 100;