import React, { useState, useEffect, useCallback } from "react"; import { rentalAPI } from "../services/api"; import { RefundPreview, Rental } from "../types"; interface RentalCancellationModalProps { show: boolean; onHide: () => void; rental: Rental; onCancellationComplete: (updatedRental: Rental) => void; } const RentalCancellationModal: React.FC = ({ show, onHide, rental, onCancellationComplete, }) => { const [refundPreview, setRefundPreview] = useState( null ); const [loading, setLoading] = useState(false); const [processing, setProcessing] = useState(false); const [error, setError] = useState(null); const [reason, setReason] = useState(""); useEffect(() => { if (show && rental) { loadRefundPreview(); } }, [show, rental]); const loadRefundPreview = async () => { try { setLoading(true); setError(null); const response = await rentalAPI.getRefundPreview(rental.id); setRefundPreview(response.data); } catch (error: any) { setError( error.response?.data?.error || "Failed to calculate refund preview" ); } finally { setLoading(false); } }; const handleCancel = async () => { if (!refundPreview) return; try { setProcessing(true); setError(null); const response = await rentalAPI.cancelRental(rental.id, reason.trim()); onCancellationComplete(response.data.rental); onHide(); } catch (error: any) { setError(error.response?.data?.error || "Failed to cancel rental"); } finally { setProcessing(false); } }; const formatCurrency = (amount: number | string | undefined) => { const numAmount = Number(amount) || 0; return `$${numAmount.toFixed(2)}`; }; const getRefundColor = (percentage: number) => { if (percentage === 0) return "danger"; if (percentage === 0.5) return "warning"; return "success"; }; const handleBackdropClick = useCallback( (e: React.MouseEvent) => { if (e.target === e.currentTarget) { onHide(); } }, [onHide] ); const handleKeyDown = useCallback( (e: KeyboardEvent) => { if (e.key === "Escape") { onHide(); } }, [onHide] ); useEffect(() => { if (show) { document.addEventListener("keydown", handleKeyDown); document.body.style.overflow = "hidden"; } else { document.removeEventListener("keydown", handleKeyDown); document.body.style.overflow = "unset"; } return () => { document.removeEventListener("keydown", handleKeyDown); document.body.style.overflow = "unset"; }; }, [show, handleKeyDown]); if (!show) return null; return (
Cancel Rental
{loading && (
Loading...
Calculating refund...
)} {error && (
{error}
)} {refundPreview && !loading && ( <>
Rental Details

Item: {rental.item?.name}

Start:{" "} {new Date(rental.startDateTime).toLocaleString()}

End:{" "} {new Date(rental.endDateTime).toLocaleString()}

Total Amount:{" "} {formatCurrency(rental.totalAmount)}

Refund Information
Refund Amount:{" "} {formatCurrency(refundPreview.refundAmount)}
{Math.round(refundPreview.refundPercentage * 100)}%

{refundPreview.reason}