mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
New front page design
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
import Footer from "./components/Footer";
|
||||||
|
import Navbar from "./components/Navbar";
|
||||||
|
|
||||||
|
export default async function MainLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Navbar />
|
||||||
|
<div className="relative min-h-content">{children}</div>
|
||||||
|
<Footer />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
+1
-1
@@ -9,7 +9,7 @@ import { FaExternalLinkAlt, FaTrophy } from "react-icons/fa";
|
|||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import DatePicker from "@/app/[locale]/tournaments/DatePicker";
|
import DatePicker from "@/app/[locale]/(main)/tournaments/DatePicker";
|
||||||
import {
|
import {
|
||||||
datePickerIsOpenAtom,
|
datePickerIsOpenAtom,
|
||||||
dateRangeAtom,
|
dateRangeAtom,
|
||||||
@@ -9,8 +9,8 @@ import Script from "next/script";
|
|||||||
import "@/css/globals.css";
|
import "@/css/globals.css";
|
||||||
import Providers from "@/providers";
|
import Providers from "@/providers";
|
||||||
|
|
||||||
import Footer from "./components/Footer";
|
import Footer from "./(main)/components/Footer";
|
||||||
import Navbar from "./components/Navbar";
|
import Navbar from "./(main)/components/Navbar";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
|
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
|
||||||
const title = Julius_Sans_One({
|
const title = Julius_Sans_One({
|
||||||
@@ -71,11 +71,11 @@ export default async function RootLayout({
|
|||||||
<body>
|
<body>
|
||||||
<Providers>
|
<Providers>
|
||||||
<NextIntlClientProvider locale={locale} messages={messages}>
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
||||||
<div className="bg-white font-sans leading-normal tracking-normal dark:bg-gray-800">
|
<div className="bg-white pb-40 font-sans leading-normal tracking-normal dark:bg-gray-700 dark:bg-gray-800">
|
||||||
<Navbar />
|
{children}
|
||||||
<div className="relative min-h-content">{children}</div>
|
|
||||||
<Footer />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
</NextIntlClientProvider>
|
</NextIntlClientProvider>
|
||||||
<Script
|
<Script
|
||||||
defer
|
defer
|
||||||
|
|||||||
+151
-26
@@ -1,44 +1,169 @@
|
|||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { GiTrophyCup } from "react-icons/gi";
|
||||||
|
import { GrLineChart } from "react-icons/gr";
|
||||||
|
import { HiUserGroup } from "react-icons/hi2";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import bgImage from "@/img/map-bg.webp";
|
import bannerImage from "@/img/banner.jpeg";
|
||||||
import { Link } from "@/utils/navigation";
|
import { Link } from "@/utils/navigation";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const t = useTranslations("Home");
|
const t = useTranslations("Home");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="relative mb-12 flex min-h-content items-center justify-center">
|
<div className="min-h-[100vh] bg-white dark:bg-gray-800">
|
||||||
<div className="absolute h-full w-full py-4 brightness-[0.2]">
|
<div className="relative mb-20 max-h-[400px]">
|
||||||
<Image
|
<Image
|
||||||
src={bgImage}
|
src={bannerImage}
|
||||||
alt="Background image of France"
|
alt="banner"
|
||||||
fill={true}
|
sizes="100vw"
|
||||||
style={{ objectFit: "cover" }}
|
style={{
|
||||||
priority
|
width: "100%",
|
||||||
|
height: "auto",
|
||||||
|
maxHeight: "400px",
|
||||||
|
objectFit: "cover",
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={twMerge(
|
||||||
|
"absolute",
|
||||||
|
"left-5 top-[50%] max-w-[50%] -translate-y-[50%]",
|
||||||
|
"sm:left-10",
|
||||||
|
"md:left-15",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
className={twMerge(
|
||||||
|
"mb-2 font-title text-2xl/6 font-bold text-white",
|
||||||
|
"sm:text-4xl",
|
||||||
|
"md:text-5xl",
|
||||||
|
)}
|
||||||
|
data-test="header1"
|
||||||
|
>
|
||||||
|
{t("title")}
|
||||||
|
</h1>
|
||||||
|
<p className={twMerge("text-sm", "sm:text-lg", "md:text-xl")}>
|
||||||
|
{t("purpose")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="absolute -bottom-[2px] w-full text-white dark:text-gray-800">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="100%"
|
||||||
|
height="auto"
|
||||||
|
viewBox="0 0 1440 128"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M0,471 L1440,471 L1440,386.338583 C1331.33333,357.446194 1239,343 1163,343 C821.995497,343 821.995497,463.944882 426,463.944882 C262.447846,463.944882 120.447846,438.076115 0,386.338583 L0,471 Z"
|
||||||
|
transform="translate(0 -343)"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="z-10 py-4 text-center text-white">
|
|
||||||
<h1 className="p-5 font-title text-5xl" data-test="header1">
|
<div className="mx-auto max-w-4xl px-4 text-black dark:text-white sm:px-10">
|
||||||
{t("title")}
|
<div
|
||||||
</h1>
|
className={twMerge(
|
||||||
<h2 className="p-5 text-3xl">{t("purpose")}</h2>
|
"grid gap-8",
|
||||||
<h3 className="mb-5 p-5 text-xl">
|
"grid-rows-[repeat(3,1fr)]",
|
||||||
{t.rich("how", {
|
"md:grid-cols-[repeat(3,1fr)] md:grid-rows-[auto_min-content_1fr_max-content]",
|
||||||
link: (chunks) => (
|
)}
|
||||||
<a href="http://www.echecs.asso.fr/" target="_blank">
|
>
|
||||||
<abbr title="Fédération Française des Échecs">{chunks}</abbr>
|
<section
|
||||||
|
className={twMerge(
|
||||||
|
"row-span-4 grid gap-4",
|
||||||
|
// We use subgrid if possible (to align columns across each button), falling back to a grid
|
||||||
|
"grid-rows-[auto_min-content_1fr_max-content]",
|
||||||
|
"grid-rows-[subgrid] gap-2",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-center text-5xl">
|
||||||
|
<GiTrophyCup />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-center text-2xl font-semibold">
|
||||||
|
{t("tournamentsTitle")}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="">{t("tournamentsInfo")}</p>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href="/tournaments"
|
||||||
|
className="mt-4 rounded-lg bg-primary px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-primary-700 hover:bg-gradient-to-br focus:outline-none focus:ring-4 focus:ring-primary-300 dark:focus:ring-primary-800"
|
||||||
|
>
|
||||||
|
{t("tournamentsLink")}
|
||||||
|
</Link>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section
|
||||||
|
className={twMerge(
|
||||||
|
"row-span-4 grid gap-4",
|
||||||
|
// We use subgrid if possible (to align columns across each button), falling back to a grid
|
||||||
|
"grid-rows-[auto_min-content_1fr_max-content]",
|
||||||
|
"grid-rows-[subgrid] gap-2",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-center text-5xl">
|
||||||
|
<HiUserGroup />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-center text-2xl font-semibold">
|
||||||
|
{t("clubsTitle")}
|
||||||
|
</h2>
|
||||||
|
<p className="">{t("clubsInfo")}</p>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href="/clubs"
|
||||||
|
className="mt-4 rounded-lg bg-primary px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-primary-700 hover:bg-gradient-to-br focus:outline-none focus:ring-4 focus:ring-primary-300 dark:focus:ring-primary-800"
|
||||||
|
>
|
||||||
|
{t("clubsLink")}
|
||||||
|
</Link>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section
|
||||||
|
className={twMerge(
|
||||||
|
"row-span-4 grid gap-4",
|
||||||
|
// We use subgrid if possible (to align columns across each button), falling back to a grid
|
||||||
|
"grid-rows-[auto_min-content_1fr_max-content]",
|
||||||
|
"grid-rows-[subgrid] gap-2",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-center text-5xl">
|
||||||
|
<GrLineChart />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-center text-2xl font-semibold">
|
||||||
|
{t("eloTitle")}
|
||||||
|
</h2>
|
||||||
|
<p className="">{t("eloInfo")}</p>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href="/elo"
|
||||||
|
className="mt-4 rounded-lg bg-primary px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-primary-700 hover:bg-gradient-to-br focus:outline-none focus:ring-4 focus:ring-primary-300 dark:focus:ring-primary-800"
|
||||||
|
>
|
||||||
|
{t("calculatorLink")}
|
||||||
|
</Link>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr className="my-10" />
|
||||||
|
|
||||||
|
<div className="text-center italic">
|
||||||
|
{t.rich("getInvolved", {
|
||||||
|
link: (str) => (
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
className="text-primary hover:bg-primary-700"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href="https://github.com/TheRealOwenRees/echecsfrance"
|
||||||
|
>
|
||||||
|
{str}
|
||||||
</a>
|
</a>
|
||||||
),
|
),
|
||||||
})}
|
})}
|
||||||
</h3>
|
</div>
|
||||||
<Link
|
|
||||||
href="/tournaments"
|
|
||||||
className="mb-2 rounded-lg bg-primary px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-primary-700 hover:bg-gradient-to-br focus:outline-none focus:ring-4 focus:ring-primary-300 dark:focus:ring-primary-800"
|
|
||||||
>
|
|
||||||
{t("mapLink")}
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.6 MiB |
+16
-4
@@ -35,9 +35,21 @@
|
|||||||
|
|
||||||
"Home": {
|
"Home": {
|
||||||
"title": "Échecs France",
|
"title": "Échecs France",
|
||||||
"purpose": "Find chess tournaments, in France, on a map",
|
"purpose": "The easiest way to find local chess tournaments and clubs in France.",
|
||||||
"how": "A graphical representation of all the chess tournaments published by the <link>FFE</link>",
|
|
||||||
"mapLink": "See the Map"
|
"tournamentsTitle": "Find your next tournament",
|
||||||
|
"tournamentsInfo": "Find upcoming tournaments easily on a map of France. Filter by date, time control, and more.",
|
||||||
|
"tournamentsLink": "Find a Tournament",
|
||||||
|
|
||||||
|
"clubsTitle": "Find a chess club",
|
||||||
|
"clubsInfo": "Looking for a chess club near you? Find one on the map and get in touch with them.",
|
||||||
|
"clubsLink": "Find a Club",
|
||||||
|
|
||||||
|
"eloTitle": "Calculate your Elo",
|
||||||
|
"eloInfo": "Use our fantastic Elo calculator to estimate your new rating after a tournament. You can enter your results manually or select a tournament from our database.",
|
||||||
|
"calculatorLink": "Go to the Calculator",
|
||||||
|
|
||||||
|
"getInvolved": "Echecs France is completely free, open source and open to contributions. Find us on <link>GitHub</link> if you want et involved."
|
||||||
},
|
},
|
||||||
|
|
||||||
"Tournaments": {
|
"Tournaments": {
|
||||||
@@ -80,7 +92,7 @@
|
|||||||
"techTitle": "Tech",
|
"techTitle": "Tech",
|
||||||
"techInfo": "<homeLink>Échecs France</homeLink> uses\u00a0:",
|
"techInfo": "<homeLink>Échecs France</homeLink> uses\u00a0:",
|
||||||
"techWith": "with",
|
"techWith": "with",
|
||||||
"contribInfo": "For more information on how to contribute, please visit our <link>GitHub</link>."
|
"contribInfo": "For more information on how to contribute, please visit our <link>GitHub</.link>."
|
||||||
},
|
},
|
||||||
|
|
||||||
"Contact": {
|
"Contact": {
|
||||||
|
|||||||
+14
-3
@@ -35,9 +35,20 @@
|
|||||||
|
|
||||||
"Home": {
|
"Home": {
|
||||||
"title": "Échecs France",
|
"title": "Échecs France",
|
||||||
"purpose": "Trouvez vos tournois d'échecs en france sur une carte",
|
"purpose": "Le moyen le plus simple de trouver des tournois d'échecs locaux et des clubs en France.",
|
||||||
"how": "Une représentation visuelle de tous les tournois d'échecs publiés par la <link>FFE</link>",
|
"tournamentsTitle": "Trouvez votre prochain tournoi",
|
||||||
"mapLink": "Voir La Carte"
|
"tournamentsInfo": "Trouvez facilement les prochains tournois sur une carte de France. Filtrez par date, contrôle du temps, et plus encore.",
|
||||||
|
"tournamentsLink": "Trouver un Tournoi",
|
||||||
|
|
||||||
|
"clubsTitle": "Trouvez un club d'échecs",
|
||||||
|
"clubsInfo": "Vous cherchez un club d'échecs près de chez vous ? Trouvez-en un sur la carte et entrez en contact avec eux.",
|
||||||
|
"clubsLink": "Trouver un Club",
|
||||||
|
|
||||||
|
"eloTitle": "Calculez votre Elo",
|
||||||
|
"eloInfo": "Utilisez notre fantastique calculateur Elo pour estimer votre nouveau classement après un tournoi. Vous pouvez saisir vos résultats manuellement ou sélectionner un tournoi dans notre base de données.",
|
||||||
|
"calculatorLink": "Aller au Calculateur",
|
||||||
|
|
||||||
|
"getInvolved": "Échecs France est complètement gratuit, open source et ouvert aux contributions. Retrouvez-nous sur <link>GitHub</link> si vous souhaitez vous impliquer."
|
||||||
},
|
},
|
||||||
|
|
||||||
"Tournaments": {
|
"Tournaments": {
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
success: "#00ac39",
|
success: "#00ac39",
|
||||||
error: "#ea5f17",
|
error: "#ea5f17",
|
||||||
|
|
||||||
|
classic: "#00ac39",
|
||||||
|
rapid: "#0086c7",
|
||||||
|
blitz: "#ddce20",
|
||||||
|
other: "#ea5f17",
|
||||||
},
|
},
|
||||||
minHeight: {
|
minHeight: {
|
||||||
// We use 100svh, falling back to the the --1svh var that we add as a polyfill for older browsers.
|
// We use 100svh, falling back to the the --1svh var that we add as a polyfill for older browsers.
|
||||||
|
|||||||
@@ -1671,20 +1671,20 @@
|
|||||||
javascript-natural-sort "0.7.1"
|
javascript-natural-sort "0.7.1"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
|
|
||||||
"@trpc/client@^10.38.1":
|
"@trpc/client@^10.45.0":
|
||||||
version "10.45.0"
|
version "10.45.1"
|
||||||
resolved "https://registry.yarnpkg.com/@trpc/client/-/client-10.45.0.tgz#67cf34857cfa7e77bc498cb837c2226a42d24bf4"
|
resolved "https://registry.yarnpkg.com/@trpc/client/-/client-10.45.1.tgz#ec80a5252ac9d3e5df2e5d8ddce1e23fc5caf5ac"
|
||||||
integrity sha512-m091R1qte9rvkvL8N1e/mzrbb8S4gb+Q4ZNJnEGDgd7kic/6a8DFgSciBTiCoSp0YwOTVhyQzSrrA/sZI6PhBg==
|
integrity sha512-nVbAk1xpIiI64WgzXGgfxPOGgHoYvffn1IsjV1D/Ri7DL4BKuo2qtZ7UQ+OuHkzH2M8j4ikSVBDpk545fOdvpw==
|
||||||
|
|
||||||
"@trpc/react-query@^10.38.1":
|
"@trpc/react-query@^10.45.0":
|
||||||
version "10.45.0"
|
version "10.45.1"
|
||||||
resolved "https://registry.yarnpkg.com/@trpc/react-query/-/react-query-10.45.0.tgz#848929e79399119e860d0212f8233d2ee83328c9"
|
resolved "https://registry.yarnpkg.com/@trpc/react-query/-/react-query-10.45.1.tgz#48454552cf5ce9a4d99712065f9309994b2476a5"
|
||||||
integrity sha512-MMc2pLwoaLZVwvLQyzJv3uEmdG3lORhifhVzR/drtavwDYwt+OEvH0w3s1zC7RaDdFpc6Nj2kkpHmdoU7BlAAw==
|
integrity sha512-48OOMpwVjQFUQJqlp9/tW1lqESZg9YEqB5iVci7mYaDzZPEs/YUcV85XKvYzgeW+7K9oShX/JMVce8muON/6uQ==
|
||||||
|
|
||||||
"@trpc/server@^10.38.1":
|
"@trpc/server@^10.45.0":
|
||||||
version "10.45.0"
|
version "10.45.1"
|
||||||
resolved "https://registry.yarnpkg.com/@trpc/server/-/server-10.45.0.tgz#be43a1a6e7f41ae86534716933717e80218ccdcb"
|
resolved "https://registry.yarnpkg.com/@trpc/server/-/server-10.45.1.tgz#481b9d6747bbb585ef91b980198dd4ff3226baf4"
|
||||||
integrity sha512-2Fwzv6nqpE0Ie/G7PeS0EVR89zLm+c1Mw7T+RAGtU807j4oaUx0zGkBXTu5u9AI+j+BYNN2GZxJcuDTAecbr1A==
|
integrity sha512-KOzBEVaHW9IxEedUP9E50y0tYxAuvlzyjn80Bpemw4rcNbT4WtJnhkFPUY+qDJl7Crt3B/oY2qMgSxVWi9toLg==
|
||||||
|
|
||||||
"@types/aria-query@^5.0.1":
|
"@types/aria-query@^5.0.1":
|
||||||
version "5.0.4"
|
version "5.0.4"
|
||||||
|
|||||||
Reference in New Issue
Block a user