feat(ott-142): sport type filter (#59)
parent
7e765341f5
commit
e6873a698f
|
After Width: | Height: | Size: 213 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
@ -0,0 +1,5 @@ |
||||
export const proceduresLexics = { |
||||
3556: 3556, |
||||
6959: 6959, |
||||
12980: 12980, |
||||
} |
||||
@ -0,0 +1,32 @@ |
||||
import React from 'react' |
||||
|
||||
import styled from 'styled-components/macro' |
||||
|
||||
import { useComboboxContext } from '@reach/combobox' |
||||
|
||||
const Wrapper = styled.div<{ isExpanded: boolean }>` |
||||
position: absolute; |
||||
right: 16px; |
||||
top: 50%; |
||||
transform: translateY(-50%); |
||||
width: 20px; |
||||
height: 20px; |
||||
background-size: 12px 12px; |
||||
background-image: url(/images/${({ isExpanded }) => ( |
||||
isExpanded |
||||
? 'arrowUp.svg' |
||||
: 'arrowDown.svg' |
||||
)}); |
||||
background-position: center; |
||||
background-repeat: no-repeat; |
||||
|
||||
:hover { |
||||
cursor: pointer; |
||||
} |
||||
` |
||||
|
||||
export const Arrow = () => { |
||||
const { isExpanded } = useComboboxContext() |
||||
|
||||
return <Wrapper isExpanded={isExpanded} /> |
||||
} |
||||
@ -0,0 +1,11 @@ |
||||
import { css } from 'styled-components' |
||||
|
||||
export type TCustomStyles = string | ReturnType<typeof css> |
||||
|
||||
type TCustomStylesMixin = { |
||||
customstyles?: TCustomStyles, |
||||
} |
||||
|
||||
export const customStylesMixin = css<TCustomStylesMixin>` |
||||
${({ customstyles }) => customstyles} |
||||
` |
||||
@ -0,0 +1,45 @@ |
||||
import React, { useState, useEffect } from 'react' |
||||
|
||||
import map from 'lodash/map' |
||||
|
||||
import type { SportList } from 'requests/getSportList' |
||||
import type { Option } from 'features/Combobox/types' |
||||
import { getSportList } from 'requests/getSportList' |
||||
import { useLexicsStore } from 'features/LexicsStore' |
||||
import { useHeaderFiltersStore } from 'features/HeaderFilters/store' |
||||
|
||||
import { CustomOption } from './styled' |
||||
|
||||
export const useSportTypeFilter = () => { |
||||
const [sportList, setSportList] = useState<SportList>([]) |
||||
const { setSelectedSportTypes } = useHeaderFiltersStore() |
||||
|
||||
const { |
||||
translate, |
||||
} = useLexicsStore() |
||||
|
||||
useEffect(() => { |
||||
getSportList().then(setSportList) |
||||
}, []) |
||||
|
||||
const options = map(sportList, ({ |
||||
id, |
||||
lexic, |
||||
name, |
||||
}) => ({ |
||||
children: <CustomOption t={lexic} image={name} />, |
||||
id, |
||||
name: translate(String(lexic)), |
||||
})) |
||||
|
||||
const onSelect = (option: Option | null) => { |
||||
if (option) { |
||||
setSelectedSportTypes(option.id) |
||||
} |
||||
} |
||||
|
||||
return { |
||||
onSelect, |
||||
options, |
||||
} |
||||
} |
||||
@ -1,5 +1,27 @@ |
||||
import React from 'react' |
||||
|
||||
import { Wrapper } from './styled' |
||||
import { Combobox } from 'features/Combobox' |
||||
|
||||
export const SportTypeFilter = () => <Wrapper /> |
||||
import { useLexicsStore } from 'features/LexicsStore' |
||||
import { useSportTypeFilter } from './hooks' |
||||
import { Wrapper, customListStyles } from './styled' |
||||
|
||||
export const SportTypeFilter = () => { |
||||
const { onSelect, options } = useSportTypeFilter() |
||||
const { translate } = useLexicsStore() |
||||
|
||||
return ( |
||||
<Wrapper> |
||||
<Combobox |
||||
id='sportTypeFilter' |
||||
options={options} |
||||
placeholder={translate('sport')} |
||||
customListStyles={customListStyles} |
||||
filterOptions={false} |
||||
onSelect={onSelect} |
||||
openOnFocus |
||||
withArrow |
||||
/> |
||||
</Wrapper> |
||||
) |
||||
} |
||||
|
||||
@ -1,3 +1,60 @@ |
||||
import styled from 'styled-components/macro' |
||||
import styled, { css } from 'styled-components/macro' |
||||
|
||||
export const Wrapper = styled.div`` |
||||
import { |
||||
ComboboxStyled, |
||||
ComboboxInputStyled, |
||||
ComboboxOptionStyled, |
||||
} from 'features/Combobox/styled' |
||||
import { T9n } from 'features/T9n' |
||||
|
||||
export const Wrapper = styled.div` |
||||
width: 50%; |
||||
|
||||
${ComboboxStyled} { |
||||
margin-top: 0; |
||||
padding-left: 18px; |
||||
} |
||||
|
||||
${ComboboxInputStyled} { |
||||
margin-left: 0; |
||||
overflow: hidden; |
||||
font-size: 18px; |
||||
|
||||
&[aria-expanded="true"] { |
||||
::placeholder { |
||||
color: #fff; |
||||
} |
||||
} |
||||
|
||||
&[aria-expanded="false"] { |
||||
::placeholder { |
||||
color: #999; |
||||
} |
||||
} |
||||
} |
||||
` |
||||
|
||||
export const CustomOption = styled(T9n)<{ image: string }>` |
||||
display: flex; |
||||
align-items: center; |
||||
height: 100%;
|
||||
|
||||
::before { |
||||
content: ''; |
||||
width: 58px; |
||||
height: 100%; |
||||
background-image: url(/images/${({ image }) => `${image}.svg`}); |
||||
background-position: center; |
||||
background-repeat: no-repeat; |
||||
} |
||||
` |
||||
|
||||
export const customListStyles = css` |
||||
left: -19px; |
||||
min-width: 460px; |
||||
|
||||
${ComboboxOptionStyled} { |
||||
height: 56px; |
||||
padding-left: 0; |
||||
} |
||||
` |
||||
|
||||
@ -0,0 +1,24 @@ |
||||
import { DATA_URL, PROCEDURES } from 'config' |
||||
import { callApi, getResponseData } from 'helpers' |
||||
|
||||
const proc = PROCEDURES.get_sport_list |
||||
|
||||
export type SportList = Array<{ |
||||
id: number, |
||||
lexic: number, |
||||
name: string, |
||||
}> |
||||
|
||||
export const getSportList = (): Promise<SportList> => { |
||||
const config = { |
||||
body: { |
||||
params: {}, |
||||
proc, |
||||
}, |
||||
} |
||||
|
||||
return callApi({ |
||||
config, |
||||
url: DATA_URL, |
||||
}).then(getResponseData(proc)) |
||||
} |
||||
Loading…
Reference in new issue