Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 46 additions & 11 deletions web/src/pages/Courts/CourtDetails/TopSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,17 @@ const SearchResultsContainer = styled(OverlayScrollbarsComponent)`
border-top-right-radius: 0;
`;

const StyledCard = styled(Card)<{ selected: boolean }>`
const StyledCard = styled(Card)<{ selected: boolean; keyboardSelected: boolean }>`
${hoverShortTransitionTiming}
height: auto;
width: 100%;
padding: ${({ selected }) => (selected ? "16px 13px" : "16px")};
padding: ${({ selected, keyboardSelected }) => (selected || keyboardSelected ? "16px 13px" : "16px")};
cursor: pointer;
border: none;
border-left: ${({ selected, theme }) => (selected ? `3px solid ${theme.primaryBlue}` : "none")};
background-color: ${({ selected, theme }) => (selected ? theme.mediumBlue : "transparent")};
border-left: ${({ selected, keyboardSelected, theme }) =>
selected || keyboardSelected ? `3px solid ${theme.primaryBlue}` : "none"};
background-color: ${({ selected, keyboardSelected, theme }) =>
selected || keyboardSelected ? theme.mediumBlue : "transparent"};
border-radius: 0;

:hover {
Expand Down Expand Up @@ -112,6 +114,7 @@ const TopSearch: React.FC = () => {
const items = useMemo(() => !isUndefined(data?.court) && [rootCourtToItems(data.court)], [data]);
const isUniversity = isKlerosUniversity();
const [search, setSearch] = useState("");
const [selectedIndex, setSelectedIndex] = useState(-1);

const filteredCourts = useMemo(() => {
if (!data?.court) return [];
Expand All @@ -122,6 +125,39 @@ const TopSearch: React.FC = () => {
return [selectedCourt, ...courts.filter((c) => c.id !== currentCourtId)];
}, [data, search, currentCourtId]);

const handleKeyDown = (e: React.KeyboardEvent) => {
if (!search || filteredCourts.length === 0) return;

switch (e.key) {
case "ArrowDown":
e.preventDefault();
setSelectedIndex((prev) => Math.min(prev + 1, filteredCourts.length - 1));
break;
case "ArrowUp":
e.preventDefault();
setSelectedIndex((prev) => Math.max(prev - 1, -1));
break;
case "Enter":
if (selectedIndex >= 0) {
navigate(`/courts/${filteredCourts[selectedIndex].id}`);
setSearch("");
setSelectedIndex(-1);
}
break;
}
};

const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value);
setSelectedIndex(-1);
};

const handleCourtClick = (courtId: string) => {
navigate(`/courts/${courtId}`);
setSearch("");
setSelectedIndex(-1);
};

return (
<Container>
{items ? (
Expand All @@ -137,18 +173,17 @@ const TopSearch: React.FC = () => {
type="text"
placeholder="Search"
value={search}
onChange={(e) => setSearch(e.target.value)}
onChange={handleSearchChange}
onKeyDown={handleKeyDown}
/>
{search && filteredCourts.length > 0 && (
<SearchResultsContainer>
{filteredCourts.map((court) => (
{filteredCourts.map((court, index) => (
<StyledCard
key={court.id}
selected={court.id === currentCourtId}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution @ManiBAJPAI22 !

I would like to keep the original logic to highlight the selected court, and make it so such that the keyboardSelected style doesn't clash with it (i.e. no primary-blue left-border). Maybe some kind of outline? also, we have a new version of the ui-components library that will eventually substitute all these components, and this new library has functionality already built-in, although we don't have a date for the migration yet.

onClick={() => {
navigate(`/courts/${court.id}`);
setSearch("");
}}
selected={selectedIndex === -1 && court.id === currentCourtId}
keyboardSelected={index === selectedIndex}
onClick={() => handleCourtClick(court.id)}
>
{court.parentName && <CourtParentSpan>{court.parentName} / </CourtParentSpan>}
<CourtNameSpan>{court.name}</CourtNameSpan>
Expand Down