Skip to content

Commit

Permalink
Merge pull request #277 from chain4travel/business-filters
Browse files Browse the repository at this point in the history
feat(partners): add RESET_ALL_BUSINESS_FIELDS action and update MenuList UI
  • Loading branch information
Ysrbolles authored Dec 2, 2024
2 parents 71c9612 + 22659b3 commit 85335ce
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 87 deletions.
249 changes: 165 additions & 84 deletions src/components/Partners/BusinessFieldFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { mdiCheckCircle } from '@mdi/js'
import { mdiCloseCircleOutline } from '@mdi/js'
import Icon from '@mdi/react'
import { Divider, Typography } from '@mui/material'
import { Box, Checkbox, Typography } from '@mui/material'
import ListItemText from '@mui/material/ListItemText'
import MenuItem from '@mui/material/MenuItem'
import Select from '@mui/material/Select'
import React from 'react'
import { ActionType, StatePartnersType, partnersActions } from '../../helpers/partnersReducer'
import React, { useState } from 'react'
import { ActionType, partnersActions, StatePartnersType } from '../../helpers/partnersReducer'

interface BusinessFieldFilterProps {
state: StatePartnersType
Expand All @@ -16,116 +16,197 @@ const BusinessFieldFilter: React.FC<BusinessFieldFilterProps> = ({
state,
dispatchPartnersActions,
}) => {
const [selectedFields, setSelectedFields] = useState<string[]>([])

// Toggle individual field
const handleFieldToggle = (selectedField: string) => {
const newSelectedFields = selectedFields.includes(selectedField)
? selectedFields.filter(field => field !== selectedField)
: [...selectedFields, selectedField]

setSelectedFields(newSelectedFields)

dispatchPartnersActions({
type: partnersActions.UPDATE_BUSINESS_FIELD,
payload: selectedField,
})
}

// Toggle entire category (select/deselect all fields in category)
const handleCategoryToggle = (category: string) => {
// Find all fields in the category
const categoryFields =
state.businessField.find(group => group.category === category)?.fields || []

// Check if all fields in the category are already selected
const allFieldsInCategorySelected = categoryFields.every(field =>
selectedFields.includes(field.fullName),
)

// Update the `selectedFields` state:
// - If all are selected, remove them
// - Otherwise, add the ones not already selected
const updatedSelectedFields = allFieldsInCategorySelected
? selectedFields.filter(field => !categoryFields.map(f => f.fullName).includes(field))
: [
...selectedFields,
...categoryFields
.filter(field => !selectedFields.includes(field.fullName)) // Avoid duplicates
.map(field => field.fullName),
]

setSelectedFields(updatedSelectedFields)
dispatchPartnersActions({
type: partnersActions.TOGGLE_CATEGORY,
payload: category,
})
}

const resetAllFields = () => {
setSelectedFields([]) // Clear selected fields from the state
dispatchPartnersActions({
type: partnersActions.RESET_ALL_BUSINESS_FIELDS,
})
}

return (
<Select
multiple
value={['default']}
onChange={() => {}}
<Box
sx={{
flex: '1 1 250px',
padding: '0',
borderRadius: '12px',
paddingRight: '0px !important',
maxWidth: { xs: '100%', sm: '50%', md: '250px' },
overflow: 'hidden',
'.MuiSelect-select ': {
boxSizing: 'border-box',
height: '40px',
padding: '10px 16px 10px 16px',
borderRadius: '12px',
display: 'flex',
alignItems: 'center',
border: theme => `solid 1px ${theme.palette.card.border}`,
},
'& .MuiPopover-paper ul': {
paddingRight: 'unset !important',
width: '100% !important',
},
'.MuiOutlinedInput-notchedOutline': {
border: 'none !important',
},
'& [aria-expanded=true]': {
background: theme =>
theme.palette.mode === 'dark'
? theme.palette.grey[600]
: theme.palette.grey[200],
boxSizing: 'border-box',
height: '40px',
},
}}
renderValue={() => <Typography variant="caption">Business fields</Typography>}
MenuProps={{
PaperProps: {
style: {
maxHeight: '400px',
overflow: 'auto',
},
},
display: 'flex',
gap: '1rem',
alignItems: 'center',
flexWrap: 'wrap',
position: 'relative',
width: '220px',
}}
>
{state?.businessField?.map((group, groupIndex) => [
<MenuItem
key={`category-${groupIndex}`}
onClick={() => handleCategoryToggle(group.category)}
sx={{
opacity: 0.48,
backgroundColor: theme =>
theme.palette.mode === 'dark'
? theme.palette.grey[800]
: theme.palette.grey[100],
py: 1,
}}
>
<Typography
variant="caption"
sx={{
fontWeight: 600,
color: theme => theme.palette.text.secondary,
}}
>
{group.category}
<Select
multiple
value={['default']} // Track selected fields dynamically
onChange={() => {}} // No-op since we're handling state manually
sx={{
flex: '1 1 220px',
padding: '0',
borderRadius: '12px',
paddingRight: '0px !important',
maxWidth: { xs: '100%', sm: '50%', md: '220px' },
overflow: 'hidden',
'.MuiSelect-select ': {
boxSizing: 'border-box',
padding: '10px 10px 10px 10px',
borderRadius: '12px',
display: 'flex',
alignItems: 'center',
border: theme => `solid 1px ${theme.palette.card.border}`,
},
'& .MuiPopover-paper ul': {
paddingRight: 'unset !important',
width: '100% !important',
},
'.MuiOutlinedInput-notchedOutline': {
border: 'none !important',
},
}}
renderValue={() => (
<Typography variant="caption">
{selectedFields.length > 0
? `Business fields (${selectedFields.length})`
: 'Business fields'}
</Typography>
</MenuItem>,

...group.fields.map((field, fieldIndex) => (
)}
MenuProps={{
PaperProps: {
style: {
maxHeight: '400px',
overflow: 'auto',
},
},
}}
>
{state?.businessField?.map((group, groupIndex) => [
<MenuItem
key={`field-${groupIndex}-${fieldIndex}`}
value={field.fullName}
onClick={() => handleFieldToggle(field.fullName)}
key={`category-${groupIndex}`}
onClick={() => handleCategoryToggle(group.category)} // Toggle category
sx={{
backgroundColor: theme =>
theme.palette.mode === 'dark' ? '#0f182a' : theme.palette.grey[100],
py: 1,
}}
>
<ListItemText
primary={
<Typography
variant="caption"
sx={{ fontWeight: field.active ? 600 : 500 }}
sx={{
fontWeight: 600,
}}
>
{field.name}
{group.category}
</Typography>
}
/>
{field.active && <Icon path={mdiCheckCircle} size={1} color="#B5E3FD" />}
</MenuItem>
)),
<Checkbox
checked={group.fields.every(field => field.active)} // All fields active
indeterminate={
group.fields.some(field => field.active) && // Some fields active
!group.fields.every(field => field.active) // Not all fields active
}
sx={{
padding: '0',
color: theme =>
theme.palette.mode === 'dark' ? '#475569' : '#64748B',
'&.Mui-checked': {
color: theme => theme.palette.secondary.main,
},
'&.MuiCheckbox-indeterminate': {
color: theme => theme.palette.secondary.main,
},
}}
/>
</MenuItem>,

groupIndex < state.businessField.length - 1 ? (
<Divider key={`divider-${groupIndex}`} sx={{ my: 1 }} />
) : null,
])}
</Select>
...group.fields.map((field, fieldIndex) => (
<MenuItem
key={`field-${groupIndex}-${fieldIndex}`}
value={field.fullName}
onClick={() => handleFieldToggle(field.fullName)} // Toggle individual field
>
<ListItemText
primary={
<Typography
variant="caption"
sx={{
fontWeight: field.active ? 600 : 500,
}}
>
{field.name}
</Typography>
}
/>
<Checkbox
checked={field.active}
sx={{
padding: '0',
color: theme =>
theme.palette.mode === 'dark' ? '#475569' : '#64748B',
'&.Mui-checked': {
color: theme => theme.palette.secondary.main,
},
}}
/>
</MenuItem>
)),
])}
</Select>
{selectedFields.length > 0 && (
<button
onClick={resetAllFields}
style={{ position: 'absolute', top: '9px', right: '40px', zIndex: 1400 }}
>
<Icon path={mdiCloseCircleOutline} size={1} />
</button>
)}
</Box>
)
}

Expand Down
13 changes: 12 additions & 1 deletion src/helpers/partnersReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export enum partnersActions {
'TOGGLE_VALIDATORS',
'TOGGLE_ON_MESSENGER',
'UPDATE_BUSINESS_FIELDS_FROM_API',
'RESET_ALL_BUSINESS_FIELDS',
}

export interface ActionType {
Expand Down Expand Up @@ -120,7 +121,17 @@ export const partnersReducer = (
...state,
businessField: action.payload,
}

case partnersActions.RESET_ALL_BUSINESS_FIELDS:
return {
...state,
businessField: state.businessField.map(group => ({
...group,
fields: group.fields.map(field => ({
...field,
active: false,
})),
})),
}
default:
return state
}
Expand Down
4 changes: 2 additions & 2 deletions src/redux/services/partners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export const partnersApi = createApi({
.map(field => field.fullName)
if (filterWith?.length > 0) {
filterWith.forEach((element, index) => {
query += `&filters[$and][${index}][business_fields][BusinessField][$eq]=${element}`
query += `&filters[$or][${index}][business_fields][BusinessField][$eq]=${element}`
})
}
}
Expand Down Expand Up @@ -510,7 +510,7 @@ export const partnersApi = createApi({
.map(field => field.fullName)
if (filterWith?.length > 0) {
filterWith.forEach((element, index) => {
query += `&filters[$and][${index}][business_fields][BusinessField][$eq]=${element}`
query += `&filters[$or][${index}][business_fields][BusinessField][$eq]=${element}`
})
}
}
Expand Down

0 comments on commit 85335ce

Please sign in to comment.