'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}
)}
);
})}
)}
);
}
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',
};
}
}