FE_Test / app /page.tsx
GitHub Actions
Deploy from GitHub Actions [test] - 2025-10-31 10:18:25
5f2aab6
'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>
);
}