import { useCallback, useEffect, useRef, useState } from 'react';
import { useFocusTrap } from '../../lib/use-focus-trap';
import { VOCAB } from '../../lib/collection-vocabulary.js';
import { Button } from '../ui';
import ReviewCardItem from './ReviewCardItem';
function confidencePercent(confidence) {
if (confidence == null || Number.isNaN(confidence)) return null;
return confidence <= 1 ? Math.round(confidence * 100) : Math.round(confidence);
}
function CheckoutFooter({
selectedCount,
isProcessing,
commitError,
onCommitOwned,
onOpenListPicker,
}) {
const selectHintId = 'checkout-select-hint';
return (
{commitError && (
{commitError}
)}
{selectedCount === 0 && (
Select at least one card
)}
);
}
export function ScannerCheckoutContent({
queue,
onOpenListPicker,
onEmpty,
headerId = 'checkout-sheet-title',
}) {
const [commitError, setCommitError] = useState(null);
const initialSelectionDoneRef = useRef(false);
const cartCards = queue.scannedCards.filter((card) => !card.processed);
const selectedCount = cartCards.filter((card) => queue.selectedCards.has(card.id)).length;
const lowConfidenceCount = cartCards.filter((card) => {
const pct = confidencePercent(card.confidence);
return pct != null && pct < 70;
}).length;
useEffect(() => {
if (initialSelectionDoneRef.current) return;
cartCards.forEach((card) => {
if (!queue.selectedCards.has(card.id)) {
queue.toggleCardSelection(card.id);
}
});
initialSelectionDoneRef.current = true;
}, [cartCards, queue]);
useEffect(() => {
if (cartCards.length === 0) {
onEmpty?.();
}
}, [cartCards.length, onEmpty]);
const handleCommitOwned = async () => {
setCommitError(null);
const beforeIds = cartCards
.filter((card) => queue.selectedCards.has(card.id))
.map((card) => card.id);
if (beforeIds.length === 0) return;
const successfulIds = await queue.commitSelectedToOwned();
if (!successfulIds?.length) {
setCommitError('Could not add cards. Try again.');
}
};
return (
<>
{lowConfidenceCount > 0 && (
{lowConfidenceCount} {lowConfidenceCount === 1 ? 'needs' : 'need'} review
)}
{cartCards.map((card) => (
queue.toggleCardSelection(card.id)}
showCheckbox
confidence={card.confidence}
onIncrement={() => queue.incrementCardQuantity(card.id)}
onDecrement={() => queue.decrementCardQuantity(card.id)}
onUpdateMetadata={(patch) => queue.updateCardMetadata(card.id, patch)}
onRemove={() => queue.removeScannedCard(card.id)}
isAdding={queue.addingCardIds?.has(card.id)}
/>
))}
>
);
}
export default function ScannerCheckoutSheet({
queue,
onClose,
onOpenListPicker,
trapActive = true,
}) {
const sheetRef = useFocusTrap(trapActive);
const backdropRef = useRef(null);
useEffect(() => {
const backdrop = backdropRef.current;
const sheet = sheetRef.current;
if (!backdrop || !sheet) return undefined;
requestAnimationFrame(() => {
backdrop.dataset.visible = 'true';
sheet.dataset.visible = 'true';
});
if (!trapActive) return undefined;
const handler = (e) => {
if (e.key === 'Escape') onClose();
};
document.addEventListener('keydown', handler);
return () => document.removeEventListener('keydown', handler);
}, [onClose, sheetRef, trapActive]);
const handleBackdropClick = useCallback(
(e) => {
if (e.target === e.currentTarget) onClose();
},
[onClose]
);
return (
);
}