"use client"; import { useEffect, useState } from "react"; import { attemptRomanceMilestone, confessRomance, fetchRomanceState, type ConfessionOutcome, type MilestoneResult, type MilestoneType, type RomanceStage, type RomanceState, } from "../lib/api"; const ROMANCE_STAGE_LABELS: Record = { NONE: "朋友(戀愛軸未啟動)", INTERESTED: "在意", AMBIGUOUS: "曖昧", PARTNER: "戀人", DEEP_PARTNER: "深度伴侶", CRISIS: "關係危機", }; const CONFESSION_OUTCOME_LABELS: Record = { INELIGIBLE: "目前角色不具戀愛軸資格,無法告白。", REJECTED_TOO_SOON: "現在提還太尷尬了,她需要一點時間緩一緩。", REJECTED: "她婉拒了……心動值受到影響。", ACCEPTED: "她答應了!你們正式成為戀人。", }; const MILESTONE_LABELS: Record = { DISTANCE_SHORTENED: "拉近距離", OCCASIONAL_CONTACT: "偶爾的肢體接觸", LATE_NIGHT_TALK: "深夜談心", HAND_HOLDING: "牽手", HUG: "擁抱", FOREHEAD_KISS: "額頭吻", CASUAL_INTIMACY: "日常親密互動", }; interface RomanceSectionProps { characterId: string; userId: string; refreshKey: number; // 每完成一輪對話就遞增,讓戀愛狀態隨事件即時更新 } // L-9:對話介面顯示心動值與戀愛階段,並提供告白/里程碑操作。 // 「不得把失敗畫成成功」:confess/milestone 的結果一律照 outcome/allowed 如實呈現,不做樂觀 UI。 export function RomanceSection({ characterId, userId, refreshKey }: RomanceSectionProps) { const [state, setState] = useState(null); const [confessionMessage, setConfessionMessage] = useState<{ outcome: ConfessionOutcome } | null>(null); const [milestoneType, setMilestoneType] = useState("DISTANCE_SHORTENED"); const [milestoneResult, setMilestoneResult] = useState(null); const [pending, setPending] = useState(false); async function refresh() { try { setState(await fetchRomanceState(characterId, userId)); } catch { // 戀愛狀態查詢失敗不影響對話本身,維持上一次已知狀態。 } } useEffect(() => { void refresh(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [characterId, userId, refreshKey]); async function handleConfess() { setPending(true); setConfessionMessage(null); try { const result = await confessRomance(characterId, userId); setConfessionMessage({ outcome: result.outcome }); await refresh(); } catch { setConfessionMessage(null); } finally { setPending(false); } } async function handleMilestone() { setPending(true); setMilestoneResult(null); try { const result = await attemptRomanceMilestone(characterId, userId, milestoneType); setMilestoneResult(result); await refresh(); } catch { setMilestoneResult(null); } finally { setPending(false); } } if (!state) { return null; } return (
心動值 {state.romanceMeter} {ROMANCE_STAGE_LABELS[state.romanceStage]}
{confessionMessage && (

{CONFESSION_OUTCOME_LABELS[confessionMessage.outcome]}

)} {milestoneResult && (

{milestoneResult.allowed ? `${milestoneResult.isFirstTime ? "(第一次)" : ""}她接受了這個舉動。` : milestoneResult.reactionLine ?? "現在還不是時候。"}

)}
); }