Fixed a bug with What will you use it for, fixed a bug with the sticky pricing card, text change

This commit is contained in:
jackiettran
2026-01-01 18:48:01 -05:00
parent 9e41f328e0
commit fe38ef430a
3 changed files with 34 additions and 20 deletions

View File

@@ -26,6 +26,18 @@ const EmbeddedStripeCheckout: React.FC<EmbeddedStripeCheckoutProps> = ({
const [sessionId, setSessionId] = useState<string>(""); const [sessionId, setSessionId] = useState<string>("");
const hasCreatedSession = useRef(false); const hasCreatedSession = useRef(false);
// Use refs to avoid recreating handleComplete when props change
const rentalDataRef = useRef(rentalData);
const onSuccessRef = useRef(onSuccess);
const onErrorRef = useRef(onError);
const sessionIdRef = useRef(sessionId);
// Keep refs up to date
rentalDataRef.current = rentalData;
onSuccessRef.current = onSuccess;
onErrorRef.current = onError;
sessionIdRef.current = sessionId;
const createCheckoutSession = useCallback(async () => { const createCheckoutSession = useCallback(async () => {
// Prevent multiple session creations // Prevent multiple session creations
if (hasCreatedSession.current) return; if (hasCreatedSession.current) return;
@@ -54,16 +66,17 @@ const EmbeddedStripeCheckout: React.FC<EmbeddedStripeCheckoutProps> = ({
createCheckoutSession(); createCheckoutSession();
}, [createCheckoutSession]); }, [createCheckoutSession]);
// Use useCallback with empty deps - refs provide access to latest values
const handleComplete = useCallback(() => { const handleComplete = useCallback(() => {
// For embedded checkout, we need to retrieve the session to get payment method // For embedded checkout, we need to retrieve the session to get payment method
(async () => { (async () => {
try { try {
if (!sessionId) { if (!sessionIdRef.current) {
throw new Error("No session ID available"); throw new Error("No session ID available");
} }
// Get the completed checkout session // Get the completed checkout session
const sessionResponse = await stripeAPI.getCheckoutSession(sessionId); const sessionResponse = await stripeAPI.getCheckoutSession(sessionIdRef.current);
const { status: sessionStatus, setup_intent } = sessionResponse.data; const { status: sessionStatus, setup_intent } = sessionResponse.data;
if (sessionStatus !== "complete") { if (sessionStatus !== "complete") {
@@ -75,8 +88,8 @@ const EmbeddedStripeCheckout: React.FC<EmbeddedStripeCheckoutProps> = ({
} }
// Extract payment method ID - handle both string ID and object cases // Extract payment method ID - handle both string ID and object cases
const paymentMethodId = typeof setup_intent.payment_method === 'string' const paymentMethodId = typeof setup_intent.payment_method === 'string'
? setup_intent.payment_method ? setup_intent.payment_method
: setup_intent.payment_method.id; : setup_intent.payment_method.id;
if (!paymentMethodId) { if (!paymentMethodId) {
@@ -85,17 +98,17 @@ const EmbeddedStripeCheckout: React.FC<EmbeddedStripeCheckoutProps> = ({
// Create the rental with the payment method ID // Create the rental with the payment method ID
const rentalPayload = { const rentalPayload = {
...rentalData, ...rentalDataRef.current,
stripePaymentMethodId: paymentMethodId stripePaymentMethodId: paymentMethodId
}; };
await rentalAPI.createRental(rentalPayload); await rentalAPI.createRental(rentalPayload);
onSuccess(); onSuccessRef.current();
} catch (error: any) { } catch (error: any) {
onError(error.response?.data?.error || error.message || "Failed to complete rental request"); onErrorRef.current(error.response?.data?.error || error.message || "Failed to complete rental request");
} }
})(); })();
}, [sessionId, rentalData, onSuccess, onError]); }, []);
if (creating) { if (creating) {
return ( return (

View File

@@ -588,7 +588,7 @@ const ItemDetail: React.FC = () => {
</div> </div>
{/* Mobile Pricing Card - shown inline on mobile */} {/* Mobile Pricing Card - shown inline on mobile */}
<div className="d-md-none mb-4"> <div className="d-md-none mb-4" id="mobile-pricing-card">
<div className="card sticky-pricing-card"> <div className="card sticky-pricing-card">
<div className="card-body text-center"> <div className="card-body text-center">
{(() => { {(() => {
@@ -1132,9 +1132,9 @@ const ItemDetail: React.FC = () => {
<button <button
className="btn btn-primary btn-lg" className="btn btn-primary btn-lg"
onClick={() => { onClick={() => {
const pricingCard = document.getElementById("pricing-card"); const mobilePricingCard = document.getElementById("mobile-pricing-card");
if (pricingCard) { if (mobilePricingCard) {
pricingCard.scrollIntoView({ mobilePricingCard.scrollIntoView({
behavior: "smooth", behavior: "smooth",
block: "start", block: "start",
}); });

View File

@@ -455,19 +455,20 @@ const RentItem: React.FC = () => {
<> <>
<div className="card mb-3"> <div className="card mb-3">
<div className="card-body"> <div className="card-body">
<h6 className="mb-3"> <p className="mb-0">
Add your payment method to complete your Add your payment method to complete your
request. You'll only be charged if the owner request. You'll only be charged if the owner
approves your request approves your request.
</h6> </p>
<EmbeddedStripeCheckout
rentalData={getRentalData()}
onSuccess={() => setCompleted(true)}
onError={(error) => setError(error)}
/>
</div> </div>
</div> </div>
<EmbeddedStripeCheckout
rentalData={getRentalData()}
onSuccess={() => setCompleted(true)}
onError={(error) => setError(error)}
/>
<div className="text-center mt-3"> <div className="text-center mt-3">
<button <button
type="button" type="button"