This commit is contained in:
@ -9,7 +9,7 @@ import {
|
|||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import toast, { Toaster } from 'react-hot-toast';
|
import toast, { Toaster } from 'react-hot-toast';
|
||||||
import AuthService from '../services/AuthService';
|
import AuthService from '../services/AuthService';
|
||||||
import { getUserReservations, payDeposit } from '../utils/api';
|
import { getRentProperty, getUserReservations, payDeposit } from '../utils/api';
|
||||||
|
|
||||||
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api';
|
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api';
|
||||||
|
|
||||||
@ -39,7 +39,10 @@ function StatusBadge({ code }) {
|
|||||||
|
|
||||||
async function enrich(reservation) {
|
async function enrich(reservation) {
|
||||||
if (!reservation.propertyId) return reservation;
|
if (!reservation.propertyId) return reservation;
|
||||||
reservation._prop = reservation.property ?? null;
|
try {
|
||||||
|
const prop = await getRentProperty(reservation.propertyId);
|
||||||
|
reservation._prop = prop?.propertyInformation ?? prop ?? null;
|
||||||
|
} catch { /* skip */ }
|
||||||
return reservation;
|
return reservation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,9 +115,9 @@ function ReservationCard({ r, onViewDetails, onPay, payingId }) {
|
|||||||
const beds = propBeds(p, r);
|
const beds = propBeds(p, r);
|
||||||
const baths = propBaths(p, r);
|
const baths = propBaths(p, r);
|
||||||
const isOwnerConfirmed = STATUS_MAP[r.status] === 'ownerConfirmed';
|
const isOwnerConfirmed = STATUS_MAP[r.status] === 'ownerConfirmed';
|
||||||
const hasTimeWindow = r.ownerApprovalDate && r.allowedPaymentPeriod;
|
const hasTimeWindow = r.ownerApprovalDate && p?.allowedPaymentPeriod;
|
||||||
const deadline = hasTimeWindow
|
const deadline = hasTimeWindow
|
||||||
? new Date(r.ownerApprovalDate).getTime() + parseTimeSpan(r.allowedPaymentPeriod)
|
? new Date(r.ownerApprovalDate).getTime() + parseTimeSpan(p.allowedPaymentPeriod)
|
||||||
: null;
|
: null;
|
||||||
const isExpired = deadline ? Date.now() > deadline : false;
|
const isExpired = deadline ? Date.now() > deadline : false;
|
||||||
const isPaying = payingId === r.id;
|
const isPaying = payingId === r.id;
|
||||||
@ -150,7 +153,7 @@ function ReservationCard({ r, onViewDetails, onPay, payingId }) {
|
|||||||
<span className="text-sm text-blue-800 font-medium flex items-center gap-1"><Timer className="w-4 h-4"/> متبقي للدفع:</span>
|
<span className="text-sm text-blue-800 font-medium flex items-center gap-1"><Timer className="w-4 h-4"/> متبقي للدفع:</span>
|
||||||
<CountdownTimer deadline={deadline} />
|
<CountdownTimer deadline={deadline} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-blue-600">مدة الدفع: {formatWindowDuration(r.allowedPaymentPeriod)}</div>
|
<div className="text-xs text-blue-600">مدة الدفع: {formatWindowDuration(p.allowedPaymentPeriod)}</div>
|
||||||
</div>}
|
</div>}
|
||||||
<div className="flex gap-3 pt-3 border-t border-gray-100">
|
<div className="flex gap-3 pt-3 border-t border-gray-100">
|
||||||
<button onClick={() => onViewDetails(r)}
|
<button onClick={() => onViewDetails(r)}
|
||||||
@ -171,9 +174,9 @@ function DetailsModal({ r, isOpen, onClose, onPay, payingId }) {
|
|||||||
if (!isOpen || !r) return null;
|
if (!isOpen || !r) return null;
|
||||||
const p = r._prop;
|
const p = r._prop;
|
||||||
const isOwnerConfirmed = STATUS_MAP[r.status] === 'ownerConfirmed';
|
const isOwnerConfirmed = STATUS_MAP[r.status] === 'ownerConfirmed';
|
||||||
const hasTimeWindow = r.ownerApprovalDate && r.allowedPaymentPeriod;
|
const hasTimeWindow = r.ownerApprovalDate && p?.allowedPaymentPeriod;
|
||||||
const deadline = hasTimeWindow
|
const deadline = hasTimeWindow
|
||||||
? new Date(r.ownerApprovalDate).getTime() + parseTimeSpan(r.allowedPaymentPeriod)
|
? new Date(r.ownerApprovalDate).getTime() + parseTimeSpan(p.allowedPaymentPeriod)
|
||||||
: null;
|
: null;
|
||||||
const isExpired = deadline ? Date.now() > deadline : false;
|
const isExpired = deadline ? Date.now() > deadline : false;
|
||||||
const isPaying = payingId === r.id;
|
const isPaying = payingId === r.id;
|
||||||
@ -217,7 +220,7 @@ function DetailsModal({ r, isOpen, onClose, onPay, payingId }) {
|
|||||||
<span className="text-blue-800 font-medium flex items-center gap-2"><Timer className="w-5 h-5"/> متبقي للدفع:</span>
|
<span className="text-blue-800 font-medium flex items-center gap-2"><Timer className="w-5 h-5"/> متبقي للدفع:</span>
|
||||||
<CountdownTimer deadline={deadline} />
|
<CountdownTimer deadline={deadline} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-blue-600 mb-3">مدة الدفع: {formatWindowDuration(r.allowedPaymentPeriod)}</div>
|
<div className="text-xs text-blue-600 mb-3">مدة الدفع: {formatWindowDuration(p.allowedPaymentPeriod)}</div>
|
||||||
{!isExpired && <button onClick={() => { onPay(r); onClose(); }} disabled={isPaying}
|
{!isExpired && <button onClick={() => { onPay(r); onClose(); }} disabled={isPaying}
|
||||||
className={`w-full py-2 rounded-xl font-medium transition-colors flex items-center justify-center gap-2 ${isPaying ? 'bg-gray-300 text-gray-500 cursor-not-allowed' : 'bg-amber-500 text-white hover:bg-amber-600'}`}>
|
className={`w-full py-2 rounded-xl font-medium transition-colors flex items-center justify-center gap-2 ${isPaying ? 'bg-gray-300 text-gray-500 cursor-not-allowed' : 'bg-amber-500 text-white hover:bg-amber-600'}`}>
|
||||||
{isPaying ? <Loader2 className="w-5 h-5 animate-spin"/> : <CreditCard className="w-5 h-5"/>} {isPaying ? 'جاري الدفع...' : 'ادفع الآن'}
|
{isPaying ? <Loader2 className="w-5 h-5 animate-spin"/> : <CreditCard className="w-5 h-5"/>} {isPaying ? 'جاري الدفع...' : 'ادفع الآن'}
|
||||||
|
|||||||
Reference in New Issue
Block a user