Skip to content

Commit a30a2c9

Browse files
committed
Improved page content height dynamic computation (accounting for navbar)
1 parent 42a3c7a commit a30a2c9

File tree

15 files changed

+104
-31
lines changed

15 files changed

+104
-31
lines changed

frontend/app/(pages)/dashboard/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import useGetActiveUser from "@/app/hooks/api_access/user/useGetActiveUser";
44
import useGetGroupChatsInfo from "@/app/hooks/api_access/group_chats/useGetGroupChatsInfo";
55
import useGetGroupChatLeaderboards from "@/app/hooks/api_access/leaderboards/useGetGroupChatLeaderboards";
66
import useNavBar from "@/app/hooks/context_imports/useNavBar";
7+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
78
import { User, GroupChatInfo, SurvivalEntry, TimeAttackEntry, QuizLeaderboardInfo } from "@/app/interfaces";
89
import { renderQuizRows, toggleModal, isTimeAttackEntry, isSurvivalEntry } from "@/app/utilities/miscFunctions";
910
import GroupChatInfoRow from "@/app/components/data-rows/GroupChatInfoRow";
@@ -49,6 +50,9 @@ export default function Dashboard() {
4950
const [selectedLeaderboardIndex, setSelectedLeaderboardIndex] = useState<number>(0); // [0, previewLeaderboards.length)
5051
const [leaderboardAnimationStatus, setLeaderboardAnimationStatus] = useState<LeaderboardAnimationStatus | null>(null);
5152

53+
// Adjust the height of the page content area
54+
useAdjustContentHeight(".navbar", ".page-content");
55+
5256
// ----------- Data Retrieval ---------
5357
useEffect(() => {
5458
const getPageData = async () => {
@@ -367,8 +371,8 @@ export default function Dashboard() {
367371
}
368372

369373
return (<>
370-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
371-
<main className="flex max-h-content overflow-y-scroll flex-col items-center justify-between">
374+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
375+
<main className="page-content flex flex-col overflow-y-scroll items-center justify-between">
372376
<div className={`relative w-[95%] lg:w-[90%] xl:w-[80%] 2xl:w-[70%] 3xl:w-[50%]`}>
373377
{renderFocusedGroupChat()}
374378
<div className="hidden lg:block">

frontend/app/(pages)/group-chats/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import useGetActiveUser from "@/app/hooks/api_access/user/useGetActiveUser";
44
import useGetGroupChatsInfo from "@/app/hooks/api_access/group_chats/useGetGroupChatsInfo";
55
import useNavBar from "@/app/hooks/context_imports/useNavBar";
6+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
67
import { User, GroupChatInfo } from "@/app/interfaces";
78
import GroupChatInfoRow from "@/app/components/data-rows/GroupChatInfoRow";
89
import WrenchIcon from "@/app/components/icons/WrenchIcon";
@@ -28,6 +29,9 @@ export default function ManageGroupChats() {
2829
const [loading, setLoading] = useState<boolean>(true);
2930
const [isDeleting, setIsDeleting] = useState<boolean>(false);
3031

32+
// Adjust the height of the page content area
33+
useAdjustContentHeight(".navbar", ".page-content");
34+
3135
// ----------- Data Retrieval ---------
3236
useEffect(() => {
3337
const getPageData = async () => {
@@ -93,8 +97,8 @@ export default function ManageGroupChats() {
9397
const totalQuizzes = groupChats.reduce((acc, curr) => acc + curr.quizzes.length, 0);
9498

9599
return (<>
96-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
97-
<main className="flex max-h-content overflow-y-scroll flex-col items-center justify-between">
100+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
101+
<main className="page-content flex flex-col overflow-y-scroll items-center justify-between">
98102
<div className="w-[97%] lg:w-[80%] xl:w-[70%] 2xl:w-[60%] 3xl:w-[40%] mt-7 sm:mt-20 mb-[75px]">
99103
{!loading &&
100104
<div className="flex flex-row w-full px-[2px] md:px-1 mb-4 md:mb-4 justify-center items-center">

frontend/app/(pages)/leaderboard/[...query]/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import useGetLeaderboard from "@/app/hooks/api_access/leaderboards/useGetLeaderb
44
import useGetQuiz from "@/app/hooks/api_access/quizzes/useGetQuiz";
55
import useValidateUrlToken from "@/app/hooks/security/useValidateUrlToken";
66
import useAuth from "@/app/hooks/context_imports/useAuth";
7+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
78

89
import { TimeAttackEntry, SurvivalEntry, TimeAttackQuiz, SurvivalQuiz } from "@/app/interfaces";
910
import { isTimeAttackEntry, isSurvivalEntry, isTimeAttackQuiz } from "@/app/utilities/miscFunctions";
@@ -42,6 +43,9 @@ export default function Leaderboard({ params }: { params: { query: string[]}}) {
4243
const [loading, setLoading] = useState<boolean>(true);
4344
const [expandedEntry, setExpandedEntry] = useState<number>(-1); // -1 means no entry is expanded
4445

46+
// Adjust the height of the page content area
47+
useAdjustContentHeight(".navbar", ".page-content");
48+
4549
// ----------- Data Retrieval ---------
4650
useEffect(() => {
4751
const getPageData = async () => {
@@ -244,8 +248,8 @@ export default function Leaderboard({ params }: { params: { query: string[]}}) {
244248
// =============== MAIN RENDER ===============
245249

246250
return (<>
247-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
248-
<main className="flex flex-col max-h-content overflow-y-scroll items-center justify-between">
251+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
252+
<main className="page-content flex flex-col overflow-y-scroll items-center justify-between">
249253
<div className="mt-7 md:mt-20 lg:mt-36 w-[97%] md:w-[70%] lg:w-[60%] xl:w-[50%] 2xl:w-[40%] 3xl:w-[30%]">
250254
<div className="flex justify-center w-full text-3xl sm:text-4xl font-bold whitespace-nowrap">
251255
<div className="relative w-[35px] h-[35px] mr-3">

frontend/app/(pages)/login/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import usePostLogin from "@/app/hooks/api_access/authentication/usePostLogin";
44
import useNavBar from "@/app/hooks/context_imports/useNavBar";
5+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
56
import UserSmallIcon from "@/app/components/icons/nav-bar/UserSmallIcon";
67
import PasswordIcon from "@/app/components/icons/nav-bar/PasswordIcon";
78

@@ -26,6 +27,9 @@ export default function Login() {
2627
// Login loading state
2728
const [loginLoading, setLoginLoading] = useState<boolean>(false);
2829

30+
// Adjust the height of the page content area
31+
useAdjustContentHeight(".navbar", ".page-content");
32+
2933
// The onChange event handler for the login form fields
3034
const handleLoginChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
3135
const { name, value } = event.target;
@@ -55,8 +59,8 @@ export default function Login() {
5559
}
5660

5761
return (<>
58-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
59-
<main className="flex flex-col min-h-content max-h-content overflow-y-scroll items-center justify-center text-white">
62+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
63+
<main className="page-content flex flex-col overflow-y-scroll items-center justify-center">
6064
<div className="relative bottom-3 md:bottom-12 mx-auto flex w-full max-w-sm flex-col">
6165
<div className="relative flex flex-col items-center mb-8">
6266
<h1 className="text-3xl font-semibold">Sign In</h1>

frontend/app/(pages)/messages/[...query]/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import useGetQuizzes from "@/app/hooks/api_access/quizzes/useGetQuizzes";
66
import useGetParticipants from "@/app/hooks/api_access/participants/useGetParticipants";
77
import usePostMessagesInQuiz from "@/app/hooks/api_access/quizzes/usePostMessagesInQuiz";
88
import useDeleteMessages from "@/app/hooks/api_access/messages/useDeleteMessages";
9+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
910

1011
import { renderQuizTypeBadge, renderResponseAlert, toggleModal, isModalOpen } from "@/app/utilities/miscFunctions";
1112
import {
@@ -83,6 +84,9 @@ export default function Messages({ params }: { params: { query: string[] }}) {
8384
// HTTP Request errors for adding/removing messages to/from quizzes, and deleting messages
8485
const [responseStatus, setResponseStatus] = useState<ResponseStatus>({ message: "", success: false, doAnimate: false });
8586

87+
// Adjust the height of the page content area
88+
useAdjustContentHeight(".navbar", ".page-content");
89+
8690
// ----------- Data Retrieval ---------
8791

8892
// Fetch stable data (group chat, quizzes, participants) - data we don't need to refresh
@@ -725,8 +729,8 @@ export default function Messages({ params }: { params: { query: string[] }}) {
725729
// =============== MAIN RENDER =================
726730

727731
return (<>
728-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
729-
<main className="flex max-h-content overflow-y-scroll flex-col items-center justify-between">
732+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
733+
<main className="page-content flex flex-col overflow-y-scroll items-center justify-between">
730734
<div className="relative w-[97%] lg:w-[90%] xl:w-[80%] 2xl:w-[70%] 3xl:w-[50%] mt-5">
731735
<div className="w-full p-2 mb-3 lg:p-8 bg-[#050507] rounded-xl border border-zinc-800 overflow-x-hidden">
732736
<div className="flex mb-2">

frontend/app/(pages)/participants/[groupChatId]/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import useGetGroupChat from "@/app/hooks/api_access/group_chats/useGetGroupChat"
44
import useGetParticipants from "@/app/hooks/api_access/participants/useGetParticipants";
55
import usePatchParticipantName from "@/app/hooks/api_access/participants/usePatchParticipantName";
66
import useDeleteParticipant from "@/app/hooks/api_access/participants/useDeleteParticipant";
7+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
78

89
import EditIcon from "@/app/components/icons/EditIcon";
910
import CheckmarkIcon from "@/app/components/icons/CheckmarkIcon";
@@ -56,6 +57,9 @@ export default function Participants({ params }: { params: { groupChatId: string
5657
const blurbRef = useRef<HTMLDivElement>(null);
5758
const nameInputRef = useRef<HTMLInputElement>(null);
5859

60+
// Adjust the height of the page content area
61+
useAdjustContentHeight(".navbar", ".page-content");
62+
5963
// ----------- Data Retrieval ---------
6064
useEffect(() => {
6165
const getPageData = async () => {
@@ -315,8 +319,8 @@ export default function Participants({ params }: { params: { groupChatId: string
315319
// =============== MAIN RENDER =================
316320

317321
return (<>
318-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
319-
<main className="relative flex flex-col items-center justify-between h-content">
322+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
323+
<main className="page-content relative flex flex-col items-center justify-between">
320324
<div className="absolute top-[50%] translate-y-[-50%] w-[97%] md:w-[80%] lg:w-[70%] xl:w-[60%] 2xl:w-[50%] 3xl:w-[40%]">
321325
<div className="flex flex-col w-full p-2 sm:p-8 bg-[#050507] rounded-xl border border-zinc-800 overflow-hidden">
322326
<div className="text-3xl sm:text-4xl mb-6 sm:mb-5 mt-4 sm:mt-0 mx-auto sm:mx-0 text-center font-semibold">

frontend/app/(pages)/quiz/[...query]/page.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { toggleModal, isModalOpen, applyTextMarkup, renderModalResponseAlert,
1313
import useGetQuizInfo from "@/app/hooks/api_access/quizzes/useGetQuizInfo";
1414
import useGetRandomQuizMessage from "@/app/hooks/api_access/messages/useGetRandomQuizMessage";
1515
import usePostLeaderboardEntry from "@/app/hooks/api_access/leaderboards/usePostLeaderboardEntry";
16+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
1617

1718
import AnimateHeight from "react-animate-height";
1819
import { Height } from "react-animate-height";
@@ -99,6 +100,9 @@ export default function Quiz({ params }: { params: { query: string[] } }) {
99100
const correctAudioRef = useRef<HTMLAudioElement>(new Audio("/correct.mp3"));
100101
const incorrectAudioRef = useRef<HTMLAudioElement>(new Audio("/incorrect.mp3"));
101102

103+
// Adjust the height of the page content area
104+
useAdjustContentHeight(".navbar", ".page-content");
105+
102106
// ----- Data Retrieval/Authentication & Initial animation triggers -----
103107
useEffect(() => {
104108
const getPageData = async () => {
@@ -745,10 +749,11 @@ export default function Quiz({ params }: { params: { query: string[] } }) {
745749
</>);
746750
}
747751

748-
return (
749-
<main className="flex min-h-screen flex-col items-center justify-center overflow-hidden
752+
return (<>
753+
<div className="navbar h-0 w-full" /> {/* Unrendered navbar ref for useAdjustContentHeight */}
754+
<main className="page-content flex flex-col items-center justify-center overflow-hidden
750755
bg-gradient-to-b from-black via-zinc-950 to-black">
751756
{renderContent}
752757
</main>
753-
);
758+
</>);
754759
}

frontend/app/(pages)/recover/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import usePostRequestPasswordReset from "@/app/hooks/api_access/authentication/usePostRequestPasswordReset";
4+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
45
import { validateEmail } from "@/app/utilities/formValidationFunctions";
56

67
import { useState } from "react";
@@ -18,6 +19,9 @@ export default function Recover() {
1819
const [emailValid, setEmailValid] = useState<boolean>(true);
1920
const [recoverLoading, setRecoverLoading] = useState<boolean>(false);
2021

22+
// Adjust the height of the page content area
23+
useAdjustContentHeight(".navbar", ".page-content");
24+
2125
const handleEmailChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
2226
const { value } = event.target;
2327
setRecoverEmail(value);
@@ -44,8 +48,8 @@ export default function Recover() {
4448
}
4549

4650
return (<>
47-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
48-
<main className="flex flex-col min-h-content max-h-content overflow-y-scroll items-center justify-center">
51+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
52+
<main className="page-content flex flex-col overflow-y-scroll items-center justify-center">
4953
<div className="relative bottom-3 md:bottom-12 mx-auto flex w-full max-w-sm flex-col">
5054
<div className="relative flex flex-col items-center mb-12 gap-2">
5155
<h1 className="text-3xl font-semibold">Account Recovery</h1>

frontend/app/(pages)/register/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import usePostRegistration from "@/app/hooks/api_access/authentication/usePostRegistration";
44
import useNavBar from "@/app/hooks/context_imports/useNavBar";
5+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
56
import { validateUsername, validateEmail, validatePassword } from "@/app/utilities/formValidationFunctions";
67

78
import Link from "next/link";
@@ -37,6 +38,9 @@ export default function Register() {
3738
// Registration error message
3839
const [registerError, setRegisterError] = useState<string>(""); // Empty string means no error
3940

41+
// Adjust the height of the page content area
42+
useAdjustContentHeight(".navbar", ".page-content");
43+
4044
const handleRegisterChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
4145
const { name, value } = event.target;
4246
if (name === "username") {
@@ -93,8 +97,8 @@ export default function Register() {
9397
// ========================================================================================================================
9498

9599
return(<>
96-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
97-
<main className="flex flex-col min-h-content max-h-content overflow-y-scroll items-center justify-center">
100+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
101+
<main className="page-content flex flex-col overflow-y-scroll items-center justify-center">
98102
<div className="relative bottom-3 md:bottom-12 mx-auto flex w-full max-w-sm flex-col">
99103
<div className="flex flex-col items-center mb-8">
100104
<h1 className="text-3xl font-semibold">Register</h1>

frontend/app/(pages)/reset-password/[userId]/[token]/page.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import usePatchPasswordReset from "@/app/hooks/api_access/authentication/usePatchPasswordReset";
44
import useValidatePasswordResetToken from "@/app/hooks/security/useValidatePasswordResetToken";
5+
import useAdjustContentHeight from "@/app/hooks/useAdjustContentHeight";
56
import { validatePassword } from "@/app/utilities/formValidationFunctions";
67

78
import { useState, useEffect } from "react";
@@ -29,6 +30,9 @@ export default function ResetPassword({ params }: { params: { userId: string, to
2930
const [newPasswordValidMessage, setNewPasswordValidMessage] = useState<string>("");
3031
const [confirmNewPasswordValid, setConfirmNewPasswordValid] = useState<boolean>(true);
3132

33+
// Adjust the height of the page content area
34+
useAdjustContentHeight(".navbar", ".page-content");
35+
3236
// Initial token validation. If successful, the user will be able to reset their password.
3337
// If the token is invalid, the user will be redirected to the login page after a delay.
3438
useEffect(() => {
@@ -121,8 +125,8 @@ export default function ResetPassword({ params }: { params: { userId: string, to
121125
}
122126

123127
return (<>
124-
<div className="w-full h-navbar" /> {/* Navbar spacer */}
125-
<main className="flex flex-col min-h-content max-h-content overflow-y-scroll items-center justify-center">
128+
<div className="navbar h-navbar w-full" /> {/* Navbar spacer */}
129+
<main className="page-content flex flex-col overflow-y-scroll items-center justify-center">
126130
<div className="relative bottom-3 md:bottom-12 mx-auto flex w-full max-w-sm flex-col">
127131
<div className="relative flex flex-col items-center mb-12 gap-2">
128132
<h1 className="text-3xl font-semibold">Reset Password</h1>

frontend/app/globals.css

+5
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,9 @@ details > summary.list-none::marker {
9696

9797
.blur-fix {
9898
transform: translateZ(0) scale(1.0, 1.0);
99+
}
100+
101+
/* Animation signalers */
102+
.will-change-transform {
103+
will-change: transform;
99104
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useEffect } from 'react';
2+
3+
// This hook adjusts the height of the main content area to fill the remaining viewport height
4+
// after the navbar height is subtracted.
5+
6+
export default function useAdjustContentHeight(navbarSelector: string, mainContentSelector: string) {
7+
useEffect(() => {
8+
const adjustContentHeight = () => {
9+
const navbar: HTMLElement | null = document.querySelector(navbarSelector);
10+
const mainContent: HTMLElement | null = document.querySelector(mainContentSelector);
11+
12+
if (navbar && mainContent) {
13+
const navbarHeight = navbar.offsetHeight;
14+
const viewportHeight = window.innerHeight;
15+
const contentHeight = viewportHeight - navbarHeight;
16+
mainContent.style.height = `${contentHeight}px`;
17+
}
18+
};
19+
20+
// Adjust content height on initial load and on window resize
21+
adjustContentHeight();
22+
window.addEventListener('resize', adjustContentHeight);
23+
24+
// Cleanup event listener on component unmount
25+
return () => window.removeEventListener('resize', adjustContentHeight);
26+
}, []);
27+
};

frontend/app/layout.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const metadata: Metadata = {
1616
export default function RootLayout({ children }: { children: React.ReactNode }) {
1717
return (
1818
<html lang="en">
19-
<body className={inter.className + " min-h-screen"} data-theme="dark">
19+
<body className={inter.className + " overflow-hidden"} data-theme="dark">
2020
<Providers>
2121
<NavBar />
2222
{children}

frontend/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "0.1.0",
44
"private": true,
55
"scripts": {
6-
"dev": "next dev",
6+
"dev": "next dev -H 0.0.0.0",
77
"build": "next build",
88
"start": "next start",
99
"lint": "next lint"

0 commit comments

Comments
 (0)