refactor filters logic
This commit is contained in:
parent
bc9e8f2164
commit
350ababe5b
@ -1,24 +1,26 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import {Body} from "../../utils/fonts";
|
import {FlexRow} from "../../utils/containers";
|
||||||
|
|
||||||
const FilterStyle = styled(Body)`
|
const FilterStyle = styled(FlexRow)`
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
border-radius: 32px;
|
border-radius: 32px;
|
||||||
border: 1px solid ${({theme}) => theme.colors.dark};
|
border: 1px solid ${({theme}) => theme.colors.dark};
|
||||||
box-shadow: ${({theme}) => theme.shadow};
|
box-shadow: ${({theme}) => theme.shadow};
|
||||||
gap: 8px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: ${({theme, active}) => active ? theme.colors.white : theme.colors.dark};
|
||||||
|
background-color: ${({theme, active}) => active ? theme.colors.darj : theme.colors.white};
|
||||||
|
|
||||||
|
* {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Filter = (props) => {
|
const Filter = (props) => {
|
||||||
return (
|
return (
|
||||||
<FilterStyle as='button'>
|
<FilterStyle as='button' active={props.active}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</FilterStyle>
|
</FilterStyle>
|
||||||
);
|
);
|
||||||
|
@ -1,123 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import {FlexColumn, FlexRow, Grid, TransBack} from "../../utils/containers";
|
|
||||||
import Button from "./Button";
|
|
||||||
import theme from "../../utils/theme";
|
|
||||||
import styled from "styled-components";
|
|
||||||
import {Medium} from "../../utils/fonts";
|
|
||||||
import Filter from "./Filter";
|
|
||||||
|
|
||||||
const FiltersMenuStyle = styled(FlexColumn)`
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
overflow-y: scroll;
|
|
||||||
width: 240px;
|
|
||||||
height: 100vh;
|
|
||||||
justify-content: space-around;
|
|
||||||
@media (max-height: 626px) {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
padding: 14px 16px 14px 24px;
|
|
||||||
box-shadow: ${({theme}) => theme.filtersShadow};
|
|
||||||
background-color: ${({theme}) => theme.colors.white};
|
|
||||||
transition: transform 0.5s ease-in-out;
|
|
||||||
z-index: 3;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const FiltersMenu = (props) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<TransBack backgroundColor={theme.colors.dark03} translateX={props.translateX}
|
|
||||||
opacity={props.opacity} onClick={props.toggleFiltersMenu}/>
|
|
||||||
<FiltersMenuStyle translateX={props.translateX} gap='16px'>
|
|
||||||
<FlexColumn width='200px' alignmentX='flex-start' gap='12px'>
|
|
||||||
<Medium as='p' textTransform='uppercase'>
|
|
||||||
Sort by
|
|
||||||
</Medium>
|
|
||||||
<Grid gridTemplateColumns='auto auto' gridGap='12px'>
|
|
||||||
<Filter>
|
|
||||||
Closing
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Closing
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Hotness
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Hotness
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Reward
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Reward
|
|
||||||
</Filter>
|
|
||||||
</Grid>
|
|
||||||
</FlexColumn>
|
|
||||||
<FlexColumn width='200px' alignmentX='flex-start' gap='12px'>
|
|
||||||
<Medium as='p' textTransform='uppercase'>
|
|
||||||
Status
|
|
||||||
</Medium>
|
|
||||||
<Grid gridTemplateColumns='auto auto' gridGap='12px'>
|
|
||||||
<Filter>
|
|
||||||
Both
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Completed
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Active
|
|
||||||
</Filter>
|
|
||||||
</Grid>
|
|
||||||
</FlexColumn>
|
|
||||||
<FlexColumn width='200px' alignmentX='flex-start' gap='12px'>
|
|
||||||
<Medium as='p' textTransform='uppercase'>
|
|
||||||
Challenge type
|
|
||||||
</Medium>
|
|
||||||
<Grid gridTemplateColumns='auto auto' gridGap='12px'>
|
|
||||||
<Filter>
|
|
||||||
All
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Tabular
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Text
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Image
|
|
||||||
</Filter>
|
|
||||||
</Grid>
|
|
||||||
</FlexColumn>
|
|
||||||
<FlexColumn width='200px' alignmentX='flex-start' gap='12px'>
|
|
||||||
<Medium as='p' textTransform='uppercase'>
|
|
||||||
Commercial
|
|
||||||
</Medium>
|
|
||||||
<Grid gridTemplateColumns='auto auto' gridGap='12px'>
|
|
||||||
<Filter>
|
|
||||||
Both
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
Yes
|
|
||||||
</Filter>
|
|
||||||
<Filter>
|
|
||||||
No
|
|
||||||
</Filter>
|
|
||||||
</Grid>
|
|
||||||
</FlexColumn>
|
|
||||||
<FlexRow gap='16px' margin='14px 0 0 0'>
|
|
||||||
<Button as='button' width='64px' height='28px'>
|
|
||||||
Done
|
|
||||||
</Button>
|
|
||||||
<Button as='button' width='64px' height='28px'
|
|
||||||
backgroundColor={theme.colors.dark}>
|
|
||||||
Clear
|
|
||||||
</Button>
|
|
||||||
</FlexRow>
|
|
||||||
</FiltersMenuStyle>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FiltersMenu;
|
|
51
src/components/elements/FiltersMenu/FiltersMenu.js
Normal file
51
src/components/elements/FiltersMenu/FiltersMenu.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {FlexColumn, FlexRow, TransBack} from "../../../utils/containers";
|
||||||
|
import Button from "../Button";
|
||||||
|
import theme from "../../../utils/theme";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import FilterBy from "../../sections/FilterBy";
|
||||||
|
import filterOptions from "./filterOptions";
|
||||||
|
|
||||||
|
const FiltersMenuStyle = styled(FlexColumn)`
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
overflow-y: scroll;
|
||||||
|
width: 240px;
|
||||||
|
height: 100vh;
|
||||||
|
justify-content: space-around;
|
||||||
|
@media (max-height: 626px) {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
padding: 14px 16px 14px 24px;
|
||||||
|
box-shadow: ${({theme}) => theme.filtersShadow};
|
||||||
|
background-color: ${({theme}) => theme.colors.white};
|
||||||
|
transition: transform 0.5s ease-in-out;
|
||||||
|
z-index: 3;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FiltersMenu = (props) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TransBack backgroundColor={theme.colors.dark03} translateX={props.translateX}
|
||||||
|
opacity={props.opacity} onClick={props.toggleFiltersMenu}/>
|
||||||
|
<FiltersMenuStyle translateX={props.translateX} gap='16px'>
|
||||||
|
<FilterBy header='Sort by' options={filterOptions[0]}/>
|
||||||
|
<FilterBy header='Status' options={filterOptions[1]}/>
|
||||||
|
<FilterBy header='Challenge type' options={filterOptions[2]}/>
|
||||||
|
<FilterBy header='Commercial' options={filterOptions[3]}/>
|
||||||
|
<FlexRow gap='16px' margin='14px 0 0 0'>
|
||||||
|
<Button as='button' width='64px' height='28px'>
|
||||||
|
Done
|
||||||
|
</Button>
|
||||||
|
<Button as='button' width='64px' height='28px'
|
||||||
|
backgroundColor={theme.colors.dark}>
|
||||||
|
Clear
|
||||||
|
</Button>
|
||||||
|
</FlexRow>
|
||||||
|
</FiltersMenuStyle>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FiltersMenu;
|
66
src/components/elements/FiltersMenu/filterOptions.js
Normal file
66
src/components/elements/FiltersMenu/filterOptions.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
const filterOptions = [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: 'Closing',
|
||||||
|
sort: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Closing',
|
||||||
|
sort: true,
|
||||||
|
rotate: '180deg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hotness',
|
||||||
|
sort: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hotness',
|
||||||
|
sort: true,
|
||||||
|
rotate: '180deg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Reward',
|
||||||
|
sort: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Reward',
|
||||||
|
sort: true,
|
||||||
|
rotate: '180deg'
|
||||||
|
}
|
||||||
|
], [
|
||||||
|
{
|
||||||
|
name: 'Both'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Completed'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Active'
|
||||||
|
},
|
||||||
|
], [
|
||||||
|
{
|
||||||
|
name: 'All'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Tabular'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Text'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Image'
|
||||||
|
},
|
||||||
|
], [
|
||||||
|
{
|
||||||
|
name: 'Both'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Yes'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'No'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
export default filterOptions;
|
1
src/components/elements/FiltersMenu/index.js
Normal file
1
src/components/elements/FiltersMenu/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export {default} from './FiltersMenu';
|
39
src/components/sections/FilterBy.js
Normal file
39
src/components/sections/FilterBy.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {FlexColumn, Grid, Svg} from "../../utils/containers";
|
||||||
|
import Filter from "../elements/Filter";
|
||||||
|
import {Body, Medium} from "../../utils/fonts";
|
||||||
|
import arrow from "../../assets/arrow.svg";
|
||||||
|
|
||||||
|
const FilterBy = (props) => {
|
||||||
|
|
||||||
|
const renderFilterOptions = () => {
|
||||||
|
return (
|
||||||
|
props.options.map((option, index) => {
|
||||||
|
return (
|
||||||
|
<Filter key={`filter_option-${index}`}>
|
||||||
|
<Body>
|
||||||
|
{option.name}
|
||||||
|
</Body>
|
||||||
|
{option.sort ?
|
||||||
|
<Svg src={arrow} rotate={option.rotate ? option.rotate : '0'}
|
||||||
|
margin={option.rotate ? '2px 0 0 0' : '0 0 2px 0'}/>
|
||||||
|
: ''}
|
||||||
|
</Filter>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FlexColumn width='200px' alignmentX='flex-start' gap='12px'>
|
||||||
|
<Medium as='p' textTransform='uppercase'>
|
||||||
|
{props.header}
|
||||||
|
</Medium>
|
||||||
|
<Grid gridTemplateColumns='auto auto' gridGap='12px'>
|
||||||
|
{renderFilterOptions()}
|
||||||
|
</Grid>
|
||||||
|
</FlexColumn>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FilterBy;
|
@ -53,7 +53,7 @@ const Challenges = () => {
|
|||||||
return (
|
return (
|
||||||
challenges.slice(n, n + ELEMENTS_PER_PAGE).map((challenge, index) => {
|
challenges.slice(n, n + ELEMENTS_PER_PAGE).map((challenge, index) => {
|
||||||
return (
|
return (
|
||||||
<MiniChallenge key={index} title={challenge.title} type={challenge.type}
|
<MiniChallenge key={`challenge-${index}`} title={challenge.title} type={challenge.type}
|
||||||
describe={challenge.describe} metric={challenge.metric}
|
describe={challenge.describe} metric={challenge.metric}
|
||||||
bestScore={challenge.bestScore} baseline={challenge.baseline}
|
bestScore={challenge.bestScore} baseline={challenge.baseline}
|
||||||
prize={challenge.prize} timeLeft={challenge.timeLeft}/>
|
prize={challenge.prize} timeLeft={challenge.timeLeft}/>
|
||||||
|
@ -51,6 +51,7 @@ const Svg = styled(Container)`
|
|||||||
mask: url(${({src}) => src}) no-repeat center;
|
mask: url(${({src}) => src}) no-repeat center;
|
||||||
width: ${({width}) => width ? width : '16px'};
|
width: ${({width}) => width ? width : '16px'};
|
||||||
height: ${({height}) => height ? height : '16px'};
|
height: ${({height}) => height ? height : '16px'};
|
||||||
|
transform: rotate(${({rotate}) => rotate ? rotate : '0'});
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const TransBack = styled(FlexRow)`
|
const TransBack = styled(FlexRow)`
|
||||||
|
Loading…
Reference in New Issue
Block a user