mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
map and table added
This commit is contained in:
@@ -1,13 +1,18 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
|
||||||
import clientPromise from "@/lib/mongodb";
|
import clientPromise from "@/lib/mongodb";
|
||||||
|
|
||||||
export async function GET(req: NextApiRequest, res: NextApiResponse) {
|
/**
|
||||||
// TODO delete req / res ?
|
* Tournament data API endpoint
|
||||||
|
* @route /api/tournaments
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function GET() {
|
||||||
try {
|
try {
|
||||||
const client = await clientPromise;
|
const client = await clientPromise;
|
||||||
const db = client.db("tournamentsFranceDB");
|
const db = client.db("tournamentsFranceDB");
|
||||||
// const data = await db.collection("tournaments").find({}).toArray();
|
|
||||||
// converts date from string into a date and then orders by date
|
/**
|
||||||
|
* Converts date from string into a date to allow ordering
|
||||||
|
*/
|
||||||
const data = await db
|
const data = await db
|
||||||
.collection("tournaments")
|
.collection("tournaments")
|
||||||
.aggregate([
|
.aggregate([
|
||||||
|
|||||||
+5
-5
@@ -1,9 +1,9 @@
|
|||||||
import Image from 'next/image'
|
import Layout from "@/components/Layout";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<main className="">
|
<Layout>
|
||||||
|
<main className=""></main>
|
||||||
</main>
|
</Layout>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-33
@@ -1,16 +1,22 @@
|
|||||||
|
import dynamic from "next/dynamic";
|
||||||
import Layout from "@/components/Layout";
|
import Layout from "@/components/Layout";
|
||||||
|
import TournamentTable from "@/components/TournamentTable";
|
||||||
|
|
||||||
export interface TournamentType {
|
/**
|
||||||
_id: string;
|
* Imports the tournament map component, ensuring CSR only.
|
||||||
location: string;
|
* @remarks SSR is not supported by react-leaflet
|
||||||
department: string;
|
*/
|
||||||
tournament: string;
|
const TournamentMapNoSSR = dynamic(
|
||||||
url: string;
|
() => import("../../components/TournamentMap"),
|
||||||
time_control: string;
|
{
|
||||||
date: string;
|
ssr: false,
|
||||||
coordinates: [number, number];
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves tournament data from /api/tournaments
|
||||||
|
* @remarks The result is cached for the revalidation period in seconds
|
||||||
|
*/
|
||||||
async function getTournaments() {
|
async function getTournaments() {
|
||||||
const res = await fetch("http://localhost:3000/api/tournaments", {
|
const res = await fetch("http://localhost:3000/api/tournaments", {
|
||||||
next: { revalidate: 300 },
|
next: { revalidate: 300 },
|
||||||
@@ -19,33 +25,13 @@ async function getTournaments() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function Tournaments() {
|
export default async function Tournaments() {
|
||||||
const data = await getTournaments();
|
const tournamentData = await getTournaments();
|
||||||
console.log(data);
|
console.log(tournamentData);
|
||||||
|
|
||||||
const tournaments = data.map((t: TournamentType) => (
|
|
||||||
<tr key={t._id}>
|
|
||||||
<td>{t.date}</td>
|
|
||||||
<td>{t.location}</td>
|
|
||||||
<td>{t.tournament}</td>
|
|
||||||
<td>{t.time_control}</td>
|
|
||||||
</tr>
|
|
||||||
));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<main className="w-full">
|
<TournamentMapNoSSR />
|
||||||
<table className="table-auto">
|
<TournamentTable tournamentData={tournamentData} />
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Ville</th>
|
|
||||||
<th>Tournois</th>
|
|
||||||
<th>Cadence</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>{tournaments}</tbody>
|
|
||||||
</table>
|
|
||||||
</main>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ export default function Layout({
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="bg-white font-sans leading-normal tracking-normal">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
{children}
|
{children}
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-1
@@ -1,3 +1,46 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
return <nav className="bg-gray-800 p-2 m-0 w-full">NAVBAR</nav>;
|
return (
|
||||||
|
<nav className="bg-gray-800 p-2 mt-0 w-full">
|
||||||
|
<div className="container mx-auto flex flex-wrap items-center">
|
||||||
|
<div className="flex w-full md:w-1/2 justify-center md:justify-start text-white font-extrabold">
|
||||||
|
<Link
|
||||||
|
className="text-white no-underline hover:text-white hover:no-underline"
|
||||||
|
href="/"
|
||||||
|
>
|
||||||
|
<span className="text-2xl pl-2">Echecs France</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full pt-2 content-center justify-between md:w-1/2 md:justify-end">
|
||||||
|
<ul className="list-reset text-white no-underline flex justify-between flex-1 md:flex-none items-center">
|
||||||
|
<li className="mr-3">
|
||||||
|
<Link
|
||||||
|
className="inline-block hover:text-gray-200 hover:text-underline py-2 px-4"
|
||||||
|
href="/tournois"
|
||||||
|
>
|
||||||
|
Tournois
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className="mr-3">
|
||||||
|
<Link
|
||||||
|
className="inline-block hover:text-gray-200 hover:text-underline py-2 px-4"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
About
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className="mr-3">
|
||||||
|
<Link
|
||||||
|
className="inline-block hover:text-gray-200 hover:text-underline py-2 px-4"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Contact
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import "leaflet/dist/leaflet.css";
|
||||||
|
import { MapContainer, TileLayer, Marker } from "react-leaflet";
|
||||||
|
|
||||||
|
export default function TournamentMap() {
|
||||||
|
const center: number[] = [47.0844, 2.3964];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section id="tournament-map" className="">
|
||||||
|
<MapContainer
|
||||||
|
center={center}
|
||||||
|
zoom={5}
|
||||||
|
scrollWheelZoom={false}
|
||||||
|
style={{ height: "50vh" }}
|
||||||
|
>
|
||||||
|
<TileLayer
|
||||||
|
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||||
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
|
/>
|
||||||
|
</MapContainer>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
interface TournamentType {
|
||||||
|
_id: string;
|
||||||
|
location: string;
|
||||||
|
department: string;
|
||||||
|
tournament: string;
|
||||||
|
url: string;
|
||||||
|
time_control: string;
|
||||||
|
date: string;
|
||||||
|
coordinates: [number, number];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TournamentTable({ tournamentData }) {
|
||||||
|
const tournaments = tournamentData.map((t: TournamentType) => (
|
||||||
|
<tr
|
||||||
|
className="border-b transition duration-300 ease-in-out hover:bg-neutral-100"
|
||||||
|
key={t._id}
|
||||||
|
>
|
||||||
|
<td>{t.date}</td>
|
||||||
|
<td>{t.location}</td>
|
||||||
|
<a href={t.url} target="_blank">
|
||||||
|
<td>{t.tournament}</td>
|
||||||
|
</a>
|
||||||
|
<td>{t.time_control}</td>
|
||||||
|
</tr>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section id="tournament-table" className="">
|
||||||
|
<table className="min-w-full text-center">
|
||||||
|
<thead className="border-b">
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Ville</th>
|
||||||
|
<th>Tournois</th>
|
||||||
|
<th>Cadence</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>{tournaments}</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
Generated
+30
@@ -14,11 +14,13 @@
|
|||||||
"autoprefixer": "10.4.14",
|
"autoprefixer": "10.4.14",
|
||||||
"eslint": "8.41.0",
|
"eslint": "8.41.0",
|
||||||
"eslint-config-next": "13.4.3",
|
"eslint-config-next": "13.4.3",
|
||||||
|
"leaflet": "^1.9.4",
|
||||||
"mongodb": "^5.5.0",
|
"mongodb": "^5.5.0",
|
||||||
"next": "13.4.3",
|
"next": "13.4.3",
|
||||||
"postcss": "8.4.23",
|
"postcss": "8.4.23",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
|
"react-leaflet": "^4.2.1",
|
||||||
"tailwindcss": "3.3.2",
|
"tailwindcss": "3.3.2",
|
||||||
"typescript": "5.0.4"
|
"typescript": "5.0.4"
|
||||||
},
|
},
|
||||||
@@ -1430,6 +1432,16 @@
|
|||||||
"url": "https://opencollective.com/unts"
|
"url": "https://opencollective.com/unts"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-leaflet/core": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"leaflet": "^1.9.0",
|
||||||
|
"react": "^18.0.0",
|
||||||
|
"react-dom": "^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rushstack/eslint-patch": {
|
"node_modules/@rushstack/eslint-patch": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.0.tgz",
|
||||||
@@ -5805,6 +5817,11 @@
|
|||||||
"language-subtag-registry": "~0.3.2"
|
"language-subtag-registry": "~0.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/leaflet": {
|
||||||
|
"version": "1.9.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||||
|
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
|
||||||
|
},
|
||||||
"node_modules/leven": {
|
"node_modules/leven": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
||||||
@@ -6888,6 +6905,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-leaflet": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-leaflet/core": "^2.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"leaflet": "^1.9.0",
|
||||||
|
"react": "^18.0.0",
|
||||||
|
"react-dom": "^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
|||||||
@@ -16,11 +16,13 @@
|
|||||||
"autoprefixer": "10.4.14",
|
"autoprefixer": "10.4.14",
|
||||||
"eslint": "8.41.0",
|
"eslint": "8.41.0",
|
||||||
"eslint-config-next": "13.4.3",
|
"eslint-config-next": "13.4.3",
|
||||||
|
"leaflet": "^1.9.4",
|
||||||
"mongodb": "^5.5.0",
|
"mongodb": "^5.5.0",
|
||||||
"next": "13.4.3",
|
"next": "13.4.3",
|
||||||
"postcss": "8.4.23",
|
"postcss": "8.4.23",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
|
"react-leaflet": "^4.2.1",
|
||||||
"tailwindcss": "3.3.2",
|
"tailwindcss": "3.3.2",
|
||||||
"typescript": "5.0.4"
|
"typescript": "5.0.4"
|
||||||
},
|
},
|
||||||
|
|||||||
+5
-13
@@ -1,18 +1,10 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: [
|
content: [
|
||||||
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
|
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
'./app/**/*.{js,ts,jsx,tsx,mdx}',
|
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {},
|
||||||
extend: {
|
|
||||||
backgroundImage: {
|
|
||||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
|
||||||
'gradient-conic':
|
|
||||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user