o2o-infinith-demo/src/pages/ReportPage.tsx

146 lines
5.4 KiB
TypeScript

import { useMemo } from 'react';
import { useParams, useLocation } from 'react-router';
import { useReport } from '../hooks/useReport';
import { useEnrichment } from '../hooks/useEnrichment';
import { ReportNav } from '../components/report/ReportNav';
import { ScreenshotProvider } from '../contexts/ScreenshotContext';
// Report section components
import ReportHeader from '../components/report/ReportHeader';
import ClinicSnapshot from '../components/report/ClinicSnapshot';
import ChannelOverview from '../components/report/ChannelOverview';
import YouTubeAudit from '../components/report/YouTubeAudit';
import InstagramAudit from '../components/report/InstagramAudit';
import FacebookAudit from '../components/report/FacebookAudit';
import OtherChannels from '../components/report/OtherChannels';
import ProblemDiagnosis from '../components/report/ProblemDiagnosis';
import TransformationProposal from '../components/report/TransformationProposal';
import RoadmapTimeline from '../components/report/RoadmapTimeline';
import KPIDashboard from '../components/report/KPIDashboard';
const REPORT_SECTIONS = [
{ id: 'header', label: '개요' },
{ id: 'clinic-snapshot', label: '의원 현황' },
{ id: 'channel-overview', label: '채널 종합' },
{ id: 'youtube-audit', label: 'YouTube' },
{ id: 'instagram-audit', label: 'Instagram' },
{ id: 'facebook-audit', label: 'Facebook' },
{ id: 'other-channels', label: '기타 채널' },
{ id: 'problem-diagnosis', label: '문제 진단' },
{ id: 'roadmap', label: '로드맵' },
{ id: 'kpi-dashboard', label: 'KPI' },
];
export default function ReportPage() {
const { id } = useParams<{ id: string }>();
const location = useLocation();
const { data: baseData, isLoading, error } = useReport(id);
// Extract enrichment params from location state (socialHandles from API) or base data
const enrichmentParams = useMemo(() => {
if (!baseData) return null;
const state = location.state as Record<string, unknown> | undefined;
const metadata = state?.metadata as Record<string, unknown> | undefined;
const socialHandles = metadata?.socialHandles as Record<string, string | null> | undefined;
// Priority: API socialHandles > transformed data > undefined
const igHandle =
socialHandles?.instagram ||
baseData.instagramAudit?.accounts?.[0]?.handle ||
undefined;
const ytHandle =
socialHandles?.youtube ||
baseData.youtubeAudit?.handle ||
undefined;
return {
reportId: baseData.id,
clinicName: baseData.clinicSnapshot.name,
instagramHandle: igHandle || undefined,
youtubeChannelId: ytHandle || undefined,
address: baseData.clinicSnapshot.location || undefined,
};
}, [baseData, location.state]);
const { status: enrichStatus, enrichedReport } = useEnrichment(baseData, enrichmentParams);
// Use enriched data when available, otherwise base data
const data = enrichedReport || baseData;
if (isLoading) {
return (
<div className="min-h-screen flex items-center justify-center pt-20">
<div className="flex flex-col items-center gap-4">
<div className="w-10 h-10 border-4 border-[#6C5CE7] border-t-transparent rounded-full animate-spin" />
<p className="text-slate-500 text-sm"> ...</p>
</div>
</div>
);
}
if (error || !data) {
return (
<div className="min-h-screen flex items-center justify-center pt-20">
<div className="text-center">
<p className="text-[#7C3A4B] font-medium mb-2"> </p>
<p className="text-slate-500 text-sm">{error ?? '리포트를 찾을 수 없습니다.'}</p>
</div>
</div>
);
}
return (
<ScreenshotProvider screenshots={data.screenshots ?? []}>
<div className="pt-20">
<ReportNav sections={REPORT_SECTIONS} />
{/* Enrichment status indicator */}
{enrichStatus === 'loading' && (
<div className="fixed bottom-6 right-6 z-50 flex items-center gap-3 px-4 py-3 bg-white rounded-xl shadow-[3px_4px_12px_rgba(0,0,0,0.06)] border border-slate-100">
<div className="w-4 h-4 border-2 border-[#6C5CE7] border-t-transparent rounded-full animate-spin" />
<span className="text-xs text-slate-500"> ...</span>
</div>
)}
<div data-report-content>
<ReportHeader
overallScore={data.overallScore}
clinicName={data.clinicSnapshot.name}
clinicNameEn={data.clinicSnapshot.nameEn}
targetUrl={data.targetUrl}
date={data.createdAt}
location={data.clinicSnapshot.location}
logoImage={data.clinicSnapshot.logoImages?.horizontal}
brandColors={data.clinicSnapshot.brandColors}
/>
<ClinicSnapshot data={data.clinicSnapshot} />
<ChannelOverview channels={data.channelScores} />
<YouTubeAudit data={data.youtubeAudit} />
<InstagramAudit data={data.instagramAudit} />
<FacebookAudit data={data.facebookAudit} />
<OtherChannels
channels={data.otherChannels}
website={data.websiteAudit}
/>
<ProblemDiagnosis diagnosis={data.problemDiagnosis} />
<TransformationProposal data={data.transformation} />
<RoadmapTimeline months={data.roadmap} />
<KPIDashboard metrics={data.kpiDashboard} />
</div>
</div>
</ScreenshotProvider>
);
}