Enhance DimensionCard component to manage expanded state using local storage; pass evaluationId prop from EvaluationDetailPage for state persistence across sessions.
This commit is contained in:
@@ -301,6 +301,7 @@ export default function EvaluationDetailPage() {
|
|||||||
<DimensionCard
|
<DimensionCard
|
||||||
dimension={dim}
|
dimension={dim}
|
||||||
index={i}
|
index={i}
|
||||||
|
evaluationId={id}
|
||||||
score={scoreMap.get(dim.id) ?? null}
|
score={scoreMap.get(dim.id) ?? null}
|
||||||
onScoreChange={handleScoreChange}
|
onScoreChange={handleScoreChange}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,33 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
const STORAGE_KEY_PREFIX = "eval-dim-expanded";
|
||||||
|
|
||||||
|
function getStoredExpanded(evaluationId: string, dimensionId: string): boolean | null {
|
||||||
|
if (typeof window === "undefined") return null;
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(`${STORAGE_KEY_PREFIX}-${evaluationId}`);
|
||||||
|
if (!raw) return null;
|
||||||
|
const obj = JSON.parse(raw) as Record<string, boolean>;
|
||||||
|
return obj[dimensionId] ?? null;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStoredExpanded(evaluationId: string, dimensionId: string, expanded: boolean): void {
|
||||||
|
if (typeof window === "undefined") return;
|
||||||
|
try {
|
||||||
|
const key = `${STORAGE_KEY_PREFIX}-${evaluationId}`;
|
||||||
|
const raw = localStorage.getItem(key);
|
||||||
|
const obj = (raw ? JSON.parse(raw) : {}) as Record<string, boolean>;
|
||||||
|
obj[dimensionId] = expanded;
|
||||||
|
localStorage.setItem(key, JSON.stringify(obj));
|
||||||
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface Dimension {
|
interface Dimension {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -22,6 +49,7 @@ interface DimensionCardProps {
|
|||||||
dimension: Dimension;
|
dimension: Dimension;
|
||||||
score: DimensionScore | null;
|
score: DimensionScore | null;
|
||||||
index: number;
|
index: number;
|
||||||
|
evaluationId?: string;
|
||||||
onScoreChange: (dimensionId: string, data: Partial<DimensionScore>) => void;
|
onScoreChange: (dimensionId: string, data: Partial<DimensionScore>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,10 +76,25 @@ function parseQuestions(s: string | null | undefined): string[] {
|
|||||||
const inputClass =
|
const inputClass =
|
||||||
"w-full rounded border border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-700/80 px-2.5 py-1.5 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 dark:placeholder-zinc-500 focus:border-cyan-500 focus:ring-1 focus:ring-cyan-500/30";
|
"w-full rounded border border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-700/80 px-2.5 py-1.5 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 dark:placeholder-zinc-500 focus:border-cyan-500 focus:ring-1 focus:ring-cyan-500/30";
|
||||||
|
|
||||||
export function DimensionCard({ dimension, score, index, onScoreChange }: DimensionCardProps) {
|
export function DimensionCard({ dimension, score, index, evaluationId, onScoreChange }: DimensionCardProps) {
|
||||||
const [notes, setNotes] = useState(score?.candidateNotes ?? "");
|
const [notes, setNotes] = useState(score?.candidateNotes ?? "");
|
||||||
const hasQuestions = parseQuestions(dimension.suggestedQuestions).length > 0;
|
const hasQuestions = parseQuestions(dimension.suggestedQuestions).length > 0;
|
||||||
const [expanded, setExpanded] = useState(hasQuestions);
|
const [expanded, setExpanded] = useState(hasQuestions);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (evaluationId && typeof window !== "undefined") {
|
||||||
|
const stored = getStoredExpanded(evaluationId, dimension.id);
|
||||||
|
if (stored !== null) setExpanded(stored);
|
||||||
|
}
|
||||||
|
}, [evaluationId, dimension.id]);
|
||||||
|
|
||||||
|
const toggleExpanded = () => {
|
||||||
|
setExpanded((e) => {
|
||||||
|
const next = !e;
|
||||||
|
if (evaluationId) setStoredExpanded(evaluationId, dimension.id, next);
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
};
|
||||||
const currentScore = score?.score ?? null;
|
const currentScore = score?.score ?? null;
|
||||||
const rubricLabels = parseRubric(dimension.rubric);
|
const rubricLabels = parseRubric(dimension.rubric);
|
||||||
const questions = parseQuestions(dimension.suggestedQuestions);
|
const questions = parseQuestions(dimension.suggestedQuestions);
|
||||||
@@ -60,7 +103,7 @@ export function DimensionCard({ dimension, score, index, onScoreChange }: Dimens
|
|||||||
<div className="rounded-lg border border-zinc-200 dark:border-zinc-600 bg-white dark:bg-zinc-800 shadow-sm dark:shadow-none overflow-hidden">
|
<div className="rounded-lg border border-zinc-200 dark:border-zinc-600 bg-white dark:bg-zinc-800 shadow-sm dark:shadow-none overflow-hidden">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setExpanded((e) => !e)}
|
onClick={toggleExpanded}
|
||||||
className="flex w-full items-center justify-between gap-4 px-4 py-3 text-left hover:bg-zinc-50 dark:hover:bg-zinc-700/50 transition-colors"
|
className="flex w-full items-center justify-between gap-4 px-4 py-3 text-left hover:bg-zinc-50 dark:hover:bg-zinc-700/50 transition-colors"
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-3 min-w-0">
|
<div className="flex items-center gap-3 min-w-0">
|
||||||
|
|||||||
Reference in New Issue
Block a user