116 lines
3.2 KiB
TypeScript
116 lines
3.2 KiB
TypeScript
/**
|
||
* CheckoutConfirmationDialog component
|
||
* Displays checkout information and requests user confirmation before proceeding.
|
||
*/
|
||
|
||
import React, { useEffect, useState } from 'react';
|
||
|
||
interface CheckoutConfirmationRequest {
|
||
price: string;
|
||
state: 'ready' | 'insufficient_funds';
|
||
sessionMetadata: {
|
||
sessionName: string;
|
||
trackId: string;
|
||
carIds: string[];
|
||
};
|
||
timeoutMs: number;
|
||
}
|
||
|
||
interface CheckoutConfirmationDialogProps {
|
||
request: CheckoutConfirmationRequest;
|
||
}
|
||
|
||
export const CheckoutConfirmationDialog: React.FC<CheckoutConfirmationDialogProps> = ({
|
||
request,
|
||
}) => {
|
||
const [remainingSeconds, setRemainingSeconds] = useState(
|
||
Math.floor(request.timeoutMs / 1000)
|
||
);
|
||
|
||
useEffect(() => {
|
||
// Countdown timer
|
||
const intervalId = setInterval(() => {
|
||
setRemainingSeconds((prev) => {
|
||
if (prev <= 1) {
|
||
clearInterval(intervalId);
|
||
window.electronAPI.confirmCheckout('timeout');
|
||
return 0;
|
||
}
|
||
return prev - 1;
|
||
});
|
||
}, 1000);
|
||
|
||
return () => clearInterval(intervalId);
|
||
}, []);
|
||
|
||
const handleConfirm = () => {
|
||
window.electronAPI.confirmCheckout('confirmed');
|
||
};
|
||
|
||
const handleCancel = () => {
|
||
window.electronAPI.confirmCheckout('cancelled');
|
||
};
|
||
|
||
return (
|
||
<div className="checkout-confirmation-dialog">
|
||
<div className="dialog-overlay">
|
||
<div className="dialog-content">
|
||
<h2>Confirm Checkout</h2>
|
||
|
||
<div className="checkout-details">
|
||
<div className="price-section">
|
||
<span className="price-label">Price:</span>
|
||
<span className="price-value">{request.price}</span>
|
||
</div>
|
||
|
||
{request.state === 'insufficient_funds' && (
|
||
<div className="warning-section">
|
||
<span className="warning-text">⚠️ Insufficient funds</span>
|
||
</div>
|
||
)}
|
||
|
||
<div className="session-info">
|
||
<div className="info-row">
|
||
<span className="info-label">Session:</span>
|
||
<span className="info-value">{request.sessionMetadata.sessionName}</span>
|
||
</div>
|
||
<div className="info-row">
|
||
<span className="info-label">Track:</span>
|
||
<span className="info-value">{request.sessionMetadata.trackId}</span>
|
||
</div>
|
||
<div className="info-row">
|
||
<span className="info-label">Cars:</span>
|
||
<span className="info-value">
|
||
{request.sessionMetadata.carIds.join(', ')}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="countdown-section">
|
||
<span className="countdown-text">
|
||
Time remaining: {remainingSeconds}s
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="dialog-actions">
|
||
<button
|
||
type="button"
|
||
className="btn btn-cancel"
|
||
onClick={handleCancel}
|
||
>
|
||
Cancel
|
||
</button>
|
||
<button
|
||
type="button"
|
||
className="btn btn-confirm"
|
||
onClick={handleConfirm}
|
||
>
|
||
Confirm
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}; |