+
diff --git a/app/[lang]/tournois/page.tsx b/app/[lang]/tournois/page.tsx
index cb97587..2263876 100644
--- a/app/[lang]/tournois/page.tsx
+++ b/app/[lang]/tournois/page.tsx
@@ -1,19 +1,38 @@
import clientPromise from "@/lib/mongodb";
import { errorLog } from "@/utils/logger";
-import { Tournament } from "@/types";
+import { Tournament, TimeControl } from "@/types";
import TournamentsDisplay from "./TournamentsDisplay";
+import { ObjectId } from "mongodb";
export const revalidate = 3600; // Revalidate cache every 6 hours
+export interface TournamentData {
+ _id: ObjectId;
+ town: string;
+ department: string;
+ tournament: string;
+ url: string;
+ time_control: "Cadence Lente" | "Rapide" | "Blitz" | "1h KO";
+ date: string;
+ coordinates: [number, number];
+}
+
+const tcMap: Record = {
+ "Cadence Lente": TimeControl.Classic,
+ Rapide: TimeControl.Rapid,
+ Blitz: TimeControl.Blitz,
+ "1h KO": TimeControl.KO,
+};
+
const getTournaments = async () => {
try {
const client = await clientPromise;
const db = client.db("tournamentsFranceDB");
const data = await db
.collection("tournaments")
- .aggregate([
+ .aggregate([
{
$addFields: {
dateParts: {
@@ -35,10 +54,11 @@ const getTournaments = async () => {
])
.toArray();
- // We map the ObjectId to a string so that it can be serialized and sent to a client component
- return data.map((t) => ({
+ return data.map((t) => ({
...t,
_id: t._id.toString(),
+ timeControl: tcMap[t.time_control],
+ latLng: { lat: t.coordinates[0], lng: t.coordinates[1] },
}));
} catch (error) {
errorLog(error);
diff --git a/app/atoms.ts b/app/atoms.ts
index 65e3b95..ebc5657 100644
--- a/app/atoms.ts
+++ b/app/atoms.ts
@@ -1,14 +1,19 @@
-import { Tournament } from '@/types';
+import { TimeControl, Tournament } from '@/types';
import { atom } from 'jotai';
import { LatLngBounds } from 'leaflet';
import atomWithDebounce from "@/utils/atomWithDebounce";
export const tournamentsAtom = atom([]);
-export const searchStringAtom = 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 oneHourKOAtom = atom(true);
+
export const {
currentValueAtom: hoveredMapTournamentIdAtom,
debouncedValueAtom: debouncedHoveredMapTournamentIdAtom,
@@ -18,12 +23,29 @@ export const {
debouncedValueAtom: debouncedHoveredListTournamentIdAtom,
} = atomWithDebounce(null);
-export const filteredTournamentsAtom = atom((get) => {
+export const filteredTournamentsByTimeControlAtom = atom((get) => {
const tournaments = get(tournamentsAtom);
- const searchString = get(searchStringAtom).trim();
+
+ const classic = get(classicAtom);
+ const rapid = get(rapidAtom);
+ const blitz = get(blitzAtom);
+ const oneHourKO = get(oneHourKOAtom);
+
+ return tournaments.filter(tournament =>
+ (tournament.timeControl === TimeControl.Classic && classic) ||
+ (tournament.timeControl === TimeControl.Rapid && rapid) ||
+ (tournament.timeControl === TimeControl.Blitz && blitz) ||
+ (tournament.timeControl === TimeControl.KO && oneHourKO));
+});
+
+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()))
@@ -32,5 +54,5 @@ export const filteredTournamentsAtom = atom((get) => {
if (mapBounds === null || !syncVisible) return tournaments;
// Filter by those in the current map bounds
- return tournaments.filter(tournament => mapBounds.contains({ lat: tournament.coordinates[0], lng: tournament.coordinates[1]}))
+ return tournaments.filter(tournament => mapBounds.contains(tournament.latLng))
})
diff --git a/messages/en.json b/messages/en.json
index a1109b3..c1668c0 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -17,13 +17,6 @@
"contactAria": "Contact Us"
},
- "App": {
- "tcClassic": "Classic",
- "tcRapid": "Rapid",
- "tcBlitz": "Blitz",
- "tcKO": "1h KO"
- },
-
"Home": {
"title": "France Echecs",
"purpose": "Find chess tournaments, in France, on a map",
@@ -41,7 +34,8 @@
"town": "Town",
"tournament": "Tournament",
"timeControl": "Time Control",
- "approx": "Géo-localisation is approximative"
+ "approx": "Géo-localisation is approximative",
+ "timeControlEnum": "{tc, select, Classic {Classic} Rapid {Rapid} Blitz {Blitz} KO {1h KO} other {{tc}}}"
},
"About": {
diff --git a/messages/fr.json b/messages/fr.json
index 2a06713..c1398db 100644
--- a/messages/fr.json
+++ b/messages/fr.json
@@ -17,13 +17,6 @@
"contactAria": "Contactez-nous"
},
- "App": {
- "tcClassic": "Cadence Lente",
- "tcRapid": "Rapide",
- "tcBlitz": "Blitz",
- "tcKO": "1h KO"
- },
-
"Home": {
"title": "Échecs France",
"purpose": "Trouvez Vos Tournois d'Échecs en France Sur Une Carte",
@@ -41,7 +34,8 @@
"town": "Ville",
"tournament": "Tournois",
"timeControl": "Cadence",
- "approx": "Géolocalisation approximative"
+ "approx": "Géolocalisation approximative",
+ "timeControlEnum": "{tc, select, Classic {Cadence Lente} Rapid {Rapide} Blitz {Blitz} KO {1h KO} other {{tc}}}"
},
"About": {
diff --git a/types.ts b/types.ts
index a7c14c5..54152ad 100644
--- a/types.ts
+++ b/types.ts
@@ -1,12 +1,21 @@
+import { LatLngLiteral } from "leaflet";
+
+export enum TimeControl {
+ Classic = "Classic",
+ Rapid = "Rapid",
+ Blitz = "Blitz",
+ KO = "KO",
+};
+
export interface Tournament {
_id: string;
town: string;
department: string;
tournament: string;
url: string;
- time_control: string;
+ timeControl: TimeControl;
date: string;
- coordinates: [number, number];
+ latLng: LatLngLiteral;
}
export type ScrollableElement = Window | HTMLElement;