From 1ecd22b5bf285c96c95e35f692d0cb0da4fe5bb7 Mon Sep 17 00:00:00 2001 From: Dylan Zhang Date: Tue, 17 Jun 2025 15:03:10 +1000 Subject: [PATCH 1/3] Updated terminal with extra features - changed actual comparisons using === to use .includes() instead for clearner comparisons - made cursor stay on terminal if redirecting using terminal --- frontend/src/components/Terminal.tsx | 123 +++++++++++++++------------ 1 file changed, 70 insertions(+), 53 deletions(-) diff --git a/frontend/src/components/Terminal.tsx b/frontend/src/components/Terminal.tsx index 3137fa5..760368b 100644 --- a/frontend/src/components/Terminal.tsx +++ b/frontend/src/components/Terminal.tsx @@ -1,66 +1,76 @@ import { useRouter } from "next/router"; -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; const Terminal = () => { - // Store the value of the input const [value, setValue] = useState(""); + const [inputFocused, setInputFocused] = useState(false); - // Automatically select the end of the input as the custom - // cursor only works at the end of the input. const inputRef = useRef(null); + const router = useRouter(); + + // Automatically focus and move cursor to the end const setInputEnd = () => { if (inputRef.current) { const len = inputRef.current.value.length; inputRef.current.setSelectionRange(len, len); } - } + }; - // Keep track of if the input is focused - const [inputFocused, setInputFocused] = useState(false); + // Use localStorage to keep focus on the terminal if redirecting using terminal + useEffect(() => { + if (localStorage.getItem("fromTerminal") === "true") { + localStorage.removeItem("fromTerminal"); + if (inputRef.current) { + inputRef.current.focus(); + setInputEnd(); + setInputFocused(true); + } + } + }, []); - // Using the router to change pages seamlessly - const router = useRouter(); const goToPage = (target: string) => { + localStorage.setItem("fromTerminal", "true"); router.push(target); }; - - // Checking for "Enter" and if so, changing to - // the inputted page + const handleKey = (key: string) => { if (key !== "Enter") return; - if (value.toLowerCase() === "~" - || value.toLowerCase() === "cd" - || value.toLowerCase() === "cd ~" - || value.toLowerCase() === "cd .." - ) { + const cmd = value.toLowerCase().trim(); + + if (["~", "cd", "cd ~", "cd .."].includes(cmd)) { goToPage("/"); - } else if (value.toLowerCase() === "cd about" - || value.toLowerCase() === "cd about us" - || value.toLowerCase() === "cd about_us" - ) { + } else if (["cd about", "cd about us", "cd about_us"].includes(cmd)) { goToPage("/about"); - } else if (value.toLowerCase() === "cd events" - || value.toLowerCase() === "cd event" - ) { + } else if (["cd events", "cd event"].includes(cmd)) { goToPage("/events"); - } else if (value.toLowerCase() === "cd resources" - || value.toLowerCase() === "cd resource" - ) { + } else if (["cd resources", "cd resource"].includes(cmd)) { goToPage("/resources"); - } else if (value.toLowerCase() === "cd sponsors" - || value.toLowerCase() === "cd sponsor" - ) { + } else if (["cd sponsors", "cd sponsor"].includes(cmd)) { goToPage("/sponsors"); - } else if (value.toLowerCase() === "cd contact" - || value.toLowerCase() === "cd contacts" - || value.toLowerCase() === "cd contact us" - || value.toLowerCase() === "cd contact_us" - ) { + } else if (["cd contact", "cd contacts", "cd contact us", "cd contact_us"].includes(cmd)) { goToPage("/contact-us"); + } else if (cmd === "cd constitution") { + goToPage("/about/constitution"); + } else if ( + ["cd execs", "cd directors", "cd subcom", "cd execs directors subcom", "cd execs-directors-subcom", "cd execs_directors_subcom"].includes(cmd) + ) { + goToPage("/about/execs-directors-subcom"); + } else if ( + ["history", "cd our history", "cd our-history", "cd our_history"].includes(cmd) + ) { + goToPage("/about/our-history"); + } else if ( + ["cd faq", "cd faqs", "cd questions", "cd frequently asked questions"].includes(cmd) + ) { + goToPage("/about/faqs"); + } else if ( + ["cd election-guide", "cd election guide", "cd election"].includes(cmd) + ) { + goToPage("/about/election-guide"); } - clearInput() + clearInput(); }; const clearInput = () => { @@ -68,33 +78,40 @@ const Terminal = () => { }; return ( - // Using relative + absolute to overlap the `input` and `span` - {/* The input */} - { - handleKey(e.key) - setInputEnd() + handleKey(e.key); + setInputEnd(); }} onChange={(e) => setValue(e.target.value)} onFocus={() => setInputFocused(true)} onBlur={() => { - clearInput() - setInputFocused(false) + clearInput(); + setInputFocused(false); }} - > - {/* The custom cursor */} + /> - {/* The invisable span that is the same length as the input */} + + {value} + {value} - {/* The custom cursor */} - _ + id="cursor" + className={`text-${ + inputFocused ? "white" : "gray-500" + } pointer-events-none inline-block animate-blink p-0 m-0`} + > + _ + - ) -} + ); +}; -export default Terminal +export default Terminal; From 55cc27b3b9ff0f5b3fb6e598b9cd747584251175 Mon Sep 17 00:00:00 2001 From: Dylan Zhang Date: Tue, 17 Jun 2025 15:10:28 +1000 Subject: [PATCH 2/3] adding comments back --- frontend/src/components/Terminal.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/components/Terminal.tsx b/frontend/src/components/Terminal.tsx index 760368b..1913d3c 100644 --- a/frontend/src/components/Terminal.tsx +++ b/frontend/src/components/Terminal.tsx @@ -33,6 +33,8 @@ const Terminal = () => { router.push(target); }; + // Checking for "Enter" and if so, changing to + // the inputted page const handleKey = (key: string) => { if (key !== "Enter") return; From 7887c2067bd1e9808f1e1ccbf816d7428fb8a779 Mon Sep 17 00:00:00 2001 From: Dylan Zhang Date: Tue, 17 Jun 2025 15:11:07 +1000 Subject: [PATCH 3/3] comment --- frontend/src/components/Terminal.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/Terminal.tsx b/frontend/src/components/Terminal.tsx index 1913d3c..e143021 100644 --- a/frontend/src/components/Terminal.tsx +++ b/frontend/src/components/Terminal.tsx @@ -8,7 +8,8 @@ const Terminal = () => { const inputRef = useRef(null); const router = useRouter(); - // Automatically focus and move cursor to the end + // Automatically select the end of the input as the custom + // cursor only works at the end of the input. const setInputEnd = () => { if (inputRef.current) { const len = inputRef.current.value.length;