fixed the api request
All checks were successful
Build frontend / build (push) Successful in 1m7s

This commit is contained in:
mouazkh
2026-04-16 22:49:15 +03:00
parent 7e0d5eaf8d
commit 32f6c7af5a

View File

@ -16,7 +16,6 @@ import {
Shield, Shield,
Phone, Phone,
Mail, Mail,
MessageCircle,
ChevronDown, ChevronDown,
ChevronUp, ChevronUp,
FileText, FileText,
@ -419,84 +418,6 @@ const ReasonDialog = ({ isOpen, onClose, onConfirm, title, defaultReason = '' })
); );
}; };
const DepositCommentDialog = ({
isOpen,
request,
isSubmitting,
onClose,
onConfirm,
}) => {
const [comment, setComment] = useState('');
useEffect(() => {
if (!isOpen) {
setComment('');
}
}, [isOpen, request?.id]);
if (!isOpen || !request) return null;
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center p-4 z-50"
onClick={isSubmitting ? undefined : onClose}
>
<motion.div
initial={{ scale: 0.95, y: 20 }}
animate={{ scale: 1, y: 0 }}
exit={{ scale: 0.95, y: 20 }}
className="bg-white rounded-2xl w-full max-w-lg p-6 shadow-2xl"
onClick={(e) => e.stopPropagation()}
>
<div className="text-center mb-5">
<div className="w-16 h-16 bg-indigo-100 rounded-full flex items-center justify-center mx-auto mb-3">
<MessageCircle className="w-8 h-8 text-indigo-600" />
</div>
<h3 className="text-xl font-bold text-gray-900">تأكيد العربون</h3>
<p className="text-sm text-gray-500 mt-1">
يمكنك إضافة تعليق اختياري، أو ترك الحقل فارغاً ليتم إرسال <span className="font-semibold">null</span>.
</p>
</div>
<div className="rounded-xl bg-gray-50 px-4 py-3 text-sm text-gray-700 mb-4 space-y-1">
<div>رقم الحجز: <span className="font-semibold">#{request.id}</span></div>
<div>العقار: <span className="font-semibold">{request.property}</span></div>
<div>المستأجر: <span className="font-semibold">{request.user}</span></div>
</div>
<textarea
value={comment}
onChange={(e) => setComment(e.target.value)}
placeholder="اكتب تعليقاً إذا أردت..."
className="w-full min-h-32 p-4 border rounded-xl resize-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
disabled={isSubmitting}
/>
<div className="flex gap-3 pt-4">
<button
onClick={() => onConfirm(comment)}
disabled={isSubmitting}
className="flex-1 bg-indigo-600 text-white py-3 rounded-xl font-medium hover:bg-indigo-700 transition-colors disabled:opacity-60 disabled:cursor-wait flex items-center justify-center gap-2"
>
{isSubmitting ? <Loader2 className="w-5 h-5 animate-spin" /> : <CreditCard className="w-5 h-5" />}
<span>{isSubmitting ? 'جاري الإرسال...' : 'تأكيد الإرسال'}</span>
</button>
<button
onClick={onClose}
disabled={isSubmitting}
className="flex-1 bg-gray-100 text-gray-700 py-3 rounded-xl font-medium hover:bg-gray-200 transition-colors disabled:opacity-60"
>
إلغاء
</button>
</div>
</motion.div>
</motion.div>
);
};
const PDFExportButton = ({ request, onExportComplete }) => { const PDFExportButton = ({ request, onExportComplete }) => {
const [isExporting, setIsExporting] = useState(false); const [isExporting, setIsExporting] = useState(false);
@ -1386,7 +1307,6 @@ export default function BookingRequests() {
const [requests, setRequests] = useState([]); const [requests, setRequests] = useState([]);
const [filter, setFilter] = useState('depositPaid'); const [filter, setFilter] = useState('depositPaid');
const [detailsDialog, setDetailsDialog] = useState({ isOpen: false, request: null }); const [detailsDialog, setDetailsDialog] = useState({ isOpen: false, request: null });
const [depositDialog, setDepositDialog] = useState({ isOpen: false, request: null });
const [confirmingDepositId, setConfirmingDepositId] = useState(null); const [confirmingDepositId, setConfirmingDepositId] = useState(null);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [loadError, setLoadError] = useState(''); const [loadError, setLoadError] = useState('');
@ -1444,16 +1364,7 @@ export default function BookingRequests() {
loadReservations(); loadReservations();
}, [loadReservations]); }, [loadReservations]);
const openDepositConfirmationDialog = (request) => { const handleDepositConfirmation = async (request) => {
setDepositDialog({ isOpen: true, request });
};
const closeDepositConfirmationDialog = () => {
if (confirmingDepositId != null) return;
setDepositDialog({ isOpen: false, request: null });
};
const handleDepositConfirmation = async (request, commentInput = null) => {
if (!AuthService.isAdmin()) { if (!AuthService.isAdmin()) {
console.warn('[Admin] Deposit confirmation blocked: current user is not admin', { console.warn('[Admin] Deposit confirmation blocked: current user is not admin', {
user: AuthService.getUser(), user: AuthService.getUser(),
@ -1483,9 +1394,9 @@ export default function BookingRequests() {
const adminUser = AuthService.getUser(); const adminUser = AuthService.getUser();
const parsedAdminId = Number(adminUser?.id); const parsedAdminId = Number(adminUser?.id);
const adminId = Number.isFinite(parsedAdminId) ? parsedAdminId : adminUser?.id; const adminId = Number.isFinite(parsedAdminId) ? parsedAdminId : adminUser?.id;
const normalizedComment = const comment =
typeof commentInput === 'string' && commentInput.trim() typeof request?.comment === 'string' && request.comment.trim()
? commentInput.trim() ? request.comment.trim()
: null; : null;
console.log('[Admin] Preparing admin confirm deposit request', { console.log('[Admin] Preparing admin confirm deposit request', {
@ -1498,7 +1409,7 @@ export default function BookingRequests() {
payload: { payload: {
reservationId, reservationId,
adminId, adminId,
comment: normalizedComment, comment,
}, },
}); });
@ -1514,13 +1425,13 @@ export default function BookingRequests() {
setConfirmingDepositId(request.id); setConfirmingDepositId(request.id);
try { try {
const result = await adminConfirmDeposit(reservationId, adminId, normalizedComment); const result = await adminConfirmDeposit(reservationId, adminId, comment);
console.log('[Admin] Deposit confirmation response', { console.log('[Admin] Deposit confirmation response', {
requestId: request?.id, requestId: request?.id,
reservationId, reservationId,
adminId, adminId,
comment: normalizedComment, comment,
status: result?.status, status: result?.status,
ok: result?.ok, ok: result?.ok,
message: result?.message, message: result?.message,
@ -1539,13 +1450,12 @@ export default function BookingRequests() {
status: RESERVATION_STATUS.depositConfirmed, status: RESERVATION_STATUS.depositConfirmed,
adminApproved: true, adminApproved: true,
securityDepositPaid: true, securityDepositPaid: true,
notes: normalizedComment || 'تم تأكيد العربون من قبل الإدارة', notes: comment || 'تم تأكيد العربون من قبل الإدارة',
} }
: req, : req,
), ),
); );
setDepositDialog({ isOpen: false, request: null });
toast.success('تم تأكيد العربون بنجاح'); toast.success('تم تأكيد العربون بنجاح');
} catch (err) { } catch (err) {
console.error('[Admin] Deposit confirmation failed:', err); console.error('[Admin] Deposit confirmation failed:', err);
@ -1670,7 +1580,7 @@ export default function BookingRequests() {
<RequestCard <RequestCard
key={request.id} key={request.id}
request={request} request={request}
onConfirmDeposit={openDepositConfirmationDialog} onConfirmDeposit={handleDepositConfirmation}
onViewDetails={(selectedRequest) => setDetailsDialog({ isOpen: true, request: selectedRequest })} onViewDetails={(selectedRequest) => setDetailsDialog({ isOpen: true, request: selectedRequest })}
confirmingDepositId={confirmingDepositId} confirmingDepositId={confirmingDepositId}
/> />
@ -1699,14 +1609,6 @@ export default function BookingRequests() {
isOpen={detailsDialog.isOpen} isOpen={detailsDialog.isOpen}
onClose={() => setDetailsDialog({ isOpen: false, request: null })} onClose={() => setDetailsDialog({ isOpen: false, request: null })}
/> />
<DepositCommentDialog
isOpen={depositDialog.isOpen}
request={depositDialog.request}
isSubmitting={confirmingDepositId === depositDialog.request?.id}
onClose={closeDepositConfirmationDialog}
onConfirm={(comment) => handleDepositConfirmation(depositDialog.request, comment)}
/>
</div> </div>
); );
} }