From 6a8b909afbe1560be95f7ad0a3e19cfe4717aec6 Mon Sep 17 00:00:00 2001 From: FifthWit Date: Thu, 14 Aug 2025 14:01:01 -0500 Subject: Switched to tailwind/vite --- frontend/src/components/Sidebar.tsx | 386 ++++++++++++++++++------------------ 1 file changed, 192 insertions(+), 194 deletions(-) (limited to 'frontend/src/components/Sidebar.tsx') diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index b55d56b..88a5297 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from "react"; +import React, { useCallback, useRef } from "react"; import { Link, useLocation } from "react-router-dom"; import { @@ -10,12 +10,11 @@ import { PortalIcon, SearchIcon, UploadIcon, -} from "@images/Images"; +} from "../images/Images"; import Login from "@components/Login"; import { UserProfile } from "@customTypes/Profile"; import { Search } from "@customTypes/Search"; import { API } from "@api/Api"; -import "@css/Sidebar.css"; interface SidebarProps { setToken: React.Dispatch>; @@ -24,6 +23,17 @@ interface SidebarProps { onUploadRun: () => void; } +function OpenSidebarIcon(){ + return ( + + ) +} + +function ClosedSidebarIcon(){ + return ( + ) +} + const Sidebar: React.FC = ({ setToken, profile, @@ -34,100 +44,38 @@ const Sidebar: React.FC = ({ undefined ); const [isSidebarLocked, setIsSidebarLocked] = React.useState(false); - const [isSidebarOpen, setSidebarOpen] = React.useState(true); + const [isSidebarOpen, setSidebarOpen] = React.useState(false); + const [selectedButtonIndex, setSelectedButtonIndex] = React.useState(1); const location = useLocation(); const path = location.pathname; - const _handle_sidebar_hide = useCallback(() => { - var btn = document.querySelectorAll( - "button.sidebar-button" - ) as NodeListOf; - const span = document.querySelectorAll( - "button.sidebar-button>span" - ) as NodeListOf; - const side = document.querySelector("#sidebar-list") as HTMLElement; - const searchbar = document.querySelector("#searchbar") as HTMLInputElement; - const uploadRunBtn = document.querySelector( - "#upload-run" - ) as HTMLInputElement; - const uploadRunSpan = document.querySelector( - "#upload-run>span" - ) as HTMLInputElement; + const sidebarRef = useRef(null); + const searchbarRef = useRef(null); + const uploadRunRef = useRef(null); + const sidebarButtonRefs = useRef<(HTMLButtonElement | null)[]>([]); + + const _handle_sidebar_toggle = useCallback(() => { + if (!sidebarRef.current) return; if (isSidebarOpen) { - if (profile) { - const login = document.querySelectorAll( - ".login>button" - )[1] as HTMLElement; - login.style.opacity = "1"; - uploadRunBtn.style.width = "310px"; - uploadRunBtn.style.padding = "0.4em 0 0 11px"; - uploadRunSpan.style.opacity = "0"; - setTimeout(() => { - uploadRunSpan.style.opacity = "1"; - }, 100); - } setSidebarOpen(false); - side.style.width = "320px"; - btn.forEach((e, i) => { - e.style.width = "310px"; - e.style.padding = "0.4em 0 0 11px"; - setTimeout(() => { - span[i].style.opacity = "1"; - }, 100); - }); - side.style.zIndex = "2"; } else { - if (profile) { - const login = document.querySelectorAll( - ".login>button" - )[1] as HTMLElement; - login.style.opacity = "0"; - uploadRunBtn.style.width = "40px"; - uploadRunBtn.style.padding = "0.4em 0 0 5px"; - uploadRunSpan.style.opacity = "0"; - } setSidebarOpen(true); - side.style.width = "40px"; - searchbar.focus(); - btn.forEach((e, i) => { - e.style.width = "40px"; - e.style.padding = "0.4em 0 0 5px"; - span[i].style.opacity = "0"; - }); - setTimeout(() => { - side.style.zIndex = "0"; - }, 300); + searchbarRef.current?.focus(); } - }, [isSidebarOpen, profile]); + }, [isSidebarOpen]); const handle_sidebar_click = useCallback( (clicked_sidebar_idx: number) => { - const btn = document.querySelectorAll("button.sidebar-button"); + setSelectedButtonIndex(clicked_sidebar_idx); if (isSidebarOpen) { setSidebarOpen(false); - _handle_sidebar_hide(); } - // clusterfuck - btn.forEach((e, i) => { - btn[i].classList.remove("sidebar-button-selected"); - btn[i].classList.add("sidebar-button-deselected"); - }); - btn[clicked_sidebar_idx].classList.add("sidebar-button-selected"); - btn[clicked_sidebar_idx].classList.remove("sidebar-button-deselected"); }, - [isSidebarOpen, _handle_sidebar_hide] + [isSidebarOpen] ); - const _handle_sidebar_lock = () => { - if (!isSidebarLocked) { - _handle_sidebar_hide(); - setIsSidebarLocked(true); - setTimeout(() => setIsSidebarLocked(false), 300); - } - }; - const _handle_search_change = async (q: string) => { const searchResponse = await API.get_search(q); setSearchData(searchResponse); @@ -135,149 +83,199 @@ const Sidebar: React.FC = ({ React.useEffect(() => { if (path === "/") { - handle_sidebar_click(1); + setSelectedButtonIndex(1); } else if (path.includes("games")) { - handle_sidebar_click(2); + setSelectedButtonIndex(2); } else if (path.includes("rankings")) { - handle_sidebar_click(3); - } - // else if (path.includes("news")) { handle_sidebar_click(4) } - // else if (path.includes("scorelog")) { handle_sidebar_click(5) } - else if (path.includes("profile")) { - handle_sidebar_click(4); + setSelectedButtonIndex(3); + } else if (path.includes("profile")) { + setSelectedButtonIndex(4); } else if (path.includes("rules")) { - handle_sidebar_click(5); + setSelectedButtonIndex(5); } else if (path.includes("about")) { - handle_sidebar_click(6); + setSelectedButtonIndex(6); } - }, [path, handle_sidebar_click]); + }, [path]); + + const getButtonClasses = (buttonIndex: number) => { + const baseClasses = "flex items-center gap-3 w-full text-left bg-inherit cursor-pointer border-none rounded-lg py-3 px-3 transition-all duration-300 hover:bg-surface1"; + const selectedClasses = selectedButtonIndex === buttonIndex ? "bg-primary text-background" : "bg-transparent text-foreground"; + + return `${baseClasses} ${selectedClasses}`; + }; + + const iconClasses = "w-6 h-6 flex-shrink-0"; return ( -