Files
MOPC-Portal/src/components/dashboard/project-list-compact.tsx

115 lines
4.1 KiB
TypeScript
Raw Normal View History

'use client'
import Link from 'next/link'
import { motion } from 'motion/react'
import { ClipboardList, ArrowRight } from 'lucide-react'
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card'
import { StatusBadge } from '@/components/shared/status-badge'
import { ProjectLogo } from '@/components/shared/project-logo'
import { getCountryName } from '@/lib/countries'
import { formatDateOnly, truncate } from '@/lib/utils'
type ProjectListCompactProps = {
projects: Array<{
id: string
title: string
teamName: string | null
country: string | null
competitionCategory: string | null
oceanIssue: string | null
logoKey: string | null
createdAt: Date
submittedAt: Date | null
status: string
}>
}
export function ProjectListCompact({ projects }: ProjectListCompactProps) {
return (
<Card>
<CardHeader className="pb-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2.5">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-brand-blue/10">
<ClipboardList className="h-4 w-4 text-brand-blue" />
</div>
<div>
<CardTitle className="text-base">Recent Projects</CardTitle>
<CardDescription className="text-xs">Latest submissions</CardDescription>
</div>
</div>
<Link
href="/admin/projects"
className="flex items-center gap-1 text-xs font-semibold uppercase tracking-wider text-brand-teal hover:text-brand-teal-light transition-colors"
>
All projects <ArrowRight className="h-3 w-3" />
</Link>
</div>
</CardHeader>
<CardContent>
{projects.length === 0 ? (
<div className="flex flex-col items-center justify-center py-10 text-center">
<div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-muted">
<ClipboardList className="h-7 w-7 text-muted-foreground/40" />
</div>
<p className="mt-3 text-sm font-medium text-muted-foreground">
No projects submitted yet
</p>
</div>
) : (
<div className="divide-y">
{projects.map((project, idx) => (
<motion.div
key={project.id}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.25, delay: 0.15 + idx * 0.04 }}
>
<Link
href={`/admin/projects/${project.id}`}
className="block"
>
<div className="flex items-center gap-3 py-3 px-1 transition-colors hover:bg-muted/40 rounded-lg group">
<ProjectLogo
project={project}
size="sm"
fallback="initials"
/>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between gap-2">
<p className="text-sm font-medium truncate group-hover:text-brand-blue transition-colors">
{truncate(project.title, 50)}
</p>
<StatusBadge
status={project.status ?? 'SUBMITTED'}
size="sm"
className="shrink-0"
/>
</div>
<p className="text-xs text-muted-foreground mt-0.5">
{[
project.teamName,
project.country ? getCountryName(project.country) : null,
formatDateOnly(project.submittedAt || project.createdAt),
]
.filter(Boolean)
.join(' \u00b7 ')}
</p>
</div>
</div>
</Link>
</motion.div>
))}
</div>
)}
</CardContent>
</Card>
)
}