fix(tarot): 해석 완료 시 자동 AI 탭 전환 + 새 리딩 시 해석 state 잔존 버그

Issue 1 — 우측 패널 탭이 hardcoded is-active로 클릭/state 없음:
- InterpretationPanel에 activeTab state 추가
- useEffect로 interpretation 도착 시 자동 'ai' 탭 전환, 없으면 'card'
- 두 탭 콘텐츠 분리: card=카드 의미·상징·조언, ai=위치 해석·종합·상호작용·근거

Issue 2 — useTarotReading hook의 interpretation이 새 리딩 시작에 잔존:
- hook에 reset() 함수 추가 (status/interpretation/readingId/error 초기화)
- Reading.jsx의 startShuffle/openCardSpread/restart/resetCards/changeSpread
  5개 액션에서 모두 reset() 호출 — 새 리딩 시작 시 이전 해석 완전 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-24 14:53:31 +09:00
parent 94569a4c45
commit a6721e6536
3 changed files with 99 additions and 65 deletions

View File

@@ -53,19 +53,21 @@ export default function Reading() {
const spread = SPREADS[spreadId];
const { slice, reshuffle } = useTarotShuffle(TAROT_DECK, 20);
const { status, interpretation, runInterpretAndSave, error } = useTarotReading();
const { status, interpretation, runInterpretAndSave, error, reset } = useTarotReading();
const startShuffle = () => {
reshuffle();
setPicks([]);
setFocusIdx(null);
setStep(1);
reset();
};
const openCardSpread = () => {
setPicks([]);
setFocusIdx(null);
setStep(2);
reset();
};
const handlePick = (card = null) => {
@@ -92,6 +94,7 @@ export default function Reading() {
const restart = () => {
setStep(1); setPicks([]); setFocusIdx(null);
reset();
};
const resetCards = () => {
@@ -99,6 +102,7 @@ export default function Reading() {
setPicks([]);
setFocusIdx(null);
setStep(1);
reset();
};
const changeSpread = (nextSpreadId) => {
@@ -107,6 +111,7 @@ export default function Reading() {
setFocusIdx(null);
setStep(1);
reshuffle();
reset();
};
const disabledIds = picks.map((p) => p.card.slug);

View File

@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
function ConfidenceBadge({ level }) {
if (!level) return null;
@@ -14,15 +14,36 @@ export default function InterpretationPanel({
selectedPosition,
selectedReversed = false,
}) {
const [activeTab, setActiveTab] = useState('card');
const [showEvidence, setShowEvidence] = useState(true);
useEffect(() => {
setActiveTab(interpretation ? 'ai' : 'card');
}, [interpretation]);
const hasAI = !!interpretation;
const renderTabs = () => (
<div className="tarot-panel__tabs">
<button
type="button"
className={activeTab === 'card' ? 'is-active' : ''}
onClick={() => setActiveTab('card')}
>카드 해석</button>
<button
type="button"
className={activeTab === 'ai' ? 'is-active' : ''}
onClick={() => setActiveTab('ai')}
disabled={!hasAI}
aria-disabled={!hasAI}
>AI 인사이트</button>
</div>
);
if (!interpretation && !selectedCard) {
return (
<aside className="tarot-panel tarot-panel--reading">
<div className="tarot-panel__tabs">
<button type="button" className="is-active">카드 해석</button>
<button type="button">AI 인사이트</button>
</div>
{renderTabs()}
<div className="tarot-panel__empty-state">
<span></span>
<p>카드를 뽑으면 이곳에 카드 의미와 AI 인사이트가 표시됩니다.</p>
@@ -44,10 +65,7 @@ export default function InterpretationPanel({
return (
<aside className="tarot-panel tarot-panel--reading">
<div className="tarot-panel__tabs">
<button type="button" className="is-active">카드 해석</button>
<button type="button">AI 인사이트</button>
</div>
{renderTabs()}
{selectedCard && (
<header className="tarot-panel__head">
@@ -65,7 +83,7 @@ export default function InterpretationPanel({
</header>
)}
{selectedCard && !interpretation && (
{activeTab === 'card' && selectedCard && (
<>
<section className="tarot-panel__section">
<h4>카드 의미 요약</h4>
@@ -86,10 +104,12 @@ export default function InterpretationPanel({
))}
</ul>
</section>
{!hasAI && (
<section className="tarot-panel__section tarot-panel__ai-note">
<h4>AI 타로 해석 </h4>
<p>모든 카드를 뽑은 해석 버튼을 누르면 질문과 스프레드 위치를 함께 반영한 리딩이 생성됩니다.</p>
</section>
)}
<div className="tarot-panel__advice-card">
<span aria-hidden></span>
<p>
@@ -100,6 +120,8 @@ export default function InterpretationPanel({
</>
)}
{activeTab === 'ai' && hasAI && (
<>
{cardDetail && (
<section className="tarot-panel__section">
<h4> 위치의 해석</h4>
@@ -125,7 +147,6 @@ export default function InterpretationPanel({
</section>
)}
{interpretation && (
<section className="tarot-panel__section">
<h4>종합 해석 <ConfidenceBadge level={interpretation.confidence} /></h4>
<p>{interpretation.summary}</p>
@@ -134,9 +155,8 @@ export default function InterpretationPanel({
<p className="tarot-panel__warning"> {interpretation.warning}</p>
)}
</section>
)}
{(interpretation?.interactions || []).length > 0 && (
{(interpretation.interactions || []).length > 0 && (
<section className="tarot-panel__section">
<h4>카드 상호작용</h4>
<ul className="tarot-interactions">
@@ -153,6 +173,8 @@ export default function InterpretationPanel({
</ul>
</section>
)}
</>
)}
</aside>
);
}

View File

@@ -96,5 +96,12 @@ export function useTarotReading() {
return interp.interpretation_json;
}, []);
return { status, interpretation, readingId, error, runInterpretAndSave };
const reset = useCallback(() => {
setStatus('idle');
setInterpretation(null);
setReadingId(null);
setError(null);
}, []);
return { status, interpretation, readingId, error, runInterpretAndSave, reset };
}