178 lines
7.7 KiB
TypeScript
Executable File
178 lines
7.7 KiB
TypeScript
Executable File
|
|
import React from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { CrawlingResponse, TargetPersona } from '../../types/api';
|
|
import { GeometricChart } from './GeometricChart';
|
|
|
|
interface AnalysisResultSectionProps {
|
|
onBack: () => void;
|
|
onGenerate?: () => void;
|
|
data: CrawlingResponse;
|
|
}
|
|
|
|
const AnalysisResultSection: React.FC<AnalysisResultSectionProps> = ({ onBack, onGenerate, data }) => {
|
|
const { t } = useTranslation();
|
|
const { processed_info, marketing_analysis } = data;
|
|
|
|
const brandIdentity = marketing_analysis?.brand_identity;
|
|
const marketPositioning = marketing_analysis?.market_positioning;
|
|
const targetPersonas = marketing_analysis?.target_persona || [];
|
|
const sellingPoints = marketing_analysis?.selling_points || [];
|
|
const targetKeywords = marketing_analysis?.target_keywords || [];
|
|
|
|
// 셀링 포인트를 score 내림차순으로 정렬
|
|
const sortedSellingPoints = [...sellingPoints].sort((a, b) => b.score - a.score);
|
|
|
|
return (
|
|
<div className="bi2-page">
|
|
{/* Header */}
|
|
<div className="bi2-header">
|
|
<button onClick={onBack} className="bi2-back-btn">
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
<path d="M15 18l-6-6 6-6" />
|
|
</svg>
|
|
<span>{t('analysis.back')}</span>
|
|
</button>
|
|
</div>
|
|
|
|
{/* Page Title */}
|
|
<div className="bi2-page-title-section">
|
|
<div className="bi2-title-icon">
|
|
<img src="/assets/images/star-icon.svg" alt="" className="bi2-star-icon" />
|
|
</div>
|
|
<div className="bi2-title-text">
|
|
<h1 className="bi2-main-title">{t('analysis.pageTitle')}</h1>
|
|
<p className="bi2-subtitle">
|
|
<span style={{ color: 'var(--Color-mint-500, #94FBE0)' }}>{t('analysis.pageDescHighlight')}</span>{t('analysis.pageDescBefore')}{processed_info?.customer_name || t('analysis.defaultBrandName')}{t('analysis.pageDescAfter')}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Main Content Container */}
|
|
<div className="bi2-main-container">
|
|
{/* 매장명 & 주소 */}
|
|
<div className="bi2-store-header">
|
|
<h2 className="bi2-store-name">{processed_info?.customer_name || t('analysis.brandNameFallback')}</h2>
|
|
<p className="bi2-store-address">{processed_info?.detail_region_info || t('analysis.addressFallback')}</p>
|
|
</div>
|
|
|
|
{/* 브랜드 정체성 */}
|
|
<div className="bi2-section">
|
|
<h3 className="bi2-section-title">{t('analysis.brandIdentity')}</h3>
|
|
<div className="bi2-identity-card">
|
|
<div className="bi2-identity-top">
|
|
<div className="bi2-identity-core">
|
|
<span className="bi2-label-sm">{t('analysis.coreValue')}</span>
|
|
<p className="bi2-core-value">{marketPositioning?.core_value || t('analysis.noInfo')}</p>
|
|
</div>
|
|
<p className="bi2-category-text">{t('analysis.categoryDefinition')} : {marketPositioning?.category_definition || t('analysis.noInfo')}</p>
|
|
</div>
|
|
<div className="bi2-identity-divider"></div>
|
|
<div className="bi2-identity-bottom">
|
|
<div className="bi2-identity-col">
|
|
<span className="bi2-label-sm">{t('analysis.locationAnalysis')}</span>
|
|
<p className="bi2-body-text">{brandIdentity?.location_feature_analysis || t('analysis.noInfo')}</p>
|
|
</div>
|
|
<div className="bi2-identity-col">
|
|
<span className="bi2-label-sm">{t('analysis.conceptScalability')}</span>
|
|
<p className="bi2-body-text">{brandIdentity?.concept_scalability || t('analysis.noInfo')}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 주요 셀링 포인트 */}
|
|
<div className="bi2-section">
|
|
<h3 className="bi2-section-title">{t('analysis.sellingPoints')}</h3>
|
|
<div className="bi2-selling-card">
|
|
{/* 레이더 차트 */}
|
|
<div className="bi2-selling-chart">
|
|
{sellingPoints.length > 0 && (
|
|
<GeometricChart data={sellingPoints} />
|
|
)}
|
|
</div>
|
|
{/* 셀링 포인트 리스트 */}
|
|
<div className="bi2-selling-list">
|
|
{sortedSellingPoints.map((sp, idx) => {
|
|
const rank = idx + 1;
|
|
const isTopThree = rank <= 3;
|
|
return (
|
|
<div key={idx} className="bi2-selling-item">
|
|
<div className={`bi2-rank-badge ${isTopThree ? 'top' : ''}`}>
|
|
{rank}
|
|
</div>
|
|
<div className="bi2-selling-item-text">
|
|
<span className="bi2-selling-name">{sp.korean_category}</span>
|
|
<span className="bi2-selling-desc">{sp.description}</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 주요 고객 유형 */}
|
|
<div className="bi2-section">
|
|
<h3 className="bi2-section-title">{t('analysis.targetPersona')}</h3>
|
|
<div className="bi2-persona-grid">
|
|
{targetPersonas.map((persona: TargetPersona, idx: number) => (
|
|
<div key={idx} className="bi2-persona-card">
|
|
<div className="bi2-persona-header">
|
|
<div className="bi2-persona-info">
|
|
<span className="bi2-persona-name">{persona.persona}</span>
|
|
<span className="bi2-persona-age">{persona.age.min_age}~{persona.age.max_age}{t('analysis.ageSuffix')}</span>
|
|
</div>
|
|
<p className="bi2-persona-desc">
|
|
{persona.decision_trigger}
|
|
</p>
|
|
</div>
|
|
<div className="bi2-persona-divider"></div>
|
|
<div className="bi2-persona-detail grow">
|
|
<span className="bi2-label-xs">{t('analysis.favorKeywords', { defaultValue: '선호 키워드' })}</span>
|
|
<p className="bi2-persona-detail-text">
|
|
{persona.favor_target.join('\n')}
|
|
</p>
|
|
</div>
|
|
<div className="bi2-persona-divider"></div>
|
|
<div className="bi2-persona-detail">
|
|
<span className="bi2-label-xs">{t('analysis.decisionTrigger', { defaultValue: '예약 결정 포인트' })}</span>
|
|
<p className="bi2-persona-detail-text">{persona.decision_trigger}</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* 추천 타겟 키워드 */}
|
|
<div className="bi2-section">
|
|
<div className="bi2-keyword-header">
|
|
<h3 className="bi2-section-title">{t('analysis.recommendedKeywords')}</h3>
|
|
<p className="bi2-keyword-subtitle">{t('analysis.keywordHint', { defaultValue: '이런 키워드로 찾을 가능성이 높아요' })}</p>
|
|
</div>
|
|
<div className="bi2-keyword-tags">
|
|
{targetKeywords.map((keyword: string, idx: number) => (
|
|
<span key={idx} className="bi2-keyword-pill">#{keyword}</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 콘텐츠 생성 버튼 */}
|
|
<div className="bi2-bottom-button-container">
|
|
<button
|
|
onClick={onGenerate}
|
|
className="bi2-generate-btn"
|
|
>
|
|
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden className="w-5 h-5">
|
|
<path d="M12 2l2.4 6.8L22 12l-7.6 3.2L12 22l-2.4-6.8L2 12l7.6-3.2L12 2z" />
|
|
</svg>
|
|
{t('analysis.generateContent')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AnalysisResultSection;
|