added popup for delete
This commit is contained in:
parent
2178df5098
commit
34ebb5d622
@ -1,11 +1,13 @@
|
|||||||
import React from 'react';
|
// import React from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import React, { useState } from 'react';
|
||||||
import Table from '@/components/common/Table';
|
import Table from '@/components/common/Table';
|
||||||
import Footer from '../common/Footer';
|
import Footer from '../common/Footer';
|
||||||
import HeaderBar from '@/components/layout/HeaderBar';
|
import HeaderBar from '@/components/layout/HeaderBar';
|
||||||
import DetailedOverview from '@/components/overview/DetailedOverview';
|
import DetailedOverview from '@/components/overview/DetailedOverview';
|
||||||
import { deleteDraftSubmission } from '@/services/submissions/submissionService';
|
import { deleteDraftSubmission } from '@/services/submissions/submissionService';
|
||||||
import { HiMiniArrowPathRoundedSquare } from "react-icons/hi2";
|
import { HiMiniArrowPathRoundedSquare } from "react-icons/hi2";
|
||||||
|
import CustomToast from '@/components/common/CustomToast';
|
||||||
|
|
||||||
const searchIconSrc = '/assets/images/material-symbols_search-rounded.svg';
|
const searchIconSrc = '/assets/images/material-symbols_search-rounded.svg';
|
||||||
const pencilIconSrc = '/assets/images/PencilSimple.svg';
|
const pencilIconSrc = '/assets/images/PencilSimple.svg';
|
||||||
@ -145,7 +147,8 @@ export const SubmissionHistory = ({ history = [], loading = false, error = '' })
|
|||||||
const [currentPage, setCurrentPage] = React.useState(1);
|
const [currentPage, setCurrentPage] = React.useState(1);
|
||||||
const [hoveredDelete, setHoveredDelete] = React.useState(null);
|
const [hoveredDelete, setHoveredDelete] = React.useState(null);
|
||||||
const [toast, setToast] = React.useState({ show: false, message: '', type: 'success' });
|
const [toast, setToast] = React.useState({ show: false, message: '', type: 'success' });
|
||||||
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||||
|
const [draftToDelete, setDraftToDelete] = useState(null);
|
||||||
const showToast = (message, type = 'success') => {
|
const showToast = (message, type = 'success') => {
|
||||||
setToast({ show: true, message, type });
|
setToast({ show: true, message, type });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -180,6 +183,12 @@ export const SubmissionHistory = ({ history = [], loading = false, error = '' })
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDeleteClick = (e, item) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setDraftToDelete(item);
|
||||||
|
setShowDeleteConfirm(true);
|
||||||
|
};
|
||||||
|
|
||||||
const handleDeleteDraft = async (e, submission) => {
|
const handleDeleteDraft = async (e, submission) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -188,19 +197,20 @@ const handleDeleteDraft = async (e, submission) => {
|
|||||||
throw new Error('No submission ID provided');
|
throw new Error('No submission ID provided');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.confirm('Are you sure you want to delete this draft?')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await deleteDraftSubmission(submission.id);
|
await deleteDraftSubmission(submission.id);
|
||||||
showToast('Draft deleted successfully', 'success');
|
showToast('Draft deleted successfully', 'error');
|
||||||
|
|
||||||
|
// Close the confirmation modal
|
||||||
|
setShowDeleteConfirm(false);
|
||||||
|
setDraftToDelete(null);
|
||||||
|
|
||||||
// Optionally reload the page or refresh data
|
// Optionally reload the page or refresh data
|
||||||
|
setTimeout(() => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
|
}, 1000);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error deleting submission:', error);
|
console.error('Error deleting submission:', error);
|
||||||
alert(error.message || 'Failed to delete draft');
|
showToast(error.message || 'Failed to delete draft', 'error');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -270,8 +280,11 @@ const handleDeleteDraft = async (e, submission) => {
|
|||||||
className="h-5 w-5 opacity-60 hover:opacity-100 transition-opacity"
|
className="h-5 w-5 opacity-60 hover:opacity-100 transition-opacity"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={(e) => handleDeleteDraft(e, item)}
|
onClick={(e) => {
|
||||||
|
e.stopPropagation(); // Prevent row click from triggering
|
||||||
|
handleDeleteClick(e, item);
|
||||||
|
}}
|
||||||
onMouseEnter={() => setHoveredDelete(item.id)}
|
onMouseEnter={() => setHoveredDelete(item.id)}
|
||||||
onMouseLeave={() => setHoveredDelete(null)}
|
onMouseLeave={() => setHoveredDelete(null)}
|
||||||
className="p-1 focus:outline-none"
|
className="p-1 focus:outline-none"
|
||||||
@ -407,6 +420,38 @@ const handleDeleteDraft = async (e, submission) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{showDeleteConfirm && (
|
||||||
|
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 p-4">
|
||||||
|
<div className="bg-white w-full max-w-md rounded-lg shadow-2xl border border-gray-200">
|
||||||
|
<div className="p-6 text-center flex flex-col gap-6">
|
||||||
|
<h3 className="text-xl font-semibold text-gray-900">Confirm Deletion</h3>
|
||||||
|
<p className="text-gray-600">Are you sure you want to delete this draft?</p>
|
||||||
|
<div className="flex justify-center gap-4">
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleDeleteDraft(e, draftToDelete);
|
||||||
|
setShowDeleteConfirm(false);
|
||||||
|
}}
|
||||||
|
className="px-4 py-2 bg-[#B52520] text-white rounded-md hover:bg-[#9D1F1B] focus:outline-none"
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setShowDeleteConfirm(false);
|
||||||
|
setDraftToDelete(null);
|
||||||
|
}}
|
||||||
|
className="px-4 py-2 border border-[#92722A] text-[#92722A] font-medium rounded-md hover:bg-[#F5F0E1] transition-colors"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@ -10,7 +10,7 @@ const caretDownSrc = '/assets/images/CaretDown.svg';
|
|||||||
const downloadIconSrc = '/assets/images/DownloadSimple.svg';
|
const downloadIconSrc = '/assets/images/DownloadSimple.svg';
|
||||||
const pencilActiveSrc = '/assets/images/PencilSimple.svg';
|
const pencilActiveSrc = '/assets/images/PencilSimple.svg';
|
||||||
const pencilInactiveSrc = '/assets/images/pencilsimple-inactive.svg';
|
const pencilInactiveSrc = '/assets/images/pencilsimple-inactive.svg';
|
||||||
// const deleteIconSrc = '/assets/images/delete.svg';
|
import CustomToast from '@/components/common/CustomToast';
|
||||||
const deleteIconSrc = '/assets/images/Trash - active.svg';
|
const deleteIconSrc = '/assets/images/Trash - active.svg';
|
||||||
const trashInactiveSrc = '/assets/images/Trash - Inactive.svg';
|
const trashInactiveSrc = '/assets/images/Trash - Inactive.svg';
|
||||||
import { deleteDraftSubmission } from '@/services/submissions/submissionService';
|
import { deleteDraftSubmission } from '@/services/submissions/submissionService';
|
||||||
@ -38,6 +38,10 @@ const Overview = () => {
|
|||||||
const [submissions, setSubmissions] = useState([]);
|
const [submissions, setSubmissions] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
|
const [toast, setToast] = useState({ show: false, message: '', type: 'success' });
|
||||||
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||||
|
const [draftToDelete, setDraftToDelete] = useState(null);
|
||||||
|
const [hoveredDelete, setHoveredDelete] = useState(null);
|
||||||
const establishmentId = localStorage.getItem('establishment_id');
|
const establishmentId = localStorage.getItem('establishment_id');
|
||||||
const [pagination, setPagination] = useState({
|
const [pagination, setPagination] = useState({
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
@ -59,25 +63,49 @@ const handleDeleteDraft = async (e, record) => {
|
|||||||
if (!record?.id) {
|
if (!record?.id) {
|
||||||
throw new Error('No submission ID provided');
|
throw new Error('No submission ID provided');
|
||||||
}
|
}
|
||||||
|
setDraftToDelete(record);
|
||||||
if (!window.confirm('Are you sure you want to delete this draft?')) {
|
setShowDeleteConfirm(true);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the delete API
|
|
||||||
await deleteDraftSubmission(record.id);
|
|
||||||
|
|
||||||
// Show success message
|
|
||||||
alert('Draft deleted successfully');
|
|
||||||
|
|
||||||
// Navigate back or refresh the page
|
|
||||||
window.location.reload();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error deleting submission:', error);
|
console.error('Error preparing to delete submission:', error);
|
||||||
alert(error.message || 'Failed to delete draft');
|
showToast(error.message || 'Error preparing to delete draft', 'error');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const confirmDeleteDraft = async () => {
|
||||||
|
if (!draftToDelete?.id) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await deleteDraftSubmission(draftToDelete.id);
|
||||||
|
|
||||||
|
// Update the submissions list by removing the deleted item
|
||||||
|
setSubmissions(prev =>
|
||||||
|
prev.filter(item => item.id !== draftToDelete.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Show success toast
|
||||||
|
showToast('Draft deleted successfully', 'error');
|
||||||
|
|
||||||
|
// Close the confirmation modal
|
||||||
|
setShowDeleteConfirm(false);
|
||||||
|
setDraftToDelete(null);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error deleting submission:', error);
|
||||||
|
showToast(error.message || 'Failed to delete draft', 'error');
|
||||||
|
setShowDeleteConfirm(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add this helper function
|
||||||
|
const showToast = (message, type = 'success') => {
|
||||||
|
setToast({ show: true, message, type });
|
||||||
|
setTimeout(() => {
|
||||||
|
setToast({ ...toast, show: false });
|
||||||
|
}, 3000);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchSubmissions = async () => {
|
const fetchSubmissions = async () => {
|
||||||
try {
|
try {
|
||||||
@ -171,17 +199,19 @@ const handleDeleteDraft = async (e, record) => {
|
|||||||
className="h-5 w-5 opacity-60 hover:opacity-100 transition-opacity"
|
className="h-5 w-5 opacity-60 hover:opacity-100 transition-opacity"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={(e) => handleDeleteDraft(e, record)}
|
onClick={(e) => handleDeleteDraft(e, record)}
|
||||||
className="focus:outline-none"
|
className="focus:outline-none group"
|
||||||
title="Delete Draft"
|
title="Delete Draft"
|
||||||
>
|
onMouseEnter={() => setHoveredDelete(record.id)}
|
||||||
|
onMouseLeave={() => setHoveredDelete(null)}
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src={deleteIconSrc}
|
src={hoveredDelete === record.id ? deleteIconSrc : trashInactiveSrc}
|
||||||
alt="Delete"
|
alt="Delete"
|
||||||
className="h-5 w-5 opacity-60 hover:opacity-100 transition-opacity text-red-500"
|
className="h-5 w-5 transition-colors"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) :
|
) :
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
@ -191,12 +221,14 @@ const handleDeleteDraft = async (e, record) => {
|
|||||||
className="w-5 h-5 text-[#92722A] opacity-60 hover:opacity-100 transition-opacity"
|
className="w-5 h-5 text-[#92722A] opacity-60 hover:opacity-100 transition-opacity"
|
||||||
style={{ filter: 'invert(36%) sepia(49%) saturate(680%) hue-rotate(1deg) brightness(89%) contrast(91%)' }}
|
style={{ filter: 'invert(36%) sepia(49%) saturate(680%) hue-rotate(1deg) brightness(89%) contrast(91%)' }}
|
||||||
/>
|
/>
|
||||||
|
{record.status === 'Rejected' && (
|
||||||
<HiMiniArrowPathRoundedSquare
|
<HiMiniArrowPathRoundedSquare
|
||||||
className="w-5 h-5 text-[#92722A] opacity-60 hover:opacity-100 transition-opacity cursor-pointer"
|
className="w-5 h-5 text-[#92722A] opacity-60 hover:opacity-100 transition-opacity cursor-pointer"
|
||||||
style={{ filter: 'invert(36%) sepia(49%) saturate(680%) hue-rotate(1deg) brightness(89%) contrast(91%)' }}
|
style={{ filter: 'invert(36%) sepia(49%) saturate(680%) hue-rotate(1deg) brightness(89%) contrast(91%)' }}
|
||||||
title="Resubmit"
|
title="Resubmit"
|
||||||
/>
|
/>
|
||||||
</div>
|
)}
|
||||||
|
</div>
|
||||||
]);
|
]);
|
||||||
}, [filteredRows, uae_currency]);
|
}, [filteredRows, uae_currency]);
|
||||||
|
|
||||||
@ -421,7 +453,49 @@ const handleDeleteDraft = async (e, record) => {
|
|||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
{showDeleteConfirm && (
|
||||||
|
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 p-4">
|
||||||
|
<div className="bg-white w-full max-w-md rounded-lg shadow-2xl border border-gray-200">
|
||||||
|
<div className="p-6 text-center flex flex-col gap-6">
|
||||||
|
<h3 className="text-xl font-semibold text-gray-900">Confirm Deletion</h3>
|
||||||
|
<p className="text-gray-600">Are you sure you want to delete this draft?</p>
|
||||||
|
<div className="flex justify-center gap-4">
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
confirmDeleteDraft();
|
||||||
|
}}
|
||||||
|
className="px-4 py-2 bg-[#B52520] text-white rounded-md hover:bg-[#9D1F1B] focus:outline-none"
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setShowDeleteConfirm(false);
|
||||||
|
setDraftToDelete(null);
|
||||||
|
}}
|
||||||
|
className="px-4 py-2 border border-[#92722A] text-[#92722A] font-medium rounded-md hover:bg-[#F5F0E1] transition-colors"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* Toast Notification */}
|
||||||
|
{toast.show && (
|
||||||
|
<div className="fixed top-4 right-4 z-[10000]">
|
||||||
|
<CustomToast
|
||||||
|
message={toast.message}
|
||||||
|
type={toast.type}
|
||||||
|
onClose={() => setToast({ ...toast, show: false })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user