'use client'; import { useTransition } from 'react'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import { Badge, Card, CardContent, CardHeader, CardTitle, IconButton, IconTrash } from '@/components/ui'; import { getGravatarUrl } from '@/lib/gravatar'; import type { OKR, KeyResult, OKRStatus, KeyResultStatus } from '@/lib/types'; import { OKR_STATUS_LABELS, KEY_RESULT_STATUS_LABELS } from '@/lib/types'; // Helper functions for status colors function getOKRStatusColor(status: OKRStatus): { bg: string; color: string } { switch (status) { case 'NOT_STARTED': return { bg: 'color-mix(in srgb, #6b7280 15%, transparent)', // gray-500 color: '#6b7280', }; case 'IN_PROGRESS': return { bg: 'color-mix(in srgb, #3b82f6 15%, transparent)', // blue-500 color: '#3b82f6', }; case 'COMPLETED': return { bg: 'color-mix(in srgb, #10b981 15%, transparent)', // green-500 (success) color: '#10b981', }; case 'CANCELLED': return { bg: 'color-mix(in srgb, #ef4444 15%, transparent)', // red-500 (destructive) color: '#ef4444', }; default: return { bg: 'color-mix(in srgb, #6b7280 15%, transparent)', color: '#6b7280', }; } } function getKeyResultStatusColor(status: KeyResultStatus): { bg: string; color: string } { switch (status) { case 'NOT_STARTED': return { bg: 'color-mix(in srgb, #6b7280 12%, transparent)', // gray-500 color: '#6b7280', }; case 'IN_PROGRESS': return { bg: 'color-mix(in srgb, #3b82f6 12%, transparent)', // blue-500 color: '#3b82f6', }; case 'COMPLETED': return { bg: 'color-mix(in srgb, #10b981 12%, transparent)', // green-500 color: '#10b981', }; case 'AT_RISK': return { bg: 'color-mix(in srgb, #f59e0b 12%, transparent)', // amber-500 (orange/yellow) color: '#f59e0b', }; default: return { bg: 'color-mix(in srgb, #6b7280 12%, transparent)', color: '#6b7280', }; } } interface OKRCardProps { okr: OKR & { teamMember?: { user: { id: string; email: string; name: string | null } } }; teamId: string; isAdmin?: boolean; compact?: boolean; } export function OKRCard({ okr, teamId, isAdmin = false, compact = false }: OKRCardProps) { const router = useRouter(); const [isPending, startTransition] = useTransition(); const progress = okr.progress || 0; const progressColor = progress >= 75 ? 'var(--success)' : progress >= 25 ? 'var(--accent)' : 'var(--destructive)'; const handleDelete = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); if (!confirm(`Êtes-vous sûr de vouloir supprimer l'OKR "${okr.objective}" ?`)) { return; } startTransition(async () => { try { const response = await fetch(`/api/okrs/${okr.id}`, { method: 'DELETE', }); if (!response.ok) { const error = await response.json(); alert(error.error || "Erreur lors de la suppression de l'OKR"); return; } router.refresh(); } catch (error) { console.error('Error deleting OKR:', error); alert("Erreur lors de la suppression de l'OKR"); } }); }; if (compact) { return (
🎯
{okr.objective} {okr.teamMember && (
{/* eslint-disable-next-line @next/next/no-img-element */} {okr.teamMember.user.name {okr.teamMember.user.name || okr.teamMember.user.email}
)}
{isAdmin && ( } label="Supprimer l'OKR" variant="destructive" size="xs" onClick={handleDelete} className="flex-shrink-0" style={{ color: 'var(--destructive)', border: '1px solid color-mix(in srgb, var(--destructive) 40%, transparent)', backgroundColor: 'color-mix(in srgb, var(--destructive) 5%, transparent)', }} disabled={isPending} /> )} {okr.period}
{/* Progress Bar */}
Progression {progress}%
{/* Status */}
{OKR_STATUS_LABELS[okr.status]} {okr.keyResults && okr.keyResults.length > 0 && ( {okr.keyResults.length} KR{okr.keyResults.length !== 1 ? 's' : ''} )}
); } return (
🎯 {okr.objective} {okr.teamMember && (
{/* eslint-disable-next-line @next/next/no-img-element */} {okr.teamMember.user.name {okr.teamMember.user.name || okr.teamMember.user.email}
)}
{/* Action Zone */}
{isAdmin && ( } label="Supprimer l'OKR" variant="destructive" size="sm" onClick={handleDelete} className="flex-shrink-0" style={{ color: 'var(--destructive)', border: '1px solid color-mix(in srgb, var(--destructive) 40%, transparent)', backgroundColor: 'color-mix(in srgb, var(--destructive) 5%, transparent)', }} disabled={isPending} /> )} {okr.period}
{/* Progress Bar */}
Progression {progress}%
{/* Status */}
Statut: {OKR_STATUS_LABELS[okr.status]}
{/* Key Results List */} {okr.keyResults && okr.keyResults.length > 0 && (
Key Results ({okr.keyResults.length})
{okr.keyResults .sort((a, b) => a.order - b.order) .map((kr: KeyResult) => { const krProgress = kr.targetValue > 0 ? (kr.currentValue / kr.targetValue) * 100 : 0; const krProgressColor = krProgress >= 100 ? 'var(--success)' : krProgress >= 50 ? 'var(--accent)' : 'var(--destructive)'; return (
{kr.title} {KEY_RESULT_STATUS_LABELS[kr.status]}
{kr.currentValue} / {kr.targetValue} {kr.unit} {Math.round(krProgress)}%
); })}
)}
); }