fix(rectification): reset fresh cases to reported time
This commit is contained in:
@@ -6,11 +6,10 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
|
||||
import { birthTimeConsultationOptionsCopy } from "@/lib/birth-time-consultation-consent";
|
||||
import {
|
||||
birthTimeDisplayState,
|
||||
birthTimePeriodOptions,
|
||||
birthTimeSourceDefaults,
|
||||
birthTimeSourceOptions,
|
||||
type BirthTimeDraft,
|
||||
type BirthTimeDraftPatch,
|
||||
type BirthTimeSource,
|
||||
} from "@/lib/birth-time-intake-model";
|
||||
|
||||
type BirthTimeIntakeProps = {
|
||||
@@ -66,47 +65,11 @@ function BirthClockSelect({ value, onChange }: BirthClockSelectProps) {
|
||||
);
|
||||
}
|
||||
|
||||
const sourceDefaults = {
|
||||
hospital_record: {
|
||||
birthTimePeriod: "",
|
||||
birthTimeClue: "",
|
||||
uncertaintyBeforeMinutes: 2,
|
||||
uncertaintyAfterMinutes: 2,
|
||||
},
|
||||
family_exact: {
|
||||
birthTimePeriod: "",
|
||||
birthTimeClue: "",
|
||||
uncertaintyBeforeMinutes: 10,
|
||||
uncertaintyAfterMinutes: 10,
|
||||
},
|
||||
approximate: {
|
||||
birthTimePeriod: "",
|
||||
birthTimeClue: "",
|
||||
uncertaintyBeforeMinutes: 30,
|
||||
uncertaintyAfterMinutes: 30,
|
||||
},
|
||||
period_only: {
|
||||
reportedTime: "",
|
||||
birthTimeClue: "",
|
||||
uncertaintyBeforeMinutes: null,
|
||||
uncertaintyAfterMinutes: null,
|
||||
},
|
||||
unknown: {
|
||||
reportedTime: "",
|
||||
birthTimePeriod: "",
|
||||
uncertaintyBeforeMinutes: null,
|
||||
uncertaintyAfterMinutes: null,
|
||||
},
|
||||
} as const satisfies Record<Exclude<BirthTimeSource, "" | "legacy_import">, BirthTimeDraftPatch>;
|
||||
|
||||
export function BirthTimeIntakeFields({ value, onPatch }: BirthTimeIntakeProps) {
|
||||
const groupId = useId();
|
||||
const source = value.birthTimeSource;
|
||||
const isConfirmed = value.birthTimeStatus === "confirmed";
|
||||
const displayState = birthTimeDisplayState(value);
|
||||
const knowledgeMode = source === "period_only" || source === "unknown"
|
||||
? "uncertain"
|
||||
: source ? "exact" : "";
|
||||
const usesClockTime = source === "hospital_record"
|
||||
|| source === "family_exact"
|
||||
|| source === "approximate"
|
||||
@@ -151,20 +114,16 @@ export function BirthTimeIntakeFields({ value, onPatch }: BirthTimeIntakeProps)
|
||||
)}
|
||||
|
||||
{!isConfirmed && <fieldset className="birth-time-source-fieldset">
|
||||
<legend>你对出生时间了解多少?</legend>
|
||||
<p className="birth-time-source-intro">不用猜具体分钟,先选一个最符合你的情况的选项。</p>
|
||||
<legend>填写出生时间</legend>
|
||||
<p className="birth-time-source-intro">请填写你初始化提供的具体出生时间。</p>
|
||||
<div className="birth-time-source-list">
|
||||
{birthTimeSourceOptions.map((option) => (
|
||||
<label
|
||||
className={`birth-time-source-option ${option.value === "family_exact"
|
||||
? knowledgeMode === "exact" ? "is-selected" : ""
|
||||
: knowledgeMode === "uncertain" ? "is-selected" : ""}`}
|
||||
className={`birth-time-source-option ${source === option.value ? "is-selected" : ""}`}
|
||||
key={option.value}
|
||||
>
|
||||
<input
|
||||
checked={option.value === "family_exact"
|
||||
? knowledgeMode === "exact"
|
||||
: knowledgeMode === "uncertain"}
|
||||
checked={source === option.value}
|
||||
name={`birth-time-source-${groupId}`}
|
||||
type="radio"
|
||||
value={option.value}
|
||||
@@ -172,7 +131,7 @@ export function BirthTimeIntakeFields({ value, onPatch }: BirthTimeIntakeProps)
|
||||
birthTimeSource: option.value,
|
||||
birthTimeStatus: "reported",
|
||||
time: "",
|
||||
...sourceDefaults[option.value],
|
||||
...birthTimeSourceDefaults[option.value],
|
||||
})}
|
||||
/>
|
||||
<span>
|
||||
@@ -197,91 +156,6 @@ export function BirthTimeIntakeFields({ value, onPatch }: BirthTimeIntakeProps)
|
||||
{source === "hospital_record" && (
|
||||
<p className="birth-time-detail-note">系统会无感检查前后 2 分钟的上升与 D9 / D10 稳定性。</p>
|
||||
)}
|
||||
{source === "approximate" && (
|
||||
<label>
|
||||
<span>可能误差</span>
|
||||
<Select
|
||||
value={value.uncertaintyBeforeMinutes?.toString() ?? ""}
|
||||
onValueChange={(nextValue) => {
|
||||
if (nextValue === null) return;
|
||||
const minutes = Number(nextValue);
|
||||
onPatch({ uncertaintyBeforeMinutes: minutes, uncertaintyAfterMinutes: minutes });
|
||||
}}
|
||||
>
|
||||
<SelectTrigger aria-label="可能误差">
|
||||
<SelectValue placeholder="选择误差范围">
|
||||
{(selectedValue) => selectedValue ? `前后 ${selectedValue} 分钟` : "选择误差范围"}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{[15, 30, 60].map((minutes) => (
|
||||
<SelectItem key={minutes} value={minutes.toString()}>前后 {minutes} 分钟</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{source === "period_only" && (
|
||||
<div className="birth-time-detail-grid birth-time-period-details onboarding-card-reveal">
|
||||
<label>
|
||||
<span>请选择最接近的时间范围</span>
|
||||
<Select
|
||||
required
|
||||
value={value.birthTimePeriod || null}
|
||||
onValueChange={(nextValue) => {
|
||||
if (typeof nextValue === "string") onPatch({ birthTimePeriod: nextValue });
|
||||
}}
|
||||
>
|
||||
<SelectTrigger aria-label="最接近的时间范围">
|
||||
<SelectValue placeholder="请选择大致时段">
|
||||
{(selectedValue) => birthTimePeriodOptions.find((option) => option.value === selectedValue)?.label ?? "请选择大致时段"}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{birthTimePeriodOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</label>
|
||||
<label>
|
||||
<span>补充描述(可选)</span>
|
||||
<textarea
|
||||
maxLength={240}
|
||||
placeholder="例如:天刚亮、午饭前后、家人记得大约 6—8 点"
|
||||
rows={2}
|
||||
value={value.birthTimeClue}
|
||||
onChange={(event) => onPatch({ birthTimeClue: event.target.value })}
|
||||
/>
|
||||
</label>
|
||||
<button
|
||||
className="button-secondary birth-time-skip-button"
|
||||
type="button"
|
||||
onClick={() => onPatch({
|
||||
birthTimeSource: "unknown",
|
||||
reportedTime: "",
|
||||
birthTimePeriod: "",
|
||||
birthTimeClue: "",
|
||||
uncertaintyBeforeMinutes: null,
|
||||
uncertaintyAfterMinutes: null,
|
||||
birthTimeStatus: "reported",
|
||||
time: "",
|
||||
})}
|
||||
>完全不清楚,跳过出生时间</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{source === "unknown" && (
|
||||
<div className="birth-time-detail-note onboarding-card-reveal" role="status">
|
||||
<p>已跳过具体出生时间。保存后可以直接使用首页功能,生时校正以后需要时再做。</p>
|
||||
<button
|
||||
className="button-secondary"
|
||||
type="button"
|
||||
onClick={() => onPatch({ birthTimeSource: "period_only", birthTimeStatus: "reported" })}
|
||||
>我可以描述一个时间范围</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -36,6 +36,11 @@ type PersistedTurn = Readonly<{
|
||||
receipt?: Readonly<{
|
||||
status: string;
|
||||
phases: readonly string[];
|
||||
tool_activities?: readonly Readonly<{
|
||||
tool: string;
|
||||
status: string;
|
||||
methods?: readonly string[];
|
||||
}>[];
|
||||
tools: readonly string[];
|
||||
methods?: readonly string[];
|
||||
skill_name?: string;
|
||||
@@ -94,6 +99,21 @@ const ACTIVE_TOOL_LABELS: Readonly<Record<PublicRectificationTool, string>> = {
|
||||
|
||||
function completedReceiptFromPersisted(receipt: PersistedTurn["receipt"]): CompletedActivityReceiptView {
|
||||
if (!receipt) return { steps: [], methods: [] };
|
||||
if (Array.isArray(receipt.tool_activities)) {
|
||||
let state = createRectificationActivityReceiptState();
|
||||
for (const activity of receipt.tool_activities) {
|
||||
if (!isPublicRectificationTool(activity.tool)
|
||||
|| (activity.status !== "completed" && activity.status !== "failed")) continue;
|
||||
state = reduceRectificationActivityReceipt(state, {
|
||||
tool: activity.tool,
|
||||
status: activity.status,
|
||||
methods: activity.status === "completed" && Array.isArray(activity.methods)
|
||||
? activity.methods.filter(isPublicRectificationMethod)
|
||||
: [],
|
||||
});
|
||||
}
|
||||
return receiptFromRectificationActivityState(state);
|
||||
}
|
||||
return {
|
||||
steps: [...new Set((receipt.tools ?? []).filter(isPublicRectificationTool))],
|
||||
methods: [...new Set((receipt.methods ?? []).filter(isPublicRectificationMethod))],
|
||||
|
||||
Reference in New Issue
Block a user