table search no submission found solved
This commit is contained in:
parent
6813f23c42
commit
83361a76e0
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -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 />
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user