Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 2x 96x 96x 96x 96x 96x 46x 96x 80x 36x 28x 36x 96x 80x 14x 30x 14x 5x 3x 5x 96x | // src/hooks/useFlyerSelection.ts
import { useState, useCallback, useEffect } from 'react';
import { useLocation, matchPath } from 'react-router-dom';
import { logger } from '../services/logger.client';
import type { Flyer } from '../types';
interface UseFlyerSelectionOptions {
flyers: Flyer[];
debugLogging?: boolean;
}
interface UseFlyerSelectionReturn {
selectedFlyer: Flyer | null;
handleFlyerSelect: (flyer: Flyer) => void;
flyerIdFromUrl: string | undefined;
}
/**
* A custom hook to manage flyer selection state, including:
* - Manual flyer selection via handleFlyerSelect
* - URL-based flyer selection (e.g., /flyers/:flyerId)
* - Auto-selection of the first flyer when none is selected
*
* @param options.flyers - Array of available flyers
* @param options.debugLogging - Enable debug logging (default: false, enabled in test env)
* @returns Object with selectedFlyer, handleFlyerSelect callback, and flyerIdFromUrl
*
* @example
* ```tsx
* const { selectedFlyer, handleFlyerSelect, flyerIdFromUrl } = useFlyerSelection({
* flyers,
* debugLogging: process.env.NODE_ENV === 'test',
* });
* ```
*/
export const useFlyerSelection = ({
flyers,
debugLogging = process.env.NODE_ENV === 'test',
}: UseFlyerSelectionOptions): UseFlyerSelectionReturn => {
const [selectedFlyer, setSelectedFlyer] = useState<Flyer | null>(null);
const location = useLocation();
// Extract flyerId from URL if present
const match = matchPath('/flyers/:flyerId', location.pathname);
const flyerIdFromUrl = match?.params.flyerId;
const handleFlyerSelect = useCallback((flyer: Flyer) => {
setSelectedFlyer(flyer);
}, []);
// Auto-select first flyer when none is selected and flyers are available
useEffect(() => {
if (!selectedFlyer && flyers.length > 0) {
if (debugLogging) {
logger.debug('[useFlyerSelection] Auto-selecting first flyer');
}
handleFlyerSelect(flyers[0]);
}
}, [flyers, selectedFlyer, handleFlyerSelect, debugLogging]);
// Handle URL-based flyer selection
useEffect(() => {
if (flyerIdFromUrl && flyers.length > 0) {
const flyerId = parseInt(flyerIdFromUrl, 10);
const flyerToSelect = flyers.find((f) => f.flyer_id === flyerId);
if (flyerToSelect && flyerToSelect.flyer_id !== selectedFlyer?.flyer_id) {
if (debugLogging) {
logger.debug(
{ flyerId, flyerToSelect: flyerToSelect.flyer_id },
'[useFlyerSelection] Selecting flyer from URL',
);
}
handleFlyerSelect(flyerToSelect);
}
}
}, [flyers, handleFlyerSelect, selectedFlyer, flyerIdFromUrl, debugLogging]);
return {
selectedFlyer,
handleFlyerSelect,
flyerIdFromUrl,
};
};
|