table search no submission found solved

This commit is contained in:
Senthamilselvi 2025-11-06 13:57:06 +05:30
parent 6813f23c42
commit 83361a76e0
2 changed files with 123 additions and 109 deletions

View File

@ -100,15 +100,13 @@ export const SubmissionHistory = ({ history = [], loading = false, error = '' })
}, [history]); }, [history]);
const filtered = normalizedHistory.filter((entry) => { const filtered = normalizedHistory.filter((entry) => {
const term = searchTerm.trim().toLowerCase(); const term = searchTerm.trim().toLowerCase().replace(/\s+/g, '');
return ( if (!term) return true;
!term ||
entry.survey_name.toLowerCase().includes(term) || return Object.values(entry).some((val) =>
entry.year.toString().includes(term) || String(val).toLowerCase().replace(/\s+/g, '').includes(term)
entry.quarter.toLowerCase().includes(term) ||
entry.status.toLowerCase().includes(term)
); );
}); });
const tableHeaders = [ const tableHeaders = [
'Survey Name', 'Survey Name',
@ -154,7 +152,7 @@ export const SubmissionHistory = ({ history = [], loading = false, error = '' })
return ( return (
<> <>
<div className="max-w-[1280px] mx-auto bg-white border border-[#E5E7EB] shadow-[0_16px_32px_rgba(15,23,42,0.06)] rounded-[8px] mt-8 w-full overflow-hidden"> <div className="max-w-[1280px] mx-auto bg-white border border-[#E5E7EB] shadow-[0_16px_32px_rgba(15,23,42,0.06)] rounded-[8px] mt-8 w-full overflow-hidden">
<div className="flex items-center justify-between px-6 pt-6 pb-4"> <div className="flex items-center justify-between px-6 pt-6 pb-4">
<h2 className="text-[18px] leading-[28px] font-medium text-[#232528]"> <h2 className="text-[18px] leading-[28px] font-medium text-[#232528]">
Submission History Submission History
@ -210,22 +208,26 @@ export const SubmissionHistory = ({ history = [], loading = false, error = '' })
<div className="flex items-center justify-center h-[500px] text-gray-500"> <div className="flex items-center justify-center h-[500px] text-gray-500">
Loading submissions... Loading submissions...
</div> </div>
) : filtered.length === 0 ? (
<div className="flex items-center justify-center py-20 text-[#7B5C1F] font-semibold text-[15px]">
No Submission Found
</div>
) : ( ) : (
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<div className="min-w-[1200px]"> <div className="min-w-[1200px]">
<Table <Table
headers={tableHeaders} headers={tableHeaders}
rows={tableRows} rows={tableRows}
separated separated
rowGapClass="border-spacing-y-1" rowGapClass="border-spacing-y-1"
pagination={{ pagination={{
currentPage, currentPage,
onPageChange: setCurrentPage, onPageChange: setCurrentPage,
pageSize, pageSize,
totalItems: filtered.length, totalItems: filtered.length,
}} }}
columnWidths={[250, 100, 100, 160, 180, 150, 120]} columnWidths={[250, 100, 100, 160, 180, 150, 120]}
/> />
</div> </div>
</div> </div>
)} )}

View File

@ -142,19 +142,23 @@ const ManageSubmissions = () => {
const statusOptions = React.useMemo(() => ['All', ...new Set(submissions.map((i) => i.status))], [submissions]); const statusOptions = React.useMemo(() => ['All', ...new Set(submissions.map((i) => i.status))], [submissions]);
const filtered = React.useMemo(() => { const filtered = React.useMemo(() => {
const term = search.trim().toLowerCase();
return submissions.filter((item) => { return submissions.filter((item) => {
const matchSearch = const allValues = Object.values(item)
!search || .map((v) => String(v ?? '').toLowerCase())
item.establishment?.toLowerCase().includes(search.toLowerCase()) || .join(' ');
item.submittedBy?.toLowerCase().includes(search.toLowerCase());
const matchSearch = !term || allValues.includes(term);
const matchYear = !year || year === 'All' || item.year === year; const matchYear = !year || year === 'All' || item.year === year;
const matchQuarter = !quarter || quarter === 'All' || item.quarter === quarter; const matchQuarter = !quarter || quarter === 'All' || item.quarter === quarter;
const matchEmirate = !emirate || emirate === 'All' || item.emirate === emirate; const matchEmirate = !emirate || emirate === 'All' || item.emirate === emirate;
const matchStatus = !status || status === 'All' || item.status === status; const matchStatus = !status || status === 'All' || item.status === status;
return matchSearch && matchYear && matchQuarter && matchEmirate && matchStatus; return matchSearch && matchYear && matchQuarter && matchEmirate && matchStatus;
}); });
}, [submissions, search, year, quarter, emirate, status]); }, [submissions, search, year, quarter, emirate, status]);
const summaryCounts = React.useMemo( const summaryCounts = React.useMemo(
() => ({ () => ({
total: submissions.length, total: submissions.length,
@ -353,87 +357,95 @@ const ManageSubmissions = () => {
</button> </button>
</div> </div>
<div className="rounded-2xl border border-[#E5E7EB] bg-white shadow overflow-hidden"> <div className="rounded-2xl border border-[#E5E7EB] bg-white shadow overflow-hidden">
<Table {toolbar}
headers={headers}
rows={tableRows} {filtered.length === 0 ? (
beforeHeader={toolbar} <div className="flex items-center justify-center py-16 text-[#7B5C1F] font-semibold text-sm border-t border-[#E5E7EB]">
separated No Submission Found
columnWidths={columnWidths} </div>
pagination={{ ) : (
currentPage, <Table
onPageChange: setCurrentPage, headers={headers}
pageSize, rows={tableRows}
totalItems: filtered.length, separated
}} columnWidths={columnWidths}
renderCell={(value, _, columnIndex) => { pagination={{
if (columnIndex === 7) currentPage,
return ( onPageChange: setCurrentPage,
<div className="flex justify-start"> pageSize,
<Badge status={String(value)}>{value}</Badge> totalItems: filtered.length,
</div> }}
); renderCell={(value, _, columnIndex) => {
if (columnIndex === 7)
return (
<div className="flex justify-start">
<Badge status={String(value)}>{value}</Badge>
</div>
);
if (columnIndex === 10) {
const item = value;
return (
<div className="flex items-center justify-center gap-[10px]">
<div className="relative group">
<CheckCircle2
size={22}
className="text-green-600 cursor-pointer hover:scale-110 transition-transform"
onClick={() =>
navigate(`/admin/validations/${item.id}`, {
state: { actionType: 'approve' },
})
}
/>
<span className="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 bg-black text-white text-xs px-2 py-[2px] rounded opacity-0 group-hover:opacity-100 transition">
Approve
</span>
</div>
<div className="relative group">
<XCircle
size={22}
className="text-red-600 cursor-pointer hover:scale-110 transition-transform"
onClick={() =>
navigate(`/admin/validations/${item.id}`, {
state: { actionType: 'reject' },
})
}
/>
<span className="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 bg-black text-white text-xs px-2 py-[2px] rounded opacity-0 group-hover:opacity-100 transition">
Reject
</span>
</div>
<div className="relative group">
<Eye
size={22}
className={`cursor-pointer hover:scale-110 transition-transform ${
item.status?.toLowerCase() === 'pending'
? 'text-[#9E792B]'
: 'text-gray-500'
}`}
onClick={() =>
navigate(`/admin/validations/${item.id}`, {
state: { actionType: 'view' },
})
}
/>
<span className="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 bg-black text-white text-xs px-2 py-[2px] rounded opacity-0 group-hover:opacity-100 transition">
View
</span>
</div>
</div>
);
}
return value;
}}
/>
)}
</div>
if (columnIndex === 10) {
const item = value;
return (
<div className="flex items-center justify-center gap-[10px]">
<div className="relative group">
<CheckCircle2
size={22}
className="text-green-600 cursor-pointer hover:scale-110 transition-transform"
onClick={() =>
navigate(`/admin/validations/${item.id}`, {
state: { actionType: 'approve' },
})
}
/>
<span className="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 bg-black text-white text-xs px-2 py-[2px] rounded opacity-0 group-hover:opacity-100 transition">
Approve
</span>
</div>
<div className="relative group">
<XCircle
size={22}
className="text-red-600 cursor-pointer hover:scale-110 transition-transform"
onClick={() =>
navigate(`/admin/validations/${item.id}`, {
state: { actionType: 'reject' },
})
}
/>
<span className="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 bg-black text-white text-xs px-2 py-[2px] rounded opacity-0 group-hover:opacity-100 transition">
Reject
</span>
</div>
<div className="relative group">
<Eye
size={22}
className={`cursor-pointer hover:scale-110 transition-transform ${
item.status?.toLowerCase() === 'pending'
? 'text-[#9E792B]'
: 'text-gray-500'
}`}
onClick={() =>
navigate(`/admin/validations/${item.id}`, {
state: { actionType: 'view' },
})
}
/>
<span className="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 bg-black text-white text-xs px-2 py-[2px] rounded opacity-0 group-hover:opacity-100 transition">
View
</span>
</div>
</div>
);
}
return value;
}}
/>
</div>
</div> </div>
</div> </div>
<Footer /> <Footer />