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" ;
43import { 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" ;
85import { isUndefined } from "utils/index" ;
9-
106import { useCourtTree , rootCourtToItems } from "queries/useCourtTree" ;
11-
127import { responsiveSize } from "styles/responsiveSize" ;
13-
8+ import { landscapeStyle } from "styles/landscapeStyle" ;
149import { StyledSkeleton } from "components/StyledSkeleton" ;
15-
1610import StakeMaintenanceButtons from "./StakeMaintenanceButton" ;
1711import { 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
2622const 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+
3374const 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