feat(WEB): 리스트 페이지 UI 레이아웃 표준화
- 공통 레이아웃 패턴 적용: [달력] → [프리셋] → [검색창] → [버튼들] - beforeTableContent → headerActions + createButton 마이그레이션 - DateRangeSelector extraActions prop 활용하여 검색창 통합 - PricingListClient 테이블 행 클릭 → 상세 이동 기능 추가 - 회계 관련 페이지 (입금/출금/매입/매출/어음/카드/예상지출 등) 정리 - 건설 관련 페이지 검색 영역 정리 - 부모 메뉴 리다이렉트 컴포넌트 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,8 @@ export default function BiddingListClient({ initialData = [], initialStats }: Bi
|
||||
// 날짜 범위
|
||||
const [startDate, setStartDate] = useState('');
|
||||
const [endDate, setEndDate] = useState('');
|
||||
// 검색어
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
// Stats 데이터
|
||||
const [stats, setStats] = useState<BiddingStats | null>(initialStats || null);
|
||||
|
||||
@@ -220,6 +222,7 @@ export default function BiddingListClient({ initialData = [], initialStats }: Bi
|
||||
|
||||
// 커스텀 필터 함수 (activeStatTab + filterValues 기반)
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'waiting' && item.status !== 'waiting') return false;
|
||||
@@ -291,6 +294,11 @@ export default function BiddingListClient({ initialData = [], initialStats }: Bi
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션: 날짜 선택기
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -410,8 +418,8 @@ export default function BiddingListClient({ initialData = [], initialStats }: Bi
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
[startDate, endDate, searchQuery, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ export default function ContractListClient({ initialData = [], initialStats }: C
|
||||
const [activeStatTab, setActiveStatTab] = useState<'all' | 'pending' | 'completed'>('all');
|
||||
const [startDate, setStartDate] = useState('');
|
||||
const [endDate, setEndDate] = useState('');
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [stats, setStats] = useState<ContractStats | null>(initialStats || null);
|
||||
|
||||
// Stats 로드
|
||||
@@ -235,6 +236,7 @@ export default function ContractListClient({ initialData = [], initialStats }: C
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'pending' && item.status !== 'pending') return false;
|
||||
@@ -304,6 +306,11 @@ export default function ContractListClient({ initialData = [], initialStats }: C
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -433,8 +440,8 @@ export default function ContractListClient({ initialData = [], initialStats }: C
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
[startDate, endDate, searchQuery, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ export default function EstimateListClient({ initialData = [], initialStats }: E
|
||||
// 날짜 범위
|
||||
const [startDate, setStartDate] = useState('');
|
||||
const [endDate, setEndDate] = useState('');
|
||||
// 검색어
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
// Stats 데이터
|
||||
const [stats, setStats] = useState<EstimateStats | null>(initialStats || null);
|
||||
// 필터 옵션 데이터
|
||||
@@ -210,6 +212,7 @@ export default function EstimateListClient({ initialData = [], initialStats }: E
|
||||
|
||||
// 커스텀 필터 함수 (activeStatTab + filterValues 기반)
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'pending' && item.status !== 'pending') return false;
|
||||
@@ -274,6 +277,11 @@ export default function EstimateListClient({ initialData = [], initialStats }: E
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션: 날짜 선택기
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -389,8 +397,8 @@ export default function EstimateListClient({ initialData = [], initialStats }: E
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, partnerOptions, estimatorOptions, handleRowClick, handleEdit]
|
||||
[startDate, endDate, searchQuery, activeStatTab, stats, partnerOptions, estimatorOptions, handleRowClick, handleEdit]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
@@ -113,6 +113,7 @@ export default function HandoverReportListClient({
|
||||
const [activeStatTab, setActiveStatTab] = useState<'all' | 'pending' | 'completed'>('all');
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [stats, setStats] = useState<HandoverReportStats | null>(initialStats || null);
|
||||
|
||||
// Stats 로드
|
||||
@@ -234,6 +235,7 @@ export default function HandoverReportListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'pending' && item.status !== 'pending') return false;
|
||||
@@ -297,6 +299,11 @@ export default function HandoverReportListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -410,8 +417,8 @@ export default function HandoverReportListClient({
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
[startDate, endDate, searchQuery, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
@@ -89,6 +89,7 @@ export default function IssueManagementListClient({
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [stats, setStats] = useState<IssueStats | null>(initialStats || null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [withdrawDialogOpen, setWithdrawDialogOpen] = useState(false);
|
||||
const [itemsToWithdraw, setItemsToWithdraw] = useState<Set<string>>(new Set());
|
||||
const [clearSelectionFn, setClearSelectionFn] = useState<(() => void) | null>(null);
|
||||
@@ -271,6 +272,7 @@ export default function IssueManagementListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab !== 'all' && item.status !== activeStatTab) return false;
|
||||
@@ -346,6 +348,11 @@ export default function IssueManagementListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -494,12 +501,12 @@ export default function IssueManagementListClient({
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit, handleCreate, handleWithdrawClick]
|
||||
[startDate, endDate, searchQuery, activeStatTab, stats, handleRowClick, handleEdit, handleCreate, handleWithdrawClick]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<UniversalListPage config={config} initialData={initialData} />
|
||||
<UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />
|
||||
|
||||
{/* 철회 확인 다이얼로그 */}
|
||||
<ConfirmDialog
|
||||
|
||||
@@ -555,6 +555,7 @@ export default function ItemManagementClient({
|
||||
onStartDateChange: setStartDate,
|
||||
onEndDateChange: setEndDate,
|
||||
},
|
||||
hideSearch: true,
|
||||
|
||||
// 등록 버튼
|
||||
createButton: {
|
||||
|
||||
@@ -59,6 +59,7 @@ export default function LaborManagementClient({
|
||||
const [startDate, setStartDate] = useState(format(startOfYear(today), 'yyyy-MM-dd'));
|
||||
const [endDate, setEndDate] = useState(format(endOfYear(today), 'yyyy-MM-dd'));
|
||||
const [stats, setStats] = useState<LaborStats>(initialStats ?? { total: 0, active: 0 });
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// Stats 로드
|
||||
useEffect(() => {
|
||||
@@ -211,6 +212,7 @@ export default function LaborManagementClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// 구분 필터
|
||||
const categoryFilter = filterValues.category as string;
|
||||
@@ -242,6 +244,11 @@ export default function LaborManagementClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -361,6 +368,7 @@ export default function LaborManagementClient({
|
||||
[
|
||||
startDate,
|
||||
endDate,
|
||||
searchQuery,
|
||||
stats,
|
||||
handleRowClick,
|
||||
handleEdit,
|
||||
@@ -371,5 +379,5 @@ export default function LaborManagementClient({
|
||||
]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
@@ -82,6 +82,7 @@ export default function ConstructionManagementListClient({
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [stats, setStats] = useState<ConstructionManagementStats | null>(initialStats || null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// 달력 관련 상태
|
||||
const [selectedCalendarDate, setSelectedCalendarDate] = useState<Date | null>(null);
|
||||
@@ -289,6 +290,7 @@ export default function ConstructionManagementListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'in_progress' && item.status !== 'in_progress') return false;
|
||||
@@ -379,6 +381,11 @@ export default function ConstructionManagementListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -530,6 +537,7 @@ export default function ConstructionManagementListClient({
|
||||
[
|
||||
startDate,
|
||||
endDate,
|
||||
searchQuery,
|
||||
activeStatTab,
|
||||
stats,
|
||||
selectedCalendarDate,
|
||||
@@ -550,5 +558,5 @@ export default function ConstructionManagementListClient({
|
||||
]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
@@ -104,12 +104,23 @@ export default function ProjectDetailClient({ projectId }: ProjectDetailClientPr
|
||||
icon={FolderKanban}
|
||||
/>
|
||||
|
||||
{/* 기간 선택 (달력 + 프리셋 버튼) */}
|
||||
{/* 기간 선택 + 검색 영역 */}
|
||||
<DateRangeSelector
|
||||
startDate={filterStartDate}
|
||||
endDate={filterEndDate}
|
||||
onStartDateChange={setFilterStartDate}
|
||||
onEndDateChange={setFilterEndDate}
|
||||
extraActions={
|
||||
<div className="relative w-full sm:w-[300px]">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder="프로젝트 검색 (현장명, 거래처, 계약번호)"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-10"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
||||
{/* 상태 카드 */}
|
||||
@@ -155,17 +166,6 @@ export default function ProjectDetailClient({ projectId }: ProjectDetailClientPr
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 검색 영역 */}
|
||||
<div className="relative max-w-md">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder="프로젝트 검색 (현장명, 거래처, 계약번호)"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-10"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 칸반 보드 */}
|
||||
<Card>
|
||||
<CardContent className="p-4 min-h-[600px]">
|
||||
|
||||
@@ -89,6 +89,7 @@ export default function OrderManagementListClient({
|
||||
// ===== 외부 상태 (UniversalListPage 외부에서 관리) =====
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// 달력 관련 상태
|
||||
const [selectedCalendarDate, setSelectedCalendarDate] = useState<Date | null>(null);
|
||||
@@ -304,6 +305,7 @@ export default function OrderManagementListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// 거래처 필터 (다중선택)
|
||||
const partnerFilters = filterValues.partners as string[];
|
||||
@@ -423,6 +425,11 @@ export default function OrderManagementListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -584,6 +591,7 @@ export default function OrderManagementListClient({
|
||||
[
|
||||
startDate,
|
||||
endDate,
|
||||
searchQuery,
|
||||
selectedCalendarDate,
|
||||
calendarEvents,
|
||||
calendarBadges,
|
||||
@@ -606,5 +614,5 @@ export default function OrderManagementListClient({
|
||||
]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
@@ -188,6 +188,7 @@ export default function PartnerListClient({ initialData = [], initialStats }: Pa
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// 악성채권 필터
|
||||
const badDebtFilter = filterValues.badDebt as string;
|
||||
|
||||
@@ -75,6 +75,7 @@ export default function ProgressBillingManagementListClient({
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [stats, setStats] = useState<ProgressBillingStats | null>(initialStats || null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// Stats 로드
|
||||
useEffect(() => {
|
||||
@@ -188,6 +189,7 @@ export default function ProgressBillingManagementListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'contractWaiting' &&
|
||||
@@ -239,6 +241,11 @@ export default function ProgressBillingManagementListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -350,8 +357,8 @@ export default function ProgressBillingManagementListClient({
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
[startDate, endDate, searchQuery, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ export default function SiteBriefingListClient({ initialData = [] }: SiteBriefin
|
||||
// 날짜 범위
|
||||
const [startDate, setStartDate] = useState('');
|
||||
const [endDate, setEndDate] = useState('');
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// ===== 핸들러 =====
|
||||
const handleRowClick = useCallback(
|
||||
@@ -187,6 +188,7 @@ export default function SiteBriefingListClient({ initialData = [] }: SiteBriefin
|
||||
|
||||
// 커스텀 필터 함수 (activeStatTab 필터링 포함)
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'scheduled' && item.attendanceStatus !== 'scheduled') return false;
|
||||
@@ -216,6 +218,11 @@ export default function SiteBriefingListClient({ initialData = [] }: SiteBriefin
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 날짜 범위 선택기
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -350,8 +357,8 @@ export default function SiteBriefingListClient({ initialData = [] }: SiteBriefin
|
||||
);
|
||||
},
|
||||
}),
|
||||
[handleRowClick, handleEdit, handleCreate, activeStatTab, startDate, endDate]
|
||||
[handleRowClick, handleEdit, handleCreate, activeStatTab, startDate, endDate, searchQuery]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ export default function SiteManagementListClient({
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [stats, setStats] = useState<SiteStats | null>(initialStats || null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// Stats 로드
|
||||
useEffect(() => {
|
||||
@@ -183,6 +184,7 @@ export default function SiteManagementListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'construction' && item.status !== 'active') return false;
|
||||
@@ -228,6 +230,11 @@ export default function SiteManagementListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -337,8 +344,8 @@ export default function SiteManagementListClient({
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit]
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit, searchQuery]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ export default function StructureReviewListClient({
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [stats, setStats] = useState<StructureReviewStats | null>(initialStats || null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// Stats 로드
|
||||
useEffect(() => {
|
||||
@@ -201,6 +202,7 @@ export default function StructureReviewListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'pending' && item.status !== 'pending') return false;
|
||||
@@ -246,6 +248,11 @@ export default function StructureReviewListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -376,8 +383,8 @@ export default function StructureReviewListClient({
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit, handleCreate]
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleEdit, handleCreate, searchQuery]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ export default function UtilityManagementListClient({
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [stats, setStats] = useState<UtilityStats | null>(initialStats || null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// Stats 로드
|
||||
useEffect(() => {
|
||||
@@ -212,6 +213,7 @@ export default function UtilityManagementListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터
|
||||
if (activeStatTab === 'waiting' && item.status !== 'scheduled' && item.status !== 'issued') return false;
|
||||
@@ -279,6 +281,11 @@ export default function UtilityManagementListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -389,8 +396,8 @@ export default function UtilityManagementListClient({
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats]
|
||||
[startDate, endDate, activeStatTab, stats, searchQuery]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ export default function WorkerStatusListClient({
|
||||
const [startDate, setStartDate] = useState<string>('');
|
||||
const [endDate, setEndDate] = useState<string>('');
|
||||
const [stats, setStats] = useState<WorkerStatusStats | null>(initialStats || null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
// Stats 로드
|
||||
useEffect(() => {
|
||||
@@ -220,6 +221,7 @@ export default function WorkerStatusListClient({
|
||||
|
||||
// 커스텀 필터 함수
|
||||
customFilterFn: (items, filterValues) => {
|
||||
if (!items || items.length === 0) return items;
|
||||
return items.filter((item) => {
|
||||
// Stats 탭 필터 (계약상태)
|
||||
if (activeStatTab !== 'all' && item.contractStatus !== activeStatTab) return false;
|
||||
@@ -300,6 +302,11 @@ export default function WorkerStatusListClient({
|
||||
return sorted;
|
||||
},
|
||||
|
||||
// 검색창 (공통 컴포넌트에서 자동 생성)
|
||||
hideSearch: true,
|
||||
searchValue: searchQuery,
|
||||
onSearchChange: setSearchQuery,
|
||||
|
||||
// 공통 헤더 옵션
|
||||
dateRangeSelector: {
|
||||
enabled: true,
|
||||
@@ -415,8 +422,8 @@ export default function WorkerStatusListClient({
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleViewDetail]
|
||||
[startDate, endDate, activeStatTab, stats, handleRowClick, handleViewDetail, searchQuery]
|
||||
);
|
||||
|
||||
return <UniversalListPage config={config} initialData={initialData} />;
|
||||
return <UniversalListPage config={config} initialData={initialData} onSearchChange={setSearchQuery} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user