From 389dca56d20581f12d553d74ef32de8fc8b8ff65 Mon Sep 17 00:00:00 2001 From: Rahaf Date: Wed, 24 Jun 2026 15:04:56 +0300 Subject: [PATCH] Edit payments --- app/payments/page.js | 617 +++++++++++++++++++++++++------------------ 1 file changed, 363 insertions(+), 254 deletions(-) diff --git a/app/payments/page.js b/app/payments/page.js index 8b6caba..5550b86 100644 --- a/app/payments/page.js +++ b/app/payments/page.js @@ -1,162 +1,28 @@ -// 'use client'; - -// import { useEffect, useState, useCallback } from 'react'; -// import { useRouter } from 'next/navigation'; -// import { motion } from 'framer-motion'; -// import { CreditCard, Loader2, Home, Calendar, Check, X, Clock } from 'lucide-react'; -// import toast, { Toaster } from 'react-hot-toast'; -// import AuthService from '@/app/services/AuthService'; -// import { getUserReservations, payDeposit } from '@/app/utils/api'; - -// const STATUS_MAP = ['pending', 'ownerConfirmed', 'depositPaid', 'depositConfirmed', 'completed', 'cancelled']; - -// const STATUS_CONFIG = { -// pending: { label: 'قيد الانتظار', color: 'bg-yellow-100 text-yellow-800 border-yellow-300', depositPaid: false }, -// ownerConfirmed: { label: 'مؤكد من المالك', color: 'bg-blue-100 text-blue-800 border-blue-300', depositPaid: false }, -// depositPaid: { label: 'تم دفع السلفة', color: 'bg-orange-100 text-orange-800 border-orange-300', depositPaid: true }, -// depositConfirmed: { label: 'تم تأكيد الدفع', color: 'bg-green-100 text-green-800 border-green-300', depositPaid: true }, -// completed: { label: 'منتهي', color: 'bg-teal-100 text-teal-800 border-teal-300', depositPaid: true }, -// cancelled: { label: 'ملغي', color: 'bg-red-100 text-red-800 border-red-300', depositPaid: false }, -// }; - -// export default function PaymentsPage() { -// const router = useRouter(); -// const [reservations, setReservations] = useState([]); -// const [loading, setLoading] = useState(true); -// const [payingId, setPayingId] = useState(null); - -// useEffect(() => { -// // Admin check removed -// // if (AuthService.isAdmin()) { -// // router.push('/'); -// // return; -// // } -// loadReservations(); -// }, [router]); - -// const loadReservations = useCallback(async () => { -// try { -// const data = await getUserReservations(); -// setReservations(Array.isArray(data) ? data : []); -// } catch (err) { -// console.error(err); -// toast.error('فشل تحميل المدفوعات'); -// } finally { -// setLoading(false); -// } -// }, []); - -// const handlePayDeposit = async (reservation) => { -// setPayingId(reservation.id); -// try { -// await payDeposit({ reservationId: reservation.id }); -// toast.success('تم دفع السلفة بنجاح!'); -// loadReservations(); -// } catch (err) { -// toast.error(err?.message || 'فشل عملية الدفع'); -// } finally { -// setPayingId(null); -// } -// }; - -// const formatCurrency = (v) => (v ?? 0).toLocaleString() + ' ل.س'; - -// if (loading) { -// return ( -//
-// -//
-// ); -// } - -// const canPay = (status) => STATUS_MAP[status] === 'pending' || STATUS_MAP[status] === 'ownerConfirmed'; - -// return ( -//
-// -//
-// -//

المدفوعات

-//

إدارة مدفوعات الحجوزات والدفعات المقدمة

-//
- -// {reservations.length === 0 ? ( -// -// -//

لا توجد معاملات مالية

-//

ستظهر هنا مدفوعاتك للحجوزات

-//
-// ) : ( -//
-// {reservations.map((r, i) => { -// const statusKey = STATUS_MAP[r.status] || 'pending'; -// const cfg = STATUS_CONFIG[statusKey]; -// const amount = r.depositAmount || r.totalPrice || 0; - -// return ( -// -//
-//
-//
-// -//
-//
-//

-// {r.propertyAddress || r._prop?.address || `عقار #${r.propertyId || r.id}`} -//

-//

حجز #{r.id}

-//
-// {new Date(r.startDate).toLocaleDateString('ar')} -// {new Date(r.endDate).toLocaleDateString('ar')} -//
-//
-//
-//
-//
{formatCurrency(amount)}
-// -// {cfg.depositPaid ? : } -// {cfg.label} -// -//
-//
- -// {canPay(r.status) && ( -//
-// -//
-// )} -//
-// ); -// })} -//
-// )} -//
-//
-// ); -// } - - - - - - - - - - 'use client'; import { useEffect, useState, useCallback } from 'react'; -import { useRouter } from 'next/navigation'; import Link from 'next/link'; import { motion } from 'framer-motion'; -import { CreditCard, Loader2, Home, Calendar, Check, X, Clock, LogIn, Lock } from 'lucide-react'; +import { + Home, + MapPin, + Phone, + ShieldCheck, + CreditCard, + Banknote, + Building, + ArrowLeftRight, + Loader2, + Check, + X, + Calendar, + Clock, + LogIn, + Lock, + Info, + Landmark, + Wallet, +} from 'lucide-react'; import toast, { Toaster } from 'react-hot-toast'; import AuthService from '@/app/services/AuthService'; import { payDeposit } from '@/app/utils/api'; @@ -164,20 +30,62 @@ import { payDeposit } from '@/app/utils/api'; const STATUS_MAP = ['pending', 'ownerConfirmed', 'depositPaid', 'depositConfirmed', 'completed', 'cancelled']; const STATUS_CONFIG = { - pending: { label: 'قيد الانتظار', color: 'bg-yellow-100 text-yellow-800 border-yellow-300', depositPaid: false }, - ownerConfirmed: { label: 'مؤكد من المالك', color: 'bg-blue-100 text-blue-800 border-blue-300', depositPaid: false }, - depositPaid: { label: 'تم دفع السلفة', color: 'bg-orange-100 text-orange-800 border-orange-300', depositPaid: true }, - depositConfirmed: { label: 'تم تأكيد الدفع', color: 'bg-green-100 text-green-800 border-green-300', depositPaid: true }, - completed: { label: 'منتهي', color: 'bg-teal-100 text-teal-800 border-teal-300', depositPaid: true }, - cancelled: { label: 'ملغي', color: 'bg-red-100 text-red-800 border-red-300', depositPaid: false }, + pending: { label: 'قيد الانتظار', color: 'bg-yellow-100 text-yellow-800 border-yellow-300', icon: Clock }, + ownerConfirmed: { label: 'مؤكد من المالك', color: 'bg-blue-100 text-blue-800 border-blue-300', icon: ShieldCheck }, + depositPaid: { label: 'تم دفع السلفة', color: 'bg-orange-100 text-orange-800 border-orange-300', icon: Wallet }, + depositConfirmed: { label: 'تم تأكيد الدفع', color: 'bg-green-100 text-green-800 border-green-300', icon: Check }, + completed: { label: 'منتهي', color: 'bg-teal-100 text-teal-800 border-teal-300', icon: Check }, + cancelled: { label: 'ملغي', color: 'bg-red-100 text-red-800 border-red-300', icon: X }, }; +const PAYMENT_METHODS = [ + { + id: 'cash', + label: 'الدفع النقدي', + desc: 'ادفع الآن عبر شام كاش مع تأكيد تلقائي للحجز', + icon: Banknote, + active: true, + }, + { + id: 'office', + label: 'نقداً', + desc: 'ادفع في مكتب المنصة. يتم التأكيد لاحقاً', + icon: Building, + active: true, + }, + { + id: 'transfer', + label: 'تحويل داخلي', + desc: 'حول من حساب داخلي ثم أرسل المرجع', + icon: ArrowLeftRight, + active: false, + }, + { + id: 'electronic', + label: 'دفع إلكتروني', + desc: 'سيتم تفعيل الدفع الإلكتروني والتحويل لاحقاً', + icon: CreditCard, + active: false, + }, +]; + +function formatCurrency(v, sign = 'ل.س') { + return `${sign} ${Number(v ?? 0).toLocaleString()}`; +} + +function formatDate(date) { + if (!date) return ''; + const d = new Date(date); + if (Number.isNaN(d.getTime())) return ''; + return d.toLocaleDateString('en-GB'); +} + export default function PaymentsPage() { - const router = useRouter(); const [reservations, setReservations] = useState([]); const [loading, setLoading] = useState(true); const [payingId, setPayingId] = useState(null); const [isGuest, setIsGuest] = useState(null); + const [selectedPayment, setSelectedPayment] = useState('cash'); const getAuthToken = () => { if (typeof window === 'undefined') return ''; @@ -214,10 +122,11 @@ export default function PaymentsPage() { const reservation = deposit?.reservation || {}; const transaction = deposit?.transaction || {}; const currency = item?.currency || {}; + const propertyInfo = reservation?.propertyInformation || {}; return { - id: reservation.id ?? deposit.reservationId ?? deposit?.reservation?.id ?? item?.reservationId ?? deposit?.id, - reservationId: reservation.id ?? deposit.reservationId ?? item?.reservationId ?? deposit?.id, + id: deposit.id ?? reservation.id ?? item?.id, + reservationId: reservation.id ?? deposit.reservationId ?? item?.reservationId, status: reservation.status ?? 0, startDate: reservation.startDate, endDate: reservation.endDate, @@ -226,7 +135,11 @@ export default function PaymentsPage() { currencySign: currency.sign || 'ل.س', currencyName: currency.name || '', currencyRate: currency.rate, + propertyName: propertyInfo.name || propertyInfo.address || reservation.propertyName || `عقار #${reservation.id || ''}`, + propertyAddress: propertyInfo.address || reservation.propertyAddress || '', + propertyCity: propertyInfo.city || reservation.city || '', _deposit: deposit, + _reservation: reservation, }; }); @@ -262,14 +175,7 @@ export default function PaymentsPage() { } }; - const formatCurrency = (v, sign = 'ل.س') => `${sign} ${Number(v ?? 0).toLocaleString()}`; - - const formatDate = (date) => { - if (!date) return ''; - const d = new Date(date); - if (Number.isNaN(d.getTime())) return ''; - return d.toLocaleDateString('en-GB'); - }; + const canPay = (status) => STATUS_MAP[status] === 'ownerConfirmed'; if (loading) { return ( @@ -306,18 +212,83 @@ export default function PaymentsPage() { ); } - const canPay = (status) => STATUS_MAP[status] === 'pending' || STATUS_MAP[status] === 'ownerConfirmed'; + const payables = reservations.filter((r) => canPay(r.status)); + const others = reservations.filter((r) => !canPay(r.status)); return (
- +

المدفوعات

إدارة مدفوعات الحجوزات والدفعات المقدمة

- {reservations.length === 0 ? ( + {payables.length > 0 && ( +
+

+ + المدفوعات المطلوبة +

+ {payables.map((r, i) => ( + + ))} +
+ )} + + {others.length > 0 && ( +
+

+ + الحجوزات السابقة +

+ {others.map((r, i) => { + const statusKey = STATUS_MAP[r.status] || 'pending'; + const cfg = STATUS_CONFIG[statusKey]; + const Icon = cfg.icon; + const amount = r.depositAmount || r.totalPrice || 0; + + return ( + +
+ #{r.reservationId || r.id} + + + {cfg.label} + +
+
+
+ + {formatDate(r.startDate)} - {formatDate(r.endDate)} +
+
+ {formatCurrency(amount, r.currencySign)} +
+
+
+ ); + })} +
+ )} + + {reservations.length === 0 && ( لا توجد معاملات مالية

ستظهر هنا مدفوعاتك للحجوزات

- ) : ( -
- {reservations.map((r, i) => { - const statusKey = STATUS_MAP[r.status] || 'pending'; - const cfg = STATUS_CONFIG[statusKey]; - const amount = r.depositAmount || r.totalPrice || 0; - - return ( - -
-
- #{r.reservationId || r.id} - - {cfg.depositPaid ? : } - {cfg.label} - -
- -
-
-
- -
-
-
Reservation
-
#{r.reservationId || r.id}
-
-
- -
-
{r.currencyName}
-
- {formatCurrency(amount, r.currencySign)} -
-
-
- -
-
- - - الفترة - - - {formatDate(r.startDate)} - {formatDate(r.endDate)} - -
- -
- - - Reservation - - #{r.reservationId || r.id} -
-
- - {canPay(r.status) && ( -
- -
- )} -
-
- ); - })} -
)}
); -} \ No newline at end of file +} + +function PaymentCard({ reservation, payingId, selectedPayment, onSelectPayment, onPay }) { + const r = reservation; + const amount = r.depositAmount || r.totalPrice || 0; + const [showCashDialog, setShowCashDialog] = useState(false); + + return ( + <> + + {/* Property details */} +
+
+
+ +
+
+

+ {r.propertyName} +

+ {(r.propertyAddress || r.propertyCity) && ( +

+ + {[r.propertyCity, r.propertyAddress].filter(Boolean).join(' - ')} +

+ )} +
+
+ +
+ + + {formatDate(r.startDate)} - {formatDate(r.endDate)} + + + + #{r.reservationId || r.id} + +
+
+ + {/* Deposit amount */} +
+
+

مبلغ التأمين (الرعبون)

+

+ {formatCurrency(amount, r.currencySign)} +

+

+ يتم دفع التأمين إلى المنصة وليس إلى المالك +

+
+
+ + {/* Payment methods note */} +
+
+ +

+ الدفع النقدي فقط هو المتاح. سيتم تفعيل الدفع الإلكتروني والتحويل لاحقاً. +

+
+
+ + {/* Payment method options */} +
+

طريقة الدفع

+
+ {PAYMENT_METHODS.map((method) => { + const isSelected = selectedPayment === method.id; + const Icon = method.icon; + return ( + + ); + })} +
+
+ + {/* Pay button */} +
+ onPay(r)} + disabled={payingId === r.id} + whileHover={{ scale: 1.01 }} + whileTap={{ scale: 0.99 }} + className="w-full bg-amber-500 hover:bg-amber-600 disabled:bg-amber-300 text-white font-bold py-4 px-6 rounded-2xl text-lg transition-all shadow-lg hover:shadow-xl flex items-center justify-center gap-3" + > + {payingId === r.id ? ( + <> + + جاري الدفع... + + ) : ( + <> + + دفع التأمين ({formatCurrency(amount, r.currencySign)}) + + )} + +
+ + {/* Cash pay button */} +
+ +
+ + {/* Cash payment dialog */} + {showCashDialog && ( +
+ +
+ +
+

الدفع النقدي قيد الانتظار

+

+ اذهب إلى موقع المنصة وادفع العربون. +
+ ستقوم المنصة بتأكيد الدفع بعد استلام المبلغ. +

+
+

موقع المنصة

+

مكتب المنصة: أبو رمانة، شارع المالكي، دمشق

+

+ + +963567823411 +

+
+
+ + + حجوزاتي + +
+
+
+ )} + + {/* Platform location */} +
+
+ +
+

موقع الدفع النقدي

+

+ مكتب المنصة: أبو رمانة، شارع المالكي، دمشق +

+

+ + +963567823411 +

+
+
+
+
+ + ); +}