Files
MOPC-Portal/src/components/dashboard/smart-actions.tsx

120 lines
3.5 KiB
TypeScript
Raw Normal View History

'use client'
import Link from 'next/link'
import type { Route } from 'next'
import {
Zap,
AlertTriangle,
AlertCircle,
Info,
ChevronRight,
CheckCircle2,
} from 'lucide-react'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { cn } from '@/lib/utils'
export type DashboardAction = {
id: string
severity: 'critical' | 'warning' | 'info'
title: string
description: string
href: string
roundId?: string
roundType?: string
count?: number
}
type SmartActionsProps = {
actions: DashboardAction[]
}
const severityOrder: Record<DashboardAction['severity'], number> = {
critical: 0,
warning: 1,
info: 2,
}
const severityConfig = {
critical: {
icon: AlertTriangle,
iconClass: 'text-red-600',
bgClass: 'bg-red-50 dark:bg-red-950/30',
borderClass: 'border-l-red-500',
},
warning: {
icon: AlertCircle,
iconClass: 'text-amber-600',
bgClass: 'bg-amber-50 dark:bg-amber-950/30',
borderClass: 'border-l-amber-500',
},
info: {
icon: Info,
iconClass: 'text-blue-600',
bgClass: 'bg-blue-50 dark:bg-blue-950/30',
borderClass: 'border-l-blue-500',
},
}
export function SmartActions({ actions }: SmartActionsProps) {
const sorted = [...actions].sort(
(a, b) => severityOrder[a.severity] - severityOrder[b.severity]
)
return (
<Card>
<CardHeader className="flex flex-row items-center gap-3 space-y-0 pb-4">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-amber-100 dark:bg-amber-900/40">
<Zap className="h-5 w-5 text-amber-600 dark:text-amber-400" />
</div>
<CardTitle className="flex-1">Action Required</CardTitle>
{actions.length > 0 && (
<Badge variant="warning">{actions.length}</Badge>
)}
</CardHeader>
<CardContent>
{sorted.length === 0 ? (
<div className="flex flex-col items-center justify-center py-8 text-center">
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900/40">
<CheckCircle2 className="h-6 w-6 text-emerald-600 dark:text-emerald-400" />
</div>
<p className="mt-3 text-sm font-medium text-muted-foreground">
All caught up!
</p>
</div>
) : (
<div className="space-y-2">
{sorted.map((action) => {
const config = severityConfig[action.severity]
const Icon = config.icon
return (
<Link
key={action.id}
href={action.href as Route}
className={cn(
'flex items-center gap-3 rounded-lg border-l-2 px-3 py-2.5 transition-colors hover:opacity-80',
config.bgClass,
config.borderClass
)}
>
<Icon className={cn('h-4 w-4 shrink-0', config.iconClass)} />
<div className="min-w-0 flex-1">
<p className="text-sm font-medium leading-tight">
{action.title}
</p>
<p className="text-xs text-muted-foreground">
{action.description}
</p>
</div>
<ChevronRight className="h-4 w-4 shrink-0 text-muted-foreground" />
</Link>
)
})}
</div>
)}
</CardContent>
</Card>
)
}