Skip to content

Commit

Permalink
refactor: webhook human areas
Browse files Browse the repository at this point in the history
  • Loading branch information
TurtIeSocks committed Mar 7, 2024
1 parent a171142 commit ed34fa8
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 74 deletions.
48 changes: 48 additions & 0 deletions src/components/BasicAccordion.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// @ts-check
import * as React from 'react'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import Typography from '@mui/material/Typography'
import Accordion from '@mui/material/Accordion'
import AccordionSummary from '@mui/material/AccordionSummary'
import AccordionDetails from '@mui/material/AccordionDetails'

import { useStorage } from '@store/useStorage'

const expandIcon = <ExpandMoreIcon />

/**
* A basic accordion component that already has the expand icon and state management
* @param {{
* stateKey?: string
* title: string
* children: React.ReactNode
* } & import('@mui/material').AccordionDetailsProps} props
* @returns
*/
export function BasicAccordion({
title,
stateKey = title,
children,
...props
}) {
const expanded = useStorage((s) => !!s.expanded[stateKey])

/** @type {(e: unknown, isExpanded: boolean )=> void} */
const handleChange = React.useCallback(
(_, isExpanded) =>
useStorage.setState((prev) => ({
expanded: { ...prev.expanded, [stateKey]: isExpanded },
})),
[stateKey],
)
return (
<Accordion expanded={expanded} onChange={handleChange}>
<AccordionSummary expandIcon={expandIcon}>
<Typography variant="h6">{title}</Typography>
</AccordionSummary>
<AccordionDetails sx={{ p: 0 }} {...props}>
{children}
</AccordionDetails>
</Accordion>
)
}
98 changes: 55 additions & 43 deletions src/features/webhooks/human/area/AreaGroup.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// @ts-check
import * as React from 'react'
import Grid2 from '@mui/material/Unstable_Grid2'
import Typography from '@mui/material/Typography'
import Divider from '@mui/material/Divider'
import Button from '@mui/material/Button'
import { useTranslation } from 'react-i18next'

import { Loading } from '@components/Loading'
import { handleClick } from '@store/useWebhookStore'
import { BasicAccordion } from '@components/BasicAccordion'
import { useWebhookStore } from '@store/useWebhookStore'

import { useGetAreas } from '../../hooks/useGetAreas'
import { MemoAreaChip } from './AreaChip'
Expand All @@ -19,71 +18,84 @@ export const AreaGroup = () => {
return loading ? (
<Loading>{t('loading', { category: t('areas') })}</Loading>
) : (
data.map(({ group, children }) => (
<GroupTile key={group} group={group}>
{children.map((child) => (
<MemoAreaChip key={`${group}_${child}`} name={child} />
))}
</GroupTile>
data.map(({ group, children }, index) => (
<React.Fragment key={group}>
{index === 0 && (
<Divider
flexItem
style={{ margin: '20px 0', width: '100%', height: 2 }}
/>
)}
<GroupTile key={group} group={group} areas={children}>
{children.map((child) => (
<MemoAreaChip key={`${group}_${child}`} name={child} />
))}
</GroupTile>
</React.Fragment>
))
)
}

/**
*
* @param {{ group: string, children: React.ReactNode[] }} props
* @returns
*/
const GroupTile = ({ group, children }) => {
const { t } = useTranslation()
/** @param {{ children: React.ReactNode[], group: string, areas: string[] }} props */
const GroupTile = ({ children, group, areas }) => {
const count = useWebhookStore(
(s) => s.human.area?.filter((a) => areas.includes(a)).length,
)
if (children.length === 0) return null
return (
<Grid2 container xs={12}>
<Divider
flexItem
style={{ margin: '20px 0', width: '100%', height: 2 }}
/>
<Grid2 xs={group ? 4 : 12} textAlign="center">
{group ? (
<BasicAccordion
title={`${group} - ${count} / ${areas.length}`}
stateKey={group}
>
{children}
</BasicAccordion>
) : (
children
)}
{/* <Grid2 xs={group ? 4 : 12} textAlign="center">
<Typography variant="h4" gutterBottom>
{group}
</Typography>
</Grid2>
{group && (
<Grid2 xs={4} textAlign="center">
<AreaAction action="none" group={group} color="primary">
{t('disable_all')}
</AreaAction>
</Grid2>
)}
{group && (
<Grid2 xs={4} textAlign="center">
<AreaAction action="all" group={group} color="secondary">
{t('enable_all')}
</AreaAction>
</Grid2>
)}
{children}
)} */}
</Grid2>
)
}

/**
*
* @param {{
* action: string,
* children: React.ReactNode,
* color: import('@mui/material').ButtonProps['color']
* group?: string
* }} props
* @returns
*/
export const AreaAction = ({ action, children, color, group }) => (
<Button
size="small"
variant="contained"
color={color}
onClick={handleClick(action, group)}
>
{children}
</Button>
)
// /**
// *
// * @param {{
// * action: string,
// * children: React.ReactNode,
// * color: import('@mui/material').ButtonProps['color']
// * group?: string
// * }} props
// * @returns
// */
// export const AreaAction = ({ action, children, color, group }) => (
// <Button
// size="small"
// variant="contained"
// color={color}
// onClick={handleClick(action, group)}
// >
// {children}
// </Button>
// )
6 changes: 3 additions & 3 deletions src/features/webhooks/human/area/Selected.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { Trans } from 'react-i18next'
import { useWebhookStore } from '@store/useWebhookStore'

export const Selected = () => {
const selectedAreas = useWebhookStore((s) => s.human.area || [])
const selectedAreas = useWebhookStore((s) => s.human.area)
return (
<Typography variant="h6" align="center">
<Trans i18nKey="selected_areas" count={selectedAreas.length}>
{{ amount: selectedAreas.length }}
<Trans i18nKey="selected_areas" count={selectedAreas?.length || 0}>
{{ amount: selectedAreas?.length || 0 }}
</Trans>
</Typography>
)
Expand Down
37 changes: 9 additions & 28 deletions src/features/webhooks/human/area/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,23 @@ import Grid from '@mui/material/Unstable_Grid2'

import { setModeBtn } from '@store/useWebhookStore'

import { AreaAction, AreaGroup } from './AreaGroup'
import { AreaGroup } from './AreaGroup'
import { Selected } from './Selected'

const Areas = () => {
const { t } = useTranslation()

return (
<Grid container xs={12} justifyContent="center" alignItems="center">
<Grid xs={6} sm={3} pb={{ xs: 2, sm: 0 }}>
<Grid xs={6} sm={3}>
<Typography variant="h6" pl={1}>
{t('areas')}
</Typography>
</Grid>
<Grid
xs={6}
sm={3}
textAlign="center"
display={{ xs: 'block', sm: 'none' }}
pb={{ xs: 2, sm: 0 }}
>
<Button
size="small"
variant="contained"
color="primary"
onClick={setModeBtn('areas')}
>
{t('choose_on_map')}
</Button>
<Grid xs={6} display={{ xs: 'none', sm: 'block' }}>
<Selected />
</Grid>
<Grid xs={6} sm={3} textAlign="center">
{/* <Grid xs={6} sm={3} textAlign="center">
<AreaAction color="primary" action="none">
{t('disable_all')}
</AreaAction>
Expand All @@ -45,13 +32,8 @@ const Areas = () => {
<AreaAction color="secondary" action="all">
{t('enable_all')}
</AreaAction>
</Grid>
<Grid
xs={6}
sm={3}
textAlign="center"
display={{ xs: 'none', sm: 'block' }}
>
</Grid> */}
<Grid xs={6} sm={3} textAlign="center">
<Button
size="small"
variant="contained"
Expand All @@ -61,11 +43,10 @@ const Areas = () => {
{t('choose_on_map')}
</Button>
</Grid>
<AreaGroup />
<Grid container xs={12} alignItems="center" justifyContent="center" />
<Grid xs={12}>
<Grid xs={12} display={{ xs: 'block', sm: 'none' }} pt={2}>
<Selected />
</Grid>
<AreaGroup />
</Grid>
)
}
Expand Down
2 changes: 2 additions & 0 deletions src/store/useStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { setDeep } from '@utils/setDeep'
* }
* searches: Record<string, string>,
* tabs: Record<string, number>,
* expanded: Record<string, boolean>,
* menus: ReturnType<import('server/src/services/ui/advMenus')>
* holidayEffects: Record<string, boolean>,
* motdIndex: number
Expand Down Expand Up @@ -121,6 +122,7 @@ export const useStorage = create(
settings: {},
searches: {},
tabs: {},
expanded: {},
userSettings: {},
icons: {},
audio: {},
Expand Down

0 comments on commit ed34fa8

Please sign in to comment.