Spaces:
Sleeping
Sleeping
| 'use client'; | |
| import PreAnalysisCheck from '@/components/pages/index/pre-analysis-check'; | |
| import PreAnalysisInput from '@/components/pages/index/pre-analysis-input'; | |
| import { ErrorDisplay } from '@/components/parts/error-display'; | |
| import { LoadingPulse } from '@/components/parts/loading-pulse'; | |
| import { NoticeDialog } from '@/components/parts/notice-dialog'; | |
| import { StatusLoading } from '@/components/parts/status-loading'; | |
| import { Button } from '@/components/ui/button'; | |
| import { useEnvironment } from '@/hooks/use-environment'; | |
| import { useNotificationPermission } from '@/hooks/use-notification-permission'; | |
| import { isAllowedUser } from '@/lib/utils'; | |
| import { useGlobalStore } from '@/store/global'; | |
| import { useResultStore } from '@/store/result'; | |
| import { useStateStore } from '@/store/state'; | |
| import { useUserStore } from '@/store/user'; | |
| import Link from 'next/link'; | |
| import { useEffect, useRef } from 'react'; | |
| export default function Home() { | |
| const { | |
| tempImagesLoading, | |
| getScoreLoading, | |
| setGetScoreLoading, | |
| analysisError, | |
| showAnalysisError, | |
| setShowAnalysisError, | |
| setAnalysisError, | |
| analysisApiStatuses, | |
| } = useStateStore(); | |
| const { tempImages, downloadData } = useResultStore(); | |
| const { setDummyMode, dummyMode } = useGlobalStore(); | |
| const { user } = useUserStore(); | |
| const { permission, isSupported, isServiceWorkerReady, requestPermission } = useNotificationPermission(); | |
| const { showDevFeatures, isProduction } = useEnvironment(); | |
| const retryButtonRef = useRef<(() => void) | undefined>(undefined); | |
| useEffect(() => { | |
| const handleBeforeUnload = (e: BeforeUnloadEvent) => { | |
| e.preventDefault(); | |
| }; | |
| window.addEventListener('beforeunload', handleBeforeUnload); | |
| return () => window.removeEventListener('beforeunload', handleBeforeUnload); | |
| }, []); | |
| // コンポーネントアンマウント時のクリーンアップ処理(ページから離れる時) | |
| useEffect(() => { | |
| return () => { | |
| console.log('[CLEANUP] Clearing loading states when leaving Home page'); | |
| // ローディング状態をクリア | |
| setGetScoreLoading(false); | |
| }; | |
| }, [setGetScoreLoading]); | |
| // 通知許可のリクエスト | |
| useEffect(() => { | |
| const requestNotificationPermission = async () => { | |
| if (isSupported && isServiceWorkerReady) { | |
| try { | |
| // 最新の通知権限状態を直接確認 | |
| const currentPermission = Notification.permission; | |
| console.log('[Home] 通知設定の初期化:', { | |
| currentPermission, | |
| hookPermission: permission, | |
| }); | |
| if (currentPermission === 'default') { | |
| // 許可が未設定の場合、許可をリクエスト | |
| await requestPermission(); | |
| } | |
| } catch (error) { | |
| console.error('通知許可エラー:', error); | |
| } | |
| } | |
| }; | |
| requestNotificationPermission(); | |
| }, [isSupported, isServiceWorkerReady, permission, requestPermission]); | |
| return ( | |
| <div className="flex h-full grow flex-col space-y-8"> | |
| {showAnalysisError ? ( | |
| <div className="flex grow flex-col items-center justify-center space-y-8"> | |
| <ErrorDisplay | |
| error={analysisError} | |
| onRetry={() => { | |
| setShowAnalysisError(false); | |
| setAnalysisError(''); | |
| // リトライ処理を実行(retryButtonRefが設定されていれば実行) | |
| if (retryButtonRef.current) { | |
| retryButtonRef.current(); | |
| } | |
| }} | |
| showBackButton={false} | |
| /> | |
| </div> | |
| ) : getScoreLoading || downloadData ? ( | |
| <div className="flex grow flex-col items-center justify-center"> | |
| <StatusLoading | |
| message="※競合分析が完了するまで5分程度かかります" | |
| statuses={analysisApiStatuses} | |
| statusDisplayNames={{ | |
| getScore: 'スコア分析', | |
| getVisScore: 'ビジュアル分析', | |
| getSummary: 'サマリー生成', | |
| getPox: 'SWOT分析', | |
| getExcel: 'Excel生成', | |
| }} | |
| statusOrder={['getScore', 'getVisScore', 'getSummary', 'getPox', 'getExcel']} | |
| showStatusPanel={true} | |
| /> | |
| </div> | |
| ) : ( | |
| <div className="mt-4 w-full space-y-8"> | |
| <div className="flex items-center justify-between"> | |
| <h1 className="text-primary-text text-3xl font-bold">競合分析</h1> | |
| <div className="flex gap-3"> | |
| {showDevFeatures && ( | |
| <> | |
| <Link href="/sample/html-preview-fv"> | |
| <Button size="lg">FV確認ページへ移動</Button> | |
| </Link> | |
| <Link href="/sample/html-preview-cn"> | |
| <Button size="lg">CN確認ページへ移動</Button> | |
| </Link> | |
| </> | |
| )} | |
| {isProduction && isAllowedUser(user?.user?.email) && ( | |
| <Link href="/admin/data"> | |
| <Button size="lg">ログデータ確認</Button> | |
| </Link> | |
| )} | |
| {isAllowedUser(user?.user?.email) && ( | |
| <Button size="lg" onClick={() => setDummyMode(!dummyMode)}> | |
| {dummyMode ? '通常モードに設定' : 'ダミーモードに設定'} | |
| </Button> | |
| )} | |
| </div> | |
| </div> | |
| {!isProduction && ( | |
| <div className="flex gap-4"> | |
| <Link href="/updatedui"> | |
| <Button variant="outline" size="lg"> | |
| 新しいUIを試す | |
| </Button> | |
| </Link> | |
| <Link href="/prediction-input"> | |
| <Button size="lg">勝敗予測を試す</Button> | |
| </Link> | |
| <Link href="/speed-comparison-input"> | |
| <Button size="lg">表示速度を試す</Button> | |
| </Link> | |
| </div> | |
| )} | |
| <div className="flex flex-col space-y-6 rounded-xl bg-white/80 px-12 py-10 shadow"> | |
| <PreAnalysisInput retryButtonRef={retryButtonRef} /> | |
| {tempImagesLoading ? ( | |
| <div className="flex flex-col items-center space-y-4 self-center py-12"> | |
| <LoadingPulse /> | |
| <div className="text-secondary-text">※データ取得に2分程度かかります</div> | |
| </div> | |
| ) : null} | |
| {tempImages.length && !tempImagesLoading ? <PreAnalysisCheck retryButtonRef={retryButtonRef} /> : null} | |
| </div> | |
| </div> | |
| )} | |
| <NoticeDialog /> | |
| </div> | |
| ); | |
| } | |