edit for portal & tender
This commit is contained in:
@@ -32,9 +32,10 @@ const toCompanyDateTime = (date: string, time: string) => {
|
||||
}
|
||||
|
||||
const formatCompanyTime = (value: string) => {
|
||||
return new Date(value).toLocaleTimeString('en-US', {
|
||||
return new Date(value).toLocaleTimeString('en-GB', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
timeZone: COMPANY_TIME_ZONE,
|
||||
})
|
||||
}
|
||||
@@ -51,6 +52,7 @@ export default function PortalLeavePage() {
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [editingId, setEditingId] = useState<string | null>(null)
|
||||
|
||||
const [form, setForm] = useState({
|
||||
leaveType: 'ANNUAL',
|
||||
@@ -74,6 +76,67 @@ export default function PortalLeavePage() {
|
||||
}
|
||||
|
||||
useEffect(() => load(), [])
|
||||
|
||||
const resetForm = () => {
|
||||
setForm({
|
||||
leaveType: 'ANNUAL',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
leaveDate: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
reason: '',
|
||||
})
|
||||
setEditingId(null)
|
||||
}
|
||||
|
||||
const openEdit = (l: any) => {
|
||||
setEditingId(l.id)
|
||||
if (l.leaveType === 'HOURLY') {
|
||||
const start = new Date(l.startDate)
|
||||
const end = new Date(l.endDate)
|
||||
const dateStr = start.toLocaleDateString('en-CA', { timeZone: COMPANY_TIME_ZONE })
|
||||
const fmt = (d: Date) =>
|
||||
d.toLocaleTimeString('en-GB', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
timeZone: COMPANY_TIME_ZONE,
|
||||
})
|
||||
setForm({
|
||||
leaveType: 'HOURLY',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
leaveDate: dateStr,
|
||||
startTime: fmt(start),
|
||||
endTime: fmt(end),
|
||||
reason: l.reason || '',
|
||||
})
|
||||
} else {
|
||||
setForm({
|
||||
leaveType: 'ANNUAL',
|
||||
startDate: String(l.startDate).split('T')[0],
|
||||
endDate: String(l.endDate).split('T')[0],
|
||||
leaveDate: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
reason: l.reason || '',
|
||||
})
|
||||
}
|
||||
setShowModal(true)
|
||||
}
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
if (!confirm('حذف طلب الإجازة؟')) return
|
||||
try {
|
||||
await portalAPI.deleteLeaveRequest(id)
|
||||
toast.success('تم حذف الطلب')
|
||||
load()
|
||||
} catch (err: any) {
|
||||
toast.error(err?.response?.data?.message || 'فشل الحذف')
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
@@ -115,19 +178,15 @@ export default function PortalLeavePage() {
|
||||
|
||||
setSubmitting(true)
|
||||
|
||||
portalAPI.submitLeaveRequest(payload)
|
||||
const action = editingId
|
||||
? portalAPI.updateLeaveRequest(editingId, payload)
|
||||
: portalAPI.submitLeaveRequest(payload)
|
||||
|
||||
action
|
||||
.then(() => {
|
||||
setShowModal(false)
|
||||
setForm({
|
||||
leaveType: 'ANNUAL',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
leaveDate: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
reason: '',
|
||||
})
|
||||
toast.success('تم إرسال طلب الإجازة')
|
||||
resetForm()
|
||||
toast.success(editingId ? 'تم تعديل الطلب' : 'تم إرسال طلب الإجازة')
|
||||
load()
|
||||
})
|
||||
.catch((err: any) => {
|
||||
@@ -151,7 +210,7 @@ export default function PortalLeavePage() {
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-2xl font-bold text-gray-900">إجازاتي</h1>
|
||||
<button
|
||||
onClick={() => setShowModal(true)}
|
||||
onClick={() => { resetForm(); setShowModal(true) }}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
@@ -202,9 +261,29 @@ export default function PortalLeavePage() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<span className={`px-3 py-1 rounded-full text-xs ${statusInfo.color}`}>
|
||||
{statusInfo.label}
|
||||
</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`px-3 py-1 rounded-full text-xs ${statusInfo.color}`}>
|
||||
{statusInfo.label}
|
||||
</span>
|
||||
{l.status === 'PENDING' && (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => openEdit(l)}
|
||||
className="text-xs text-teal-600 hover:underline"
|
||||
>
|
||||
تعديل
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleDelete(l.id)}
|
||||
className="text-xs text-red-600 hover:underline"
|
||||
>
|
||||
حذف
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
@@ -213,7 +292,11 @@ export default function PortalLeavePage() {
|
||||
</div>
|
||||
|
||||
{/* الفورم */}
|
||||
<Modal isOpen={showModal} onClose={() => setShowModal(false)} title="طلب إجازة جديد">
|
||||
<Modal
|
||||
isOpen={showModal}
|
||||
onClose={() => { setShowModal(false); resetForm() }}
|
||||
title={editingId ? 'تعديل طلب الإجازة' : 'طلب إجازة جديد'}
|
||||
>
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
|
||||
{/* نوع الإجازة */}
|
||||
@@ -315,7 +398,7 @@ export default function PortalLeavePage() {
|
||||
<div className="flex justify-end gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowModal(false)}
|
||||
onClick={() => { setShowModal(false); resetForm() }}
|
||||
className="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg"
|
||||
>
|
||||
إلغاء
|
||||
@@ -326,7 +409,7 @@ export default function PortalLeavePage() {
|
||||
disabled={submitting}
|
||||
className="px-4 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 disabled:opacity-50"
|
||||
>
|
||||
{submitting ? 'جاري الإرسال...' : 'إرسال الطلب'}
|
||||
{submitting ? 'جاري الإرسال...' : (editingId ? 'حفظ التعديل' : 'إرسال الطلب')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user