submission bugs fixed
This commit is contained in:
parent
b444718d8b
commit
8bbb66a649
@ -31,10 +31,10 @@ const SubmissionTable = ({ selectedQuarter, selectedYear }) => {
|
|||||||
|
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
let list = [...data];
|
let list = [...data];
|
||||||
if (selectedQuarter !== 'None') {
|
if (selectedQuarter !== 'All') {
|
||||||
list = list.filter((item) => item.quarter === selectedQuarter);
|
list = list.filter((item) => item.quarter === selectedQuarter);
|
||||||
}
|
}
|
||||||
if (selectedYear !== 'None') {
|
if (selectedYear !== 'All') {
|
||||||
list = list.filter((item) => String(item.year) === String(selectedYear));
|
list = list.filter((item) => String(item.year) === String(selectedYear));
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
@ -42,11 +42,11 @@ const SubmissionTable = ({ selectedQuarter, selectedYear }) => {
|
|||||||
|
|
||||||
const titleText = useMemo(() => {
|
const titleText = useMemo(() => {
|
||||||
const count = filtered.length;
|
const count = filtered.length;
|
||||||
if (selectedQuarter !== 'None' && selectedYear !== 'None') {
|
if (selectedQuarter !== 'All' && selectedYear !== 'All') {
|
||||||
return `Recent 10 Submissions for Selected Quarter ${selectedQuarter} ${selectedYear} (${count})`;
|
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})`;
|
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})`;
|
return `Recent 10 Submissions for Selected Year ${selectedYear} (${count})`;
|
||||||
} else {
|
} else {
|
||||||
return `Recent 10 Submissions (${count})`;
|
return `Recent 10 Submissions (${count})`;
|
||||||
|
|||||||
@ -21,8 +21,8 @@ const AdminDashboard = () => {
|
|||||||
pending: 0,
|
pending: 0,
|
||||||
});
|
});
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [selectedQuarter, setSelectedQuarter] = useState('None');
|
const [selectedQuarter, setSelectedQuarter] = useState('All');
|
||||||
const [selectedYear, setSelectedYear] = useState('None');
|
const [selectedYear, setSelectedYear] = useState('All');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchDashboardData = async () => {
|
const fetchDashboardData = async () => {
|
||||||
@ -70,7 +70,7 @@ const AdminDashboard = () => {
|
|||||||
onChange={(e) => setSelectedQuarter(e.target.value)}
|
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]"
|
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>Q1</option>
|
||||||
<option>Q2</option>
|
<option>Q2</option>
|
||||||
<option>Q3</option>
|
<option>Q3</option>
|
||||||
@ -82,7 +82,7 @@ const AdminDashboard = () => {
|
|||||||
onChange={(e) => setSelectedYear(e.target.value)}
|
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]"
|
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>2025</option>
|
||||||
<option>2024</option>
|
<option>2024</option>
|
||||||
<option>2023</option>
|
<option>2023</option>
|
||||||
|
|||||||
@ -26,17 +26,17 @@ const formatDateTime = (value) => {
|
|||||||
if (!value) return '—';
|
if (!value) return '—';
|
||||||
const date = new Date(value);
|
const date = new Date(value);
|
||||||
if (Number.isNaN(date.getTime())) return '—';
|
if (Number.isNaN(date.getTime())) return '—';
|
||||||
const formatted = date.toLocaleString('en-GB', {
|
const formatted = date.toLocaleString('en-AE', {
|
||||||
day: '2-digit',
|
day: '2-digit',
|
||||||
month: '2-digit',
|
month: '2-digit',
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '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 Badge = ({ children, status }) => {
|
||||||
const variant = STATUS_VARIANTS[status] || { background: '#F2F4F7', text: '#475467', border: '#EAECF0' };
|
const variant = STATUS_VARIANTS[status] || { background: '#F2F4F7', text: '#475467', border: '#EAECF0' };
|
||||||
return (
|
return (
|
||||||
@ -175,7 +175,7 @@ const ManageSubmissions = () => {
|
|||||||
'Submission Date & Time',
|
'Submission Date & Time',
|
||||||
'Status',
|
'Status',
|
||||||
'Reviewer',
|
'Reviewer',
|
||||||
'Reviewer On',
|
'Reviewed On',
|
||||||
'Actions',
|
'Actions',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -232,7 +232,42 @@ const ManageSubmissions = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (error) return <div className="flex items-center justify-center h-screen text-red-600">{error}</div>;
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="min-h-screen bg-[#F6F5F1]">
|
<div className="min-h-screen bg-[#F6F5F1]">
|
||||||
@ -270,22 +305,53 @@ const ManageSubmissions = () => {
|
|||||||
</nav>
|
</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] rounded-[12px] bg-white px-5 py-3 shadow items-center justify-between">
|
||||||
<div className="flex flex-wrap gap-[6px]">
|
<div className="flex flex-wrap gap-[6px]">
|
||||||
{Object.entries(summaryCounts).map(([key, val]) => {
|
{Object.entries(summaryCounts).map(([key, val]) => {
|
||||||
const v = SUMMARY_VARIANTS[key];
|
const v = SUMMARY_VARIANTS[key];
|
||||||
return (
|
return (
|
||||||
<div key={key} className="inline-flex items-center gap-[6px] rounded-[8px] px-2 py-[2px]" style={{ background: v.background }}>
|
<div
|
||||||
<span className="font-medium text-[13px]" style={{ color: v.label }}>
|
key={key}
|
||||||
{key.charAt(0).toUpperCase() + key.slice(1)}:
|
className="inline-flex items-center gap-[6px] rounded-[8px] px-2 py-[2px]"
|
||||||
</span>
|
style={{ background: v.background }}
|
||||||
<span className="font-semibold text-[13px]" style={{ color: v.value }}>
|
>
|
||||||
{val}
|
<span className="font-medium text-[13px]" style={{ color: v.label }}>
|
||||||
</span>
|
{key.charAt(0).toUpperCase() + key.slice(1)}:
|
||||||
</div>
|
</span>
|
||||||
);
|
<span className="font-semibold text-[13px]" style={{ color: v.value }}>
|
||||||
})}
|
{val}
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</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">
|
<div className="rounded-2xl border border-[#E5E7EB] bg-white shadow overflow-hidden">
|
||||||
<Table
|
<Table
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user