refactor(WEB): 레이아웃 및 설정 관리 개선
- AuthenticatedLayout: FCM 통합 및 레이아웃 개선 - logout: 로그아웃 시 FCM 토큰 정리 로직 추가 - AccountInfoManagement: 계정 정보 관리 UI 개선 - not-found 페이지 스타일 개선 - 환경변수 예시 파일 업데이트
This commit is contained in:
@@ -4,6 +4,7 @@ import { useAuthGuard } from '@/hooks/useAuthGuard';
|
||||
import AuthenticatedLayout from '@/layouts/AuthenticatedLayout';
|
||||
import { RootProvider } from '@/contexts/RootProvider';
|
||||
import { ApiErrorProvider } from '@/contexts/ApiErrorContext';
|
||||
import { FCMProvider } from '@/contexts/FCMProvider';
|
||||
|
||||
/**
|
||||
* Protected Layout
|
||||
@@ -13,6 +14,7 @@ import { ApiErrorProvider } from '@/contexts/ApiErrorContext';
|
||||
* - Apply common layout (sidebar, header) to all protected pages
|
||||
* - Provide global context (RootProvider)
|
||||
* - Provide API error handling context (ApiErrorProvider)
|
||||
* - Initialize FCM push notifications (Capacitor native apps)
|
||||
* - Prevent browser back button cache issues
|
||||
* - Centralized protection for all routes under (protected)
|
||||
*
|
||||
@@ -35,9 +37,9 @@ export default function ProtectedLayout({
|
||||
// 🚨 ApiErrorProvider: Server Action 401 에러 시 자동 로그인 리다이렉트
|
||||
return (
|
||||
<RootProvider>
|
||||
<ApiErrorProvider>
|
||||
<AuthenticatedLayout>{children}</AuthenticatedLayout>
|
||||
</ApiErrorProvider>
|
||||
<ApiErrorProvider>
|
||||
<AuthenticatedLayout>{children}</AuthenticatedLayout>
|
||||
</ApiErrorProvider>
|
||||
</RootProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { SearchX, Home, ArrowLeft, Map } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
@@ -12,6 +15,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
* - 보호된 경로 내에서 404 발생 시 표시
|
||||
*/
|
||||
export default function ProtectedNotFoundPage() {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-[calc(100vh-200px)] p-4">
|
||||
<Card className="w-full max-w-2xl border border-border/20 bg-card/50 backdrop-blur">
|
||||
@@ -56,13 +60,11 @@ export default function ProtectedNotFoundPage() {
|
||||
<div className="flex flex-col sm:flex-row gap-3 pt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
asChild
|
||||
className="flex-1 rounded-xl"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
<Link href="javascript:history.back()">
|
||||
<ArrowLeft className="w-4 h-4 mr-2" />
|
||||
이전 페이지
|
||||
</Link>
|
||||
<ArrowLeft className="w-4 h-4 mr-2" />
|
||||
이전 페이지
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
import { AccountInfoClient } from '@/components/settings/AccountInfoManagement';
|
||||
import { getAccountInfo } from '@/components/settings/AccountInfoManagement/actions';
|
||||
|
||||
export default function AccountInfoPage() {
|
||||
return <AccountInfoClient />;
|
||||
}
|
||||
export default async function AccountInfoPage() {
|
||||
const result = await getAccountInfo();
|
||||
|
||||
if (!result.success || !result.data) {
|
||||
// 실패 시 빈 데이터로 렌더링 (클라이언트에서 에러 처리)
|
||||
return (
|
||||
<AccountInfoClient
|
||||
initialAccountInfo={{
|
||||
id: '',
|
||||
email: '',
|
||||
profileImage: undefined,
|
||||
role: '',
|
||||
status: 'active',
|
||||
isTenantMaster: false,
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
}}
|
||||
initialTermsAgreements={[]}
|
||||
initialMarketingConsent={{
|
||||
email: { agreed: false },
|
||||
sms: { agreed: false },
|
||||
}}
|
||||
error={result.error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AccountInfoClient
|
||||
initialAccountInfo={result.data.accountInfo}
|
||||
initialTermsAgreements={result.data.termsAgreements}
|
||||
initialMarketingConsent={result.data.marketingConsent}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { SearchX, Home, ArrowLeft } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
@@ -11,10 +14,11 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
* - notFound() 함수 호출 시
|
||||
*
|
||||
* 특징:
|
||||
* - 서버 컴포넌트 (metadata 지원 가능)
|
||||
* - 클라이언트 컴포넌트 (router.back() 사용)
|
||||
* - 다국어 지원 (next-intl)
|
||||
*/
|
||||
export default function NotFoundPage() {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center p-4 bg-gradient-to-br from-background via-background to-muted/20">
|
||||
<Card className="w-full max-w-2xl border border-border/20 bg-card/80 backdrop-blur-xl shadow-2xl">
|
||||
@@ -54,13 +58,11 @@ export default function NotFoundPage() {
|
||||
<div className="flex flex-col sm:flex-row gap-3 pt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
asChild
|
||||
className="flex-1 rounded-xl"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
<Link href="javascript:history.back()">
|
||||
<ArrowLeft className="w-4 h-4 mr-2" />
|
||||
이전 페이지
|
||||
</Link>
|
||||
<ArrowLeft className="w-4 h-4 mr-2" />
|
||||
이전 페이지
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user