Skip payment process if item is free to borrow

This commit is contained in:
jackiettran
2025-09-22 22:02:08 -04:00
parent 3e76769a3e
commit 67cc997ddc
7 changed files with 245 additions and 68 deletions

View File

@@ -152,7 +152,10 @@ const RentalCancellationModal: React.FC<RentalCancellationModalProps> = ({
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">
{success ? "Refund Confirmation" : "Cancel Rental"}
{success
? (rental.totalAmount > 0 ? "Refund Confirmation" : "Cancellation Confirmation")
: "Cancel Rental"
}
</h5>
<button
type="button"
@@ -167,22 +170,26 @@ const RentalCancellationModal: React.FC<RentalCancellationModalProps> = ({
<div className="mb-4">
<i className="bi bi-check-circle-fill text-success" style={{ fontSize: '4rem' }}></i>
</div>
<h3 className="text-success mb-3">Refund Processed Successfully!</h3>
<div className="alert alert-success mb-4">
<h5 className="mb-3">
<strong>{formatCurrency(processedRefund.amount)}</strong> has been refunded
</h5>
<div className="small text-muted">
<p className="mb-2">
<i className="bi bi-clock me-2"></i>
Your refund will appear in your payment method within <strong>3-5 business days</strong>
</p>
<p className="mb-0">
<i className="bi bi-credit-card me-2"></i>
Refund will be processed to your original payment method
</p>
<h3 className="text-success mb-3">
{rental.totalAmount > 0 ? 'Refund Processed Successfully!' : 'Rental Cancelled Successfully!'}
</h3>
{rental.totalAmount > 0 && (
<div className="alert alert-success mb-4">
<h5 className="mb-3">
<strong>{formatCurrency(processedRefund.amount)}</strong> has been refunded
</h5>
<div className="small text-muted">
<p className="mb-2">
<i className="bi bi-clock me-2"></i>
Your refund will appear in your payment method within <strong>3-5 business days</strong>
</p>
<p className="mb-0">
<i className="bi bi-credit-card me-2"></i>
Refund will be processed to your original payment method
</p>
</div>
</div>
</div>
)}
<p className="text-muted mb-4">
Thank you for using our platform. We hope you'll rent with us again soon!
</p>
@@ -227,28 +234,30 @@ const RentalCancellationModal: React.FC<RentalCancellationModalProps> = ({
</div>
</div>
<div className="mb-4">
<h5>Refund Information</h5>
<div
className={`alert alert-${getRefundColor(
refundPreview.refundPercentage
)}`}
>
<div className="d-flex justify-content-between align-items-center">
<div>
<strong>Refund Amount:</strong>{" "}
{formatCurrency(refundPreview.refundAmount)}
</div>
<div>
<strong>
{Math.round(refundPreview.refundPercentage * 100)}%
</strong>
{rental.totalAmount > 0 && (
<div className="mb-4">
<h5>Refund Information</h5>
<div
className={`alert alert-${getRefundColor(
refundPreview.refundPercentage
)}`}
>
<div className="d-flex justify-content-between align-items-center">
<div>
<strong>Refund Amount:</strong>{" "}
{formatCurrency(refundPreview.refundAmount)}
</div>
<div>
<strong>
{Math.round(refundPreview.refundPercentage * 100)}%
</strong>
</div>
</div>
<hr />
<small>{refundPreview.reason}</small>
</div>
<hr />
<small>{refundPreview.reason}</small>
</div>
</div>
)}
<form>
<div className="mb-3">
@@ -310,11 +319,13 @@ const RentalCancellationModal: React.FC<RentalCancellationModalProps> = ({
Processing...
</>
) : (
`Cancel with ${
refundPreview.refundAmount > 0
? `Refund ${formatCurrency(refundPreview.refundAmount)}`
: "No Refund"
}`
rental.totalAmount > 0
? `Cancel with ${
refundPreview.refundAmount > 0
? `Refund ${formatCurrency(refundPreview.refundAmount)}`
: "No Refund"
}`
: "Cancel Rental"
)}
</button>
)}

View File

@@ -143,6 +143,21 @@ const RentItem: React.FC = () => {
}
};
const handleFreeBorrow = async () => {
const rentalData = getRentalData();
if (!rentalData) return;
try {
setError(null);
await rentalAPI.createRental(rentalData);
setCompleted(true);
} catch (error: any) {
setError(
error.response?.data?.error || "Failed to create rental request"
);
}
};
const handleChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
@@ -202,7 +217,7 @@ const RentItem: React.FC = () => {
<i className="bi bi-check-circle-fill display-1 text-success mb-3"></i>
<h3>Rental Request Sent!</h3>
<p className="mb-3">
Your rental request has been submitted to the owner.
Your rental request has been submitted to the owner.
You'll only be charged if they approve your request.
</p>
<div className="d-grid gap-2 d-md-block">
@@ -225,17 +240,54 @@ const RentItem: React.FC = () => {
) : (
<div className="card mb-4">
<div className="card-body">
<h5 className="card-title">Complete Your Rental Request</h5>
<p className="text-muted small mb-3">
Add your payment method to complete your rental request.
You'll only be charged if the owner approves your request.
</p>
<h5 className="card-title">
{totalCost === 0
? "Complete Your Borrow Request"
: "Complete Your Rental Request"}
</h5>
{totalCost > 0 && (
<p className="text-muted small mb-3">
Add your payment method to complete your rental request.
You'll only be charged if the owner approves your
request.
</p>
)}
{!manualSelection.startDate || !manualSelection.endDate || !getRentalData() ? (
{!manualSelection.startDate ||
!manualSelection.endDate ||
!getRentalData() ? (
<div className="alert alert-info">
<i className="bi bi-info-circle me-2"></i>
Please complete the rental dates and details above to proceed with payment setup.
Please complete the rental dates and details above to
proceed with{" "}
{totalCost === 0
? "your borrow request"
: "payment setup"}
.
</div>
) : totalCost === 0 ? (
<>
<div className="alert alert-success">
<i className="bi bi-check-circle me-2"></i>
This item is free to borrow! No payment required
</div>
<div className="d-grid gap-2">
<button
type="button"
className="btn btn-primary"
onClick={handleFreeBorrow}
>
Confirm Borrow Request
</button>
<button
type="button"
className="btn btn-outline-secondary"
onClick={() => navigate(`/items/${id}`)}
>
Cancel Request
</button>
</div>
</>
) : (
<>
<EmbeddedStripeCheckout
@@ -243,7 +295,7 @@ const RentItem: React.FC = () => {
onSuccess={() => setCompleted(true)}
onError={(error) => setError(error)}
/>
<div className="text-center mt-3">
<button
type="button"
@@ -280,7 +332,7 @@ const RentItem: React.FC = () => {
<p className="text-muted small">
{item.city && item.state
? `${item.city}, ${item.state}`
: ''}
: ""}
</p>
<hr />