import React, { useState, useEffect } 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(""); const [success, setSuccess] = useState(false); const [processedRefund, setProcessedRefund] = useState<{ amount: number; refundId?: string; } | null>(null); const [updatedRental, setUpdatedRental] = useState(null); useEffect(() => { if (show && rental) { loadRefundPreview(); } }, [show, rental]); const loadRefundPreview = async () => { try { setLoading(true); setError(null); // Check if rental status allows cancellation before making API call if (rental.status !== "pending" && rental.status !== "confirmed") { let errorMessage = "This rental cannot be cancelled"; if (rental.status === "active") { errorMessage = "Cannot cancel rental - the rental period has already started"; } else if (rental.status === "completed") { errorMessage = "Cannot cancel rental - the rental has already been completed"; } else if (rental.status === "cancelled") { errorMessage = "This rental has already been cancelled"; } setError(errorMessage); return; } 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; // Validate reason is provided const trimmedReason = reason.trim(); if (!trimmedReason) { setError("Please provide a cancellation reason"); return; } try { setProcessing(true); setError(null); const response = await rentalAPI.cancelRental(rental.id, trimmedReason); // Store refund details for confirmation screen setProcessedRefund({ amount: refundPreview.refundAmount, refundId: response.data.rental.stripeRefundId }); // Store updated rental data for later callback setUpdatedRental(response.data.rental); // Show success confirmation instead of closing immediately setSuccess(true); // Don't call onCancellationComplete here - wait until user clicks "Done" } catch (error: any) { setError(error.response?.data?.error || "Failed to cancel rental"); } finally { setProcessing(false); } }; const handleClose = () => { // Call parent callback with updated rental data if we have it if (updatedRental) { onCancellationComplete(updatedRental); } // Reset all states when closing setRefundPreview(null); setLoading(false); setProcessing(false); setError(null); setReason(""); setSuccess(false); setProcessedRefund(null); setUpdatedRental(null); onHide(); }; 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"; }; useEffect(() => { if (show) { document.body.style.overflow = "hidden"; } else { document.body.style.overflow = "unset"; } return () => { document.body.style.overflow = "unset"; }; }, [show]); if (!show) return null; return (
{success ? (rental.totalAmount > 0 ? "Refund Confirmation" : "Cancellation Confirmation") : "Cancel Rental" }
{success && processedRefund ? (

{rental.totalAmount > 0 ? 'Refund Processed Successfully!' : 'Rental Cancelled Successfully!'}

{rental.totalAmount > 0 && (
{formatCurrency(processedRefund.amount)} has been refunded

Your refund will appear in your payment method within 3-5 business days

Refund will be processed to your original payment method

)}

Thank you for using our platform. We hope you'll rent with us again soon!

) : ( <> {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)}

{rental.totalAmount > 0 && (
Refund Information
Refund Amount:{" "} {formatCurrency(refundPreview.refundAmount)}
{Math.round(refundPreview.refundPercentage * 100)}%

{refundPreview.reason}
)}