From c106e9297c62ac63565d8f0388860cf08052711c Mon Sep 17 00:00:00 2001 From: vivi Date: Sun, 2 Nov 2025 09:10:40 -0600 Subject: [PATCH 1/6] Update SearchResults.tsx Added navigation trough sections with left, right, up, down keys. --- client/src/components/SearchResults.tsx | 59 ++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/client/src/components/SearchResults.tsx b/client/src/components/SearchResults.tsx index 7da1f74..e9cf508 100644 --- a/client/src/components/SearchResults.tsx +++ b/client/src/components/SearchResults.tsx @@ -238,13 +238,68 @@ const Results = React.memo(function Results({ search, sectionId, router }: Resul void debouncedNavigate(id); }, [sectionId, debouncedNavigate]); + // Arrow key navigation between sections + // TODO: 1. Navigating to another page (bug), 2. Whitespace issues, 3. Show a little tutorial or hint about this feature + // Notes to self: npm install, cd client, npm run dev + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + // Don't handle arrow keys if user is typing in an input field or textarea + const target = event.target as HTMLElement; + if ( + target.tagName === 'INPUT' || + target.tagName === 'TEXTAREA' || + target.isContentEditable + ) { + return; + } + + // Only handle arrow keys when a section is selected + if (!sections || sections.length === 0 || !sectionId) { + return; + } + + // Find the current section index + const currentIndex = sections.findIndex((s) => s.id === sectionId); + + if (currentIndex === -1) { + return; + } + + let newIndex = -1; + + if (event.key === "ArrowLeft" || event.key === "ArrowUp") { + // Navigate to previous section + newIndex = currentIndex > 0 ? currentIndex - 1 : currentIndex; + event.preventDefault(); + } else if (event.key === "ArrowRight" || event.key === "ArrowDown") { + // Navigate to next section + newIndex = currentIndex < sections.length - 1 ? currentIndex + 1 : currentIndex; + event.preventDefault(); + } + + // Navigate to the new section if index changed + if (newIndex !== -1 && newIndex !== currentIndex) { + const target = sections[newIndex]; + if (target && typeof target.id === "number") { + handleClick(target.id); + } + } + }; + + // Add event listener + window.addEventListener("keydown", handleKeyDown); + // Cleanup + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, [sections, sectionId, handleClick]); const handleSubmit = useCallback(({ search }: SearchQuery) => { void stableRouter.current.push({ pathname: "/results", query: { search }, - }).catch(error => { + }).catch((error: unknown) => { console.error('Navigation error:', error); }); }, []); @@ -265,7 +320,7 @@ const Results = React.memo(function Results({ search, sectionId, router }: Resul duration: 400, smooth: true }); - }).catch(error => { + }).catch((error: unknown) => { console.error('Navigation error:', error); }); }, []); From 6211622619ca13645851fce44f639db43587a8b3 Mon Sep 17 00:00:00 2001 From: vivi Date: Sat, 29 Nov 2025 15:33:45 -0600 Subject: [PATCH 2/6] Completed Keyboard Navigation Features added: 1) Arrow Navigation: Top and Left have the same function AND Bottom and Right have the same function. 2) 5 classes on a given page instead of 8 so there's no whitespace. 3) Navigation through the page numbers (numbers and formatting ie I've made everything center aligned and added those first and last page buttons) 4) First course selected by default. --- client/src/components/SearchResults.tsx | 41 +++- .../src/components/SearchResultsContent.tsx | 2 +- client/src/components/SectionContent.tsx | 4 +- client/src/components/SectionList.tsx | 213 +++++++++++++----- 4 files changed, 196 insertions(+), 64 deletions(-) diff --git a/client/src/components/SearchResults.tsx b/client/src/components/SearchResults.tsx index e9cf508..4c15b79 100644 --- a/client/src/components/SearchResults.tsx +++ b/client/src/components/SearchResults.tsx @@ -11,7 +11,7 @@ import { normalizeName } from "../utils/index"; import { useDb } from "../utils/useDb"; import Search from "./Search"; import SearchResultsContent from "./SearchResultsContent"; -import SectionList from "./SectionList"; +import { SectionList } from "./SectionList"; const Container = styled.div` display: block; @@ -52,7 +52,10 @@ interface ResultsProps { } const Results = React.memo(function Results({ search, sectionId, router }: ResultsProps) { + // Track current page for SectionList pagination + const [currentPage, setCurrentPage] = useState(1); const scrollRef = useRef(null); + const hasAutoSelected = useRef(false); const { data: db } = useDb(); @@ -74,6 +77,36 @@ const Results = React.memo(function Results({ search, sectionId, router }: Resul } ); + // Auto-select first section when sections load and no section is selected + useEffect(() => { + if (sections && sections.length > 0 && !sectionId && !hasAutoSelected.current) { + hasAutoSelected.current = true; + const firstSection = sections[0]; + if (firstSection) { + void router.push({ + pathname: "/results", + query: { search, sectionId: firstSection.id }, + }, undefined, { shallow: true }); + } + } + }, [sections, sectionId, search, router]); + + // Reset auto-select flag when search changes + useEffect(() => { + hasAutoSelected.current = false; + }, [search]); + + // Update page when sectionId changes (arrow navigation or click) + useEffect(() => { + if (sections && sections.length > 0) { + const idx = sections.findIndex(s => s.id === sectionId); + if (idx !== -1) { + const newPage = Math.floor(idx / 5) + 1; + setCurrentPage(newPage); + } + } + }, [sectionId, sections]); + // get the section data const { data: section, @@ -239,8 +272,6 @@ const Results = React.memo(function Results({ search, sectionId, router }: Resul }, [sectionId, debouncedNavigate]); // Arrow key navigation between sections - // TODO: 1. Navigating to another page (bug), 2. Whitespace issues, 3. Show a little tutorial or hint about this feature - // Notes to self: npm install, cd client, npm run dev useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { // Don't handle arrow keys if user is typing in an input field or textarea @@ -343,6 +374,8 @@ const Results = React.memo(function Results({ search, sectionId, router }: Resul loading={sectionsStatus === "loading"} id={sectionId} error={sectionsError} + page={currentPage} + setPage={setCurrentPage} /> @@ -369,4 +402,4 @@ const Results = React.memo(function Results({ search, sectionId, router }: Resul prevProps.sectionId === nextProps.sectionId; }); -export default Results; +export default Results; \ No newline at end of file diff --git a/client/src/components/SearchResultsContent.tsx b/client/src/components/SearchResultsContent.tsx index 7939218..0b0a658 100644 --- a/client/src/components/SearchResultsContent.tsx +++ b/client/src/components/SearchResultsContent.tsx @@ -69,7 +69,7 @@ export default function SearchResultsContent({ } else { return ( - Nothing to see here, select a section! + {/* Nothing to see here, select a section! */} ); } diff --git a/client/src/components/SectionContent.tsx b/client/src/components/SectionContent.tsx index 3906478..2bfc5c4 100644 --- a/client/src/components/SectionContent.tsx +++ b/client/src/components/SectionContent.tsx @@ -299,11 +299,11 @@ const FlexSmall = styled.div` `; interface SectionContentProps { - // relatedSections: Grades[]; section: Grades; instructor: RMPInstructor; courseRating: number | null; - // handleRelatedSectionClick: (search: string, id: number) => void; + relatedSections?: Grades[]; + handleRelatedSectionClick?: (search: string, id: number) => void; } const getDifficultyColor = (difficulty: number): string => { diff --git a/client/src/components/SectionList.tsx b/client/src/components/SectionList.tsx index 6080926..2621d15 100644 --- a/client/src/components/SectionList.tsx +++ b/client/src/components/SectionList.tsx @@ -1,4 +1,4 @@ -import { FrownTwoTone, UserOutlined } from "@ant-design/icons"; +import { FrownTwoTone, UserOutlined, LeftOutlined, RightOutlined, DoubleLeftOutlined, DoubleRightOutlined } from "@ant-design/icons"; import type { Grades } from "@utd-grades/db"; import { List, Popover as AntPopover, Spin } from "antd"; import React, { ReactNode, useEffect, useState } from "react"; @@ -89,6 +89,42 @@ const IconWrapper = styled.div` margin-right: 8; `; +const PaginationContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 16px 10px; + font-family: var(--font-family); +`; + +const PaginationButton = styled.button<{ active?: boolean; disabled?: boolean }>` + min-width: 28px; + height: 28px; + padding: 0 8px; + border: 1px solid ${props => props.active ? 'rgb(0, 116, 224)' : '#d9d9d9'}; + background: ${props => props.active ? 'rgb(0, 116, 224)' : props.disabled ? '#f5f5f5' : '#fff'}; + color: ${props => props.active ? '#fff' : props.disabled ? '#bfbfbf' : 'rgba(0, 0, 0, 0.85)'}; + border-radius: 2px; + cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'}; + font-family: var(--font-family); + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + + &:hover { + ${props => !props.disabled && !props.active && css` + border-color: rgb(0, 116, 224); + color: rgb(0, 116, 224); + `} + } + + &:focus { + outline: none; + } +`; + // FIXME (median) // const AverageWrapper = styled.div<{ average: number }>` // color: ${(p) => getLetterGradeColor(getLetterGrade(p.average))}; @@ -113,14 +149,29 @@ interface SectionListProps { data: Grades[] | undefined; onClick: (id: number) => void; error: unknown; + page: number; + setPage: React.Dispatch>; } -export default function SectionList({ loading, id, data, onClick, error }: SectionListProps) { - const [page, setPage] = useState(1); +export function SectionList({ loading, id, data, onClick, error, page, setPage }: SectionListProps) { + const pageSize = 5; + const totalPages = data ? Math.ceil(data.length / pageSize) : 0; + + // Calculate which pages to show (max 3 pages) + const getPageNumbers = () => { + if (totalPages <= 3) { + return Array.from({ length: totalPages }, (_, i) => i + 1); + } - useEffect(() => { - setPage(1); - }, [data]); + // Always show current page and try to show 1 before and 1 after + if (page === 1) { + return [1, 2, 3]; + } else if (page === totalPages) { + return [totalPages - 2, totalPages - 1, totalPages]; + } else { + return [page - 1, page, page + 1]; + } + }; const popover = ( @@ -155,57 +206,105 @@ export default function SectionList({ loading, id, data, onClick, error }: Secti if (data.length < 1) { return emptyMessage; } else { + const pageNumbers = getPageNumbers(); + const startIndex = (page - 1) * pageSize; + const endIndex = startIndex + pageSize; + const currentPageData = data.slice(startIndex, endIndex); + return ( - - itemLayout="vertical" - size="large" - pagination={{ - pageSize: 8, - style: { - marginRight: "10px", - }, - showSizeChanger: false, - current: page, - onChange: (page) => setPage(page), - }} - dataSource={data} - renderItem={(item) => ( - } - child={item.totalStudents.toString()} - key="students-total" - />, - // FIXME (median) - // } - // child={ - // - // {getLetterGrade(item.average)} - // - // } - // key="average" - // />, - ]} - onClick={() => onClick(item.id)} - > - - {item.subject} {item.catalogNumber}.{item.section} - - } - // FIXME (no professor): non null assertion - description={`${item.instructor1!.last}, ${item.instructor1!.first} - ${ - item.semester.season - } ${item.semester.year}`} - /> - + <> + + itemLayout="vertical" + size="large" + dataSource={currentPageData} + renderItem={(item) => ( + } + child={item.totalStudents.toString()} + key="students-total" + />, + // FIXME (median) + // } + // child={ + // + // {getLetterGrade(item.average)} + // + // } + // key="average" + // />, + ]} + onClick={() => onClick(item.id)} + > + + {item.subject} {item.catalogNumber}.{item.section} + + } + // FIXME (no professor): non null assertion + description={`${item.instructor1!.last}, ${item.instructor1!.first} - ${ + item.semester.season + } ${item.semester.year}`} + /> + + )} + /> + {totalPages > 1 && ( + + setPage(1)} + aria-label="First page" + title="First page" + > + + + + setPage(page - 1)} + aria-label="Previous page" + title="Previous page" + > + + + + {pageNumbers.map((pageNum) => ( + setPage(pageNum)} + title={`Page ${pageNum}`} + > + {pageNum} + + ))} + + setPage(page + 1)} + aria-label="Next page" + title="Next page" + > + + + + setPage(totalPages)} + aria-label="Last page" + title="Last page" + > + + + )} - /> + ); } } else if (loading) { @@ -214,7 +313,7 @@ export default function SectionList({ loading, id, data, onClick, error }: Secti itemLayout="vertical" size="large" pagination={{ - pageSize: 8, + pageSize: 5, }} > @@ -227,4 +326,4 @@ export default function SectionList({ loading, id, data, onClick, error }: Secti } else { return emptyMessage; } -} +} \ No newline at end of file From a0e8091fb1094d8fd5743cffc3ae8b504392f3a2 Mon Sep 17 00:00:00 2001 From: vivi Date: Sat, 29 Nov 2025 16:27:51 -0600 Subject: [PATCH 3/6] Removed unused imports --- client/src/components/SectionList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/SectionList.tsx b/client/src/components/SectionList.tsx index 2621d15..4ab2be2 100644 --- a/client/src/components/SectionList.tsx +++ b/client/src/components/SectionList.tsx @@ -1,7 +1,7 @@ import { FrownTwoTone, UserOutlined, LeftOutlined, RightOutlined, DoubleLeftOutlined, DoubleRightOutlined } from "@ant-design/icons"; import type { Grades } from "@utd-grades/db"; import { List, Popover as AntPopover, Spin } from "antd"; -import React, { ReactNode, useEffect, useState } from "react"; +import React, { ReactNode} from "react"; import styled, { css } from "styled-components"; // FIXME (median) // import { getLetterGrade, getLetterGradeColor } from "../utils"; From 2162517b3c97de2899b2b74cf8e9c65ed4f550fd Mon Sep 17 00:00:00 2001 From: vivi Date: Sat, 10 Jan 2026 21:52:32 -0600 Subject: [PATCH 4/6] Updated navigation & Changed accent colors Notes: Fonts, landing page, and Dark Mode are on Bennet's branch. TODO after merging with Bennett's branch: dark mode colors. --- client/src/components/Header.tsx | 13 ++++ client/src/components/SearchResults.tsx | 4 +- client/src/components/SectionList.tsx | 13 ++-- client/src/pages/styles.css | 97 ++++++++++++++++++++++++- 4 files changed, 118 insertions(+), 9 deletions(-) diff --git a/client/src/components/Header.tsx b/client/src/components/Header.tsx index 4f0f07b..b942a10 100644 --- a/client/src/components/Header.tsx +++ b/client/src/components/Header.tsx @@ -20,6 +20,19 @@ const Back = styled(Button) <{ $dummy?: boolean }>` border: none; box-shadow: none; visibility: ${(props) => (props.$dummy ? "hidden" : "visible")}; + + &:hover, + &:focus, + &:active { + color: rgb(198, 198, 198) !important; + background: none !important; + } + + &:hover .anticon, + &:focus .anticon, + &:active .anticon { + color: rgb(198, 198, 198) !important; + } `; const HeaderText = styled.a` diff --git a/client/src/components/SearchResults.tsx b/client/src/components/SearchResults.tsx index 4c15b79..002055d 100644 --- a/client/src/components/SearchResults.tsx +++ b/client/src/components/SearchResults.tsx @@ -298,11 +298,11 @@ const Results = React.memo(function Results({ search, sectionId, router }: Resul let newIndex = -1; - if (event.key === "ArrowLeft" || event.key === "ArrowUp") { + if (event.key === "ArrowLeft") { // Navigate to previous section newIndex = currentIndex > 0 ? currentIndex - 1 : currentIndex; event.preventDefault(); - } else if (event.key === "ArrowRight" || event.key === "ArrowDown") { + } else if (event.key === "ArrowRight") { // Navigate to next section newIndex = currentIndex < sections.length - 1 ? currentIndex + 1 : currentIndex; event.preventDefault(); diff --git a/client/src/components/SectionList.tsx b/client/src/components/SectionList.tsx index 4ab2be2..757bc4f 100644 --- a/client/src/components/SectionList.tsx +++ b/client/src/components/SectionList.tsx @@ -35,7 +35,7 @@ const Item = styled(List.Item)<{ selected: boolean }>` `; const selectedStyles = css` - border-right: 6px solid rgb(0, 116, 224) !important; + border-right: 6px solid #333 !important; box-shadow: inset -5px 0px 10px rgba(0, 0, 0, 0.05); background-color: #fcfcfc; `; @@ -102,9 +102,9 @@ const PaginationButton = styled.button<{ active?: boolean; disabled?: boolean }> min-width: 28px; height: 28px; padding: 0 8px; - border: 1px solid ${props => props.active ? 'rgb(0, 116, 224)' : '#d9d9d9'}; - background: ${props => props.active ? 'rgb(0, 116, 224)' : props.disabled ? '#f5f5f5' : '#fff'}; - color: ${props => props.active ? '#fff' : props.disabled ? '#bfbfbf' : 'rgba(0, 0, 0, 0.85)'}; + border: 1px solid ${props => props.active ? 'rgb(198, 198, 198 )' : '#d9d9d9'}; + background: ${props => props.active ? 'rgb(198, 198, 198 )' : props.disabled ? '#f5f5f5' : '#fff'}; + color: ${props => props.active ? '#333' : props.disabled ? '#bfbfbf' : 'rgba(0, 0, 0, 0.85)'}; border-radius: 2px; cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'}; font-family: var(--font-family); @@ -115,8 +115,9 @@ const PaginationButton = styled.button<{ active?: boolean; disabled?: boolean }> &:hover { ${props => !props.disabled && !props.active && css` - border-color: rgb(0, 116, 224); - color: rgb(0, 116, 224); + border-color: rgb(198, 198, 198 ); + color: #333; + background: #fafafa; `} } diff --git a/client/src/pages/styles.css b/client/src/pages/styles.css index 516a57b..752d7bc 100644 --- a/client/src/pages/styles.css +++ b/client/src/pages/styles.css @@ -12,6 +12,8 @@ --box-shadow-active: 0 2px 1px rgba(151, 151, 151, 0.09), 0 4px 2px rgba(151, 151, 151, 0.09), 0 8px 4px rgba(151, 151, 151, 0.09), 0 16px 8px rgba(151, 151, 151, 0.09), 0 32px 16px rgba(151, 151, 151, 0.09); + --ant-wave-shadow-color: rgb(198, 198, 198); + --antd-wave-shadow-color: rgb(198, 198, 198); } html, @@ -30,15 +32,108 @@ body { width: 100%; } +.ant-input, +.ant-input-search-button { + height: 40px !important; +} + .ant-input { border-radius: 20px 0 0 20px !important; } +.ant-input:hover, .ant-input:focus { outline: none !important; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1) !important; + border-color: rgb(116, 116, 116) !important; + box-shadow: none !important; + border-width: 1px !important; + } .ant-input-search-button { border-radius: 0 20px 20px 0 !important; + border-color: rgb(198, 198, 198 ) !important; + border-width: 1px !important; + color: #333 !important; +} + +.ant-input-search-button:hover, +.ant-input-search-button:focus { + border-color: rgb(116, 116, 116) !important; + color: #333 !important; +} + +.ant-input-affix-wrapper:hover, +.ant-input-affix-wrapper:focus-within, +.ant-input-affix-wrapper-focused { + border-color: rgb(198, 198, 198) !important; + box-shadow: none !important; +} + +.ant-btn { + --ant-wave-shadow-color: rgb(198, 198, 198); + --antd-wave-shadow-color: rgb(198, 198, 198); +} + +.ant-btn:focus, +.ant-btn:active, +.ant-btn:focus-visible { + outline: none !important; + border-color: rgb(198, 198, 198) !important; +} + +.ant-wave, +.ant-wave-holder, +.ant-click-animating-node, +.ant-click-animating { + --ant-wave-shadow-color: rgb(198, 198, 198) !important; + --antd-wave-shadow-color: rgb(198, 198, 198) !important; +} + +.ant-btn-primary, +.ant-btn-primary:hover, +.ant-btn-primary:focus { + background-color: rgb(198, 198, 198 ) !important; + border-color: rgb(198, 198, 198 ) !important; + color: #333 !important; +} + +.ant-menu-item-selected { + background-color: rgb(198, 198, 198 ) !important; +} + +.ant-menu-item-active { + background-color: rgb(198, 198, 198 ) !important; +} + +.ant-card-bordered { + border: 1px solid rgb(198, 198, 198 ) !important; +} + +.ant-select-item-option-selected:not(.ant-select-item-option-disabled) { + background-color: rgb(198, 198, 198 ) !important; +} + +.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) { + background-color: rgb(198, 198, 198 ) !important; + border-color: rgb(198, 198, 198 ) !important; + color: #333 !important; +} + +.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover { + background-color: rgb(217, 217, 217) !important; + border-color: rgb(217, 217, 217) !important; + color: #333 !important; +} + +.ant-radio-button-wrapper:hover { + color: #333 !important; +} + +a { + color: #333; +} + +a:hover { + color: #555; } \ No newline at end of file From 55b883d9f8b3bd907bb2cbbbd8134f8da2d97bb9 Mon Sep 17 00:00:00 2001 From: vivi Date: Sat, 10 Jan 2026 22:17:17 -0600 Subject: [PATCH 5/6] Added Search Bar Hotkey! --- client/src/components/Core.tsx | 52 ++++++++++++++++++++++++++++++++ client/src/components/Search.tsx | 1 + 2 files changed, 53 insertions(+) diff --git a/client/src/components/Core.tsx b/client/src/components/Core.tsx index ab0b788..3cf54c9 100644 --- a/client/src/components/Core.tsx +++ b/client/src/components/Core.tsx @@ -1,6 +1,7 @@ import { HeartTwoTone } from "@ant-design/icons"; import { Popover } from "antd"; import type { ReactNode } from "react"; +import { useEffect } from "react"; import styled from "styled-components"; const Container = styled.div` @@ -96,6 +97,57 @@ interface CoreProps { } function Core({ children }: CoreProps) { + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + const target = event.target as HTMLElement | null; + if ( + target && + (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) + ) { + return; + } + + if (!(event.ctrlKey || event.metaKey)) return; + + const keyIsSlash = event.key === "/" || event.code === "Slash"; + if (!keyIsSlash) return; + + event.preventDefault(); + + let inputEl = document.getElementById("search-bar") as HTMLElement | null; + let input: HTMLInputElement | null = null; + + if (inputEl) { + if (inputEl instanceof HTMLInputElement) { + input = inputEl; + } else { + input = inputEl.querySelector("input") as HTMLInputElement | null; + } + } + + if (!input) { + input = document.querySelector( + ".ant-input-search input, input#search-bar, input[placeholder^=\"ex. CS\"]" + ); + } + + if (input) { + input.focus(); + try { + const len = input.value ? input.value.length : 0; + input.setSelectionRange(len, len); + } catch (e) { + // ignore + } + } + }; + + window.addEventListener("keydown", handleKeyDown); + + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, []); const donors = (

diff --git a/client/src/components/Search.tsx b/client/src/components/Search.tsx index 5866eda..32a3cc1 100644 --- a/client/src/components/Search.tsx +++ b/client/src/components/Search.tsx @@ -79,6 +79,7 @@ export default function Search({ onSubmit, initialSearchValue: initialSearch = " value={searchValue} > onSubmit({ search })} name="search" size="large" From 8a9cb758a8733cb383322aef1a3c2b830feb8b43 Mon Sep 17 00:00:00 2001 From: vivi Date: Sat, 10 Jan 2026 22:27:16 -0600 Subject: [PATCH 6/6] Updated Core.tsx --- client/src/components/Core.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/components/Core.tsx b/client/src/components/Core.tsx index 3cf54c9..91b7fee 100644 --- a/client/src/components/Core.tsx +++ b/client/src/components/Core.tsx @@ -114,14 +114,14 @@ function Core({ children }: CoreProps) { event.preventDefault(); - let inputEl = document.getElementById("search-bar") as HTMLElement | null; + const inputEl = document.getElementById("search-bar"); let input: HTMLInputElement | null = null; if (inputEl) { if (inputEl instanceof HTMLInputElement) { input = inputEl; } else { - input = inputEl.querySelector("input") as HTMLInputElement | null; + input = inputEl.querySelector("input"); } }