refund and delayed charge

This commit is contained in:
jackiettran
2025-09-04 16:44:47 -04:00
parent b59fc07fc3
commit b22e4fa910
19 changed files with 1255 additions and 594 deletions

View File

@@ -1,9 +1,9 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useRef } from "react";
import { useParams, useNavigate, useSearchParams } from "react-router-dom";
import { Item } from "../types";
import { useAuth } from "../contexts/AuthContext";
import { itemAPI, rentalAPI } from "../services/api";
import StripePaymentForm from "../components/StripePaymentForm";
import EmbeddedStripeCheckout from "../components/EmbeddedStripeCheckout";
const RentItem: React.FC = () => {
const { id } = useParams<{ id: string }>();
@@ -27,6 +27,7 @@ const RentItem: React.FC = () => {
});
const [totalCost, setTotalCost] = useState(0);
const [completed, setCompleted] = useState(false);
const convertToUTC = (dateString: string, timeString: string): string => {
if (!dateString || !timeString) {
@@ -117,8 +118,29 @@ const RentItem: React.FC = () => {
}
};
const handlePaymentSuccess = () => {
console.log("Stripe checkout session created successfully");
const getRentalData = () => {
try {
const startDateTime = convertToUTC(
manualSelection.startDate,
manualSelection.startTime
);
const endDateTime = convertToUTC(
manualSelection.endDate,
manualSelection.endTime
);
return {
itemId: id,
startDateTime,
endDateTime,
deliveryMethod: formData.deliveryMethod,
deliveryAddress: formData.deliveryAddress,
totalAmount: totalCost,
};
} catch (error: any) {
setError(error.message);
return null;
}
};
const handleChange = (
@@ -173,42 +195,69 @@ const RentItem: React.FC = () => {
<div className="row">
<div className="col-md-8">
<div className="card mb-4">
<div className="card-body">
<h5 className="card-title">Payment</h5>
<StripePaymentForm
total={totalCost}
itemName={item.name}
rentalData={{
itemId: item.id,
startDateTime: convertToUTC(
manualSelection.startDate,
manualSelection.startTime
),
endDateTime: convertToUTC(
manualSelection.endDate,
manualSelection.endTime
),
totalAmount: totalCost,
deliveryMethod: "pickup",
}}
onSuccess={handlePaymentSuccess}
onError={(error) => setError(error)}
disabled={
!manualSelection.startDate || !manualSelection.endDate
}
/>
<button
type="button"
className="btn btn-secondary mt-2"
onClick={() => navigate(`/items/${id}`)}
>
Cancel
</button>
{completed ? (
<div className="card mb-4">
<div className="card-body text-center">
<div className="alert alert-success">
<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.
You'll only be charged if they approve your request.
</p>
<div className="d-grid gap-2 d-md-block">
<button
className="btn btn-primary me-2"
onClick={() => navigate("/my-rentals")}
>
View My Rentals
</button>
<button
className="btn btn-outline-secondary"
onClick={() => navigate("/")}
>
Continue Browsing
</button>
</div>
</div>
</div>
</div>
</div>
) : (
<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>
{!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.
</div>
) : (
<>
<EmbeddedStripeCheckout
rentalData={getRentalData()}
onSuccess={() => setCompleted(true)}
onError={(error) => setError(error)}
/>
<div className="text-center mt-3">
<button
type="button"
className="btn btn-outline-secondary"
onClick={() => navigate(`/items/${id}`)}
>
Cancel Request
</button>
</div>
</>
)}
</div>
</div>
)}
</div>
<div className="col-md-4">