// js/App.jsx // 메인 앱 컴포넌트 - 페이지 라우팅 및 상태관리 window.App = function() { const { useState, useCallback } = React; // 페이지 상태: 'landing' | 'diagnosis' | 'loading' | 'result' const [page, setPage] = useState('landing'); const [productInfo, setProductInfo] = useState(null); const [diagnosisResult, setDiagnosisResult] = useState(null); // 진단 시작 const handleStart = useCallback((formData) => { setProductInfo(formData); setPage('diagnosis'); }, []); // 진단 완료 const handleDiagnosisComplete = useCallback((answers) => { // 로딩 화면 표시 setPage('loading'); // P-CODE 계산 (약간의 딜레이로 UX 향상) setTimeout(() => { try { const helpers = window.PCODE_HELPERS; // 역채점 함수 const reverseScore = (score) => 6 - score; const average = (scores) => scores.reduce((a, b) => a + b, 0) / scores.length; // AXIS 1: U/S (Q1-6, 모두 역채점) const usScores = [1, 2, 3, 4, 5, 6].map(qId => reverseScore(answers[qId] || 3)); const usAverage = average(usScores); const usCode = usAverage >= 3.0 ? 'S' : 'U'; const usPercentage = Math.round(usAverage * 20); // AXIS 2: T/C (Q7-12, 모두 역채점) const tcScores = [7, 8, 9, 10, 11, 12].map(qId => reverseScore(answers[qId] || 3)); const tcAverage = average(tcScores); const tcCode = tcAverage >= 3.0 ? 'C' : 'T'; const tcPercentage = Math.round(tcAverage * 20); // AXIS 3: F/E (Q13 역채점, Q14-18 정채점) const feScores = [13, 14, 15, 16, 17, 18].map((qId, index) => { const ans = answers[qId] || 3; return index === 0 ? reverseScore(ans) : ans; }); const feAverage = average(feScores); const feCode = feAverage >= 3.0 ? 'E' : 'F'; const fePercentage = Math.round(feAverage * 20); // AXIS 4: P/G (Q19-24, 모두 정채점) const pgScores = [19, 20, 21, 22, 23, 24].map(qId => answers[qId] || 3); const pgAverage = average(pgScores); const pgCode = pgAverage >= 3.0 ? 'G' : 'P'; const pgPercentage = Math.round(pgAverage * 20); // 최종 P-CODE const pCode = `${usCode}${tcCode}${feCode}${pgCode}`; const typeData = window.PCODE_TYPES[pCode]; const result = { id: Date.now(), timestamp: new Date().toISOString(), productName: productInfo.productName, category: productInfo.category, price: productInfo.price, productLink: productInfo.productLink || '', pcode: pCode, scores: { us: usPercentage, tc: tcPercentage, fe: fePercentage, pg: pgPercentage }, axes: { us: { code: usCode, percentage: usPercentage, average: usAverage }, tc: { code: tcCode, percentage: tcPercentage, average: tcAverage }, fe: { code: feCode, percentage: fePercentage, average: feAverage }, pg: { code: pgCode, percentage: pgPercentage, average: pgAverage } }, typeData: typeData, answers: answers }; // localStorage 저장 helpers.storage.saveResult({ id: result.id, timestamp: result.timestamp, productName: result.productName, category: result.category, price: result.price, pcode: result.pcode, scores: result.scores }); setDiagnosisResult(result); setPage('result'); } catch (error) { console.error('P-CODE calculation error:', error); setPage('diagnosis'); alert('결과 계산 중 오류가 발생했습니다. 다시 시도해주세요.'); } }, 1500); // 1.5초 로딩 }, [productInfo]); // 처음으로 돌아가기 const handleRestart = useCallback(() => { setPage('landing'); setProductInfo(null); setDiagnosisResult(null); window.scrollTo({ top: 0, behavior: 'smooth' }); }, []); // 질문 페이지에서 뒤로가기 const handleBackToForm = useCallback(() => { setPage('landing'); }, []); // 로딩 화면 if (page === 'loading') { return (
{productInfo?.productName}의 성향을 분석하고 있습니다
{/* 진행 표시 */}