Skip to content

Commit 1ede3d4

Browse files
committed
feat: add the search bar in courts page
1 parent 9daf106 commit 1ede3d4

File tree

1 file changed

+90
-15
lines changed

1 file changed

+90
-15
lines changed

web/src/pages/Courts/TopSearch.tsx

+90-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
import React, { useMemo } from "react";
2-
import styled from "styled-components";
3-
1+
import React, { useState, useMemo } from "react";
2+
import styled, { css } from "styled-components";
43
import { useNavigate } from "react-router-dom";
5-
6-
import { DropdownCascader } from "@kleros/ui-components-library";
7-
4+
import { Card, DropdownCascader, Searchbar } from "@kleros/ui-components-library";
85
import { isUndefined } from "utils/index";
9-
106
import { useCourtTree, rootCourtToItems } from "queries/useCourtTree";
11-
127
import { responsiveSize } from "styles/responsiveSize";
13-
8+
import { landscapeStyle } from "styles/landscapeStyle";
149
import { StyledSkeleton } from "components/StyledSkeleton";
15-
1610
import StakeMaintenanceButtons from "./StakeMaintenanceButton";
1711
import { isKlerosUniversity } from "src/consts";
1812

@@ -21,6 +15,8 @@ const Container = styled.div`
2115
display: flex;
2216
justify-content: space-between;
2317
align-items: center;
18+
gap: 8px 16px;
19+
flex-wrap: wrap;
2420
`;
2521

2622
const StyledDropdownCascader = styled(DropdownCascader)`
@@ -30,19 +26,98 @@ const StyledDropdownCascader = styled(DropdownCascader)`
3026
}
3127
`;
3228

29+
const SearchBarContainer = styled.div`
30+
display: flex;
31+
flex-wrap: wrap;
32+
position: relative;
33+
${landscapeStyle(
34+
() => css`
35+
flex: 1;
36+
`
37+
)}
38+
`;
39+
40+
const StyledSearchbar = styled(Searchbar)`
41+
width: 100%;
42+
input {
43+
font-size: 16px;
44+
height: 45px;
45+
padding-top: 0px;
46+
padding-bottom: 0px;
47+
}
48+
`;
49+
50+
const SearchResultsContainer = styled.div`
51+
position: absolute;
52+
margin-top: 45px;
53+
max-height: 400px;
54+
width: 100%;
55+
flex-direction: column;
56+
border-radius: 4px;
57+
overflow-y: auto;
58+
z-index: 1;
59+
background-color: ${({ theme }) => theme.whiteBackground};
60+
`;
61+
62+
const StyledCard = styled(Card)`
63+
height: auto;
64+
width: 100%;
65+
padding: 16px;
66+
color: ${({ theme }) => theme.primaryText};
67+
cursor: pointer;
68+
`;
69+
70+
function flattenCourts(court) {
71+
return court ? [court, ...(court.children || []).flatMap(flattenCourts)] : [];
72+
}
73+
3374
const TopSearch: React.FC = () => {
3475
const { data } = useCourtTree();
3576
const navigate = useNavigate();
3677
const items = useMemo(() => !isUndefined(data) && [rootCourtToItems(data.court)], [data]);
3778
const isUniversity = isKlerosUniversity();
79+
const [search, setSearch] = useState("");
80+
const filteredCourts = useMemo(
81+
() =>
82+
data?.court ? flattenCourts(data.court).filter((c) => c.name.toLowerCase().includes(search.toLowerCase())) : [],
83+
[data, search]
84+
);
85+
3886
return (
3987
<Container>
4088
{items ? (
41-
<StyledDropdownCascader
42-
items={items}
43-
onSelect={(path: string | number) => navigate(path.toString())}
44-
placeholder="Select Court"
45-
/>
89+
<>
90+
<StyledDropdownCascader
91+
items={items}
92+
onSelect={(path) => navigate(path.toString())}
93+
placeholder="Select Court"
94+
/>
95+
<SearchBarContainer>
96+
<StyledSearchbar
97+
dir="auto"
98+
type="text"
99+
placeholder="Search"
100+
value={search}
101+
onChange={(e) => setSearch(e.target.value)}
102+
/>
103+
{search && filteredCourts.length > 0 && (
104+
<SearchResultsContainer>
105+
{filteredCourts.map((court) => (
106+
<StyledCard
107+
hover
108+
key={court.id}
109+
onClick={() => {
110+
navigate(`/courts/${court.id}`);
111+
setSearch("");
112+
}}
113+
>
114+
{court.name}
115+
</StyledCard>
116+
))}
117+
</SearchResultsContainer>
118+
)}
119+
</SearchBarContainer>
120+
</>
46121
) : (
47122
<StyledSkeleton width={240} height={42} />
48123
)}

0 commit comments

Comments
 (0)