-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* first version * changed layout for activities on landing page * changed limit for activities on landing page
- Loading branch information
Showing
8 changed files
with
290 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import { Button, Divider, Stack, Theme, useMediaQuery } from '@mui/material'; | ||
import { makeStyles } from 'makeStyles'; | ||
import { useCallback, useMemo, useState } from 'react'; | ||
import { useForm } from 'react-hook-form'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { argsToParams } from 'utils'; | ||
|
||
import { useEvents } from 'hooks/Event'; | ||
import { useIsAuthenticated } from 'hooks/User'; | ||
import { useAnalytics } from 'hooks/Utils'; | ||
|
||
import Bool from 'components/inputs/Bool'; | ||
import SubmitButton from 'components/inputs/SubmitButton'; | ||
import TextField from 'components/inputs/TextField'; | ||
import Expand from 'components/layout/Expand'; | ||
import Pagination from 'components/layout/Pagination'; | ||
import Paper from 'components/layout/Paper'; | ||
import EventListItem, { EventListItemLoading } from 'components/miscellaneous/EventListItem'; | ||
import NotFoundIndicator from 'components/miscellaneous/NotFoundIndicator'; | ||
|
||
const useStyles = makeStyles()((theme) => ({ | ||
grid: { | ||
display: 'grid', | ||
gridTemplateColumns: '3fr 1fr', | ||
gridGap: theme.spacing(2), | ||
alignItems: 'self-start', | ||
paddingBottom: theme.spacing(2), | ||
|
||
[theme.breakpoints.down('lg')]: { | ||
gridTemplateColumns: '1fr', | ||
}, | ||
}, | ||
list: { | ||
display: 'grid', | ||
gridTemplateColumns: '1fr', | ||
gap: theme.spacing(1), | ||
[theme.breakpoints.down('lg')]: { | ||
order: 1, | ||
}, | ||
}, | ||
settings: { | ||
display: 'grid', | ||
gridGap: theme.spacing(1), | ||
position: 'sticky', | ||
top: 80, | ||
|
||
[theme.breakpoints.down('lg')]: { | ||
order: 0, | ||
position: 'static', | ||
top: 0, | ||
}, | ||
}, | ||
})); | ||
|
||
type Filters = { | ||
activity: boolean; | ||
search?: string; | ||
open_for_sign_up?: boolean; | ||
user_favorite?: boolean; | ||
expired: boolean; | ||
}; | ||
|
||
const ActivitiesDefaultView = () => { | ||
const isAuthenticated = useIsAuthenticated(); | ||
const { event } = useAnalytics(); | ||
const getInitialFilters = useCallback((): Filters => { | ||
const params = new URLSearchParams(location.search); | ||
const activity = true; | ||
const expired = params.get('expired') ? Boolean(params.get('expired') === 'true') : false; | ||
const open_for_sign_up = params.get('open_for_sign_up') ? Boolean(params.get('open_for_sign_up') === 'true') : undefined; | ||
const user_favorite = params.get('user_favorite') ? Boolean(params.get('user_favorite') === 'true') : undefined; | ||
const search = params.get('search') || undefined; | ||
return { activity, expired, search, open_for_sign_up, user_favorite }; | ||
}, []); | ||
const { classes } = useStyles(); | ||
const navigate = useNavigate(); | ||
const lgDown = useMediaQuery((theme: Theme) => theme.breakpoints.down('lg')); | ||
const [filters, setFilters] = useState<Filters>(getInitialFilters()); | ||
const { data, error, hasNextPage, fetchNextPage, isLoading, isFetching } = useEvents(filters); | ||
const events = useMemo(() => (data ? data.pages.map((page) => page.results).flat() : []), [data]); | ||
const { register, control, handleSubmit, setValue, formState } = useForm<Filters>({ defaultValues: getInitialFilters() }); | ||
const isEmpty = useMemo(() => (data !== undefined ? !data.pages.some((page) => Boolean(page.results.length)) : false), [data]); | ||
|
||
const resetFilters = () => { | ||
setValue('search', ''); | ||
setValue('expired', false); | ||
setValue('user_favorite', false); | ||
setFilters({ activity: true, expired: false, open_for_sign_up: false, user_favorite: false }); | ||
navigate(`${location.pathname}${argsToParams({ expired: false })}`, { replace: true }); | ||
}; | ||
|
||
const search = (data: Filters) => { | ||
event('search', 'events', JSON.stringify(data)); | ||
setFilters(data); | ||
navigate(`${location.pathname}${argsToParams(data)}`, { replace: true }); | ||
!lgDown || setSearchFormExpanded((prev) => !prev); | ||
}; | ||
|
||
const [searchFormExpanded, setSearchFormExpanded] = useState(false); | ||
|
||
const SearchForm = () => ( | ||
<form onSubmit={handleSubmit(search)}> | ||
<TextField disabled={isFetching} formState={formState} label='Søk' margin='none' {...register('search')} /> | ||
<Bool control={control} formState={formState} label='Tidligere' name='expired' type='switch' /> | ||
<Bool control={control} formState={formState} label='Kun med åpen påmelding' name='open_for_sign_up' type='switch' /> | ||
{isAuthenticated && <Bool control={control} formState={formState} label='Favoritter' name='user_favorite' type='switch' />} | ||
<SubmitButton disabled={isFetching} formState={formState}> | ||
Søk | ||
</SubmitButton> | ||
<Divider sx={{ my: 1 }} /> | ||
<Button color='error' fullWidth onClick={resetFilters} variant='outlined'> | ||
Tilbakestill | ||
</Button> | ||
</form> | ||
); | ||
|
||
return ( | ||
<> | ||
<div className={classes.grid}> | ||
<div className={classes.list}> | ||
{isLoading && <EventListItemLoading />} | ||
{isEmpty && <NotFoundIndicator header='Fant ingen arrangementer' />} | ||
{error && <Paper>{error.detail}</Paper>} | ||
{data !== undefined && ( | ||
<Pagination fullWidth hasNextPage={hasNextPage} isLoading={isFetching} nextPage={() => fetchNextPage()}> | ||
<Stack gap={1}> | ||
{events.map((event) => ( | ||
<EventListItem event={event} key={event.id} /> | ||
))} | ||
</Stack> | ||
</Pagination> | ||
)} | ||
{isFetching && <EventListItemLoading />} | ||
</div> | ||
{lgDown ? ( | ||
<div> | ||
<Expand expanded={searchFormExpanded} flat header='Filtrering' onChange={() => setSearchFormExpanded((prev) => !prev)}> | ||
<SearchForm /> | ||
</Expand> | ||
</div> | ||
) : ( | ||
<Paper className={classes.settings}> | ||
<SearchForm /> | ||
</Paper> | ||
)} | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default ActivitiesDefaultView; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { Stack, styled, Theme, Typography, useMediaQuery } from '@mui/material'; | ||
import { useCallback, useState } from 'react'; | ||
|
||
import { useEvents } from 'hooks/Event'; | ||
|
||
import EventListItem, { EventListItemLoading } from 'components/miscellaneous/EventListItem'; | ||
|
||
const Container = styled('div')(({ theme }) => ({ | ||
display: 'grid', | ||
alignItems: 'self-start', | ||
gridTemplateColumns: '1fr 1fr', | ||
gap: theme.spacing(1), | ||
})); | ||
|
||
const Text = styled(Typography)(({ theme }) => ({ | ||
color: theme.palette.text.secondary, | ||
p: 0.5, | ||
})); | ||
|
||
const NO_OF_EVENTS_TO_SHOW = 6; | ||
const NO_OF_EVENTS_TO_SHOW_MD_DOWN = 4; | ||
|
||
type Filters = { | ||
activity: boolean; | ||
}; | ||
|
||
const ActivityEventsListView = () => { | ||
const mdDown = useMediaQuery((theme: Theme) => theme.breakpoints.down('md')); | ||
const getInitialFilters = useCallback((): Filters => { | ||
const activity = true; | ||
return { activity }; | ||
}, []); | ||
const [filters] = useState<Filters>(getInitialFilters()); | ||
|
||
const { data, isLoading } = useEvents(filters); | ||
|
||
if (isLoading) { | ||
return ( | ||
<Stack gap={1}> | ||
<EventListItemLoading /> | ||
<EventListItemLoading /> | ||
<EventListItemLoading /> | ||
</Stack> | ||
); | ||
} else if (!data?.pages[0]?.results.length) { | ||
return ( | ||
<Text align='center' variant='subtitle1'> | ||
Ingen kommende arrangementer | ||
</Text> | ||
); | ||
} else if (mdDown) { | ||
return ( | ||
<Stack gap={1}> | ||
{data?.pages[0]?.results.slice(0, NO_OF_EVENTS_TO_SHOW_MD_DOWN).map((event) => ( | ||
<EventListItem event={event} key={event.id} /> | ||
))} | ||
</Stack> | ||
); | ||
} | ||
|
||
return ( | ||
<Container> | ||
{data?.pages[0].results.length ? ( | ||
data?.pages[0]?.results.slice(0, NO_OF_EVENTS_TO_SHOW).map((event) => <EventListItem event={event} key={event.id} />) | ||
) : ( | ||
<Stack gap={1}> | ||
<Text align='center' variant='subtitle1'> | ||
Ingen kommende aktiviteter | ||
</Text> | ||
</Stack> | ||
)} | ||
</Container> | ||
); | ||
}; | ||
|
||
export default ActivityEventsListView; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.