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:
@@ -7,7 +7,7 @@
|
||||
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import { BoardDetail } from '@/components/board/BoardDetail';
|
||||
import { getPost } from '@/components/board/actions';
|
||||
import type { Post, Comment } from '@/components/board/types';
|
||||
@@ -60,11 +60,7 @@ export default function BoardDetailPage() {
|
||||
}, [boardCode, postId, router]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-gray-400" />
|
||||
</div>
|
||||
);
|
||||
return <ContentLoadingSpinner text="게시글을 불러오는 중..." />;
|
||||
}
|
||||
|
||||
if (!post) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { useRouter, useParams } from 'next/navigation';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import { BoardForm } from '@/components/board/BoardManagement/BoardForm';
|
||||
import { getBoardById, updateBoard } from '@/components/board/BoardManagement/actions';
|
||||
import { forceRefreshMenus } from '@/lib/utils/menuRefresh';
|
||||
@@ -64,11 +65,7 @@ export default function BoardEditPage() {
|
||||
|
||||
// 로딩 상태
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
);
|
||||
return <ContentLoadingSpinner text="게시판 정보를 불러오는 중..." />;
|
||||
}
|
||||
|
||||
// 에러 상태
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { useRouter, useParams } from 'next/navigation';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import { BoardDetail } from '@/components/board/BoardManagement/BoardDetail';
|
||||
import { getBoardById, deleteBoard } from '@/components/board/BoardManagement/actions';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@@ -74,11 +75,7 @@ export default function BoardDetailPage() {
|
||||
|
||||
// 로딩 상태
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
);
|
||||
return <ContentLoadingSpinner text="게시판 정보를 불러오는 중..." />;
|
||||
}
|
||||
|
||||
// 에러 상태
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useRouter, useParams } from 'next/navigation';
|
||||
import { ArrowLeft, Save, MessageSquare, Loader2 } from 'lucide-react';
|
||||
import { ArrowLeft, Save, MessageSquare } from 'lucide-react';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import { PageLayout } from '@/components/organisms/PageLayout';
|
||||
import { PageHeader } from '@/components/organisms/PageHeader';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
@@ -146,9 +147,7 @@ export default function DynamicBoardEditPage() {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
<ContentLoadingSpinner text="게시글을 불러오는 중..." />
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useParams, useRouter, useSearchParams } from 'next/navigation';
|
||||
import DynamicItemForm from '@/components/items/DynamicItemForm';
|
||||
import type { DynamicFormData, BOMLine } from '@/components/items/DynamicItemForm/types';
|
||||
import type { ItemType } from '@/types/item';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import {
|
||||
isMaterialType,
|
||||
transformMaterialDataForSave,
|
||||
@@ -391,12 +391,7 @@ export default function EditItemPage() {
|
||||
|
||||
// 로딩 상태
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center py-12 gap-4">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
||||
<p className="text-muted-foreground">품목 정보 로딩 중...</p>
|
||||
</div>
|
||||
);
|
||||
return <ContentLoadingSpinner text="품목 정보를 불러오는 중..." />;
|
||||
}
|
||||
|
||||
// 에러 상태
|
||||
|
||||
@@ -11,7 +11,7 @@ import { useParams, useRouter, useSearchParams } from 'next/navigation';
|
||||
import { notFound } from 'next/navigation';
|
||||
import ItemDetailClient from '@/components/items/ItemDetailClient';
|
||||
import type { ItemMaster, ItemType, ProductCategory, PartType, PartUsage } from '@/types/item';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
|
||||
// Materials 타입 (SM, RM, CS는 Material 테이블 사용)
|
||||
const MATERIAL_TYPES = ['SM', 'RM', 'CS'];
|
||||
@@ -255,12 +255,7 @@ export default function ItemDetailPage() {
|
||||
|
||||
// 로딩 상태
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center py-12 gap-4">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
||||
<p className="text-muted-foreground">품목 정보 로딩 중...</p>
|
||||
</div>
|
||||
);
|
||||
return <ContentLoadingSpinner text="품목 정보를 불러오는 중..." />;
|
||||
}
|
||||
|
||||
// 에러 상태
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
|
||||
import { Suspense } from 'react';
|
||||
import ProductionDashboard from '@/components/production/ProductionDashboard';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
|
||||
export default function ProductionDashboardPage() {
|
||||
return (
|
||||
<Suspense fallback={<div className="text-center py-8">로딩 중...</div>}>
|
||||
<Suspense fallback={<ContentLoadingSpinner text="생산 현황을 불러오는 중..." />}>
|
||||
<ProductionDashboard />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import ItemForm from '@/components/items/ItemForm';
|
||||
import type { ItemMaster } from '@/types/item';
|
||||
import type { CreateItemFormData } from '@/lib/utils/validation';
|
||||
@@ -189,11 +190,7 @@ export default function EditItemPage() {
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<div className="text-center py-8">로딩 중...</div>
|
||||
</div>
|
||||
);
|
||||
return <ContentLoadingSpinner text="품목 정보를 불러오는 중..." />;
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import { use, useEffect, useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
import ItemDetailClient from '@/components/items/ItemDetailClient';
|
||||
import type { ItemMaster } from '@/types/item';
|
||||
|
||||
@@ -159,11 +160,7 @@ export default function ItemDetailPage({
|
||||
}, [id]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<div className="text-muted-foreground">로딩 중...</div>
|
||||
</div>
|
||||
);
|
||||
return <ContentLoadingSpinner text="품목 정보를 불러오는 중..." />;
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
|
||||
import { Suspense } from 'react';
|
||||
import WorkerScreen from '@/components/production/WorkerScreen';
|
||||
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
|
||||
|
||||
export default function WorkerScreenPage() {
|
||||
return (
|
||||
<Suspense fallback={<div className="text-center py-8">로딩 중...</div>}>
|
||||
<Suspense fallback={<ContentLoadingSpinner text="작업자 화면을 불러오는 중..." />}>
|
||||
<WorkerScreen />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
@@ -97,17 +97,17 @@ export function Day1ChecklistPanel({
|
||||
return (
|
||||
<div className="bg-white rounded-lg border border-gray-200 overflow-hidden h-full flex flex-col">
|
||||
{/* 헤더 + 검색 */}
|
||||
<div className="bg-gray-100 px-4 py-3 border-b border-gray-200">
|
||||
<h3 className="font-semibold text-gray-900 mb-2">점검표 항목</h3>
|
||||
<div className="bg-gray-100 px-2 sm:px-4 py-2 sm:py-3 border-b border-gray-200">
|
||||
<h3 className="font-semibold text-gray-900 text-sm sm:text-base mb-2">점검표 항목</h3>
|
||||
{/* 검색 입력 */}
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" />
|
||||
<Search className="absolute left-2 sm:left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="항목 검색..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="w-full pl-9 pr-8 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
className="w-full pl-8 sm:pl-9 pr-8 py-1.5 sm:py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
/>
|
||||
{searchTerm && (
|
||||
<button
|
||||
@@ -121,7 +121,7 @@ export function Day1ChecklistPanel({
|
||||
</div>
|
||||
{/* 검색 결과 카운트 */}
|
||||
{searchTerm && (
|
||||
<div className="mt-2 text-xs text-gray-500">
|
||||
<div className="mt-1.5 sm:mt-2 text-xs text-gray-500">
|
||||
{filteredCategories.length > 0
|
||||
? `${filteredCategories.reduce((sum, cat) => sum + cat.subItems.length, 0)}개 항목 검색됨`
|
||||
: '검색 결과가 없습니다'
|
||||
@@ -151,7 +151,7 @@ export function Day1ChecklistPanel({
|
||||
type="button"
|
||||
onClick={() => toggleCategory(category.id)}
|
||||
className={cn(
|
||||
'w-full flex items-center justify-between px-4 py-3 text-left transition-colors',
|
||||
'w-full flex items-center justify-between px-2 sm:px-4 py-2 sm:py-3 text-left transition-colors',
|
||||
'hover:bg-gray-50',
|
||||
allCompleted && 'bg-green-50'
|
||||
)}
|
||||
@@ -231,7 +231,7 @@ function SubItemRow({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center gap-3 px-4 py-2.5 cursor-pointer transition-colors',
|
||||
'flex items-center gap-2 sm:gap-3 px-2 sm:px-4 py-2 sm:py-2.5 cursor-pointer transition-colors',
|
||||
isSelected
|
||||
? 'bg-blue-100 border-l-4 border-blue-500'
|
||||
: 'hover:bg-gray-100 border-l-4 border-transparent',
|
||||
|
||||
@@ -35,22 +35,22 @@ export function Day1DocumentSection({
|
||||
return (
|
||||
<div className="bg-white rounded-lg border border-gray-200 overflow-hidden h-full flex flex-col">
|
||||
{/* 헤더 */}
|
||||
<div className="bg-gray-100 px-4 py-3 border-b border-gray-200">
|
||||
<h3 className="font-semibold text-gray-900">기준 문서화</h3>
|
||||
<div className="bg-gray-100 px-2 sm:px-4 py-2 sm:py-3 border-b border-gray-200">
|
||||
<h3 className="font-semibold text-gray-900 text-sm sm:text-base">기준 문서화</h3>
|
||||
</div>
|
||||
|
||||
{/* 콘텐츠 */}
|
||||
<div className="flex-1 overflow-y-auto p-4 space-y-4">
|
||||
<div className="flex-1 overflow-y-auto p-3 sm:p-4 space-y-3 sm:space-y-4">
|
||||
{/* 항목 정보 */}
|
||||
<div className="bg-blue-50 rounded-lg p-4">
|
||||
<h4 className="font-medium text-blue-900 mb-2">{checkItem.title}</h4>
|
||||
<p className="text-sm text-blue-700">{checkItem.description}</p>
|
||||
<div className="bg-blue-50 rounded-lg p-3 sm:p-4">
|
||||
<h4 className="font-medium text-blue-900 mb-1 sm:mb-2 text-sm sm:text-base">{checkItem.title}</h4>
|
||||
<p className="text-xs sm:text-sm text-blue-700">{checkItem.description}</p>
|
||||
</div>
|
||||
|
||||
{/* 기준 문서 목록 */}
|
||||
<div>
|
||||
<h5 className="text-sm font-medium text-gray-700 mb-2">관련 기준 문서</h5>
|
||||
<div className="space-y-2">
|
||||
<h5 className="text-xs sm:text-sm font-medium text-gray-700 mb-1.5 sm:mb-2">관련 기준 문서</h5>
|
||||
<div className="space-y-1.5 sm:space-y-2">
|
||||
{checkItem.standardDocuments.map((doc) => (
|
||||
<DocumentRow
|
||||
key={doc.id}
|
||||
@@ -63,7 +63,7 @@ export function Day1DocumentSection({
|
||||
</div>
|
||||
|
||||
{/* 확인 버튼 */}
|
||||
<div className="pt-4 border-t border-gray-200">
|
||||
<div className="pt-3 sm:pt-4 border-t border-gray-200">
|
||||
<Button
|
||||
onClick={onConfirmComplete}
|
||||
disabled={isCompleted}
|
||||
@@ -101,7 +101,7 @@ function DocumentRow({ document, isSelected, onSelect }: DocumentRowProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center gap-3 p-3 rounded-lg border cursor-pointer transition-colors',
|
||||
'flex items-center gap-2 sm:gap-3 p-2 sm:p-3 rounded-lg border cursor-pointer transition-colors',
|
||||
isSelected
|
||||
? 'bg-blue-50 border-blue-300'
|
||||
: 'bg-gray-50 border-gray-200 hover:bg-gray-100'
|
||||
@@ -110,12 +110,12 @@ function DocumentRow({ document, isSelected, onSelect }: DocumentRowProps) {
|
||||
>
|
||||
{/* 아이콘 */}
|
||||
<div className={cn(
|
||||
'flex-shrink-0 w-10 h-10 rounded-lg flex items-center justify-center',
|
||||
'flex-shrink-0 w-8 h-8 sm:w-10 sm:h-10 rounded-lg flex items-center justify-center',
|
||||
document.fileName?.endsWith('.pdf')
|
||||
? 'bg-red-100 text-red-600'
|
||||
: 'bg-green-100 text-green-600'
|
||||
)}>
|
||||
<FileText className="h-5 w-5" />
|
||||
<FileText className="h-4 w-4 sm:h-5 sm:w-5" />
|
||||
</div>
|
||||
|
||||
{/* 문서 정보 */}
|
||||
|
||||
@@ -27,19 +27,19 @@ export function Day1DocumentViewer({ document }: Day1DocumentViewerProps) {
|
||||
return (
|
||||
<div className="bg-white rounded-lg border border-gray-200 overflow-hidden h-full flex flex-col">
|
||||
{/* 헤더 */}
|
||||
<div className="bg-gray-100 px-4 py-3 border-b border-gray-200 flex items-center justify-between">
|
||||
<div className="bg-gray-100 px-2 sm:px-4 py-2 sm:py-3 border-b border-gray-200 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className={cn(
|
||||
'w-8 h-8 rounded flex items-center justify-center',
|
||||
'w-6 h-6 sm:w-8 sm:h-8 rounded flex items-center justify-center',
|
||||
isPdf ? 'bg-red-100 text-red-600' :
|
||||
isExcel ? 'bg-green-100 text-green-600' :
|
||||
'bg-gray-200 text-gray-600'
|
||||
)}>
|
||||
<FileText className="h-4 w-4" />
|
||||
<FileText className="h-3 w-3 sm:h-4 sm:w-4" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-medium text-gray-900 text-sm">{document.title}</h3>
|
||||
<p className="text-xs text-gray-500">
|
||||
<h3 className="font-medium text-gray-900 text-xs sm:text-sm">{document.title}</h3>
|
||||
<p className="text-[10px] sm:text-xs text-gray-500">
|
||||
{document.version !== '-' && <span className="mr-2">{document.version}</span>}
|
||||
{document.date}
|
||||
</p>
|
||||
@@ -47,60 +47,60 @@ export function Day1DocumentViewer({ document }: Day1DocumentViewerProps) {
|
||||
</div>
|
||||
|
||||
{/* 툴바 */}
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex items-center gap-0.5 sm:gap-1">
|
||||
<button
|
||||
type="button"
|
||||
className="p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
className="p-1.5 sm:p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
title="축소"
|
||||
>
|
||||
<ZoomOut className="h-4 w-4" />
|
||||
<ZoomOut className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
className="p-1.5 sm:p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
title="확대"
|
||||
>
|
||||
<ZoomIn className="h-4 w-4" />
|
||||
<ZoomIn className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
className="hidden sm:block p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
title="전체화면"
|
||||
>
|
||||
<Maximize2 className="h-4 w-4" />
|
||||
</button>
|
||||
<div className="w-px h-6 bg-gray-300 mx-1" />
|
||||
<div className="hidden sm:block w-px h-6 bg-gray-300 mx-1" />
|
||||
<button
|
||||
type="button"
|
||||
className="p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
className="hidden sm:block p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
title="인쇄"
|
||||
>
|
||||
<Printer className="h-4 w-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
className="p-1.5 sm:p-2 rounded hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors"
|
||||
title="다운로드"
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
<Download className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 문서 미리보기 영역 */}
|
||||
<div className="flex-1 bg-gray-200 p-4 overflow-auto">
|
||||
<div className="bg-white rounded shadow-lg max-w-3xl mx-auto min-h-[600px]">
|
||||
<div className="flex-1 bg-gray-200 p-2 sm:p-4 overflow-auto">
|
||||
<div className="bg-white rounded shadow-lg max-w-3xl mx-auto min-h-[400px] sm:min-h-[600px]">
|
||||
{/* Mock 문서 내용 */}
|
||||
<DocumentPreviewContent document={document} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 푸터 */}
|
||||
<div className="bg-gray-100 px-4 py-2 border-t border-gray-200 flex items-center justify-between">
|
||||
<span className="text-xs text-gray-500">
|
||||
<div className="bg-gray-100 px-2 sm:px-4 py-1.5 sm:py-2 border-t border-gray-200 flex items-center justify-between">
|
||||
<span className="text-[10px] sm:text-xs text-gray-500 truncate max-w-[60%]">
|
||||
파일명: {document.fileName || '-'}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">
|
||||
<span className="text-[10px] sm:text-xs text-gray-500">
|
||||
1 / 1 페이지
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -25,24 +25,27 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }:
|
||||
: 0;
|
||||
|
||||
return (
|
||||
<div className="mb-4 space-y-3">
|
||||
<div className="mb-3 md:mb-4 space-y-2 md:space-y-3">
|
||||
{/* 탭 버튼 */}
|
||||
<div className="flex gap-3">
|
||||
<div className="flex gap-2 md:gap-3">
|
||||
{/* 1일차 탭 */}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onDayChange(1)}
|
||||
className={cn(
|
||||
'flex-1 flex items-center justify-center gap-2 py-3 px-4 rounded-lg border-2 transition-all',
|
||||
'flex-1 flex items-center justify-center gap-1 sm:gap-2 py-2 sm:py-3 px-2 sm:px-4 rounded-lg border-2 transition-all',
|
||||
activeDay === 1
|
||||
? 'bg-blue-600 border-blue-600 text-white shadow-lg'
|
||||
: 'bg-white border-gray-200 text-gray-700 hover:border-blue-300 hover:bg-blue-50'
|
||||
)}
|
||||
>
|
||||
<Calendar className="h-4 w-4" />
|
||||
<span className="font-medium">1일차: 기준/매뉴얼 심사</span>
|
||||
<Calendar className="h-4 w-4 shrink-0" />
|
||||
<span className="font-medium text-xs sm:text-sm">
|
||||
<span className="hidden sm:inline">1일차: 기준/매뉴얼</span>
|
||||
<span className="sm:hidden">1일차</span>
|
||||
</span>
|
||||
<span className={cn(
|
||||
'text-xs px-2 py-0.5 rounded-full ml-2',
|
||||
'text-[10px] sm:text-xs px-1.5 sm:px-2 py-0.5 rounded-full ml-1 sm:ml-2 shrink-0',
|
||||
activeDay === 1 ? 'bg-blue-500 text-white' : 'bg-gray-100 text-gray-600'
|
||||
)}>
|
||||
{day1Progress.completed}/{day1Progress.total}
|
||||
@@ -54,16 +57,19 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }:
|
||||
type="button"
|
||||
onClick={() => onDayChange(2)}
|
||||
className={cn(
|
||||
'flex-1 flex items-center justify-center gap-2 py-3 px-4 rounded-lg border-2 transition-all',
|
||||
'flex-1 flex items-center justify-center gap-1 sm:gap-2 py-2 sm:py-3 px-2 sm:px-4 rounded-lg border-2 transition-all',
|
||||
activeDay === 2
|
||||
? 'bg-blue-600 border-blue-600 text-white shadow-lg'
|
||||
: 'bg-white border-gray-200 text-gray-700 hover:border-blue-300 hover:bg-blue-50'
|
||||
)}
|
||||
>
|
||||
<Calendar className="h-4 w-4" />
|
||||
<span className="font-medium">2일차: 로트추적 심사</span>
|
||||
<Calendar className="h-4 w-4 shrink-0" />
|
||||
<span className="font-medium text-xs sm:text-sm">
|
||||
<span className="hidden sm:inline">2일차: 로트추적</span>
|
||||
<span className="sm:hidden">2일차</span>
|
||||
</span>
|
||||
<span className={cn(
|
||||
'text-xs px-2 py-0.5 rounded-full ml-2',
|
||||
'text-[10px] sm:text-xs px-1.5 sm:px-2 py-0.5 rounded-full ml-1 sm:ml-2 shrink-0',
|
||||
activeDay === 2 ? 'bg-blue-500 text-white' : 'bg-gray-100 text-gray-600'
|
||||
)}>
|
||||
{day2Progress.completed}/{day2Progress.total}
|
||||
@@ -72,11 +78,14 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }:
|
||||
</div>
|
||||
|
||||
{/* 진행률 - 3줄 표시 */}
|
||||
<div className="bg-white rounded-lg border border-gray-200 px-4 py-3 space-y-2">
|
||||
<div className="bg-white rounded-lg border border-gray-200 px-2 sm:px-4 py-2 sm:py-3 space-y-1.5 sm:space-y-2">
|
||||
{/* 전체 심사 진행률 */}
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm font-medium text-gray-700 w-28 shrink-0">전체 심사</span>
|
||||
<div className="flex-1 h-2.5 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div className="flex items-center gap-2 sm:gap-3">
|
||||
<span className="text-xs sm:text-sm font-medium text-gray-700 w-14 sm:w-28 shrink-0">
|
||||
<span className="hidden sm:inline">전체 심사</span>
|
||||
<span className="sm:hidden">전체</span>
|
||||
</span>
|
||||
<div className="flex-1 h-2 sm:h-2.5 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div
|
||||
className={cn(
|
||||
'h-full rounded-full transition-all duration-500',
|
||||
@@ -86,7 +95,7 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }:
|
||||
/>
|
||||
</div>
|
||||
<span className={cn(
|
||||
'text-sm font-bold w-16 text-right',
|
||||
'text-xs sm:text-sm font-bold w-12 sm:w-16 text-right shrink-0',
|
||||
overallPercentage === 100 ? 'text-green-600' : 'text-blue-600'
|
||||
)}>
|
||||
{totalCompleted}/{totalItems}
|
||||
@@ -94,9 +103,12 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }:
|
||||
</div>
|
||||
|
||||
{/* 1일차 진행률 */}
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm text-gray-600 w-28 shrink-0">1일차: 기준/매뉴얼</span>
|
||||
<div className="flex-1 h-2 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div className="flex items-center gap-2 sm:gap-3">
|
||||
<span className="text-xs sm:text-sm text-gray-600 w-14 sm:w-28 shrink-0">
|
||||
<span className="hidden sm:inline">1일차: 기준/매뉴얼</span>
|
||||
<span className="sm:hidden">1일차</span>
|
||||
</span>
|
||||
<div className="flex-1 h-1.5 sm:h-2 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div
|
||||
className={cn(
|
||||
'h-full rounded-full transition-all duration-500',
|
||||
@@ -106,7 +118,7 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }:
|
||||
/>
|
||||
</div>
|
||||
<span className={cn(
|
||||
'text-sm font-medium w-16 text-right',
|
||||
'text-xs sm:text-sm font-medium w-12 sm:w-16 text-right shrink-0',
|
||||
day1Percentage === 100 ? 'text-green-600' : 'text-gray-600'
|
||||
)}>
|
||||
{day1Progress.completed}/{day1Progress.total}
|
||||
@@ -114,9 +126,12 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }:
|
||||
</div>
|
||||
|
||||
{/* 2일차 진행률 */}
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm text-gray-600 w-28 shrink-0">2일차: 로트추적</span>
|
||||
<div className="flex-1 h-2 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div className="flex items-center gap-2 sm:gap-3">
|
||||
<span className="text-xs sm:text-sm text-gray-600 w-14 sm:w-28 shrink-0">
|
||||
<span className="hidden sm:inline">2일차: 로트추적</span>
|
||||
<span className="sm:hidden">2일차</span>
|
||||
</span>
|
||||
<div className="flex-1 h-1.5 sm:h-2 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div
|
||||
className={cn(
|
||||
'h-full rounded-full transition-all duration-500',
|
||||
@@ -126,7 +141,7 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }:
|
||||
/>
|
||||
</div>
|
||||
<span className={cn(
|
||||
'text-sm font-medium w-16 text-right',
|
||||
'text-xs sm:text-sm font-medium w-12 sm:w-16 text-right shrink-0',
|
||||
day2Percentage === 100 ? 'text-green-600' : 'text-gray-600'
|
||||
)}>
|
||||
{day2Progress.completed}/{day2Progress.total}
|
||||
|
||||
@@ -51,15 +51,15 @@ export const DocumentList = ({ documents, routeCode, onViewDocument }: DocumentL
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg p-4 shadow-sm h-full flex flex-col overflow-hidden">
|
||||
<h2 className="font-bold text-gray-800 text-sm mb-4">
|
||||
<div className="bg-white rounded-lg p-3 sm:p-4 shadow-sm h-full flex flex-col overflow-hidden">
|
||||
<h2 className="font-bold text-gray-800 text-xs sm:text-sm mb-3 sm:mb-4">
|
||||
관련 서류{' '}
|
||||
{routeCode && (
|
||||
<span className="text-gray-400 font-normal ml-1">({routeCode})</span>
|
||||
)}
|
||||
</h2>
|
||||
|
||||
<div className="space-y-3 overflow-y-auto flex-1">
|
||||
<div className="space-y-2 sm:space-y-3 overflow-y-auto flex-1">
|
||||
{!routeCode ? (
|
||||
<div className="flex items-center justify-center h-32 text-gray-400 text-sm">
|
||||
수주루트를 선택해주세요.
|
||||
@@ -74,7 +74,7 @@ export const DocumentList = ({ documents, routeCode, onViewDocument }: DocumentL
|
||||
<div key={doc.id} className="border border-gray-200 rounded-lg overflow-hidden">
|
||||
<div
|
||||
onClick={() => handleDocClick(doc)}
|
||||
className={`p-4 flex justify-between items-center transition-colors ${
|
||||
className={`p-3 sm:p-4 flex justify-between items-center transition-colors ${
|
||||
hasItems ? 'cursor-pointer hover:bg-gray-50' : 'cursor-default opacity-60'
|
||||
} ${isExpanded ? 'bg-green-50' : 'bg-white'}`}
|
||||
>
|
||||
@@ -99,13 +99,13 @@ export const DocumentList = ({ documents, routeCode, onViewDocument }: DocumentL
|
||||
</div>
|
||||
|
||||
{isExpanded && hasMultipleItems && (
|
||||
<div className="bg-white px-4 pb-4 space-y-2">
|
||||
<div className="h-px bg-gray-100 w-full mb-3" />
|
||||
<div className="bg-white px-3 sm:px-4 pb-3 sm:pb-4 space-y-1.5 sm:space-y-2">
|
||||
<div className="h-px bg-gray-100 w-full mb-2 sm:mb-3" />
|
||||
{doc.items!.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
onClick={() => handleItemClick(doc, item)}
|
||||
className="flex items-center justify-between border border-gray-100 p-3 rounded cursor-pointer hover:bg-green-50 hover:border-green-200 transition-colors group"
|
||||
className="flex items-center justify-between border border-gray-100 p-2 sm:p-3 rounded cursor-pointer hover:bg-green-50 hover:border-green-200 transition-colors group"
|
||||
>
|
||||
<div>
|
||||
<div className="text-xs font-bold text-gray-700">{item.title}</div>
|
||||
|
||||
@@ -24,13 +24,13 @@ export const Filters = ({
|
||||
const years = [2025, 2024, 2023, 2022, 2021];
|
||||
|
||||
return (
|
||||
<div className="w-full bg-white p-4 rounded-lg mb-4 shadow-sm">
|
||||
<div className="w-full bg-white p-3 sm:p-4 rounded-lg mb-3 sm:mb-4 shadow-sm">
|
||||
{/* 상단: 년도/분기 선택 */}
|
||||
<div className="flex flex-wrap items-end gap-4 mb-4">
|
||||
<div className="flex flex-wrap items-end gap-3 sm:gap-4 mb-3 sm:mb-4">
|
||||
{/* Year Selection */}
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="text-xs font-semibold text-gray-500">년도</span>
|
||||
<div className="w-32">
|
||||
<div className="w-28 sm:w-32">
|
||||
<select
|
||||
value={selectedYear}
|
||||
onChange={(e) => onYearChange(parseInt(e.target.value))}
|
||||
@@ -78,7 +78,7 @@ export const Filters = ({
|
||||
className="w-full pl-10 pr-4 py-2 border border-gray-200 rounded-md text-sm focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500"
|
||||
/>
|
||||
</div>
|
||||
<button className="bg-[#1e3a8a] text-white px-6 py-2 rounded-md text-sm hover:bg-blue-800 transition-colors whitespace-nowrap">
|
||||
<button className="bg-[#1e3a8a] text-white px-4 sm:px-6 py-2 rounded-md text-sm hover:bg-blue-800 transition-colors whitespace-nowrap">
|
||||
조회
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -6,10 +6,10 @@ interface HeaderProps {
|
||||
|
||||
export const Header = ({ rightContent }: HeaderProps) => {
|
||||
return (
|
||||
<div className="w-full bg-[#1e3a8a] text-white p-6 rounded-lg mb-4 shadow-md flex items-center justify-between h-24">
|
||||
<div className="w-full bg-[#1e3a8a] text-white p-3 sm:p-6 rounded-lg mb-3 sm:mb-4 shadow-md flex items-center justify-between h-16 sm:h-24">
|
||||
<div className="flex flex-col justify-center">
|
||||
<h1 className="text-2xl font-bold mb-1">품질인정심사 시스템</h1>
|
||||
<p className="text-sm opacity-80 text-blue-100">SAM - Smart Automation Management</p>
|
||||
<h1 className="text-lg sm:text-2xl font-bold mb-0.5 sm:mb-1">품질인정심사 시스템</h1>
|
||||
<p className="text-xs sm:text-sm opacity-80 text-blue-100">SAM - Smart Automation Management</p>
|
||||
</div>
|
||||
{rightContent && (
|
||||
<div className="flex items-center">
|
||||
|
||||
@@ -12,15 +12,15 @@ interface ReportListProps {
|
||||
|
||||
export const ReportList = ({ reports, selectedId, onSelect }: ReportListProps) => {
|
||||
return (
|
||||
<div className="bg-white rounded-lg p-4 shadow-sm h-full flex flex-col">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="font-bold text-lg text-gray-800">품질관리서 목록</h2>
|
||||
<span className="bg-blue-100 text-blue-800 text-xs font-bold px-2 py-1 rounded-full">
|
||||
<div className="bg-white rounded-lg p-3 sm:p-4 shadow-sm h-full flex flex-col">
|
||||
<div className="flex items-center justify-between mb-3 sm:mb-4">
|
||||
<h2 className="font-bold text-sm sm:text-lg text-gray-800">품질관리서 목록</h2>
|
||||
<span className="bg-blue-100 text-blue-800 text-[10px] sm:text-xs font-bold px-1.5 sm:px-2 py-0.5 sm:py-1 rounded-full">
|
||||
{reports.length}건
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3 overflow-y-auto flex-1">
|
||||
<div className="space-y-2 sm:space-y-3 overflow-y-auto flex-1">
|
||||
{reports.length === 0 ? (
|
||||
<div className="flex items-center justify-center h-32 text-gray-400 text-sm">
|
||||
해당 조건의 품질관리서가 없습니다.
|
||||
@@ -32,23 +32,23 @@ export const ReportList = ({ reports, selectedId, onSelect }: ReportListProps) =
|
||||
<div
|
||||
key={report.id}
|
||||
onClick={() => onSelect(report)}
|
||||
className={`rounded-lg p-4 cursor-pointer relative hover:shadow-md transition-all ${
|
||||
className={`rounded-lg p-3 sm:p-4 cursor-pointer relative hover:shadow-md transition-all ${
|
||||
isSelected
|
||||
? 'border-2 border-blue-500 bg-blue-50'
|
||||
: 'border border-gray-200 bg-white hover:border-blue-300'
|
||||
}`}
|
||||
>
|
||||
<div className="absolute top-4 right-4 text-xs text-gray-400 bg-gray-100 px-2 py-1 rounded">
|
||||
<div className="absolute top-3 sm:top-4 right-3 sm:right-4 text-[10px] sm:text-xs text-gray-400 bg-gray-100 px-1.5 sm:px-2 py-0.5 sm:py-1 rounded">
|
||||
{report.quarter}
|
||||
</div>
|
||||
|
||||
<h3 className={`font-bold text-lg mb-1 ${isSelected ? 'text-blue-900' : 'text-gray-800'}`}>
|
||||
<h3 className={`font-bold text-sm sm:text-lg mb-1 ${isSelected ? 'text-blue-900' : 'text-gray-800'}`}>
|
||||
{report.code}
|
||||
</h3>
|
||||
<p className="text-gray-700 font-medium mb-1">{report.siteName}</p>
|
||||
<p className="text-sm text-gray-500 mb-3">인정품목: {report.item}</p>
|
||||
<p className="text-xs sm:text-base text-gray-700 font-medium mb-1">{report.siteName}</p>
|
||||
<p className="text-xs sm:text-sm text-gray-500 mb-2 sm:mb-3">인정품목: {report.item}</p>
|
||||
|
||||
<div className={`flex items-center gap-2 p-2 rounded text-sm font-medium ${
|
||||
<div className={`flex items-center gap-1.5 sm:gap-2 p-1.5 sm:p-2 rounded text-xs sm:text-sm font-medium ${
|
||||
isSelected ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 text-gray-600'
|
||||
}`}>
|
||||
<Package size={16} />
|
||||
|
||||
@@ -27,15 +27,15 @@ export const RouteList = ({ routes, selectedId, onSelect, onToggleItem, reportCo
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg p-4 shadow-sm h-full flex flex-col overflow-hidden">
|
||||
<h2 className="font-bold text-gray-800 text-sm mb-4">
|
||||
<div className="bg-white rounded-lg p-3 sm:p-4 shadow-sm h-full flex flex-col overflow-hidden">
|
||||
<h2 className="font-bold text-gray-800 text-xs sm:text-sm mb-3 sm:mb-4">
|
||||
수주루트 목록{' '}
|
||||
{reportCode && (
|
||||
<span className="text-gray-400 font-normal ml-1">({reportCode})</span>
|
||||
)}
|
||||
</h2>
|
||||
|
||||
<div className="space-y-3 overflow-y-auto flex-1">
|
||||
<div className="space-y-2 sm:space-y-3 overflow-y-auto flex-1">
|
||||
{routes.length === 0 ? (
|
||||
<div className="flex items-center justify-center h-32 text-gray-400 text-sm">
|
||||
{reportCode ? '수주루트가 없습니다.' : '품질관리서를 선택해주세요.'}
|
||||
@@ -51,7 +51,7 @@ export const RouteList = ({ routes, selectedId, onSelect, onToggleItem, reportCo
|
||||
<div key={route.id} className="border border-gray-200 rounded-lg overflow-hidden">
|
||||
<div
|
||||
onClick={() => handleClick(route)}
|
||||
className={`p-4 cursor-pointer flex justify-between items-start transition-colors ${
|
||||
className={`p-3 sm:p-4 cursor-pointer flex justify-between items-start transition-colors ${
|
||||
isSelected ? 'bg-green-50 border-b border-green-100' : 'bg-white hover:bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
@@ -87,8 +87,8 @@ export const RouteList = ({ routes, selectedId, onSelect, onToggleItem, reportCo
|
||||
</div>
|
||||
|
||||
{isExpanded && route.subItems.length > 0 && (
|
||||
<div className="bg-white p-3 space-y-2">
|
||||
<div className="text-xs font-bold text-gray-600 mb-2 flex items-center gap-1">
|
||||
<div className="bg-white p-2 sm:p-3 space-y-1.5 sm:space-y-2">
|
||||
<div className="text-xs font-bold text-gray-600 mb-1.5 sm:mb-2 flex items-center gap-1">
|
||||
<MapPin size={10} /> 개소별 제품로트
|
||||
</div>
|
||||
{route.subItems.map((item) => (
|
||||
|
||||
@@ -228,7 +228,7 @@ export default function QualityInspectionPage() {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="w-full min-h-[calc(100vh-64px)] lg:h-[calc(100vh-64px)] p-6 bg-slate-100 flex flex-col lg:overflow-hidden">
|
||||
<div className="w-full min-h-[calc(100vh-64px)] lg:h-[calc(100vh-64px)] p-3 sm:p-4 md:p-5 lg:p-6 bg-slate-100 flex flex-col lg:overflow-hidden">
|
||||
{/* 헤더 (설정 버튼 포함) */}
|
||||
<Header
|
||||
rightContent={<SettingsButton onClick={() => setSettingsOpen(true)} />}
|
||||
@@ -272,9 +272,9 @@ export default function QualityInspectionPage() {
|
||||
|
||||
{activeDay === 1 ? (
|
||||
// ===== 1일차: 기준/매뉴얼 심사 =====
|
||||
<div className="flex-1 grid grid-cols-12 gap-4 lg:min-h-0">
|
||||
<div className="flex-1 grid grid-cols-12 gap-3 sm:gap-4 lg:min-h-0">
|
||||
{/* 좌측: 점검표 항목 */}
|
||||
<div className={`col-span-12 min-h-[300px] lg:min-h-0 lg:h-full overflow-auto ${
|
||||
<div className={`col-span-12 min-h-[250px] sm:min-h-[300px] lg:min-h-0 lg:h-full overflow-auto ${
|
||||
displaySettings.showDocumentSection && displaySettings.showDocumentViewer
|
||||
? 'lg:col-span-3'
|
||||
: displaySettings.showDocumentSection || displaySettings.showDocumentViewer
|
||||
@@ -291,7 +291,7 @@ export default function QualityInspectionPage() {
|
||||
|
||||
{/* 중앙: 기준 문서화 */}
|
||||
{displaySettings.showDocumentSection && (
|
||||
<div className={`col-span-12 min-h-[250px] lg:min-h-0 lg:h-full overflow-auto ${
|
||||
<div className={`col-span-12 min-h-[200px] sm:min-h-[250px] lg:min-h-0 lg:h-full overflow-auto ${
|
||||
displaySettings.showDocumentViewer ? 'lg:col-span-4' : 'lg:col-span-8'
|
||||
}`}>
|
||||
<Day1DocumentSection
|
||||
@@ -306,7 +306,7 @@ export default function QualityInspectionPage() {
|
||||
|
||||
{/* 우측: 문서 뷰어 */}
|
||||
{displaySettings.showDocumentViewer && (
|
||||
<div className={`col-span-12 min-h-[250px] lg:min-h-0 lg:h-full overflow-auto ${
|
||||
<div className={`col-span-12 min-h-[200px] sm:min-h-[250px] lg:min-h-0 lg:h-full overflow-auto ${
|
||||
displaySettings.showDocumentSection ? 'lg:col-span-5' : 'lg:col-span-8'
|
||||
}`}>
|
||||
<Day1DocumentViewer document={selectedStandardDoc} />
|
||||
@@ -325,8 +325,8 @@ export default function QualityInspectionPage() {
|
||||
onSearchChange={handleSearchChange}
|
||||
/>
|
||||
|
||||
<div className="flex-1 grid grid-cols-12 gap-6 lg:min-h-0">
|
||||
<div className="col-span-12 lg:col-span-3 min-h-[300px] lg:min-h-0 lg:h-full overflow-auto lg:overflow-hidden">
|
||||
<div className="flex-1 grid grid-cols-12 gap-3 sm:gap-4 lg:gap-6 lg:min-h-0">
|
||||
<div className="col-span-12 lg:col-span-3 min-h-[250px] sm:min-h-[300px] lg:min-h-0 lg:h-full overflow-auto lg:overflow-hidden">
|
||||
<ReportList
|
||||
reports={filteredReports}
|
||||
selectedId={selectedReport?.id || null}
|
||||
@@ -334,7 +334,7 @@ export default function QualityInspectionPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="col-span-12 lg:col-span-4 min-h-[250px] lg:min-h-0 lg:h-full overflow-auto lg:overflow-hidden">
|
||||
<div className="col-span-12 lg:col-span-4 min-h-[200px] sm:min-h-[250px] lg:min-h-0 lg:h-full overflow-auto lg:overflow-hidden">
|
||||
<RouteList
|
||||
routes={currentRoutes}
|
||||
selectedId={selectedRoute?.id || null}
|
||||
@@ -344,7 +344,7 @@ export default function QualityInspectionPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="col-span-12 lg:col-span-5 min-h-[250px] lg:min-h-0 lg:h-full overflow-auto lg:overflow-hidden">
|
||||
<div className="col-span-12 lg:col-span-5 min-h-[200px] sm:min-h-[250px] lg:min-h-0 lg:h-full overflow-auto lg:overflow-hidden">
|
||||
<DocumentList
|
||||
documents={currentDocuments}
|
||||
routeCode={selectedRoute?.code || null}
|
||||
|
||||
Reference in New Issue
Block a user