From 2fd05915a7e33f43c6739196c5c61aeead1104d3 Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Thu, 8 Feb 2024 22:23:22 +0000 Subject: [PATCH 1/3] Added Navbar with nested entries --- src/components/Navbar.tsx | 438 +++++++++++++++++---------- src/components/NestedNavbarEntry.tsx | 76 +++++ src/translation/navbar.json | 6 +- 3 files changed, 358 insertions(+), 162 deletions(-) create mode 100644 src/components/NestedNavbarEntry.tsx diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index fbf09cc..1c2fd82 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,176 +1,292 @@ /* eslint-disable @next/next/no-img-element */ "use client"; - +import React from "react"; import Link from "next/link"; import Image from "next/image"; import clsx from "clsx"; -import {BsList, BsXLg} from "react-icons/bs"; -import {Fragment, useEffect, useState} from "react"; -import {Dialog, Menu, Transition} from "@headlessui/react"; -import {useRouter} from "next/navigation"; +import { BsList, BsXLg } from "react-icons/bs"; +import { Fragment, useState } from "react"; +import { Dialog, Transition } from "@headlessui/react"; import translation from "@/translation/navbar.json"; +import NestedNavbarEntry from "@/components/NestedNavbarEntry"; const items = [ - {page: "/", key: "home"}, - {page: "/services", key: "services"}, - {page: "/price", key: "price"}, - {page: "/about", key: "about"}, - {page: "/history", key: "history"}, - {page: "/contact", key: "contact"}, + { page: "/", key: "home" }, + { page: "/services", key: "services" }, + { page: "/price", key: "price" }, + { page: "/about", key: "about" }, + { page: "/history", key: "history" }, + { page: "/contact", key: "contact" }, + { + key: "country_manager", + page: "", + entries: [ + { + key: "Egypt", + entries: [ + { + name: "Modern Technology", + number: "+226578480830", + email: "egypt@encoach.com", + }, + ], + }, + { + key: "Oman", + entries: [ + { + name: "Smartway education", + number: "+9689944094", + email: "oman@encoach.com", + }, + { name: "MTI", number: "+9687445609", email: "mti@encoach.com" }, + ], + }, + { + key: "Saudi Arabia", + entries: [ + { + name: "Edutrach services", + number: "+96658499347", + email: "edu@encoach.com", + }, + ], + }, + ], + }, ]; -export default function Navbar({currentPage, language}: {currentPage: string; language: "en" | "ar"}) { - const [isOpen, setIsOpen] = useState(false); +export default function Navbar({ + currentPage, + language, +}: { + currentPage: string; + language: "en" | "ar"; +}) { + const [isOpen, setIsOpen] = useState(false); - return ( - <> -
- - EnCoach logo - -
- {items.map((item) => ( - - {(translation as any)[item.key][language]} - - ))} -
-
- - {translation.platform[language]} - - - {translation.join[language]} - - {language === "ar" ? ( - - EN - - ) : ( - - AR - - )} -
-
+ return ( + <> +
+ + EnCoach logo + +
+ {items.map((item) => + item.entries ? ( + + ) : ( + + {(translation as any)[item.key][language]} + + ) + )} +
+
+ + {translation.platform[language]} + + + {translation.join[language]} + + {language === "ar" ? ( + + EN + + ) : ( + + AR + + )} +
+
- - setIsOpen(false)}> - -
- + + setIsOpen(false)} + > + +
+ -
-
- - - - - EnCoach logo - -
- {language === "ar" ? ( - - EN - - ) : ( - - AR - - )} -
setIsOpen(false)} tabIndex={0}> - setIsOpen(false)} /> -
-
-
-
- {items.map((item) => ( - - {(translation as any)[item.key][language]} - - ))} - - {translation.join[language]} - - - {translation.platform[language]} - -
-
-
-
-
-
-
+
+
+ + + + + EnCoach logo + +
+ {language === "ar" ? ( + + EN + + ) : ( + + AR + + )} +
setIsOpen(false)} + tabIndex={0} + > + setIsOpen(false)} + /> +
+
+
+
+ {items.map((item) => ( + + {(translation as any)[item.key][language]} + + ))} + + {translation.join[language]} + + + {translation.platform[language]} + +
+
+
+
+
+
+
-
- - EnCoach logo - -
- {language === "ar" ? ( - - EN - - ) : ( - - AR - - )} -
setIsOpen(true)}> - setIsOpen(true)} /> -
-
-
- - ); +
+ + EnCoach logo + +
+ {language === "ar" ? ( + + EN + + ) : ( + + AR + + )} +
setIsOpen(true)}> + setIsOpen(true)} /> +
+
+
+ + ); } diff --git a/src/components/NestedNavbarEntry.tsx b/src/components/NestedNavbarEntry.tsx new file mode 100644 index 0000000..34d706e --- /dev/null +++ b/src/components/NestedNavbarEntry.tsx @@ -0,0 +1,76 @@ +import React from "react"; +import clsx from "clsx"; + +interface NavbarNestedEntry { + name: string; + number: string; + email: string; +} +interface NavbarEntry { + key: string; + entries: { + key: string; + entries: NavbarNestedEntry[]; + }[]; +} +const NestedSubmenus = ({ entry }: { entry: NavbarEntry }) => { + const [open, setOpen] = React.useState(null); + + return ( + + ); +}; + +const NestedNavbarEntry = ({ + entry, + language, + translation +}: { + entry: NavbarEntry; + language: "en" | "ar"; + translation: any +}) => { + const [open, setOpen] = React.useState(null); + + return ( +
setOpen(entry.key)} + onMouseLeave={() => setOpen(null)} + > + + {translation[entry.key][language]} + + +
+ ); +}; + +export default NestedNavbarEntry; \ No newline at end of file diff --git a/src/translation/navbar.json b/src/translation/navbar.json index 08e6609..b032635 100644 --- a/src/translation/navbar.json +++ b/src/translation/navbar.json @@ -30,5 +30,9 @@ "join": { "en": "Join", "ar": "انضم إلينا" + }, + "country_manager": { + "en": "Country Manager", + "ar": "المدير المحلي" } -} \ No newline at end of file +} From 4e9d9c9fe3be1ad69a65cf45a6a6130b8b18daa1 Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Thu, 8 Feb 2024 22:27:41 +0000 Subject: [PATCH 2/3] Added missing translation --- src/components/Navbar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 1c2fd82..b19600a 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -19,7 +19,7 @@ const items = [ { page: "/contact", key: "contact" }, { key: "country_manager", - page: "", + page: '', entries: [ { key: "Egypt", @@ -88,7 +88,7 @@ export default function Navbar({ key={item.key} entry={item} language={language} - translation={translation} + translation={translation} /> ) : ( Date: Thu, 15 Feb 2024 00:01:48 +0000 Subject: [PATCH 3/3] Updated Navbar to use nested entries and added a page to display contact information --- src/app/contacts/[country]/page.tsx | 78 ++++++++++++++++++++++++++++ src/components/Navbar.tsx | 70 +++++++++++-------------- src/components/NestedNavbarEntry.tsx | 76 --------------------------- src/contacts.json | 36 +++++++++++++ 4 files changed, 143 insertions(+), 117 deletions(-) create mode 100644 src/app/contacts/[country]/page.tsx delete mode 100644 src/components/NestedNavbarEntry.tsx create mode 100644 src/contacts.json diff --git a/src/app/contacts/[country]/page.tsx b/src/app/contacts/[country]/page.tsx new file mode 100644 index 0000000..b7eb476 --- /dev/null +++ b/src/app/contacts/[country]/page.tsx @@ -0,0 +1,78 @@ +import Footer from "@/components/Footer"; +import Navbar from "@/components/Navbar"; +import Title from "@/components/Title"; +import contacts from "../../../contacts.json"; + +interface Contact { + key: string; + label: string; + entries: { + name: string; + number: string; + email: string; + }[]; +} + +type Language = "en" | "ar"; + +interface PageProps { + params: { + country: string; + }; + searchParams: { + page: string; + language: Language; + }; +} + +export function generateStaticParams() { + // down the line, this is required to be loaded from a CMS + // for now, we'll just use a JSON file + + // do not forget the actually render this as multiple languages + return contacts.map(({ key }) => ({ + country: key.toLowerCase().replaceAll(" ", ""), + })); +} + +export default function Page({ + params: { country }, + searchParams: { page = "/contacts", language = "en" }, +}: PageProps) { + // this approach will not be viable later on when we have multiple languages + // or use the data from the server + // replace this with a fetch to the CMS + const contact = contacts.find(({ key }) => key === country) as Contact; + + return ( +
+ + +
+
+ {`${contact.label} Contacts`} +
+
+ +
+ {contact.entries.map((entry) => ( +
+

+ Name: + {entry.name} +

+

+ Number: + {entry.number} +

+

+ Email: + {entry.email} +

+
+ ))} +
+
+
+ ); +} diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index b19600a..78b05a7 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -8,7 +8,7 @@ import { BsList, BsXLg } from "react-icons/bs"; import { Fragment, useState } from "react"; import { Dialog, Transition } from "@headlessui/react"; import translation from "@/translation/navbar.json"; -import NestedNavbarEntry from "@/components/NestedNavbarEntry"; +import contacts from "@/contacts.json"; const items = [ { page: "/", key: "home" }, @@ -19,40 +19,11 @@ const items = [ { page: "/contact", key: "contact" }, { key: "country_manager", - page: '', - entries: [ - { - key: "Egypt", - entries: [ - { - name: "Modern Technology", - number: "+226578480830", - email: "egypt@encoach.com", - }, - ], - }, - { - key: "Oman", - entries: [ - { - name: "Smartway education", - number: "+9689944094", - email: "oman@encoach.com", - }, - { name: "MTI", number: "+9687445609", email: "mti@encoach.com" }, - ], - }, - { - key: "Saudi Arabia", - entries: [ - { - name: "Edutrach services", - number: "+96658499347", - email: "edu@encoach.com", - }, - ], - }, - ], + page: "/contacts", + entries: contacts.map((data) => ({ + key: data.key, + label: data.label, + })), }, ]; @@ -64,7 +35,6 @@ export default function Navbar({ language: "en" | "ar"; }) { const [isOpen, setIsOpen] = useState(false); - return ( <>
@@ -84,12 +54,30 @@ export default function Navbar({ > {items.map((item) => item.entries ? ( - + className={clsx( + "group relative hover:border-b-mti-purple-light transition duration-300 ease-in-out hover:border-b-2 z-10 cursor-pointer", + currentPage === item.page && + "border-b-mti-purple-light border-b-2" + )} + > + + {translation[item.key as keyof typeof translation][language]} + +
    + {item.entries?.map((innerEntry) => ( +
  • + + {innerEntry.label} + +
  • + ))} +
+ ) : ( { - const [open, setOpen] = React.useState(null); - - return ( -
    - {entry.entries.map((entry) => ( -
  • -
    setOpen(entry.key)} - onMouseLeave={() => setOpen(null)} - > - {entry.key} - {open === entry.key && ( -
      - {entry.entries.map((value) => ( -
    • - {value.name} -
    • - ))} -
    - )} -
    -
  • - ))} -
- ); -}; - -const NestedNavbarEntry = ({ - entry, - language, - translation -}: { - entry: NavbarEntry; - language: "en" | "ar"; - translation: any -}) => { - const [open, setOpen] = React.useState(null); - - return ( -
setOpen(entry.key)} - onMouseLeave={() => setOpen(null)} - > - - {translation[entry.key][language]} - - -
- ); -}; - -export default NestedNavbarEntry; \ No newline at end of file diff --git a/src/contacts.json b/src/contacts.json new file mode 100644 index 0000000..f69e645 --- /dev/null +++ b/src/contacts.json @@ -0,0 +1,36 @@ +[ + { + "label": "Egypt", + "key": "egypt", + "entries": [ + { + "name": "Modern Technology", + "number": "+226578480830", + "email": "egypt@encoach.com" + } + ] + }, + { + "label": "Oman", + "key": "oman", + "entries": [ + { + "name": "Smartway education", + "number": "+9689944094", + "email": "oman@encoach.com" + }, + { "name": "MTI", "number": "+9687445609", "email": "mti@encoach.com" } + ] + }, + { + "label": "Saudi Arabia", + "key": "saudiarabia", + "entries": [ + { + "name": "Edutrach services", + "number": "+96658499347", + "email": "edu@encoach.com" + } + ] + } +]