Skip to content

Commit

Permalink
Merge pull request #332 from UTDNebula/fix-load-on-enter
Browse files Browse the repository at this point in the history
Fix load on enter
  • Loading branch information
TyHil authored Jan 5, 2025
2 parents d17c071 + cb8e860 commit cc4b8f4
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 148 deletions.
41 changes: 13 additions & 28 deletions src/components/common/TableSortLabel/tableSortLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
import {
styled,
TableSortLabel as _TableSortLabel,
type TableSortLabelProps,
useMediaQuery,
} from '@mui/material';
import React from 'react';

function TableSortLabel(props: TableSortLabelProps) {
//Selected arrow color
const sortArrowColor = useMediaQuery('(prefers-color-scheme: dark)')
? 'white'
: 'black';

//Change arrow color for TableSortLabel
const StyledTableSortLabel = styled(_TableSortLabel)({
'& .MuiTableSortLabel-icon': {
opacity: 0.5, // Ensure the arrow is always visible
},
'&.Mui-active .MuiTableSortLabel-icon': {
color: sortArrowColor, // Brighten the arrow
},
});

return <StyledTableSortLabel {...props} />;
}

export default TableSortLabel;
import { styled, TableSortLabel } from '@mui/material';

//Change arrow color for TableSortLabel
const StyledTableSortLabel = styled(TableSortLabel)({
'& .MuiTableSortLabel-icon': {
opacity: 0.5, // Ensure the arrow is always visible
},
'&.Mui-active .MuiTableSortLabel-icon': {
color: 'var(--mui-palette-text-primary)', // Brighten the arrow
},
});

export default StyledTableSortLabel;
37 changes: 18 additions & 19 deletions src/components/navigation/topMenu/topMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Share } from '@mui/icons-material';
import { IconButton, Snackbar, Tooltip, useMediaQuery } from '@mui/material';
import { IconButton, Snackbar, Tooltip } from '@mui/material';
import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
Expand All @@ -8,11 +8,19 @@ import React, { useState } from 'react';
import Background from '@/../public/background.png';
import SearchBar from '@/components/search/SearchBar/searchBar';

/**
* Props type used by the TopMenu component
*/
interface TopMenuProps {
resultsLoading: 'loading' | 'done' | 'error';
setResultsLoading: () => void;
}

/**
* This is a component to hold UTD Trends branding and basic navigation
* @returns
*/
export function TopMenu() {
export function TopMenu({ resultsLoading, setResultsLoading }: TopMenuProps) {
const router = useRouter();
const [openCopied, setOpenCopied] = useState(false);

Expand Down Expand Up @@ -42,23 +50,9 @@ export function TopMenu() {
alert(url);
}

const matches = useMediaQuery('(min-width: 640px)');
const searchBar = (
<SearchBar
manageQuery="onSelect"
className={'shrink ' + (matches ? 'basis-[32rem]' : 'basis-full')}
input_className="[&>.MuiInputBase-root]:bg-white [&>.MuiInputBase-root]:dark:bg-haiti"
/>
);

return (
<>
<div
className={
'relative overflow-hidden flex items-center gap-y-0 gap-x-4 md:gap-x-8 lg:gap-x-16 py-1 md:py-2 px-4 md:px-8 lg:px-16 bg-lighten dark:bg-darken' +
(matches ? '' : ' flex-wrap')
}
>
<div className="relative overflow-hidden flex items-center gap-y-0 gap-x-4 md:gap-x-8 lg:gap-x-16 py-1 md:py-2 px-4 md:px-8 lg:px-16 bg-lighten dark:bg-darken flex-wrap sm:flex-nowrap">
<Image
src={Background}
alt="gradient background"
Expand All @@ -71,7 +65,13 @@ export function TopMenu() {
>
UTD TRENDS
</Link>
{matches && searchBar}
<SearchBar
manageQuery="onSelect"
resultsLoading={resultsLoading}
setResultsLoading={setResultsLoading}
className="order-last basis-full sm:order-none sm:basis-[32rem] shrink"
input_className="[&>.MuiInputBase-root]:bg-white [&>.MuiInputBase-root]:dark:bg-haiti"
/>
<Tooltip title="Share link to search" className="ml-auto">
<IconButton
className="aspect-square"
Expand All @@ -91,7 +91,6 @@ export function TopMenu() {
<Share className="text-3xl mr-1" />
</IconButton>
</Tooltip>
{!matches && searchBar}
</div>
<Snackbar
open={openCopied}
Expand Down
3 changes: 2 additions & 1 deletion src/components/search/Filters/filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import {
InputLabel,
ListItemText,
MenuItem,
Select,
Tooltip,
} from '@mui/material';
import Select, { type SelectChangeEvent } from '@mui/material/Select';
import type { SelectChangeEvent } from '@mui/material/Select';
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';

Expand Down
98 changes: 64 additions & 34 deletions src/components/search/SearchBar/searchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Autocomplete, Button, TextField, Tooltip } from '@mui/material';
import {
Autocomplete,
Button,
CircularProgress,
TextField,
Tooltip,
} from '@mui/material';
import match from 'autosuggest-highlight/match';
import parse from 'autosuggest-highlight/parse';
import { useRouter } from 'next/router';
import React, { useEffect, useRef, useState } from 'react';
import React, { type Key, useEffect, useRef, useState } from 'react';

import {
decodeSearchQueryLabel,
Expand All @@ -15,8 +21,10 @@ import {
* Props type used by the SearchBar component
*/
interface SearchProps {
manageQuery?: 'onSelect' | 'onChange';
manageQuery?: 'onSelect';
onSelect?: (value: SearchQuery[]) => void;
resultsLoading?: 'loading' | 'done' | 'error';
setResultsLoading?: () => void;
className?: string;
input_className?: string;
autoFocus?: boolean;
Expand All @@ -31,6 +39,8 @@ interface SearchProps {
const SearchBar = ({
manageQuery,
onSelect,
resultsLoading,
setResultsLoading,
className,
input_className,
autoFocus,
Expand Down Expand Up @@ -64,6 +74,46 @@ const SearchBar = ({
}
}, [router.isReady, router.query.searchTerms]); // useEffect is called every time the query changes

// updateValue -> onSelect_internal -> updateQueries - clicking enter on an autocomplete suggestion in topMenu Searchbar
// updateValue -> onSelect_internal -> onSelect (custom function) - clicking enter on an autocomplete suggestion in home page SearchBar
// params.inputProps.onKeyDown -> handleKeyDown -> onSelect_internal -> updateQueries/onSelect - clicking enter in the SearchBar
// Button onClick -> onSelect_internal -> updateQueries/onSelect - Pressing the "Search" Button

//change all values
function updateValue(newValue: SearchQuery[]) {
setValue(newValue);
onSelect_internal(newValue); // clicking enter to select a autocomplete suggestion triggers a new search (it also 'Enters' for the searchbar)
}

function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {
if (event.key === 'Enter' && inputValue === '') {
event.preventDefault();
event.stopPropagation();
onSelect_internal(value);
}
}

//update parent and queries
function onSelect_internal(newValue: SearchQuery[]) {
// called by updateValue(), handleKeyDown(), and is assigned to the button onClick action
if (
router.query.searchTerms ==
newValue.map((el) => searchQueryLabel(el)).join(',')
)
// do not initiate a new search when the searchTerms haven't changed
return;
setErrorTooltip(!newValue.length); //Check if tooltip needs to be displayed
if (newValue.length && typeof setResultsLoading !== 'undefined') {
setResultsLoading();
}
if (typeof onSelect !== 'undefined') {
onSelect(newValue);
}
if (newValue.length && manageQuery === 'onSelect') {
updateQueries(newValue);
}
}

//update url with what's in value
function updateQueries(newValue: SearchQuery[]) {
if (typeof manageQuery !== 'undefined' && router.isReady) {
Expand Down Expand Up @@ -147,40 +197,14 @@ const SearchBar = ({
});
}

//update parent and queries
function onChange_internal(newValue: SearchQuery[]) {
if (manageQuery === 'onChange') {
updateQueries(newValue);
}
}

//add value
function addValue(newValue: SearchQuery) {
setValue((old) => {
const oldAndNew = [...old, newValue];
onChange_internal(oldAndNew);
return oldAndNew;
});
}

//change all values
function updateValue(newValue: SearchQuery[]) {
if (newValue.length) setErrorTooltip(false); //close the tooltip if there is at least 1 valid search term
setValue(newValue);
onSelect_internal(newValue); // clicking enter to select a autocomplete suggestion triggers a new search (it also 'Enters' for the searchbar)
}

//update parent and queries
function onSelect_internal(newValue: SearchQuery[]) {
setErrorTooltip(!newValue.length); //Check if tooltip needs to be displayed
if (typeof onSelect !== 'undefined') {
onSelect(newValue);
}
if (newValue.length && manageQuery === 'onSelect') {
updateQueries(newValue);
}
}

useEffect(() => {
fetch('/api/autocomplete');
}, []);
Expand All @@ -191,7 +215,7 @@ const SearchBar = ({
multiple
freeSolo
loading={loading}
//highligh first option to add with enter
//highlight first option to add with enter
autoHighlight={true}
clearOnBlur={false}
className="grow"
Expand Down Expand Up @@ -233,6 +257,7 @@ const SearchBar = ({
loadNewOptions(newInputValue);
}}
renderInput={(params) => {
params.inputProps.onKeyDown = handleKeyDown;
return (
<TextField
{...params}
Expand Down Expand Up @@ -270,7 +295,7 @@ const SearchBar = ({
}
}
}}
renderOption={(props, option, { inputValue }) => {
renderOption={(props: { key: Key }, option, { inputValue }) => {
const text =
typeof option === 'string' ? option : searchQueryLabel(option);
//add spaces between prefix and course number
Expand All @@ -289,8 +314,9 @@ const SearchBar = ({
),
);
const parts = parse(text, matches);
const { key, ...otherProps } = props;
return (
<li {...props}>
<li key={key} {...otherProps}>
{parts.map((part, index) => (
<span
key={index}
Expand Down Expand Up @@ -320,12 +346,16 @@ const SearchBar = ({
disableElevation
size="large"
className={
'shrink-0 normal-case bg-royal hover:bg-royalDark' +
'h-11 w-[5.5rem] shrink-0 normal-case bg-royal hover:bg-royalDark' +
(value.length == 0 ? ' text-cornflower-200' : '')
} //darkens the text when no valid search terms are entered (pseudo-disables the search button)
onClick={() => onSelect_internal(value)}
>
Search
{resultsLoading === 'loading' ? (
<CircularProgress className="h-6 w-6 text-cornflower-50 dark:text-cornflower-800" />
) : (
'Search'
)}
</Button>
</Tooltip>
</div>
Expand Down
34 changes: 26 additions & 8 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import '@/styles/globals.css';

import { useMediaQuery } from '@mui/material';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { GoogleAnalytics } from '@next/third-parties/google';
import { SpeedInsights } from '@vercel/speed-insights/react';
Expand All @@ -10,6 +9,7 @@ import localFont from 'next/font/local';
import Head from 'next/head';
import { useRouter } from 'next/router';
import React from 'react';
import resolveConfig from 'tailwindcss/resolveConfig';

import tailwindConfig from '@/../tailwind.config.js';
import FeedbackPopup from '@/components/common/FeedbackPopup/feedbackPopup';
Expand Down Expand Up @@ -75,26 +75,44 @@ const kallisto = localFont({
variable: '--font-kallisto',
});

const fullTailwindConfig = resolveConfig(tailwindConfig);

function MyApp({ Component, pageProps }: AppProps) {
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
const muiTheme = createTheme({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const colors = fullTailwindConfig.theme.colors as any;
const palette = {
palette: {
mode: prefersDarkMode ? 'dark' : 'light',
//copied from tailwind.config.js
primary: {
main: tailwindConfig.theme.extend.colors.royal,
main: colors.royal as string,
},
secondary: {
main: tailwindConfig.theme.extend.colors.royal,
light: tailwindConfig.theme.extend.colors.periwinkle,
main: colors.royal as string,
light: colors.periwinkle as string,
},
error: {
main: tailwindConfig.theme.extend.colors.persimmon['500'],
main: colors.persimmon['500'] as string,
},
},
};
const muiTheme = createTheme({
cssVariables: true,
colorSchemes: {
light: palette,
dark: palette,
},
typography: {
fontFamily: 'inherit',
},
breakpoints: {
values: {
xs: 0,
sm: parseInt(fullTailwindConfig.theme.screens.sm),
md: parseInt(fullTailwindConfig.theme.screens.md),
lg: parseInt(fullTailwindConfig.theme.screens.lg),
xl: parseInt(fullTailwindConfig.theme.screens.xl),
},
},
});

const router = useRouter();
Expand Down
Loading

0 comments on commit cc4b8f4

Please sign in to comment.