fix(WEB): 토큰 만료 시 무한 로딩 대신 로그인 리다이렉트 처리
- 52개 이상의 컴포넌트에 isNextRedirectError 처리 추가 - Server Action의 redirect() 에러가 catch 블록에서 삼켜지는 문제 해결 - access_token + refresh_token 모두 만료 시 정상적으로 로그인 페이지로 리다이렉트 수정된 영역: - accounting: 10개 컴포넌트 - production: 12개 컴포넌트 - hr: 5개 컴포넌트 - settings: 8개 컴포넌트 - approval: 5개 컴포넌트 - items: 20개+ 컴포넌트 - board: 5개 컴포넌트 - quality: 4개 컴포넌트 - material, outbound, quotes 등 기타 컴포넌트 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@ import { Alert, AlertDescription } from '@/components/ui/alert';
|
||||
import { PageLayout } from '@/components/organisms/PageLayout';
|
||||
import { toast } from 'sonner';
|
||||
import { createInspection } from './actions';
|
||||
import { isNextRedirectError } from '@/lib/utils/redirect-error';
|
||||
import { inspectionItemsTemplate, judgeMeasurement } from './mockData';
|
||||
import type { InspectionItem, QualityCheckItem, MeasurementItem } from './types';
|
||||
|
||||
@@ -147,6 +148,7 @@ export function InspectionCreate() {
|
||||
toast.error(result.error || '검사 등록에 실패했습니다.');
|
||||
}
|
||||
} catch (error) {
|
||||
if (isNextRedirectError(error)) throw error;
|
||||
console.error('[InspectionCreate] handleSubmit error:', error);
|
||||
toast.error('검사 등록 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { ClipboardCheck, Printer, Paperclip, Loader2 } from 'lucide-react';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
@@ -27,6 +28,7 @@ import {
|
||||
import { PageLayout } from '@/components/organisms/PageLayout';
|
||||
import { toast } from 'sonner';
|
||||
import { getInspectionById, updateInspection } from './actions';
|
||||
import { isNextRedirectError } from '@/lib/utils/redirect-error';
|
||||
import { judgmentColorMap, judgeMeasurement } from './mockData';
|
||||
import type { Inspection, InspectionItem, QualityCheckItem, MeasurementItem } from './types';
|
||||
|
||||
@@ -63,6 +65,7 @@ export function InspectionDetail({ id }: InspectionDetailProps) {
|
||||
toast.error(result.error || '검사 데이터를 불러오는데 실패했습니다.');
|
||||
}
|
||||
} catch (error) {
|
||||
if (isNextRedirectError(error)) throw error;
|
||||
console.error('[InspectionDetail] loadInspection error:', error);
|
||||
toast.error('검사 데이터 로드 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
@@ -173,6 +176,7 @@ export function InspectionDetail({ id }: InspectionDetailProps) {
|
||||
toast.error(result.error || '검사 수정에 실패했습니다.');
|
||||
}
|
||||
} catch (error) {
|
||||
if (isNextRedirectError(error)) throw error;
|
||||
console.error('[InspectionDetail] handleSubmitEdit error:', error);
|
||||
toast.error('검사 수정 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
@@ -199,9 +203,7 @@ export function InspectionDetail({ id }: InspectionDetailProps) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
<ContentLoadingSpinner text="검사 정보를 불러오는 중..." />
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Plus, ClipboardCheck, Clock, PlayCircle, CheckCircle2, AlertTriangle, Loader2 } from 'lucide-react';
|
||||
import { Plus, ClipboardCheck, Clock, PlayCircle, CheckCircle2, AlertTriangle } from 'lucide-react';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { TableCell, TableRow } from '@/components/ui/table';
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
import { ListMobileCard, InfoField } from '@/components/organisms/ListMobileCard';
|
||||
import { toast } from 'sonner';
|
||||
import { getInspections, getInspectionStats } from './actions';
|
||||
import { isNextRedirectError } from '@/lib/utils/redirect-error';
|
||||
import { statusColorMap, inspectionTypeLabels } from './mockData';
|
||||
import type { Inspection, InspectionStatus, InspectionStats } from './types';
|
||||
|
||||
@@ -77,6 +79,7 @@ export function InspectionList() {
|
||||
setStatsData(statsResult.data);
|
||||
}
|
||||
} catch (error) {
|
||||
if (isNextRedirectError(error)) throw error;
|
||||
console.error('[InspectionList] loadData error:', error);
|
||||
toast.error('데이터 로드 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
@@ -273,11 +276,7 @@ export function InspectionList() {
|
||||
|
||||
// 로딩 상태
|
||||
if (isLoading && inspections.length === 0) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-16">
|
||||
<Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
);
|
||||
return <ContentLoadingSpinner text="검사 목록을 불러오는 중..." />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user