import { TimeControl, Tournament } from '@/types'; import { atom } from 'jotai'; import { LatLngBounds } from 'leaflet'; import atomWithDebounce from "@/utils/atomWithDebounce"; export const tournamentsAtom = atom([]); export const mapBoundsAtom = atom(null); export const syncVisibleAtom = atom(true); export const searchStringAtom = atom(''); export const classicAtom = atom(true); export const rapidAtom = atom(true); export const blitzAtom = atom(true); export const otherAtom = atom(true); export const { currentValueAtom: hoveredMapTournamentIdAtom, debouncedValueAtom: debouncedHoveredMapTournamentIdAtom, } = atomWithDebounce(null); export const { debouncedValueAtom: debouncedHoveredListTournamentIdAtom, } = atomWithDebounce(null, 300, true); export const filteredTournamentsByTimeControlAtom = atom((get) => { const tournaments = get(tournamentsAtom); const classic = get(classicAtom); const rapid = get(rapidAtom); const blitz = get(blitzAtom); const other = get(otherAtom); return tournaments.filter(tournament => (tournament.timeControl === TimeControl.Classic && classic) || (tournament.timeControl === TimeControl.Rapid && rapid) || (tournament.timeControl === TimeControl.Blitz && blitz) || (tournament.timeControl === TimeControl.Other && other)); }); export const filteredTournamentsListAtom = atom((get) => { const tournaments = get(filteredTournamentsByTimeControlAtom); const mapBounds = get(mapBoundsAtom); const syncVisible = get(syncVisibleAtom); const searchString = get(searchStringAtom).trim(); // When searching, we search all the tournament, regardless of the map display if (searchString !== '') return tournaments.filter((t) => t.town.includes(searchString.toUpperCase())) // If we not syncing to the map, return all tournaments if (mapBounds === null || !syncVisible) return tournaments; // Filter by those in the current map bounds return tournaments.filter(tournament => mapBounds.contains(tournament.latLng)) })