update expense-claims

This commit is contained in:
Aya
2026-05-03 10:30:03 +03:00
parent 11d14c01d2
commit 345ba195f8
11 changed files with 492 additions and 364 deletions

View File

@@ -69,13 +69,33 @@ export default function ManagedExpenseClaimsPage() {
loadClaims(statusFilter);
}, [statusFilter]);
async function openAttachment(attachment: any) {
try {
const blob = await portalAPI.viewExpenseClaimAttachment(attachment.id);
const blobUrl = window.URL.createObjectURL(
new Blob([blob], { type: attachment.mimeType })
);
window.open(blobUrl, '_blank');
setTimeout(() => {
window.URL.revokeObjectURL(blobUrl);
}, 10000);
} catch (error) {
alert('تعذر فتح المرفق');
}
}
async function handleApprove(id: string) {
const confirmed = window.confirm('هل أنت متأكد من الموافقة على طلب كشف المصاريف؟');
if (!confirmed) return;
const note = window.prompt(
'ملاحظة مع الموافقة (اتركها فارغة إذا لا توجد):',
'',
);
if (note === null) return;
try {
setSubmittingId(id);
await portalAPI.approveManagedExpenseClaim(id);
await portalAPI.approveManagedExpenseClaim(id, note.trim() || undefined);
await loadClaims(statusFilter);
} catch (error: any) {
alert(error?.response?.data?.message || 'تعذر تنفيذ الموافقة');
@@ -309,6 +329,27 @@ export default function ManagedExpenseClaimsPage() {
</div>
</div>
)}
{claim.attachments && claim.attachments.length > 0 ? (
<div className="mt-3 space-y-2">
<div className="text-sm font-medium text-gray-800">المرفقات:</div>
<div className="space-y-1">
{claim.attachments.map((attachment) => (
<a
key={attachment.id}
href={`${process.env.NEXT_PUBLIC_API_URL}/hr/portal/expense-claims/attachments/${attachment.id}/view`}
target="_blank"
rel="noreferrer"
className="block rounded-lg border bg-white px-3 py-2 text-sm text-blue-600 hover:underline"
>
{attachment.originalName}
</a>
))}
</div>
</div>
) : null}
{claim.status === 'REJECTED' && claim.rejectedReason ? (
<div className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">
@@ -317,6 +358,13 @@ export default function ManagedExpenseClaimsPage() {
</div>
) : null}
{claim.status === 'APPROVED' && claim.approvalNote ? (
<div className="rounded-lg bg-green-50 px-3 py-2 text-sm text-green-700">
<span className="font-medium">ملاحظة المعتمِد:</span>{' '}
{claim.approvalNote}
</div>
) : null}
{claim.status === 'PENDING' ? (
<div className="flex items-center gap-2 pt-2">
<button