diff --git a/frontend/src/components/Terminal.tsx b/frontend/src/components/Terminal.tsx index 3137fa5..e143021 100644 --- a/frontend/src/components/Terminal.tsx +++ b/frontend/src/components/Terminal.tsx @@ -1,66 +1,79 @@ 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); + + const inputRef = useRef(null); + const router = useRouter(); // Automatically select the end of the input as the custom // cursor only works at the end of the input. - const inputRef = useRef(null); 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 +81,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;