68f0759eef
Closing a discriminator used to leave GET without a card after refresh. Write the next dated question in the same request, skip childhood career and move probes, and do not continue a read-only turn when that question is already persisted. Co-authored-by: Cursor <cursoragent@cursor.com>
79 lines
2.5 KiB
TypeScript
79 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef, useState } from "react";
|
|
import type {
|
|
ChoiceKey,
|
|
RectificationChoiceCard as ChoiceCard,
|
|
} from "@/lib/rectification-agentic/v9/choice-card";
|
|
|
|
type RectificationChoiceCardProps = Readonly<{
|
|
card: ChoiceCard;
|
|
pending: boolean;
|
|
disabled: boolean;
|
|
selectedKey?: ChoiceKey | "stop" | "";
|
|
onSelect: (key: ChoiceKey) => void;
|
|
onStop: () => void;
|
|
}>;
|
|
|
|
export function RectificationChoiceCard(props: RectificationChoiceCardProps) {
|
|
const [localSelected, setLocalSelected] = useState<ChoiceKey | "stop" | "">("");
|
|
const selectedKey = props.selectedKey || localSelected;
|
|
const firstChoiceRef = useRef<HTMLButtonElement | null>(null);
|
|
const answered = Boolean(selectedKey);
|
|
|
|
useEffect(() => {
|
|
if (props.pending || answered) return;
|
|
firstChoiceRef.current?.focus();
|
|
}, [answered, props.card.question_id, props.pending]);
|
|
|
|
function select(key: ChoiceKey) {
|
|
if (props.pending || props.disabled || selectedKey) return;
|
|
setLocalSelected(key);
|
|
props.onSelect(key);
|
|
}
|
|
|
|
function stop() {
|
|
if (props.pending || props.disabled || selectedKey) return;
|
|
setLocalSelected("stop");
|
|
props.onStop();
|
|
}
|
|
|
|
return (
|
|
<section
|
|
className={`rectification-choice-card${props.pending ? " is-pending" : ""}${answered ? " is-answered" : ""}`}
|
|
aria-label={props.card.scoring ? "校正判断" : "盘外核对"}
|
|
>
|
|
<fieldset
|
|
className="birth-time-choice-question"
|
|
disabled={props.pending || props.disabled || answered}
|
|
data-answered={answered ? "true" : "false"}
|
|
>
|
|
<legend>{props.card.prompt}</legend>
|
|
{props.card.why ? <p className="rectification-choice-why">{props.card.why}</p> : null}
|
|
<div className="birth-time-primary-choices">
|
|
{props.card.options.map((option, index) => (
|
|
<button
|
|
key={option.key}
|
|
ref={index === 0 ? firstChoiceRef : undefined}
|
|
type="button"
|
|
className="birth-time-choice-option is-primary"
|
|
data-selected={selectedKey === option.key ? "true" : "false"}
|
|
onClick={() => select(option.key)}
|
|
>
|
|
<strong>{option.key}.</strong> {option.label}
|
|
</button>
|
|
))}
|
|
<button
|
|
type="button"
|
|
className="birth-time-choice-option is-primary"
|
|
data-selected={selectedKey === "stop" ? "true" : "false"}
|
|
onClick={stop}
|
|
>
|
|
{props.card.stop_label}
|
|
</button>
|
|
</div>
|
|
</fieldset>
|
|
</section>
|
|
);
|
|
}
|