Add candidateTeam field to evaluations; update related components and API endpoints for consistency
This commit is contained in:
@@ -32,6 +32,7 @@ interface Evaluation {
|
||||
id: string;
|
||||
candidateName: string;
|
||||
candidateRole: string;
|
||||
candidateTeam?: string | null;
|
||||
evaluatorName: string;
|
||||
evaluationDate: string;
|
||||
templateId: string;
|
||||
@@ -70,10 +71,10 @@ export default function EvaluationDetailPage() {
|
||||
const tmpl = templatesData.find((t: { id: string }) => t.id === evalData.templateId);
|
||||
if (tmpl?.dimensions?.length) {
|
||||
const dimMap = new Map(tmpl.dimensions.map((d: { id: string }) => [d.id, d]));
|
||||
evalData.template.dimensions = evalData.template.dimensions.map((d: { id: string }) => ({
|
||||
...d,
|
||||
suggestedQuestions: d.suggestedQuestions ?? dimMap.get(d.id)?.suggestedQuestions,
|
||||
}));
|
||||
evalData.template.dimensions = evalData.template.dimensions.map((d: { id: string; suggestedQuestions?: string | null }) => ({
|
||||
...d,
|
||||
suggestedQuestions: d.suggestedQuestions ?? dimMap.get(d.id)?.suggestedQuestions,
|
||||
}));
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
@@ -117,26 +118,32 @@ export default function EvaluationDetailPage() {
|
||||
const scores = e.dimensionScores.map((ds) =>
|
||||
ds.dimensionId === dimensionId ? { ...ds, ...data } : ds
|
||||
);
|
||||
return { ...e, dimensionScores: scores };
|
||||
const next = { ...e, dimensionScores: scores };
|
||||
if (data.score !== undefined) {
|
||||
setTimeout(() => handleSave(next, { skipRefresh: true }), 0);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!evaluation) return;
|
||||
const handleSave = async (evalOverride?: Evaluation | null, options?: { skipRefresh?: boolean }) => {
|
||||
const toSave = evalOverride ?? evaluation;
|
||||
if (!toSave) return;
|
||||
setSaving(true);
|
||||
try {
|
||||
const res = await fetch(`/api/evaluations/${id}`, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
candidateName: evaluation.candidateName,
|
||||
candidateRole: evaluation.candidateRole,
|
||||
evaluatorName: evaluation.evaluatorName,
|
||||
evaluationDate: evaluation.evaluationDate,
|
||||
status: evaluation.status,
|
||||
findings: evaluation.findings,
|
||||
recommendations: evaluation.recommendations,
|
||||
dimensionScores: (evaluation.dimensionScores ?? []).map((ds) => ({
|
||||
candidateName: toSave.candidateName,
|
||||
candidateRole: toSave.candidateRole,
|
||||
candidateTeam: toSave.candidateTeam ?? null,
|
||||
evaluatorName: toSave.evaluatorName,
|
||||
evaluationDate: typeof toSave.evaluationDate === "string" ? toSave.evaluationDate : new Date(toSave.evaluationDate).toISOString(),
|
||||
status: toSave.status,
|
||||
findings: toSave.findings,
|
||||
recommendations: toSave.recommendations,
|
||||
dimensionScores: (toSave.dimensionScores ?? []).map((ds) => ({
|
||||
dimensionId: ds.dimensionId,
|
||||
evaluationId: id,
|
||||
score: ds.score,
|
||||
@@ -148,11 +155,14 @@ export default function EvaluationDetailPage() {
|
||||
}),
|
||||
});
|
||||
if (res.ok) {
|
||||
fetchEval();
|
||||
if (!options?.skipRefresh) fetchEval();
|
||||
} else {
|
||||
const data = await res.json();
|
||||
alert(data.error ?? "Save failed");
|
||||
const data = await res.json().catch(() => ({}));
|
||||
alert(data.error ?? `Save failed (${res.status})`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Save error:", err);
|
||||
alert("Erreur lors de la sauvegarde");
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
@@ -203,11 +213,15 @@ export default function EvaluationDetailPage() {
|
||||
<div className="space-y-6">
|
||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||
<h1 className="font-mono text-base font-medium text-zinc-800 dark:text-zinc-100">
|
||||
{evaluation.candidateName} <span className="text-zinc-500">/</span> {evaluation.candidateRole}
|
||||
{evaluation.candidateName}
|
||||
{evaluation.candidateTeam && (
|
||||
<span className="text-zinc-500"> ({evaluation.candidateTeam})</span>
|
||||
)}
|
||||
<span className="text-zinc-500"> / </span> {evaluation.candidateRole}
|
||||
</h1>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={handleSave}
|
||||
onClick={() => handleSave()}
|
||||
disabled={saving}
|
||||
className="rounded border border-zinc-300 dark:border-zinc-600 bg-zinc-100 dark:bg-zinc-700 px-3 py-1.5 font-mono text-xs text-zinc-700 dark:text-zinc-300 hover:bg-zinc-200 dark:hover:bg-zinc-700 disabled:opacity-50"
|
||||
>
|
||||
@@ -233,6 +247,7 @@ export default function EvaluationDetailPage() {
|
||||
<CandidateForm
|
||||
candidateName={evaluation.candidateName}
|
||||
candidateRole={evaluation.candidateRole}
|
||||
candidateTeam={evaluation.candidateTeam ?? ""}
|
||||
evaluatorName={evaluation.evaluatorName}
|
||||
evaluationDate={evaluation.evaluationDate.split("T")[0]}
|
||||
templateId={evaluation.templateId}
|
||||
|
||||
Reference in New Issue
Block a user