260 lines
7.7 KiB
JavaScript
260 lines
7.7 KiB
JavaScript
import React, { useState, useMemo } from 'react';
|
|
import Table from '@/components/common/Table';
|
|
// Import SVG files as URLs in Vite
|
|
import SearchIcon from '@/assets/images/material-symbols_search-rounded.svg';
|
|
import CheckCircle from '@/assets/images/check-circle-fill 1.svg';
|
|
import XCircle from '@/assets/images/warning-circle-fill 1.svg';
|
|
import EyeIcon from '@/assets/images/User-active.svg';
|
|
|
|
const submissions = [
|
|
{
|
|
establishment: 'CASCADE MARINE FOODS LLC',
|
|
emirate: 'Sharjah',
|
|
productCount: '5',
|
|
year: '2025',
|
|
quarter: 'Q4',
|
|
lastSubmission: '10/12/2024',
|
|
deadline: '20/12/2024',
|
|
},
|
|
{
|
|
establishment: 'Khazan meat factory',
|
|
emirate: 'Sharjah',
|
|
productCount: '8',
|
|
year: '2025',
|
|
quarter: 'Q3',
|
|
lastSubmission: '15/11/2024',
|
|
deadline: '15/12/2024',
|
|
},
|
|
{
|
|
establishment: 'SPINNEYS FRESH FOOD INDUSTRIES L.L.C',
|
|
emirate: 'Dubai',
|
|
productCount: '6',
|
|
year: '2025',
|
|
quarter: 'Q2',
|
|
lastSubmission: '12/12/2024',
|
|
deadline: '10/12/2024',
|
|
},
|
|
{
|
|
establishment: 'FRESHLY FROZEN FOODS FACTORY L.L.C',
|
|
emirate: 'Dubai',
|
|
productCount: '8',
|
|
year: '2025',
|
|
quarter: 'Q1',
|
|
lastSubmission: '08/12/2024',
|
|
deadline: '18/12/2024',
|
|
},
|
|
{
|
|
establishment: 'SAHAR FOOD INDUSTRY (L.L.C)',
|
|
emirate: 'Dubai',
|
|
productCount: '8',
|
|
year: '2025',
|
|
quarter: 'Q4',
|
|
lastSubmission: '08/12/2024',
|
|
deadline: '18/12/2024',
|
|
},
|
|
{
|
|
establishment: 'CONTINENTAL FOOD PROCESSING LLC',
|
|
emirate: 'Ajman',
|
|
productCount: '8',
|
|
year: '2025',
|
|
quarter: 'Q3',
|
|
lastSubmission: '08/12/2024',
|
|
deadline: '18/12/2024',
|
|
},
|
|
{
|
|
establishment: 'AL KHAZNA POULTRY FARM',
|
|
emirate: 'Abu Dhabi',
|
|
productCount: '8',
|
|
year: '2025',
|
|
quarter: 'Q2',
|
|
lastSubmission: '08/12/2024',
|
|
deadline: '18/12/2024',
|
|
},
|
|
{
|
|
establishment: 'DIAMOND MEAT PROCESSING L.L.C',
|
|
emirate: 'Abu Dhabi',
|
|
productCount: '8',
|
|
year: '2025',
|
|
quarter: 'Q2',
|
|
lastSubmission: '08/12/2024',
|
|
deadline: '18/12/2024',
|
|
},
|
|
{
|
|
establishment: 'ALLIANCE FOODS CO L.L.C',
|
|
emirate: 'Abu Dhabi',
|
|
productCount: '8',
|
|
year: '2025',
|
|
quarter: 'Q2',
|
|
lastSubmission: '08/12/2024',
|
|
deadline: '18/12/2024',
|
|
},
|
|
{
|
|
establishment: 'KRUSTASIA FOODS L.L.C',
|
|
emirate: 'Dubai',
|
|
productCount: '4',
|
|
year: '2025',
|
|
quarter: 'Q1',
|
|
lastSubmission: '14/12/2024',
|
|
deadline: '21/12/2024',
|
|
},
|
|
];
|
|
|
|
const SubmissionTable = () => {
|
|
const [search, setSearch] = useState('');
|
|
const [selectedYear, setSelectedYear] = useState('2025');
|
|
const [selectedQuarter, setSelectedQuarter] = useState('Q4');
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
// Filter submissions by selected year and quarter
|
|
const filteredByQuarterYear = useMemo(() => {
|
|
return submissions.filter(
|
|
(item) => item.year === selectedYear && item.quarter === selectedQuarter
|
|
);
|
|
}, [selectedYear, selectedQuarter]);
|
|
|
|
// Apply search filter to the filteredByQuarterYear results
|
|
const filtered = useMemo(() => {
|
|
if (!search.trim()) return filteredByQuarterYear;
|
|
const normalized = search.trim().toLowerCase();
|
|
return filteredByQuarterYear.filter((item) =>
|
|
Object.values(item).join(' ').toLowerCase().includes(normalized)
|
|
);
|
|
}, [search, filteredByQuarterYear]);
|
|
|
|
const headers = [
|
|
'Establishment',
|
|
'Emirates',
|
|
'Year',
|
|
'Quarter',
|
|
'Product Count',
|
|
'Submitted By',
|
|
'Submission Date & Time',
|
|
'Status',
|
|
'Reviewer',
|
|
'Reviewer On',
|
|
'Actions',
|
|
];
|
|
|
|
const renderStatusBadge = (status) => {
|
|
const normalized = status?.toLowerCase();
|
|
if (normalized === 'approved') {
|
|
return (
|
|
<span className="px-3 py-1 rounded-md text-green-700 bg-green-50 font-medium text-sm">
|
|
Approved
|
|
</span>
|
|
);
|
|
} else if (normalized === 'rejected') {
|
|
return (
|
|
<span className="px-3 py-1 rounded-md text-red-600 bg-red-50 font-medium text-sm">
|
|
Rejected
|
|
</span>
|
|
);
|
|
} else if (normalized === 'pending') {
|
|
return (
|
|
<span className="px-3 py-1 rounded-md text-blue-600 bg-blue-50 font-medium text-sm">
|
|
Pending
|
|
</span>
|
|
);
|
|
} else {
|
|
return (
|
|
<span className="px-3 py-1 rounded-md text-gray-600 bg-gray-50 font-medium text-sm">
|
|
{status || '-'}
|
|
</span>
|
|
);
|
|
}
|
|
};
|
|
|
|
const tableRows = filtered.map((item) => [
|
|
item.establishment,
|
|
item.emirate,
|
|
item.year,
|
|
item.quarter,
|
|
item.productCount,
|
|
item.submittedBy,
|
|
item.submissionDateTime,
|
|
renderStatusBadge(item.status),
|
|
item.reviewer,
|
|
item.reviewedOn,
|
|
<div className="flex items-center justify-center gap-3">
|
|
<img src={CheckCircle} alt="Approve" className="text-green-600 w-5 h-5 cursor-pointer hover:scale-110 transition-transform" />
|
|
<img src={XCircle} alt="Reject" className="text-red-500 w-5 h-5 cursor-pointer hover:scale-110 transition-transform" />
|
|
<img src={EyeIcon} alt="View" className="text-gray-500 w-5 h-5 cursor-pointer hover:scale-110 transition-transform" />
|
|
</div>,
|
|
]);
|
|
|
|
const columnWidths = [240, 120, 100, 100, 130, 150, 180, 150, 150, 180, 120];
|
|
|
|
const titleText = useMemo(() => {
|
|
const count = filtered.length;
|
|
if (selectedQuarter !== 'None' && selectedYear !== 'None') {
|
|
return `Recent 10 Submissions for Selected Quarter ${selectedQuarter} ${selectedYear} (${count})`;
|
|
} else if (selectedQuarter !== 'None') {
|
|
return `Recent 10 Submissions for Selected Quarter ${selectedQuarter} (${count})`;
|
|
} else if (selectedYear !== 'None') {
|
|
return `Recent 10 Submissions for Selected Year ${selectedYear} (${count})`;
|
|
} else {
|
|
return `Recent 10 Submissions (${count})`;
|
|
}
|
|
}, [selectedQuarter, selectedYear, filtered]);
|
|
|
|
const toolbar = (
|
|
<div className="px-6 pt-6 pb-4">
|
|
<div className="mx-auto flex h-10 w-full max-w-[1280px] items-center justify-between gap-4">
|
|
<h2 className="text-[18px] leading-[28px] font-medium text-[#232528]">
|
|
{titleText}
|
|
</h2>
|
|
<div className="relative w-[280px]">
|
|
<img
|
|
src={SearchIcon}
|
|
alt="Search"
|
|
className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4"
|
|
/>
|
|
<input
|
|
type="text"
|
|
value={search}
|
|
onChange={(event) => setSearch(event.target.value)}
|
|
placeholder="Search Establishment or Status"
|
|
className="h-10 w-full rounded-md border border-[#C3C6CB] pl-9 pr-3 text-sm focus:outline-none focus:ring-1 focus:ring-[#92722A]"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<div
|
|
className="border border-[#E5E7EB] bg-white shadow-[0_16px_32px_rgba(15,23,42,0.06)] rounded-[8px]"
|
|
style={{ width: '1250px', height: '706px' }}
|
|
>
|
|
<div className="space-y-[1px] overflow-x-auto">
|
|
{toolbar}
|
|
{loading ? (
|
|
<div className="flex items-center justify-center h-[500px] text-gray-500">
|
|
Loading submissions...
|
|
</div>
|
|
) : (
|
|
<div className="min-w-[1200px]">
|
|
<Table
|
|
headers={headers}
|
|
rows={tableRows}
|
|
separated
|
|
rowGapClass="border-spacing-y-1"
|
|
columnWidths={columnWidths}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex justify-end px-6 pb-6">
|
|
<button
|
|
type="button"
|
|
className="inline-flex h-[44px] w-[168px] items-center justify-center gap-2 rounded-md bg-[#9E792B] text-sm font-medium text-white shadow-[0_8px_18px_rgba(146,114,42,0.35)] hover:bg-[#846522]"
|
|
>
|
|
View All Submissions
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SubmissionTable |