From e08f4591c68fadd75442849402ecd10fde7597f8 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 3 Apr 2024 01:18:44 +0000 Subject: [PATCH 01/10] Rename / Transition to Headless UI Tab Control --- frontend-next/src/app/app/page.js | 2 +- frontend-next/src/app/chat/page.js | 2 +- .../components/app/{main_tab => page}/chat.js | 0 .../components/app/{main_tab => page}/home.js | 0 .../src/components/app/sidebar/home.js | 121 +++++++++--------- 5 files changed, 60 insertions(+), 65 deletions(-) rename frontend-next/src/components/app/{main_tab => page}/chat.js (100%) rename frontend-next/src/components/app/{main_tab => page}/home.js (100%) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index 75d60e3..f63fcfc 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -10,7 +10,7 @@ import { useGeolocated } from "react-geolocated"; import { Header } from "../../components/app/header"; // Main Tab Imports -import { MainTabHome } from "../../components/app/main_tab/home"; +import { MainTabHome } from "../../components/app/page/home"; // Sidebar Imports import { Home_Sidebar } from "../../components/app/sidebar/home"; diff --git a/frontend-next/src/app/chat/page.js b/frontend-next/src/app/chat/page.js index b5fecd5..e4ec728 100644 --- a/frontend-next/src/app/chat/page.js +++ b/frontend-next/src/app/chat/page.js @@ -9,7 +9,7 @@ import { useAuthState } from "react-firebase-hooks/auth" import { Header } from "../../components/app/header"; // Main Tab Imports -import { MainTabChatRoom } from "../../components/app/main_tab/chat"; +import { MainTabChatRoom } from "../../components/app/page/chat"; // Sidebar Imports import { Chat_Sidebar } from "../../components/app/sidebar/chat"; diff --git a/frontend-next/src/components/app/main_tab/chat.js b/frontend-next/src/components/app/page/chat.js similarity index 100% rename from frontend-next/src/components/app/main_tab/chat.js rename to frontend-next/src/components/app/page/chat.js diff --git a/frontend-next/src/components/app/main_tab/home.js b/frontend-next/src/components/app/page/home.js similarity index 100% rename from frontend-next/src/components/app/main_tab/home.js rename to frontend-next/src/components/app/page/home.js diff --git a/frontend-next/src/components/app/sidebar/home.js b/frontend-next/src/components/app/sidebar/home.js index dbfce0b..5bf9eed 100644 --- a/frontend-next/src/components/app/sidebar/home.js +++ b/frontend-next/src/components/app/sidebar/home.js @@ -2,6 +2,8 @@ import { Form, useForm } from "react-hook-form"; import { database } from "../../../../firebase-config"; import { ref, set, get } from "firebase/database"; import { useEffect, useState } from "react"; +import { Tab } from '@headlessui/react' + import { ChatRoomSidebar } from "../datatypes"; // Sidebar on Home Page, with various functionality (create, nearby, my rooms) @@ -50,12 +52,16 @@ function CreateRoom({ loc }) { ); } +function classNames(...classes) { + return classes.filter(Boolean).join(' ') +} + export function Home_Sidebar({ user, location, loadingLoc }) { - const [tab, setTab] = useState("rooms"); + const [tab, setTab] = useState("nearby"); const [nearbyArr, setNearbyArr] = useState([]) const [nearbyArrReady, setNearbyArrReady] = useState(false) @@ -98,71 +104,60 @@ export function Home_Sidebar({ return (
-
-
-
{ - setTab("nearby"); - }} - > - Nearby -
-
{ - setTab("rooms"); - }} - > - My Rooms -
-
{ - setTab("create"); - }} - > - Create -
-
-
- {tab == "nearby" && ( -
-
- {!nearbyArr && !loadingLoc && ( + + + + classNames( + 'w-[31%]', + selected + ? 'bg-cyan-500 text-white font-bold shadow hover:bg-white/[0.6] hover:text-black' + : 'hover:bg-cyan-500/[0.6] hover:text-white hover:font-bold' + )} defaultIndex={1}>Nearby + + classNames( + 'w-[31%]', + selected + ? 'bg-cyan-500 text-white font-bold shadow hover:bg-white/[0.6] hover:text-black' + : 'hover:bg-cyan-500/[0.6] hover:text-white hover:font-bold' + )}>My Rooms + + classNames( + 'w-[31%]', + selected + ? 'bg-cyan-500 text-white font-bold shadow hover:bg-white/[0.6] hover:text-black' + : 'hover:bg-cyan-500/[0.6] hover:text-white hover:font-bold' + )}>Create + + + +
- No Nearby Rooms -
- Create One? + {!nearbyArr && !loadingLoc && ( +
+ No Nearby Rooms +
+ Create One? +
+ )} + {loadingLoc &&
Loading...
} + {nearbyArrReady && nearbyArr}
- )} +
+
+ +
+
+ {!myRoomArr &&
No User Saved Rooms
} + {myRoomArr} +
+
+
+ + {!loadingLoc && } {loadingLoc &&
Loading...
} - {nearbyArrReady && nearbyArr} -
-
- )} - {tab == "rooms" && ( -
-
- {!myRoomArr &&
No User Saved Rooms
} - {myRoomArr} -
-
- )} - {tab == "create" && !loadingLoc && } - {tab == "create" && loadingLoc &&
Loading...
} + + +
); -- 2.52.0 From 6179f8d4c2ab203e528e707101a799b0a7c0bd73 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 3 Apr 2024 21:52:55 +0000 Subject: [PATCH 02/10] Initial --- frontend-next/src/app/app/page.js | 1 + frontend-next/src/app/login/page.js | 6 +-- frontend-next/src/app/page.js | 22 +++++----- frontend-next/src/app/register/page.js | 6 +-- frontend-next/src/components/app/datatypes.js | 41 +++++++++---------- frontend-next/src/components/app/header.js | 13 +++--- .../src/components/app/profile/ProfileRoom.js | 5 ++- 7 files changed, 47 insertions(+), 47 deletions(-) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index 75d60e3..c057526 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -5,6 +5,7 @@ import { auth, database } from "../../../firebase-config"; import { ref, onValue } from "firebase/database"; import { useAuthState } from "react-firebase-hooks/auth" import { useGeolocated } from "react-geolocated"; +import Link from "next/link" // Header Import import { Header } from "../../components/app/header"; diff --git a/frontend-next/src/app/login/page.js b/frontend-next/src/app/login/page.js index 29885e0..f6b287d 100644 --- a/frontend-next/src/app/login/page.js +++ b/frontend-next/src/app/login/page.js @@ -46,9 +46,9 @@ function Login() {
- + - + Chat with friends!

Login

@@ -109,7 +109,7 @@ function Login() { Log In
- Need an account? Sign Up + Need an account? Sign Up
diff --git a/frontend-next/src/app/page.js b/frontend-next/src/app/page.js index dee3a1c..91ac733 100644 --- a/frontend-next/src/app/page.js +++ b/frontend-next/src/app/page.js @@ -1,6 +1,6 @@ "use client"; import { useState, useEffect } from "react"; - +import Link from "next/link" import { auth, database } from "../../firebase-config"; import { ref, get } from "firebase/database"; import { onAuthStateChanged } from "firebase/auth"; @@ -53,24 +53,24 @@ function Home() {
{!isAuthenticated && ( )} {isAuthenticated && ( - - - + + + )} {!isLoadingLoc && roomCount == 1 && (
diff --git a/frontend-next/src/app/register/page.js b/frontend-next/src/app/register/page.js index 6aba36d..f3c64ee 100644 --- a/frontend-next/src/app/register/page.js +++ b/frontend-next/src/app/register/page.js @@ -61,9 +61,9 @@ function Register() {
- + - + Chat with friends!

Register

@@ -110,7 +110,7 @@ function Register() { Register
- Have an account? Log In + Have an account? Login
diff --git a/frontend-next/src/components/app/datatypes.js b/frontend-next/src/components/app/datatypes.js index ab5469d..a6b95e6 100644 --- a/frontend-next/src/components/app/datatypes.js +++ b/frontend-next/src/components/app/datatypes.js @@ -1,3 +1,5 @@ +import Link from "next/link" + // Colors for Messages const userColors = [ "#ff80ed", @@ -40,13 +42,11 @@ export function Chat({ chatObj }) {
- + {chatObj.user} - + : {chatObj.body}
@@ -73,13 +73,11 @@ export function SystemMessage({ chatObj }) {
- + {chatObj.user} - + {" "} has {chatObj.body} the room.
@@ -93,25 +91,24 @@ export function SystemMessage({ chatObj }) { // Member for Active/Room members in sidebar export function Member({ memberObj }) { return ( - +
{memberObj.username}
-
+ ); } // Chat Room Object for myRooms and Nearby in sidebar export function ChatRoomSidebar({ roomObj }) { return ( -
location.href = "/chat?room=" + roomObj.path + "/" + roomObj.name + "-" + roomObj.timestamp} - className="border-[black] border-1 shadow-lg p-2 m-2 rounded-lg cursor-pointer" - > -
-
{roomObj.name}
-
{roomObj.description}
-
+
+ +
+
{roomObj.name}
+
{roomObj.description}
+
+
); } diff --git a/frontend-next/src/components/app/header.js b/frontend-next/src/components/app/header.js index f6605f7..ea4e72b 100644 --- a/frontend-next/src/components/app/header.js +++ b/frontend-next/src/components/app/header.js @@ -2,6 +2,7 @@ import { auth, database } from "../../../firebase-config"; import { ref, set, remove } from "firebase/database"; import { signOut } from "firebase/auth"; import { Popover } from "@headlessui/react"; +import Link from "next/link" function logout() { @@ -83,9 +84,9 @@ export function Header({ return (
- + - +
{mainTab == "chat" && isMyRoom == false && ( @@ -137,19 +138,19 @@ export function Header({ diff --git a/frontend-next/src/components/app/profile/ProfileRoom.js b/frontend-next/src/components/app/profile/ProfileRoom.js index 80e6268..799c8cc 100644 --- a/frontend-next/src/components/app/profile/ProfileRoom.js +++ b/frontend-next/src/components/app/profile/ProfileRoom.js @@ -1,4 +1,5 @@ import { Geo } from "../map/geo"; +import Link from "next/link" import { dateOptions } from "../datatypes"; // Display of Rooms on user profile @@ -18,14 +19,14 @@ export function ProfileRoom({ room }) {
Created on {new Date(room.timestamp).toLocaleString(dateOptions)}
- Open Room - +
); -- 2.52.0 From 8bca33a039ef50086c098e9337dd82f027b4126e Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 3 Apr 2024 22:04:19 +0000 Subject: [PATCH 03/10] Good to Release --- frontend-next/src/app/login/page.js | 1 + frontend-next/src/app/register/page.js | 1 + frontend-next/src/app/user/[stub]/page.js | 4 ++-- frontend-next/src/components/app/datatypes.js | 6 +++--- frontend-next/src/components/app/header.js | 6 +++--- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/frontend-next/src/app/login/page.js b/frontend-next/src/app/login/page.js index f6b287d..0cb57ae 100644 --- a/frontend-next/src/app/login/page.js +++ b/frontend-next/src/app/login/page.js @@ -1,5 +1,6 @@ "use client"; import { useForm, Form } from "react-hook-form"; +import Link from "next/link" import { useRouter } from "next/navigation"; import "../globals.css"; diff --git a/frontend-next/src/app/register/page.js b/frontend-next/src/app/register/page.js index f3c64ee..f475d56 100644 --- a/frontend-next/src/app/register/page.js +++ b/frontend-next/src/app/register/page.js @@ -2,6 +2,7 @@ import { useRouter } from "next/navigation"; import { useForm, Form } from "react-hook-form"; import "../globals.css"; +import Link from "next/link" import { useState } from "react"; import { diff --git a/frontend-next/src/app/user/[stub]/page.js b/frontend-next/src/app/user/[stub]/page.js index 17bc135..8134315 100644 --- a/frontend-next/src/app/user/[stub]/page.js +++ b/frontend-next/src/app/user/[stub]/page.js @@ -120,12 +120,12 @@ function UserProfile({ params }) { }} className="w-[120px] p-2 cursor-pointer bg-cyan-500 text-white font-bold rounded-full text-center" > - Edit Profile{" "} + Edit Profile )} {!isOwner && ( - Add Friend{" "} + Add Friend )}
diff --git a/frontend-next/src/components/app/datatypes.js b/frontend-next/src/components/app/datatypes.js index a6b95e6..15f97f5 100644 --- a/frontend-next/src/components/app/datatypes.js +++ b/frontend-next/src/components/app/datatypes.js @@ -42,7 +42,7 @@ export function Chat({ chatObj }) {
- {chatObj.user} @@ -73,7 +73,7 @@ export function SystemMessage({ chatObj }) {
- {chatObj.user} @@ -103,7 +103,7 @@ export function Member({ memberObj }) { export function ChatRoomSidebar({ roomObj }) { return (
- +
{roomObj.name}
{roomObj.description}
diff --git a/frontend-next/src/components/app/header.js b/frontend-next/src/components/app/header.js index ea4e72b..01d58d5 100644 --- a/frontend-next/src/components/app/header.js +++ b/frontend-next/src/components/app/header.js @@ -27,7 +27,6 @@ function closeChatRoom(roomObj, user) { payload ); remove(ref(database, `/rooms/${path}/users/online/${user.uid}`)); - location.href = "/app"; } // Adds room to myRooms @@ -112,14 +111,15 @@ export function Header({ )} {mainTab == "chat" && ( - { closeChatRoom(chatRoomObj, user); }} + href="/app" className="p-2 cursor-pointer bg-cyan-500 text-white font-bold rounded-full mr-5 flex items-center" > Close Chat - + )} -- 2.52.0 From b7ec08f5efe8a090bfbd9d541cf86ccbbc30f0d1 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 3 Apr 2024 22:08:25 +0000 Subject: [PATCH 04/10] Final Touches --- frontend-next/.eslintrc.json | 2 +- frontend-next/src/app/app/page.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend-next/.eslintrc.json b/frontend-next/.eslintrc.json index 6b2f9c6..471d759 100644 --- a/frontend-next/.eslintrc.json +++ b/frontend-next/.eslintrc.json @@ -4,6 +4,6 @@ "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }], "jsx-a11y/alt-text": "off", "@next/next/no-img-element": "off", - "no-console": "on", + "no-console": 1 } } diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index c057526..75d60e3 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -5,7 +5,6 @@ import { auth, database } from "../../../firebase-config"; import { ref, onValue } from "firebase/database"; import { useAuthState } from "react-firebase-hooks/auth" import { useGeolocated } from "react-geolocated"; -import Link from "next/link" // Header Import import { Header } from "../../components/app/header"; -- 2.52.0 From d09a527c9d1961353a805b34a642c1362d37fa9e Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 3 Apr 2024 22:21:29 +0000 Subject: [PATCH 05/10] Change homepage coords to new Geolocated import --- frontend-next/src/app/page.js | 44 ++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/frontend-next/src/app/page.js b/frontend-next/src/app/page.js index 91ac733..ef500dd 100644 --- a/frontend-next/src/app/page.js +++ b/frontend-next/src/app/page.js @@ -3,6 +3,7 @@ import { useState, useEffect } from "react"; import Link from "next/link" import { auth, database } from "../../firebase-config"; import { ref, get } from "firebase/database"; +import { useGeolocated } from "react-geolocated"; import { onAuthStateChanged } from "firebase/auth"; function Home() { @@ -21,29 +22,34 @@ function Home() { }); }, []); + const { coords } = useGeolocated({ + positionOptions: { + enableHighAccuracy: false, + }, + userDecisionTimeout: 5000, + }); + useEffect(() => { - if ("geolocation" in navigator) { - // Retrieve latitude & longitude coordinates from `navigator.geolocation` Web API - navigator.geolocation.getCurrentPosition(({ coords }) => { - var path = - String(coords.latitude.toFixed(2)).replace(".", "") + - "/" + - String(coords.longitude.toFixed(2)).replace(".", ""); - get(ref(database, `/rooms/${path}`)).then((snapshot) => { - if (snapshot.exists()) { - var count = 0; - for (var room in snapshot.val()) { - count += 1; - } - setRoomCount(count); - } else { - setRoomCount(0); + if (coords) { + var path = + String(coords.latitude.toFixed(2)).replace(".", "") + + "/" + + String(coords.longitude.toFixed(2)).replace(".", ""); + get(ref(database, `/rooms/${path}`)).then((snapshot) => { + if (snapshot.exists()) { + var count = 0; + for (var room in snapshot.val()) { + count += 1; } - setLoadingLoc(false); - }); + setRoomCount(count); + } else { + setRoomCount(0); + } + setLoadingLoc(false); }); } - }); + }, [coords]) + return (
-- 2.52.0 From 323b7b555a69f1dbbc9855750408d9e166c5d0df Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 3 Apr 2024 23:25:47 +0000 Subject: [PATCH 06/10] Notification Functions Added --- frontend-next/package-lock.json | 766 +++++++++++++++++- frontend-next/package.json | 4 + frontend-next/src/app/app/page.js | 1 + frontend-next/src/components/app/header.js | 7 +- .../app/notifications/notifications.js | 99 +++ 5 files changed, 853 insertions(+), 24 deletions(-) diff --git a/frontend-next/package-lock.json b/frontend-next/package-lock.json index e31d9a5..acc54de 100644 --- a/frontend-next/package-lock.json +++ b/frontend-next/package-lock.json @@ -8,7 +8,11 @@ "name": "chatmaps", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.5", "@headlessui/react": "^1.7.18", + "@mui/icons-material": "^5.15.14", + "@mui/material": "^5.15.14", "firebase": "^10.6.0", "next": "^14.1.0", "pigeon-maps": "^0.21.3", @@ -48,11 +52,127 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dependencies": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "dependencies": { + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/runtime": { "version": "7.24.1", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -60,6 +180,152 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", + "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz", + "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.2", + "@emotion/serialize": "^1.1.4", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -601,6 +867,40 @@ "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.5.tgz", "integrity": "sha512-eSkJsnhBWv5kCTSU1tSUVl9mpFu+5NXXunZc83le8GMjMlsWwQArSc7cJJ4yl+aDFY0NGLi0AjZWMn1axOrkRg==" }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "node_modules/@grpc/grpc-js": { "version": "1.9.14", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.14.tgz", @@ -771,6 +1071,261 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.14.tgz", + "integrity": "sha512-on75VMd0XqZfaQW+9pGjSNiqW+ghc5E2ZSLRBXwcXl/C4YzjfyjrLPhrEpKnR9Uym9KXBvxrhoHfPcczYHweyA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.14.tgz", + "integrity": "sha512-vj/51k7MdFmt+XVw94sl30SCvGx6+wJLsNYjZRgxhS6y3UtnWnypMOsm3Kmg8TN+P0dqwsjy4/fX7B1HufJIhw==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.14.tgz", + "integrity": "sha512-kEbRw6fASdQ1SQ7LVdWR5OlWV3y7Y54ZxkLzd6LV5tmz+NpO3MJKZXSfgR0LHMP7meKsPiMm4AuzV0pXDpk/BQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/core-downloads-tracker": "^5.15.14", + "@mui/system": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/private-theming": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.14.tgz", + "integrity": "sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.14", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", + "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.14.tgz", + "integrity": "sha512-auXLXzUaCSSOLqJXmsAaq7P96VPRXg2Rrz6OHNV7lr+kB8lobUF+/N84Vd9C4G/wvCXYPs5TYuuGBRhcGbiBGg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.14", + "@mui/styled-engine": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", + "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.14.tgz", + "integrity": "sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/@next/env": { "version": "14.1.4", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.4.tgz", @@ -965,6 +1520,15 @@ "node": ">=14" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -1072,6 +1636,33 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + }, + "node_modules/@types/react": { + "version": "18.2.74", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.74.tgz", + "integrity": "sha512-9AEqNZZyBx8OdZpxzQlaFEVCSFUM2YXJH46yPOiOpm078k6ZLOCcuAzGum/zK8YBwY+dbahVNbHrbgrAwIRlqw==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", @@ -1548,6 +2139,20 @@ "dequal": "^2.0.3" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1654,7 +2259,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -1791,6 +2395,14 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1822,6 +2434,34 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1848,6 +2488,11 @@ "node": ">=4" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -2007,6 +2652,15 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2038,6 +2692,14 @@ "node": ">=10.13.0" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.23.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", @@ -2208,7 +2870,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -2718,6 +3379,11 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2849,7 +3515,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3141,7 +3806,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -3149,6 +3813,14 @@ "node": ">= 0.4" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", @@ -3172,7 +3844,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3239,6 +3910,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", @@ -3310,7 +3986,6 @@ "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, "dependencies": { "hasown": "^2.0.0" }, @@ -3664,6 +4339,11 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3755,8 +4435,7 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/locate-path": { "version": "6.0.0", @@ -3992,7 +4671,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4178,7 +4856,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -4186,6 +4863,23 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4216,8 +4910,7 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { "version": "1.10.1", @@ -4248,7 +4941,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -4467,7 +5159,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -4592,8 +5283,22 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } }, "node_modules/read-cache": { "version": "1.0.0", @@ -4640,8 +5345,7 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", @@ -4673,7 +5377,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -4690,7 +5393,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -4959,6 +5661,14 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -5182,6 +5892,11 @@ } } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -5220,7 +5935,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -5301,6 +6015,14 @@ "node": ">=0.8" } }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/frontend-next/package.json b/frontend-next/package.json index f7091b2..03da846 100644 --- a/frontend-next/package.json +++ b/frontend-next/package.json @@ -9,7 +9,11 @@ "lint": "next lint" }, "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.5", "@headlessui/react": "^1.7.18", + "@mui/icons-material": "^5.15.14", + "@mui/material": "^5.15.14", "firebase": "^10.6.0", "next": "^14.1.0", "pigeon-maps": "^0.21.3", diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index f63fcfc..4a0b2e1 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -6,6 +6,7 @@ import { ref, onValue } from "firebase/database"; import { useAuthState } from "react-firebase-hooks/auth" import { useGeolocated } from "react-geolocated"; + // Header Import import { Header } from "../../components/app/header"; diff --git a/frontend-next/src/components/app/header.js b/frontend-next/src/components/app/header.js index 01d58d5..1fb986d 100644 --- a/frontend-next/src/components/app/header.js +++ b/frontend-next/src/components/app/header.js @@ -4,6 +4,7 @@ import { signOut } from "firebase/auth"; import { Popover } from "@headlessui/react"; import Link from "next/link" +import { NotificationPanel } from "./notifications/notifications"; function logout() { signOut(auth); @@ -122,6 +123,10 @@ export function Header({ )} + {/* Notifications Panel */} + + + {/*"Profile Dropdown TODO: MOVE TO PROFILE IMPORT - req user, take logout function with"*/}
@@ -152,8 +157,6 @@ export function Header({ Sign Out
- -
diff --git a/frontend-next/src/components/app/notifications/notifications.js b/frontend-next/src/components/app/notifications/notifications.js index e69de29..01ebe34 100644 --- a/frontend-next/src/components/app/notifications/notifications.js +++ b/frontend-next/src/components/app/notifications/notifications.js @@ -0,0 +1,99 @@ +import { Popover } from "@headlessui/react"; +import Link from "next/link" +import NotificationsIcon from '@mui/icons-material/Notifications'; +import NotificationsPausedIcon from '@mui/icons-material/NotificationsPaused'; +import CloseIcon from '@mui/icons-material/Close'; + +import { database } from "../../../../firebase-config"; +import { ref, set, remove } from "firebase/database"; + +/** + * Notification Object + * @constructor + * @param {user.notification} data - Notification data + * @returns {Notification} - Notification Component + */ +function Notification({data}) { + return ( +
+
+
{removeNotification(data.id)}}>
+
+
+ {data.title}
+ {data.byline}
+
+
+ ) +} + +/** + * Removes Notification + * @param {String} ruser - Receiving user UID (User Whose Notifications are being removed) + * @param {String} dataID - Notification ID + * @returns {void} + */ +function removeNotification(ruser, dataID) { + remove(ref(database, `/user/${ruser}/notifications/${dataID}`)) +} + +/** +* Creates New Notification +* @param {String} title - Title of the notification +* @param {String} byline - Byline of the notification +* @param {String} action - Action to perform (friend request [fr], more to come) +* @param {String} suser - Sending user UID +* @param {String} ruser - Receiving user UID +* @returns {void} +*/ + +function createNotification(title, byline, action, suser, ruser) { + var timestamp = new Date().getTime(); + var payload = { + title: title, + byline: byline, + action: action, + suser: suser, + ruser: ruser + }; + set(ref(database, `/user/${ruser}/notifications/${timestamp}-${suser}`), payload); +} + +/** + * Notification Panel + * @constructor + * @param {user} user - User object (from Firebase) + * @returns {NotificationPanel} - Notification Panel Component + */ +export function NotificationPanel({user}) { + var notificationsMap = [] + if (user.notification) { + for (var notificationPackage in user.notification) { + notificationsMap.push() + } + var isNotifications = true + } else { + var isNotifications = false + } + + return ( + + +
+ +
+
+ + +
+ {isNotifications && notificationsMap} + {!isNotifications && +
+ All caught up! +
+ } +
+
+
+ ) +} \ No newline at end of file -- 2.52.0 From 9feead28cd72583f18a1f338fd11a27a707852c6 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 3 Apr 2024 23:27:30 +0000 Subject: [PATCH 07/10] Slight Change --- frontend-next/src/components/app/notifications/notifications.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend-next/src/components/app/notifications/notifications.js b/frontend-next/src/components/app/notifications/notifications.js index 01ebe34..77bd66d 100644 --- a/frontend-next/src/components/app/notifications/notifications.js +++ b/frontend-next/src/components/app/notifications/notifications.js @@ -1,5 +1,4 @@ import { Popover } from "@headlessui/react"; -import Link from "next/link" import NotificationsIcon from '@mui/icons-material/Notifications'; import NotificationsPausedIcon from '@mui/icons-material/NotificationsPaused'; import CloseIcon from '@mui/icons-material/Close'; @@ -46,7 +45,6 @@ function removeNotification(ruser, dataID) { * @param {String} ruser - Receiving user UID * @returns {void} */ - function createNotification(title, byline, action, suser, ruser) { var timestamp = new Date().getTime(); var payload = { -- 2.52.0 From 7bf163d77c7170159c82bbe94e58ba1d8b4e95ca Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 3 Apr 2024 23:36:11 +0000 Subject: [PATCH 08/10] Move Profile Panel to Profile Component Directory --- frontend-next/src/components/app/header.js | 44 ++---------------- .../components/app/profile/ProfilePanel.js | 46 +++++++++++++++++++ 2 files changed, 50 insertions(+), 40 deletions(-) create mode 100644 frontend-next/src/components/app/profile/ProfilePanel.js diff --git a/frontend-next/src/components/app/header.js b/frontend-next/src/components/app/header.js index 1fb986d..8a71e2a 100644 --- a/frontend-next/src/components/app/header.js +++ b/frontend-next/src/components/app/header.js @@ -1,14 +1,9 @@ -import { auth, database } from "../../../firebase-config"; +import { database } from "../../../firebase-config"; import { ref, set, remove } from "firebase/database"; -import { signOut } from "firebase/auth"; -import { Popover } from "@headlessui/react"; import Link from "next/link" import { NotificationPanel } from "./notifications/notifications"; - -function logout() { - signOut(auth); -} +import { ProfilePanel } from "./profile/ProfilePanel" // Closes chat room function closeChatRoom(roomObj, user) { @@ -126,39 +121,8 @@ export function Header({ {/* Notifications Panel */} - {/*"Profile Dropdown TODO: MOVE TO PROFILE IMPORT - req user, take logout function with"*/} - - -
-
{user.firstName}
-
- -
-
-
- - -
- - View Profile - - - Sign Out - -
-
-
+ {/*Profile Dropdown */} +
); diff --git a/frontend-next/src/components/app/profile/ProfilePanel.js b/frontend-next/src/components/app/profile/ProfilePanel.js new file mode 100644 index 0000000..b9ee881 --- /dev/null +++ b/frontend-next/src/components/app/profile/ProfilePanel.js @@ -0,0 +1,46 @@ +import { Popover } from "@headlessui/react"; +import { auth } from "../../../../firebase-config"; +import { signOut } from "firebase/auth"; +import Link from "next/link" + + +function logout() { + signOut(auth); +} + +export function ProfilePanel({user}) { + return ( + + +
+
{user.firstName}
+
+ +
+
+
+ + +
+ + View Profile + + + Sign Out + +
+
+
+ ) +} \ No newline at end of file -- 2.52.0 From 5dd891c5b254e4e5f36782baf171284d2b8e5071 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Thu, 4 Apr 2024 01:39:08 +0000 Subject: [PATCH 09/10] JS Docs for all Files --- frontend-next/src/app/app/page.js | 49 ++++++++++--------- frontend-next/src/app/chat/page.js | 37 +++++++------- frontend-next/src/app/login/page.js | 29 ++++++----- frontend-next/src/app/onboarding/page.js | 12 +++++ frontend-next/src/app/page.js | 12 +++-- frontend-next/src/app/register/page.js | 30 ++++++++---- frontend-next/src/app/user/[stub]/page.js | 14 +++--- frontend-next/src/components/app/datatypes.js | 43 ++++++++++------ frontend-next/src/components/app/header.js | 43 +++++++++++----- frontend-next/src/components/app/map/geo.js | 12 +++-- .../app/notifications/notifications.js | 8 ++- frontend-next/src/components/app/page/chat.js | 22 +++++++-- frontend-next/src/components/app/page/home.js | 18 +++++-- .../src/components/app/profile/Interest.js | 7 ++- .../src/components/app/profile/ProfileEdit.js | 24 ++++++--- .../components/app/profile/ProfilePanel.js | 15 +++++- .../src/components/app/profile/ProfileRoom.js | 9 +++- .../src/components/app/sidebar/chat.js | 11 +++-- .../src/components/app/sidebar/home.js | 40 +++++++++++---- 19 files changed, 297 insertions(+), 138 deletions(-) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index 4a0b2e1..b8a6c96 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -1,29 +1,31 @@ "use client"; // System Imports import { useState, useEffect } from "react"; + +// Dependencies +import { useGeolocated } from "react-geolocated"; + +// Firebase Imports import { auth, database } from "../../../firebase-config"; import { ref, onValue } from "firebase/database"; import { useAuthState } from "react-firebase-hooks/auth" -import { useGeolocated } from "react-geolocated"; - -// Header Import +// Component Imports import { Header } from "../../components/app/header"; +import { HomePage } from "../../components/app/page/home"; +import { Sidebar } from "../../components/app/sidebar/home"; -// Main Tab Imports -import { MainTabHome } from "../../components/app/page/home"; - -// Sidebar Imports -import { Home_Sidebar } from "../../components/app/sidebar/home"; - -// Contains most everything for the app homepage +/** +* Contains most everything for the app homepage +* @returns {Object} Home Page +*/ function Home() { - // It's time to document and change these awful variable names // State variables for app page - const [user, setUser] = useState(null); + const [user, setUser] = useState(null); // user data const [loadingLoc, setLoadingLoc] = useState(true); // location variable loading, true = loading, false = finished loading - const [authUser, loading] = useAuthState(auth) + const [authUser] = useAuthState(auth) // auth user object (used to obtain other user object) + // Authentication Verification / Redirection if Profile Data not Filled out useEffect(() => { if (authUser) { onValue(ref(database, `users/${authUser.uid}`), (userData) => { @@ -37,14 +39,15 @@ function Home() { } }, [authUser]) - const { coords } = - useGeolocated({ - positionOptions: { - enableHighAccuracy: false, - }, - userDecisionTimeout: 5000, - }); + // Gets current location + const { coords } = useGeolocated({ + positionOptions: { + enableHighAccuracy: false, + }, + userDecisionTimeout: 5000, + }); + // If theres a location, go ahead and show location based stuff useEffect(() => { if (coords) { setLoadingLoc(false); @@ -65,15 +68,15 @@ function Home() { {/* Main Page Section */}
{!loadingLoc && ( - + )} {loadingLoc && ( - + )}
{/* Sidebar (Right Side of Page) */} - { if (authUser) { onValue(ref(database, `users/${authUser.uid}`), (userData) => { @@ -36,7 +37,7 @@ function Home() { } }, [authUser]) - + // Users URL params to load proper chatroom, then logs the user into that room useEffect(() => { if (user) { const searchParams = new URLSearchParams(document.location.search); @@ -82,11 +83,11 @@ function Home() { /> {/* Main Page Section */}
- +
{/* Sidebar (Right Side of Page) */} -
@@ -95,4 +96,4 @@ function Home() { ); } -export default Home; \ No newline at end of file +export default Chat; \ No newline at end of file diff --git a/frontend-next/src/app/login/page.js b/frontend-next/src/app/login/page.js index 0cb57ae..567afac 100644 --- a/frontend-next/src/app/login/page.js +++ b/frontend-next/src/app/login/page.js @@ -1,28 +1,27 @@ "use client"; +// System Imports +import "../globals.css"; import { useForm, Form } from "react-hook-form"; import Link from "next/link" import { useRouter } from "next/navigation"; -import "../globals.css"; -// Firebase imports +// Firebase Imports import { auth } from "../../../firebase-config"; -import { - setPersistence, - signInWithEmailAndPassword, - indexedDBLocalPersistence, -} from "firebase/auth"; +import {setPersistence,signInWithEmailAndPassword,indexedDBLocalPersistence } from "firebase/auth"; +/** + * Login Page + * @returns {Object} Login Page +*/ function Login() { var router = useRouter(); - //var { register, handleSubmit } = useForm(); - var { - register, - control, - setError, - handleSubmit, - formState: { errors, isSubmitting, isSubmitted }, - } = useForm(); + var {register,control,setError,handleSubmit,formState: { errors, isSubmitting, isSubmitted },} = useForm(); + /** + * Logs into Firebase authentication + * @param {JSON} data - User Login Data (data.email, data.password) + * @returns {void} + */ function authenticate(data) { setPersistence(auth, indexedDBLocalPersistence).then(() => { signInWithEmailAndPassword(auth, data.email, data.password).then( diff --git a/frontend-next/src/app/onboarding/page.js b/frontend-next/src/app/onboarding/page.js index 0d994cc..9ab96fa 100644 --- a/frontend-next/src/app/onboarding/page.js +++ b/frontend-next/src/app/onboarding/page.js @@ -1,11 +1,19 @@ "use client"; +// System Imports import "../globals.css"; import { useForm } from "react-hook-form"; import { useRouter } from "next/navigation"; + +// Firebase Imports import { ref, set } from "firebase/database"; import { auth, database } from "../../../firebase-config"; import { onAuthStateChanged } from "firebase/auth"; +/** + * Creates user data in Firebase DB + * @param {JSON} data - User data to be stored in Firebase DB ( from form ) + * @return {Boolean} - True if user data is stored, False if user data is not stored + */ function createUser(data) { onAuthStateChanged(auth, (user) => { if (user.uid) { @@ -20,6 +28,10 @@ function createUser(data) { }); } +/** + * Onboarding Page + * @returns {Object} - Onboarding Page + */ function Onboarding() { var router = useRouter(); var { register, handleSubmit } = useForm(); diff --git a/frontend-next/src/app/page.js b/frontend-next/src/app/page.js index ef500dd..cf91df4 100644 --- a/frontend-next/src/app/page.js +++ b/frontend-next/src/app/page.js @@ -6,10 +6,14 @@ import { ref, get } from "firebase/database"; import { useGeolocated } from "react-geolocated"; import { onAuthStateChanged } from "firebase/auth"; +/** + * Home Page + * @returns {Object} - Home Page + */ function Home() { - const [isLoadingLoc, setLoadingLoc] = useState(true); - const [roomCount, setRoomCount] = useState(null); - const [isAuthenticated, setAuth] = useState(false); + const [isLoadingLoc, setLoadingLoc] = useState(true); // is location loading? + const [roomCount, setRoomCount] = useState(null); // local room count + const [isAuthenticated, setAuth] = useState(false); // is user authenticated? // Authentication useEffect(() => { @@ -22,6 +26,7 @@ function Home() { }); }, []); + // Grab Location const { coords } = useGeolocated({ positionOptions: { enableHighAccuracy: false, @@ -29,6 +34,7 @@ function Home() { userDecisionTimeout: 5000, }); + // Update room count on location fix useEffect(() => { if (coords) { var path = diff --git a/frontend-next/src/app/register/page.js b/frontend-next/src/app/register/page.js index f475d56..aa8ec4e 100644 --- a/frontend-next/src/app/register/page.js +++ b/frontend-next/src/app/register/page.js @@ -1,18 +1,21 @@ "use client"; +// System Imports +import "../globals.css"; +import { useState } from "react"; import { useRouter } from "next/navigation"; import { useForm, Form } from "react-hook-form"; -import "../globals.css"; import Link from "next/link" -import { useState } from "react"; -import { - createUserWithEmailAndPassword, - signInWithEmailAndPassword, - setPersistence, - indexedDBLocalPersistence, -} from "firebase/auth"; +// Firebase Imports +import {createUserWithEmailAndPassword,signInWithEmailAndPassword,setPersistence,indexedDBLocalPersistence,} from "firebase/auth"; import { auth } from "../../../firebase-config"; +/** + * Signs up user in Firebase Authentication + * @param {JSON} data - User signup data (data.email, data.password) + * @returns {Boolean} - True if user is signed up, False if user is not signed up + * @async + */ async function Signup(data) { var userCredential = await createUserWithEmailAndPassword( auth, @@ -22,7 +25,7 @@ async function Signup(data) { if (userCredential.user) { setPersistence(auth, indexedDBLocalPersistence).then(() => { signInWithEmailAndPassword(auth, data.email, data.password).then( - (res) => { + () => { return true; } ); @@ -31,7 +34,10 @@ async function Signup(data) { return false; } } - +/** + * Register Page + * @returns {Object} - Registration Page + */ function Register() { var router = useRouter(); var { @@ -46,6 +52,10 @@ function Register() { return data.password === data.passwordCheck; }; + /** + * Form onSubmit Handler + * @params {JSON} data - Form data + */ function onSubmit({ data }) { if (passwordMatch(data)) { setPasswordMismatch(false); diff --git a/frontend-next/src/app/user/[stub]/page.js b/frontend-next/src/app/user/[stub]/page.js index 8134315..b7f0d46 100644 --- a/frontend-next/src/app/user/[stub]/page.js +++ b/frontend-next/src/app/user/[stub]/page.js @@ -15,13 +15,15 @@ import { Interest } from "../../../components/app/profile/Interest"; // Header Import import { Header } from "../../../components/app/header"; -// User Profile Page +/** + * User Profile Page + * @param {URLSearchParams} params - URL Parameters + * @returns {Object} - User Profile Page + */ function UserProfile({ params }) { - // It's time to document and change these awful variable names - // State variables for app page - const [profileData, setProfileData] = useState(null); - const [isAuthenticated, setIsAuthenticated] = useState(false); - const [user, setUser] = useState(null); + const [profileData, setProfileData] = useState(null); // Profile Data + const [isAuthenticated, setIsAuthenticated] = useState(false); // Determines if user is authenticated + const [user, setUser] = useState(null); // User Data const [userInterestArray, setUserInterestArray] = useState(null); // Array of user's interests const [userRoomsArray, setUserRoomsArray] = useState(null); // Array of user's rooms const [isOwner, setIsOwner] = useState(false); // Determines if user is owner of profile diff --git a/frontend-next/src/components/app/datatypes.js b/frontend-next/src/components/app/datatypes.js index 15f97f5..93f2afe 100644 --- a/frontend-next/src/components/app/datatypes.js +++ b/frontend-next/src/components/app/datatypes.js @@ -26,6 +26,11 @@ let dateOptions = { minute: "2-digit", }; +/** + * Generates Color based on string hash + * @param {String} user_str - Username / String for hashing + * @returns {String} - Color Hex Code Index in userColors + */ const generateColor = (user_str) => { // hashes username for consistent colors, maybe all functionality to pick color later let hash = 0; @@ -36,7 +41,12 @@ const generateColor = (user_str) => { return index; }; -// Chat Message + +/** + * Chat Message Object + * @props {JSON} chatObj - Chat Object + * @returns {Object} - Chat Message Component + */ export function Chat({ chatObj }) { return (
@@ -57,18 +67,13 @@ export function Chat({ chatObj }) { ); } -// System Chat Message -export function SystemMessage({ chatObj }) { - const generateColor = (user_str) => { - // hashes username for consistent colors, maybe all functionality to pick color later - let hash = 0; - for (let i = 0; i < user_str.length; i++) { - hash = user_str.charCodeAt(i) + (hash * 32 - hash); - } - const index = Math.abs(hash) % userColors.length; - return index; - }; +/** + * System Chat Message Object + * @prop {JSON} chatObj - Chat Object + * @returns {Object} - System Chat Message Component + */ +export function SystemMessage({ chatObj }) { return (
@@ -88,7 +93,11 @@ export function SystemMessage({ chatObj }) { ); } -// Member for Active/Room members in sidebar +/** + * Member Object for Sidebar + * @prop {JSON} memberObj - Member Object + * @returns {Object} - Member Component + */ export function Member({ memberObj }) { return ( @@ -99,7 +108,11 @@ export function Member({ memberObj }) { ); } -// Chat Room Object for myRooms and Nearby in sidebar +/** + * Chat Room Object for Sidebar + * @prop {JSON} roomObj - Room Object + * @returns {Object} - Chat Room Component + */ export function ChatRoomSidebar({ roomObj }) { return (
@@ -114,4 +127,4 @@ export function ChatRoomSidebar({ roomObj }) { } // This will be removed once dateOptions is no longer used in this file -export { dateOptions }; +export { dateOptions }; \ No newline at end of file diff --git a/frontend-next/src/components/app/header.js b/frontend-next/src/components/app/header.js index 8a71e2a..29dc01b 100644 --- a/frontend-next/src/components/app/header.js +++ b/frontend-next/src/components/app/header.js @@ -1,11 +1,20 @@ -import { database } from "../../../firebase-config"; -import { ref, set, remove } from "firebase/database"; +// System Imports import Link from "next/link" +// Firebase Imports +import { database } from "../../../firebase-config"; +import { ref, set, remove } from "firebase/database"; + +// Component Imports import { NotificationPanel } from "./notifications/notifications"; import { ProfilePanel } from "./profile/ProfilePanel" -// Closes chat room +/** + * Closes Open Chat Room + * @param {JSON} roomObj - Room Object + * @param {JSON} user - User Object + * @returns {void} + */ function closeChatRoom(roomObj, user) { var path = roomObj.path + "/" + roomObj.name + "-" + roomObj.timestamp; var payload = { @@ -25,7 +34,12 @@ function closeChatRoom(roomObj, user) { remove(ref(database, `/rooms/${path}/users/online/${user.uid}`)); } -// Adds room to myRooms +/** + * Adds Chat Room to My Rooms + * @param {JSON} chatRoomObj - Chat Room Object + * @param {JSON} user - User Object + * @returns {void} + */ function addToMyRooms(chatRoomObj, user) { set( ref( @@ -46,7 +60,12 @@ function addToMyRooms(chatRoomObj, user) { set(ref(database, `/rooms/${path}/users/all/${user.uid}`), user); } -// Deletes saved room from myRooms +/** + * Removes Chat Room from My Rooms + * @param {JSON} chatRoomObj - Chat Room Object + * @param {JSON} user - User Object + * @returns {void} + */ function removeFromMyRooms(chatRoomObj, user) { var path = chatRoomObj.path + "/" + chatRoomObj.name + "-" + chatRoomObj.timestamp; @@ -59,12 +78,14 @@ function removeFromMyRooms(chatRoomObj, user) { remove(ref(database, `/rooms/${path}/users/all/${user.uid}`)); } -export function Header({ - mainTab, - chatRoomObj, - user, -}) { - +/** + * Header Component + * @prop {String} mainTab - Main Tab + * @prop {JSON} chatRoomObj - Chat Room Object + * @prop {JSON} user - User Object + */ +export function Header({mainTab,chatRoomObj,user,}) { + if (mainTab == "chat") { var roomName = chatRoomObj.name + "-" + chatRoomObj.timestamp; if (user.rooms != null && roomName in user.rooms) { diff --git a/frontend-next/src/components/app/map/geo.js b/frontend-next/src/components/app/map/geo.js index 5e621ee..f5e3182 100644 --- a/frontend-next/src/components/app/map/geo.js +++ b/frontend-next/src/components/app/map/geo.js @@ -1,8 +1,14 @@ import { Map, Marker, ZoomControl } from "pigeon-maps"; -// Map module for main page and chat room sidebar (and eventually user profile) -// Constructs Map and Markers -// TODO: Need to get rest of marker handling here or in marker file. +/** + * Geo Component for Wrapping Map + * @constructor + * @prop {JSON} loc - Location Object {latitude, longitude} + * @prop {Number} zoom - Zoom Level + * @prop {Boolean} locMarker - Show Location Marker + * @prop {Markers[]} markers - Array of Markers + * @returns {Map} - Geo Component (As Map) + */ export function Geo({ loc, zoom, locMarker, markers }) { if (loc) { return ( diff --git a/frontend-next/src/components/app/notifications/notifications.js b/frontend-next/src/components/app/notifications/notifications.js index 77bd66d..08bfcaf 100644 --- a/frontend-next/src/components/app/notifications/notifications.js +++ b/frontend-next/src/components/app/notifications/notifications.js @@ -1,15 +1,19 @@ +// System Imports import { Popover } from "@headlessui/react"; + +// Icon Imports import NotificationsIcon from '@mui/icons-material/Notifications'; import NotificationsPausedIcon from '@mui/icons-material/NotificationsPaused'; import CloseIcon from '@mui/icons-material/Close'; +// Firebase Imports import { database } from "../../../../firebase-config"; import { ref, set, remove } from "firebase/database"; /** * Notification Object * @constructor - * @param {user.notification} data - Notification data + * @prop {user.notification} data - Notification data * @returns {Notification} - Notification Component */ function Notification({data}) { @@ -60,7 +64,7 @@ function createNotification(title, byline, action, suser, ruser) { /** * Notification Panel * @constructor - * @param {user} user - User object (from Firebase) + * @prop {user} user - User object (from Firebase) * @returns {NotificationPanel} - Notification Panel Component */ export function NotificationPanel({user}) { diff --git a/frontend-next/src/components/app/page/chat.js b/frontend-next/src/components/app/page/chat.js index 28d6cae..63b8442 100644 --- a/frontend-next/src/components/app/page/chat.js +++ b/frontend-next/src/components/app/page/chat.js @@ -1,11 +1,20 @@ -import { Chat, SystemMessage } from "../datatypes"; -import { useState } from "react"; +// Dependency Imports import { Form, useForm } from "react-hook-form"; + +// Firebase Imports import { ref, set } from "firebase/database"; import { database } from "../../../../firebase-config"; -// Chatroom Module for Primary Tab -export function MainTabChatRoom({ roomObj, user }) { +// Component Imports +import { Chat, SystemMessage } from "../datatypes"; + +/** + * Chat Room Component + * @prop {JSON} roomObj - Room Object + * @prop {JSON} user - User Object + * @returns {Object} - Chat Room Component + */ +export function ChatRoom({ roomObj, user }) { var { register, control, reset, handleSubmit } = useForm(); // Message updater @@ -30,6 +39,11 @@ export function MainTabChatRoom({ roomObj, user }) { } var chats = chatsArr.reverse(); + /** + * Send Message in Chatroom + * @param {JSON} data - Message data to send (from form) + * @returns {void} + */ function sendMessage(data) { reset(); var payload = { diff --git a/frontend-next/src/components/app/page/home.js b/frontend-next/src/components/app/page/home.js index ce93d35..1fbf3fa 100644 --- a/frontend-next/src/components/app/page/home.js +++ b/frontend-next/src/components/app/page/home.js @@ -1,7 +1,11 @@ import { Geo } from "../map/geo"; -// Module for Welcome Message on main tab landing page -function WelcomeMessage({ user }) { +/** + * Module for Welcome Message on main tab landing page + * @prop {JSON} user - User Object + * @returns {Object} - Welcome Message Component + */ + function WelcomeMessage({ user }) { return (
@@ -12,8 +16,14 @@ function WelcomeMessage({ user }) { ); } -// Primary App Landing Page -export function MainTabHome({ loc, markers, user }) { +/** + * Primary App Landing Page + * @prop {JSON} loc - Location Object {latitude, longitude} + * @prop {Markers[]} markers - Array of Markers + * @prop {JSON} user - User Object + * @returns {Object} - Home Page Component + */ +export function HomePage({ loc, markers, user }) { return ( <> diff --git a/frontend-next/src/components/app/profile/Interest.js b/frontend-next/src/components/app/profile/Interest.js index ef5c28d..f2c9cb3 100644 --- a/frontend-next/src/components/app/profile/Interest.js +++ b/frontend-next/src/components/app/profile/Interest.js @@ -1,5 +1,8 @@ -// Interests for Profile -// Making this its own file since we could do a bit more with this in the future +/** + * Interest for Profile + * @prop {String} interest - Interest item + * @returns {Object} - Interest Component + */ export function Interest({ interest }) { return (
diff --git a/frontend-next/src/components/app/profile/ProfileEdit.js b/frontend-next/src/components/app/profile/ProfileEdit.js index 5efe0bd..5845302 100644 --- a/frontend-next/src/components/app/profile/ProfileEdit.js +++ b/frontend-next/src/components/app/profile/ProfileEdit.js @@ -1,9 +1,19 @@ +// System Imports import { useForm, Form } from "react-hook-form"; -import { database, storage } from "../../../../firebase-config"; -import { ref as sRef, getDownloadURL } from "firebase/storage"; -import { ref, update } from "firebase/database"; -import { uploadBytes } from "firebase/storage"; +// Firebase Imports +import { database, storage } from "../../../../firebase-config"; +import { ref as sRef, getDownloadURL,uploadBytes } from "firebase/storage"; +import { ref, update } from "firebase/database"; + + +/** + * Profile Edit Component + * @prop {JSON} profileData - Profile Data + * @prop {JSON} user - User Object + * @prop {Function} onSave - Save Function + * @returns {Object} - Profile Edit Component + */ export function ProfileEdit({ profileData, user, onSave }) { var { register, control } = useForm(); @@ -11,9 +21,11 @@ export function ProfileEdit({ profileData, user, onSave }) { onSave(false); }; - // Handles clicking save button + /** + * Handles clicking save button + * @prop {JSON} data - Data to save + */ function save({ data }) { - // Profile pic handling if (data.pfp[0]) { // image stuff diff --git a/frontend-next/src/components/app/profile/ProfilePanel.js b/frontend-next/src/components/app/profile/ProfilePanel.js index b9ee881..4df9d11 100644 --- a/frontend-next/src/components/app/profile/ProfilePanel.js +++ b/frontend-next/src/components/app/profile/ProfilePanel.js @@ -1,13 +1,24 @@ +// System Imports import { Popover } from "@headlessui/react"; -import { auth } from "../../../../firebase-config"; -import { signOut } from "firebase/auth"; import Link from "next/link" +// Firebase Imports +import { auth } from "../../../../firebase-config"; +import { signOut } from "firebase/auth"; +/** + * Logs out from Firebase Authentication + * @returns {void} + */ function logout() { signOut(auth); } +/** + * Profile Panel Component + * @prop {JSON} user - User Object + * @returns {Object} - Profile Panel Component + */ export function ProfilePanel({user}) { return ( diff --git a/frontend-next/src/components/app/profile/ProfileRoom.js b/frontend-next/src/components/app/profile/ProfileRoom.js index 799c8cc..796978f 100644 --- a/frontend-next/src/components/app/profile/ProfileRoom.js +++ b/frontend-next/src/components/app/profile/ProfileRoom.js @@ -1,8 +1,15 @@ +// System Imports import { Geo } from "../map/geo"; import Link from "next/link" + +// Component Imports import { dateOptions } from "../datatypes"; -// Display of Rooms on user profile +/** + * Profile Room Component + * @prop {JSON} room - Room Object + * @returns {Object} - Profile Room Component + */ export function ProfileRoom({ room }) { return (
diff --git a/frontend-next/src/components/app/sidebar/chat.js b/frontend-next/src/components/app/sidebar/chat.js index bb3f25d..a32d24a 100644 --- a/frontend-next/src/components/app/sidebar/chat.js +++ b/frontend-next/src/components/app/sidebar/chat.js @@ -1,11 +1,14 @@ +// Component Imports import { Geo } from "../map/geo"; - import { Member } from "../datatypes" // Sidebar when in a Chatrooms -export function Chat_Sidebar({ - chatRoomObj, -}) { +/** + * Sidebar while in Chatroom + * @prop {JSON} chatRoomObj - Chatroom Object + * @returns {Object} - Sidebar Component + */ +export function Sidebar({chatRoomObj}) { // Active users list if ( chatRoomObj.hasOwnProperty("users") && diff --git a/frontend-next/src/components/app/sidebar/home.js b/frontend-next/src/components/app/sidebar/home.js index 5bf9eed..2bd9180 100644 --- a/frontend-next/src/components/app/sidebar/home.js +++ b/frontend-next/src/components/app/sidebar/home.js @@ -1,17 +1,31 @@ +// System Imports import { Form, useForm } from "react-hook-form"; -import { database } from "../../../../firebase-config"; -import { ref, set, get } from "firebase/database"; import { useEffect, useState } from "react"; + +// Dependency Imports import { Tab } from '@headlessui/react' +// Firebase Imports +import { database } from "../../../../firebase-config"; +import { ref, set, get } from "firebase/database"; +// Component Imports import { ChatRoomSidebar } from "../datatypes"; -// Sidebar on Home Page, with various functionality (create, nearby, my rooms) -// CreateRoom Module for Sidebar Create Tab + +/** + * Create Room Component for /app Sidebar + * @prop {JSON} loc - Location Object (latitude, longitude) + * @returns {Object} - Create Room Component + */ function CreateRoom({ loc }) { var { register, control, reset, handleSubmit } = useForm(); + /** + * Creates Room in Firebase DB + * @prop {JSON} data - Room Data + * @returns {void} + */ function createRoom(data) { reset(); var path = @@ -52,15 +66,23 @@ function CreateRoom({ loc }) { ); } +/** + * Joins class names together for Tailwind CSS + * @param {...String} classes - Class names + * @returns {String} - Class names (joined) + */ function classNames(...classes) { return classes.filter(Boolean).join(' ') } -export function Home_Sidebar({ - user, - location, - loadingLoc -}) { +/** + * App Page Sidebar Component + * @prop {JSON} user - User Object + * @prop {JSON} location - Location Object (latitude, longitude) + * @prop {Boolean} loadingLoc - Loading Location State + * @returns {Object} - App Page Sidebar Component + */ +export function Sidebar({user,location,loadingLoc}) { const [tab, setTab] = useState("nearby"); const [nearbyArr, setNearbyArr] = useState([]) const [nearbyArrReady, setNearbyArrReady] = useState(false) -- 2.52.0 From 370c7c39f5982cc0380af2ae4ea67d2ff7c18ddb Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Thu, 4 Apr 2024 02:03:32 +0000 Subject: [PATCH 10/10] Add jsdoc workflow --- .github/workflows/jsdoc.yaml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/jsdoc.yaml diff --git a/.github/workflows/jsdoc.yaml b/.github/workflows/jsdoc.yaml new file mode 100644 index 0000000..562103b --- /dev/null +++ b/.github/workflows/jsdoc.yaml @@ -0,0 +1,26 @@ +name: JSDoc to GH Pages + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Build + uses: andstor/jsdoc-action@v1 + with: + source_dir: ./frontend-next + output_dir: ./jsdoc + template: minami + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jsdoc \ No newline at end of file -- 2.52.0