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 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