nav updated

This commit is contained in:
Owen Rees
2023-06-09 16:50:32 +02:00
parent 4cf8566a59
commit 1ad2f1b306
19 changed files with 173 additions and 61 deletions
+2
View File
@@ -1,5 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
TODO
# dependencies
/node_modules
/.pnp
+26
View File
@@ -0,0 +1,26 @@
footer
light/dark theme
tests for tournois, testing the loading of map and table, then counting the markers
logo for navbar and favicon
tournament table scroll
hover on table needs fixing - this only seemed to happen once I moved the logic into its own hook
document my new hook
error handling
e2e tests for tournament page:
- make sure number of markers = tournamentData.length
home page
about page
contact page
SEO
+1 -1
View File
@@ -3,7 +3,7 @@ import Layout from "@/components/Layout";
export default function About() {
return (
<Layout>
<header className="grid h-[calc(100%-144px)] md:h-[calc(100%-112px)] place-items-center">
<header className="grid h-[calc(100%-156px)] md:h-[calc(100%-124px)] place-items-center">
<div className="relative h-full w-full bg-amber-200"></div>
<div className="absolute">
<h1>About Page</h1>
+1 -1
View File
@@ -3,7 +3,7 @@ import Layout from "@/components/Layout";
export default function Contact() {
return (
<Layout>
<header className="grid h-[calc(100%-144px)] md:h-[calc(100%-112px)] place-items-center">
<header className="grid h-[calc(100%-156px)] md:h-[calc(100%-124px)] place-items-center">
<div className="relative h-full w-full bg-amber-200"></div>
<div className="absolute">
<h1>Contact Page</h1>
+21 -6
View File
@@ -1,14 +1,29 @@
import Link from "next/link";
import Layout from "@/components/Layout";
export default function Home() {
return (
<Layout>
<header className="grid h-[calc(100%-144px)] md:h-[calc(100%-112px)] place-items-center">
<div className="relative h-full w-full bg-[url('/images/map-bg.jpg')] brightness-[0.2]"></div>
<div className="absolute">
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<header className="grid h-[calc(100%-156px)] md:h-[calc(100%-124px)] place-items-center">
<div className="relative h-full w-full bg-[url('/images/map-bg.jpg')] bg-cover bg-center brightness-[0.2]"></div>
<div className="absolute text-center">
<h1 className="text-5xl p-5">Echecs France</h1>
<h2 className="text-3xl p-5 capitalize">
Find chess tournaments in France on a map
</h2>
<h3 className="text-xl p-5 mb-5">
A visual representation of all the chess tournaments published by
the{" "}
<Link href="http://www.echecs.asso.fr/" target="_blank">
<abbr title="Fédération Française des Échecs">FFE</abbr>
</Link>
</h3>
<Link
href="/tournois"
className="text-white bg-gradient-to-r from-teal-400 via-teal-500 to-teal-600 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-teal-300 dark:focus:ring-teal-800 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2"
>
Get Started
</Link>
</div>
</header>
</Layout>
+4 -2
View File
@@ -1,7 +1,9 @@
export default function Footer() {
return (
<footer className="w-full bg-gray-800 text-white p-3">
<p>Footer</p>
<footer className="grid grid-cols-2 bg-gray-800 text-white p-3">
<div>
<p>&copy; {new Date().getFullYear()} - Owen Rees</p>
</div>
</footer>
);
}
+1 -1
View File
@@ -7,7 +7,7 @@ export default function Layout({
children: React.ReactNode;
}) {
return (
<div className="h-screen bg-white font-sans leading-normal tracking-normal">
<div className="h-screen min-h-[400px] bg-white font-sans leading-normal tracking-normal">
<Navbar />
{children}
<Footer />
+8 -8
View File
@@ -2,7 +2,7 @@ import Link from "next/link";
export default function Navbar() {
return (
<nav className="bg-gray-800 p-2 mt-0 w-full">
<nav className="bg-gray-800 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
@@ -13,26 +13,26 @@ export default function Navbar() {
</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">
<ul className="list-reset text-white no-underline flex flex-1 md:flex-none items-center">
<li className="mr-10">
<Link
className="inline-block hover:text-gray-200 hover:text-underline py-2 px-4"
className="inline-block border-b-4 py-5 border-transparent hover:border-teal-600 transition-all ease-in-out duration-300"
href="/tournois"
>
Tournois
</Link>
</li>
<li className="mr-3">
<li className="mr-10">
<Link
className="inline-block hover:text-gray-200 hover:text-underline py-2 px-4"
className="inline-block border-b-4 py-5 border-transparent hover:border-teal-600 transition-all ease-in-out duration-300"
href="/about"
>
About
</Link>
</li>
<li className="mr-3">
<li className="mr-10">
<Link
className="inline-block hover:text-gray-200 hover:text-underline py-2 px-4"
className="inline-block border-b-4 py-5 border-transparent hover:border-teal-600 transition-all ease-in-out duration-300"
href="/contact"
>
Contact
+1 -1
View File
@@ -24,7 +24,7 @@ export default function TournamentMap({ tournamentData }: TournamentDataProps) {
return (
<section
id="tournament-map"
className="grid h-[calc(100vh-96px)] md:h-[calc(100vh-64px)]"
className="grid h-[calc(100vh-108px)] md:h-[calc(100vh-76px)]"
>
<MapContainer
center={center}
+1 -1
View File
@@ -7,7 +7,7 @@ export default defineConfig({
// implement node event listeners here
},
},
chromeWebSecurity: false,
component: {
devServer: {
framework: "next",
+5 -3
View File
@@ -12,12 +12,13 @@ const navbarFooterCheck = () => {
});
};
describe("Verify component mount", () => {
describe("Verify home page", () => {
beforeEach(() => {
cy.mount(<Home />);
});
it("should have the correct h1 tags with website name included", () => {
it("correct h1 tags with website name included", () => {
cy.get("h1").contains("echecs france", { matchCase: false });
});
@@ -29,7 +30,7 @@ describe("Verify about page", () => {
cy.mount(<About />);
});
it("should have the correct h1 tags with page title included", () => {
it("correct h1 tags with page title included", () => {
cy.get("h1").contains("about", { matchCase: false });
});
@@ -41,9 +42,10 @@ describe("Verify contact page", () => {
cy.mount(<Contact />);
});
it("should have the correct h1 tags with page title included", () => {
it("correct h1 tags with page title included", () => {
cy.get("h1").contains("contact", { matchCase: false });
});
navbarFooterCheck();
});
});
+55
View File
@@ -0,0 +1,55 @@
import { Tournament } from "@/types";
import getTournaments from "@/utils/getTournamentData";
import { createLayerGroups } from "@/utils/layerGroups";
// TODO cy.wrap() for promise resolution
// TODO DRY - variables and data fetching can be done before tests under the first describe block
describe("Unit tests of utils directory", () => {
describe("Retrieve tournament data from DB", () => {
let response: Tournament[];
let results: Tournament[];
describe("France", () => {
before(async () => {
response = await getTournaments("france");
results = response.splice(0, 5);
});
it("log first 5 results", () => {
results.forEach((result) => cy.log(JSON.stringify(result)));
});
it("check tournament urls are active", () => {
results.forEach((result) => cy.request(result.url));
});
});
});
describe("Create layer groups for map markers", () => {
let response: Tournament[];
let results: Tournament[];
describe("France", () => {
const timeControls = [
{ name: "Cadence Lente", colour: "green" },
{ name: "Rapide", colour: "blue" },
{ name: "Blitz", colour: "yellow" },
{ name: "1h KO", colour: "red" },
];
before(async () => {
response = await getTournaments("france");
results = response.splice(0, 5);
});
it("generate layer groups", () => {
const result = timeControls.map((timeControl) => {
return createLayerGroups(timeControl.name, timeControl.colour, {
tournamentData: results,
});
});
cy.wrap(result.length).should("be.greaterThan", 0);
});
});
});
});
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
View File
@@ -2,6 +2,7 @@ import { Tournament } from "@/types";
import { useState } from "react";
// TODO change 'any'
// TODO document this hook with TSDoc
const useTournamentDataFilter = (
initialState: Tournament[]
): (any | ((searchQuery: string) => void))[] => {
+4 -3
View File
@@ -7,9 +7,10 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "jest",
"cypress:open": "cypress open",
"cypress:run": "cypress run"
"test:e2e": "cypress run",
"test:component": "cypress run --component",
"test": "npm run test:component && npm run test:e2e",
"cypress": "cypress open"
},
"dependencies": {
"@types/node": "20.2.3",
+1
View File
@@ -3,6 +3,7 @@
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"types": ["cypress"],
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
+14 -7
View File
@@ -1,8 +1,17 @@
import { TournamentDataProps } from "@/types";
import { LatLngLiteral } from "leaflet";
import L from "leaflet";
import { LayerGroup, LayersControl, Marker, Popup } from "react-leaflet";
const coordinateRandomisation = (lat: number, lng: number): LatLngLiteral => {
const randomisation = () => Math.random() * (-0.01 - 0.01) + 0.01;
return {
lat: lat + randomisation(),
lng: lng + randomisation(),
};
};
export const createLayerGroups = (
timeControl: string,
colour: string,
@@ -12,7 +21,6 @@ export const createLayerGroups = (
(t) => t.time_control === timeControl
);
// TODO consider moving this into its own function
const iconOptions = new L.Icon({
iconUrl: `images/leaflet/marker-icon-2x-${colour}.png`,
shadowUrl: "images/leaflet/marker-shadow.png",
@@ -23,13 +31,12 @@ export const createLayerGroups = (
});
const layerGroup = filteredTournaments.map((t) => {
// TODO move this coorindate randomisation into its own function to follow SRP
const coordinates = {
lat: t.coordinates[0] + Math.random() * (-0.01 - 0.01) + 0.01,
lng: t.coordinates[1] + Math.random() * (-0.01 - 0.01) + 0.01,
};
return (
<Marker position={coordinates} key={t._id} icon={iconOptions}>
<Marker
position={coordinateRandomisation(t.coordinates[0], t.coordinates[1])}
key={t._id}
icon={iconOptions}
>
<Popup>
<p>
{t.date}