o2o-infinith-frontend/src/features/report/pages/UserReportPage.tsx

94 lines
3.8 KiB
TypeScript

/**
* UserReportPage — `/clinics/:clinicId/report/:id`
*
* 계약된 병원 유저가 워크스페이스 안에서 보는 리포트 화면.
* 본문은 GuestReportPage 와 동일하지만:
* - 상단에 워크스페이스 액션바 (워크스페이스로 돌아가기, 플랜 생성, 다시 분석)
* - 하단의 도입 문의 CTA 없음
*/
import { Link, useParams } from 'react-router';
import { ArrowLeft, Sparkles, RefreshCw } from 'lucide-react';
import { useReportPageData } from '../hooks/useReportPageData';
import { ReportNav } from '../components/ReportNav';
import { ScreenshotProvider } from '../stores/ScreenshotContext';
import { REPORT_SECTIONS } from '@/shared/constants/reportSections';
import ReportBody from '../components/ReportBody';
import { DownloadMenuButton } from '../components/DownloadMenuButton';
export default function UserReportPage() {
const { clinicId, id } = useParams<{ clinicId: string; id: string }>();
const { data, isLoading, error, enrichStatus } = useReportPageData(id);
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}
leftSlot={
<Link
to={`/clinics/${clinicId}`}
className="inline-flex items-center gap-1.5 text-xs font-medium text-slate-500 hover:text-primary-900 transition-colors"
>
<ArrowLeft size={14} />
</Link>
}
rightSlot={
<div className="flex items-center gap-2">
<DownloadMenuButton
filename={`${data.clinicSnapshot.name}_Marketing_Intelligence_Report`}
report={data}
/>
<Link
to={`/report/loading`}
className="inline-flex items-center gap-1.5 px-3.5 py-2 rounded-full text-xs font-medium text-slate-600 bg-slate-50 border border-slate-200 hover:bg-white hover:border-slate-300 transition-all"
>
<RefreshCw size={12} />
</Link>
<Link
to={`/clinics/${clinicId}/plan/${id}`}
className="inline-flex items-center gap-1.5 px-4 py-2 rounded-full text-xs font-semibold text-white bg-gradient-to-r from-[#4F1DA1] to-[#021341] shadow-sm hover:opacity-90 transition-all"
>
<Sparkles size={12} />
</Link>
</div>
}
/>
{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>
)}
<ReportBody data={data} />
</div>
</ScreenshotProvider>
);
}