submission bugs fixed
This commit is contained in:
parent
b444718d8b
commit
8bbb66a649
@ -31,10 +31,10 @@ const SubmissionTable = ({ selectedQuarter, selectedYear }) => {
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
let list = [...data];
|
||||
if (selectedQuarter !== 'None') {
|
||||
if (selectedQuarter !== 'All') {
|
||||
list = list.filter((item) => item.quarter === selectedQuarter);
|
||||
}
|
||||
if (selectedYear !== 'None') {
|
||||
if (selectedYear !== 'All') {
|
||||
list = list.filter((item) => String(item.year) === String(selectedYear));
|
||||
}
|
||||
return list;
|
||||
@ -42,11 +42,11 @@ const SubmissionTable = ({ selectedQuarter, selectedYear }) => {
|
||||
|
||||
const titleText = useMemo(() => {
|
||||
const count = filtered.length;
|
||||
if (selectedQuarter !== 'None' && selectedYear !== 'None') {
|
||||
if (selectedQuarter !== 'All' && selectedYear !== 'All') {
|
||||
return `Recent 10 Submissions for Selected Quarter ${selectedQuarter} ${selectedYear} (${count})`;
|
||||
} else if (selectedQuarter !== 'None') {
|
||||
} else if (selectedQuarter !== 'All') {
|
||||
return `Recent 10 Submissions for Selected Quarter ${selectedQuarter} (${count})`;
|
||||
} else if (selectedYear !== 'None') {
|
||||
} else if (selectedYear !== 'All') {
|
||||
return `Recent 10 Submissions for Selected Year ${selectedYear} (${count})`;
|
||||
} else {
|
||||
return `Recent 10 Submissions (${count})`;
|
||||
|
||||
@ -21,8 +21,8 @@ const AdminDashboard = () => {
|
||||
pending: 0,
|
||||
});
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedQuarter, setSelectedQuarter] = useState('None');
|
||||
const [selectedYear, setSelectedYear] = useState('None');
|
||||
const [selectedQuarter, setSelectedQuarter] = useState('All');
|
||||
const [selectedYear, setSelectedYear] = useState('All');
|
||||
|
||||
useEffect(() => {
|
||||
const fetchDashboardData = async () => {
|
||||
@ -70,7 +70,7 @@ const AdminDashboard = () => {
|
||||
onChange={(e) => setSelectedQuarter(e.target.value)}
|
||||
className="border border-[#D0D5DD] rounded-md h-8 px-2 text-sm focus:outline-none focus:ring-1 focus:ring-[#92722A]"
|
||||
>
|
||||
<option>None</option>
|
||||
<option>All</option>
|
||||
<option>Q1</option>
|
||||
<option>Q2</option>
|
||||
<option>Q3</option>
|
||||
@ -82,7 +82,7 @@ const AdminDashboard = () => {
|
||||
onChange={(e) => setSelectedYear(e.target.value)}
|
||||
className="border border-[#D0D5DD] rounded-md h-8 px-2 text-sm focus:outline-none focus:ring-1 focus:ring-[#92722A]"
|
||||
>
|
||||
<option>None</option>
|
||||
<option>All</option>
|
||||
<option>2025</option>
|
||||
<option>2024</option>
|
||||
<option>2023</option>
|
||||
|
||||
@ -26,17 +26,17 @@ const formatDateTime = (value) => {
|
||||
if (!value) return '—';
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) return '—';
|
||||
const formatted = date.toLocaleString('en-GB', {
|
||||
const formatted = date.toLocaleString('en-AE', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: true,
|
||||
hour12: false,
|
||||
timeZone: 'Asia/Dubai',
|
||||
});
|
||||
return formatted.replace(/\s?(am|pm)$/i, (m) => m.toUpperCase());
|
||||
return formatted;
|
||||
};
|
||||
|
||||
const Badge = ({ children, status }) => {
|
||||
const variant = STATUS_VARIANTS[status] || { background: '#F2F4F7', text: '#475467', border: '#EAECF0' };
|
||||
return (
|
||||
@ -175,7 +175,7 @@ const ManageSubmissions = () => {
|
||||
'Submission Date & Time',
|
||||
'Status',
|
||||
'Reviewer',
|
||||
'Reviewer On',
|
||||
'Reviewed On',
|
||||
'Actions',
|
||||
];
|
||||
|
||||
@ -232,7 +232,42 @@ const ManageSubmissions = () => {
|
||||
);
|
||||
|
||||
if (error) return <div className="flex items-center justify-center h-screen text-red-600">{error}</div>;
|
||||
|
||||
const downloadCsv = (data) => {
|
||||
if (!data.length) return;
|
||||
|
||||
const headers = ['Establishment', 'Year', 'Quarter', 'Status', 'Submission On', 'Products'];
|
||||
const csvRows = [headers.join(',')];
|
||||
|
||||
data.forEach((item) => {
|
||||
const establishment = item.establishment || '—';
|
||||
const year = item.year || '—';
|
||||
const quarter = item.quarter || '—';
|
||||
|
||||
const normalized = String(item.status || '').toLowerCase();
|
||||
let status = '—';
|
||||
if (normalized === 'pending') status = 'Under Review';
|
||||
else if (normalized === 'rejected') status = 'Returned';
|
||||
else if (['submitted', 'approved'].includes(normalized)) status = 'Approved';
|
||||
|
||||
const submissionOn = item.submittedAt || '—';
|
||||
const productCount = Number(item.products) || 0;
|
||||
const products = `${productCount} ${productCount === 1 ? 'product' : 'products'}`;
|
||||
|
||||
const row = [establishment, year, quarter, status, submissionOn, products];
|
||||
csvRows.push(row.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(','));
|
||||
});
|
||||
|
||||
const blob = new Blob([csvRows.join('\n')], { type: 'text/csv;charset=utf-8;' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.setAttribute('download', 'submissions.csv');
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="min-h-screen bg-[#F6F5F1]">
|
||||
@ -270,22 +305,53 @@ const ManageSubmissions = () => {
|
||||
</nav>
|
||||
|
||||
<div className="flex flex-wrap gap-[6px] rounded-[12px] bg-white px-5 py-3 shadow items-center justify-between">
|
||||
<div className="flex flex-wrap gap-[6px]">
|
||||
{Object.entries(summaryCounts).map(([key, val]) => {
|
||||
const v = SUMMARY_VARIANTS[key];
|
||||
return (
|
||||
<div key={key} className="inline-flex items-center gap-[6px] rounded-[8px] px-2 py-[2px]" style={{ background: v.background }}>
|
||||
<span className="font-medium text-[13px]" style={{ color: v.label }}>
|
||||
{key.charAt(0).toUpperCase() + key.slice(1)}:
|
||||
</span>
|
||||
<span className="font-semibold text-[13px]" style={{ color: v.value }}>
|
||||
{val}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-[6px]">
|
||||
{Object.entries(summaryCounts).map(([key, val]) => {
|
||||
const v = SUMMARY_VARIANTS[key];
|
||||
return (
|
||||
<div
|
||||
key={key}
|
||||
className="inline-flex items-center gap-[6px] rounded-[8px] px-2 py-[2px]"
|
||||
style={{ background: v.background }}
|
||||
>
|
||||
<span className="font-medium text-[13px]" style={{ color: v.label }}>
|
||||
{key.charAt(0).toUpperCase() + key.slice(1)}:
|
||||
</span>
|
||||
<span className="font-semibold text-[13px]" style={{ color: v.value }}>
|
||||
{val}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => downloadCsv(filtered)}
|
||||
disabled={!filtered.length}
|
||||
className={`inline-flex h-10 items-center gap-2 rounded-md border px-4 text-sm font-medium ${
|
||||
filtered.length
|
||||
? 'border-[#92722A] text-[#92722A] hover:bg-[#F2ECCF]'
|
||||
: 'border-gray-200 text-gray-400 cursor-not-allowed'
|
||||
}`}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-4 w-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5m0 0l5-5m-5 5V4"
|
||||
/>
|
||||
</svg>
|
||||
<span>Export CSV</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-[#E5E7EB] bg-white shadow overflow-hidden">
|
||||
<Table
|
||||
|
||||
Loading…
Reference in New Issue
Block a user