'use client'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui'; import { Badge } from '@/components/ui'; import { Input } from '@/components/ui'; import { Button } from '@/components/ui'; import type { OKR, KeyResult } from '@/lib/types'; import { OKR_STATUS_LABELS } from '@/lib/types'; type OKRWithTeam = OKR & { team?: { id: string; name: string; } | null; }; interface CurrentQuarterOKRsProps { okrs: OKRWithTeam[]; period: string; canEdit?: boolean; } export function CurrentQuarterOKRs({ okrs, period, canEdit = false }: CurrentQuarterOKRsProps) { const [isExpanded, setIsExpanded] = useState(true); const router = useRouter(); if (okrs.length === 0) { return null; } return ( {isExpanded && (
{okrs.map((okr) => { const statusColors = getOKRStatusColor(okr.status); return (
router.refresh()} /> {OKR_STATUS_LABELS[okr.status]} {okr.progress !== undefined && ( {okr.progress}% )}
{okr.description && (

{okr.description}

)} {okr.keyResults && okr.keyResults.length > 0 && (
    {okr.keyResults.slice(0, 5).map((kr) => ( router.refresh()} /> ))} {okr.keyResults.length > 5 && (
  • +{okr.keyResults.length - 5} autre {okr.keyResults.length - 5 > 1 ? 's' : ''}
  • )}
)} {okr.team && (
Équipe: {okr.team.name}
)}
); })}
Voir tous les objectifs
)}
); } function EditableObjective({ okr, canEdit, onUpdate, }: { okr: OKRWithTeam; canEdit: boolean; onUpdate: () => void; }) { const [isEditing, setIsEditing] = useState(false); const [objective, setObjective] = useState(okr.objective); const [updating, setUpdating] = useState(false); const handleSave = async () => { setUpdating(true); try { const res = await fetch(`/api/okrs/${okr.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ objective: objective.trim() }), }); if (!res.ok) { const err = await res.json(); alert(err.error || 'Erreur lors de la mise à jour'); return; } setIsEditing(false); onUpdate(); } catch (e) { console.error(e); alert('Erreur lors de la mise à jour'); } finally { setUpdating(false); } }; if (canEdit && isEditing) { return (
setObjective(e.target.value)} className="flex-1 h-8 text-sm" autoFocus />
); } return (

setIsEditing(true) : undefined} role={canEdit ? 'button' : undefined} > {okr.objective}

); } function EditableKeyResultRow({ kr, okrId, canEdit, onUpdate, }: { kr: KeyResult; okrId: string; canEdit: boolean; onUpdate: () => void; }) { const [isEditing, setIsEditing] = useState(false); const [currentValue, setCurrentValue] = useState(kr.currentValue); const [updating, setUpdating] = useState(false); const krProgress = kr.targetValue > 0 ? Math.round((kr.currentValue / kr.targetValue) * 100) : 0; const handleSave = async () => { setUpdating(true); try { const res = await fetch(`/api/okrs/${okrId}/key-results/${kr.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ currentValue: Number(currentValue) }), }); if (!res.ok) { const err = await res.json(); alert(err.error || 'Erreur lors de la mise à jour'); return; } setIsEditing(false); onUpdate(); } catch (e) { console.error(e); alert('Erreur lors de la mise à jour'); } finally { setUpdating(false); } }; if (canEdit && isEditing) { return (
  • {kr.title}
    setCurrentValue(Number(e.target.value))} min={0} max={kr.targetValue * 2} step="0.1" className="h-6 w-16 text-xs" /> / {kr.targetValue} {kr.unit}
  • ); } return (
  • {kr.title} {kr.currentValue}/{kr.targetValue} {kr.unit} ({krProgress}%) {canEdit && ( )}
  • ); } function getOKRStatusColor(status: OKR['status']): { bg: string; color: string } { switch (status) { case 'NOT_STARTED': return { bg: 'color-mix(in srgb, #6b7280 15%, transparent)', color: '#6b7280', }; case 'IN_PROGRESS': return { bg: 'color-mix(in srgb, #3b82f6 15%, transparent)', color: '#3b82f6', }; case 'COMPLETED': return { bg: 'color-mix(in srgb, #10b981 15%, transparent)', color: '#10b981', }; case 'CANCELLED': return { bg: 'color-mix(in srgb, #ef4444 15%, transparent)', color: '#ef4444', }; default: return { bg: 'color-mix(in srgb, #6b7280 15%, transparent)', color: '#6b7280', }; } }