// js/components/LandingPage.jsx // 랜딩 페이지 + 제품 정보 입력 폼 window.LandingPage = function({ onStart }) { const { useState, useCallback } = React; const helpers = window.PCODE_HELPERS; const [formData, setFormData] = useState({ productName: '', category: '', price: '', productLink: '' }); const [errors, setErrors] = useState({}); const [touched, setTouched] = useState({}); // 유효성 검사 const validate = useCallback((data) => { const newErrors = {}; if (!data.productName.trim()) { newErrors.productName = '제품명을 입력해주세요.'; } else if (data.productName.trim().length > 50) { newErrors.productName = '제품명은 50자 이내로 입력해주세요.'; } if (!data.category) { newErrors.category = '카테고리를 선택해주세요.'; } if (!data.price) { newErrors.price = '가격을 입력해주세요.'; } else if (Number(data.price) <= 0) { newErrors.price = '유효한 가격을 입력해주세요.'; } if (data.productLink && !helpers.isValidUrl(data.productLink)) { newErrors.productLink = '유효한 URL 형식으로 입력해주세요. (예: https://...)'; } return newErrors; }, [helpers]); // 폼이 유효한지 확인 const isFormValid = useCallback(() => { const errs = validate(formData); return Object.keys(errs).length === 0; }, [formData, validate]); // 입력 변경 핸들러 const handleChange = useCallback((field, value) => { const newData = { ...formData, [field]: value }; setFormData(newData); if (touched[field]) { const newErrors = validate(newData); setErrors(prev => ({ ...prev, [field]: newErrors[field] || null })); } }, [formData, touched, validate]); // 블러 핸들러 const handleBlur = useCallback((field) => { setTouched(prev => ({ ...prev, [field]: true })); const newErrors = validate(formData); setErrors(prev => ({ ...prev, [field]: newErrors[field] || null })); }, [formData, validate]); // 폼 제출 const handleSubmit = useCallback((e) => { e.preventDefault(); // 모든 필드 터치 표시 setTouched({ productName: true, category: true, price: true, productLink: true }); const validationErrors = validate(formData); setErrors(validationErrors); if (Object.keys(validationErrors).length === 0) { onStart(formData); } }, [formData, validate, onStart]); // 최근 결과 불러오기 const recentResults = helpers.storage.getResults().slice(0, 3); return (
{/* Hero Section */}
{/* Background decorations */}
{/* Header */}
제조사/브랜드 대표 전용 무료 진단

What's Your P-CODE? 🎯

제품의 MBTI를 만나세요

P-CODE는 제품의 성향을 분석해주는 16가지 유형 진단 시스템입니다.
당신의 제품이 어떤 성격을 지녔는지 알아보세요.

{/* Feature Cards */}
{[ { icon: '🎯', title: '16가지 유형', desc: 'MBTI처럼 4축으로 분석하는 제품 성향 진단' }, { icon: '📊', title: '24개 문항', desc: '4개 핵심 축을 정밀하게 측정하는 전문 질문' }, { icon: '🚀', title: '전략 가이드', desc: '유형별 마케팅 전략과 채널 추천 제공' }, ].map((item, i) => (
{item.icon}

{item.title}

{item.desc}

))}
{/* 축 설명 */}

P-CODE 분석 4개 축

{[ { axis: 'U ↔ S', name: '실용성 vs 스타일', color: 'from-blue-400 to-pink-400' }, { axis: 'T ↔ C', name: '트렌드 vs 클래식', color: 'from-green-400 to-yellow-400' }, { axis: 'F ↔ E', name: '기능 vs 감성', color: 'from-red-400 to-purple-400' }, { axis: 'P ↔ G', name: '개인용 vs 선물용', color: 'from-gray-400 to-yellow-400' }, ].map((item, i) => (
{item.axis}

{item.name}

))}
{/* Form Section */}

제품 정보 입력

진단을 시작하기 전에 제품 기본 정보를 입력해주세요

{/* 제품명 */}
handleChange('productName', e.target.value)} onBlur={() => handleBlur('productName')} placeholder="예: 프리미엄 무선 이어폰 X100" maxLength={50} className={`w-full px-4 py-3 border-2 rounded-xl text-gray-800 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-300 transition-all ${ errors.productName ? 'border-red-300 bg-red-50' : 'border-gray-200 focus:border-indigo-400' }`} />
{errors.productName ? (

{errors.productName}

) : } {formData.productName.length}/50
{/* 카테고리 */}
{errors.category && (

{errors.category}

)}
{/* 가격 */}
handleChange('price', e.target.value)} onBlur={() => handleBlur('price')} placeholder="예: 89000" min="1" className={`w-full px-4 py-3 pr-12 border-2 rounded-xl text-gray-800 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-300 transition-all ${ errors.price ? 'border-red-300 bg-red-50' : 'border-gray-200 focus:border-indigo-400' }`} />
{formData.price && !errors.price && (

= {helpers.formatPrice(formData.price)}원

)} {errors.price && (

{errors.price}

)}
{/* 제품 링크 (선택) */}
handleChange('productLink', e.target.value)} onBlur={() => handleBlur('productLink')} placeholder="https://www.example.com/product" className={`w-full px-4 py-3 border-2 rounded-xl text-gray-800 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-300 transition-all ${ errors.productLink ? 'border-red-300 bg-red-50' : 'border-gray-200 focus:border-indigo-400' }`} /> {errors.productLink && (

{errors.productLink}

)}
{/* 진단 시작 버튼 */}
{!isFormValid() && (

필수 항목(제품명, 카테고리, 가격)을 모두 입력하면 활성화됩니다

)}
{/* 안내 */}
ℹ️

진단 안내

  • • 24개의 질문에 5점 척도로 답변합니다
  • • 솔직하고 현재 상황에 맞게 답변할수록 정확도가 높아집니다
  • • 소요 시간: 약 5-10분
  • • 모든 문항에 반드시 답변해야 합니다
{/* 최근 진단 결과 */} {recentResults.length > 0 && (

최근 진단 기록

{recentResults.map(r => (
{r.productName} {r.category}
{window.PCODE_TYPES[r.pcode]?.emoji} {r.pcode}
))}
)}
); };