From 550cdba5a73d4e44309f82fe3bdc1391874b1923 Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Mon, 16 Oct 2023 23:52:41 +0100 Subject: [PATCH] Started improving the responsiveness of the application --- src/components/High/Layout.tsx | 9 +- src/components/Low/ProgressBar.tsx | 5 +- src/components/MobileMenu.tsx | 133 ++++++++++++++++++++++ src/components/Navbar.tsx | 72 +++++++----- src/pages/index.tsx | 174 ++++++++++++++--------------- 5 files changed, 264 insertions(+), 129 deletions(-) create mode 100644 src/components/MobileMenu.tsx diff --git a/src/components/High/Layout.tsx b/src/components/High/Layout.tsx index ecbd571d..45c04b3a 100644 --- a/src/components/High/Layout.tsx +++ b/src/components/High/Layout.tsx @@ -19,13 +19,12 @@ export default function Layout({user, children, className, navDisabled = false, return (
- -
{children} diff --git a/src/components/Low/ProgressBar.tsx b/src/components/Low/ProgressBar.tsx index c1b447db..658772f2 100644 --- a/src/components/Low/ProgressBar.tsx +++ b/src/components/Low/ProgressBar.tsx @@ -7,9 +7,10 @@ interface Props { color: "red" | "rose" | "purple" | Module; useColor?: boolean; className?: string; + textClassName?: string; } -export default function ProgressBar({label, percentage, color, useColor = false, className}: Props) { +export default function ProgressBar({label, percentage, color, useColor = false, className, textClassName}: Props) { const progressColorClass: {[key in typeof color]: string} = { red: "bg-mti-red-light", rose: "bg-mti-rose-light", @@ -32,7 +33,7 @@ export default function ProgressBar({label, percentage, color, useColor = false, style={{width: `${percentage}%`}} className={clsx("absolute transition-all duration-300 ease-in-out top-0 left-0 h-full overflow-hidden", progressColorClass[color])} /> - {label} + {label}
); } diff --git a/src/components/MobileMenu.tsx b/src/components/MobileMenu.tsx new file mode 100644 index 00000000..015ea1e6 --- /dev/null +++ b/src/components/MobileMenu.tsx @@ -0,0 +1,133 @@ +import {User} from "@/interfaces/user"; +import {Dialog, Transition} from "@headlessui/react"; +import axios from "axios"; +import clsx from "clsx"; +import Image from "next/image"; +import Link from "next/link"; +import {useRouter} from "next/router"; +import {Fragment} from "react"; +import {BsShield, BsShieldFill, BsXLg} from "react-icons/bs"; + +interface Props { + isOpen: boolean; + onClose: () => void; + path: string; + user: User; +} + +export default function MobileMenu({isOpen, onClose, path, user}: Props) { + const router = useRouter(); + + const logout = async () => { + axios.post("/api/logout").finally(() => { + setTimeout(() => router.reload(), 500); + }); + }; + + return ( + + + +
+ + +
+
+ + + + + EnCoach logo + +
+ +
+
+
+ + Dashboard + + + Exams + + + Exercises + + + Stats + + + Record + + {user.type !== "student" && ( + + Admin + + )} + + Profile + + + + Logout + +
+
+
+
+
+
+
+ ); +} diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 9972f84e..da51607d 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -5,19 +5,24 @@ import {preventNavigation} from "@/utils/navigation.disabled"; import {useRouter} from "next/router"; import axios from "axios"; import {RiLogoutBoxFill} from "react-icons/ri"; -import {BsPower} from "react-icons/bs"; +import {BsList, BsPower} from "react-icons/bs"; import clsx from "clsx"; import moment from "moment"; +import MobileMenu from "./MobileMenu"; +import {useState} from "react"; interface Props { user: User; navDisabled?: boolean; focusMode?: boolean; onFocusLayerMouseEnter?: () => void; + path: string; } /* eslint-disable @next/next/no-img-element */ -export default function Navbar({user, navDisabled = false, focusMode = false, onFocusLayerMouseEnter}: Props) { +export default function Navbar({user, path, navDisabled = false, focusMode = false, onFocusLayerMouseEnter}: Props) { + const [isMenuOpen, setIsMenuOpen] = useState(false); + const disableNavigation = preventNavigation(navDisabled, focusMode); const router = useRouter(); @@ -40,35 +45,40 @@ export default function Navbar({user, navDisabled = false, focusMode = false, on }; return ( -
- - EnCoach's Logo -

EnCoach

- -
- {showExpirationDate() && ( - - {!user.subscriptionExpirationDate && "Unlimited"} - {user.subscriptionExpirationDate && moment(user.subscriptionExpirationDate).format("DD/MM/YYYY")} - - )} - - {user.name} - {user.name} - + <> + {user && setIsMenuOpen(false)} user={user} />} +
+ + EnCoach's Logo +

EnCoach

-
- {focusMode && } -
+
+ {showExpirationDate() && ( + + {!user.subscriptionExpirationDate && "Unlimited"} + {user.subscriptionExpirationDate && moment(user.subscriptionExpirationDate).format("DD/MM/YYYY")} + + )} + + {user.name} + {user.name} + +
setIsMenuOpen(true)}> + +
+
+ {focusMode && } + + ); } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 7477ab2c..13a1d99f 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -20,6 +20,7 @@ import axios from "axios"; import DemographicInformationInput from "@/components/DemographicInformationInput"; import moment from "moment"; import Link from "next/link"; +import {MODULE_ARRAY} from "@/utils/moduleUtils"; export const getServerSideProps = withIronSessionSsr(({req, res}) => { const user = req.session.user; @@ -158,28 +159,37 @@ export default function Home() { {user && ( -
- {user.name} -
-
+
+ {user.name} +
+ {user.name} +
-

{user.name}

+

{user.name}

{capitalize(user.type)}
-
+
@@ -209,100 +219,82 @@ export default function Home() {
+ + + +
+
+
+ +
+
+ {totalExams(stats)} + Exams +
+
+
+
+ +
+
+ {stats.length} + Exercises +
+
+
+
+ +
+
+ {stats.length > 0 ? averageScore(stats) : 0}% + Average Score +
+
+
-
+ +
Bio {user.bio || "Your bio will appear here, you can change it by clicking on your name in the top right corner."}
+
Score History -
-
-
-
- +
+ {MODULE_ARRAY.map((module) => ( +
+
+
+ {module === "reading" && } + {module === "listening" && } + {module === "writing" && } + {module === "speaking" && } +
+
+ {capitalize(module)} + + Level {user.levels[module]} / Level {user.desiredLevels[module]} + +
-
- Reading - - Level {user.levels.reading} / Level {user.desiredLevels.reading} - +
+
-
- -
-
-
-
-
- -
-
- Writing - - Level {user.levels.writing} / Level {user.desiredLevels.writing} - -
-
-
- -
-
-
-
-
- -
-
- Listening - - Level {user.levels.listening} / Level {user.desiredLevels.listening} - -
-
-
- -
-
-
-
-
- -
-
- Speaking - - Level {user.levels.speaking} / Level {user.desiredLevels.speaking} - -
-
-
- -
-
+ ))}