Files
konstitisyon.nu/components/versions/version-filters.js
T

206 lines
5.8 KiB
JavaScript
Raw Normal View History

2025-07-23 18:50:16 +04:00
import {useState, useMemo} from 'react'
import PropTypes from 'prop-types'
import Box from '@mui/material/Box'
import FormControl from '@mui/material/FormControl'
import InputLabel from '@mui/material/InputLabel'
import Select from '@mui/material/Select'
import MenuItem from '@mui/material/MenuItem'
import TextField from '@mui/material/TextField'
import Chip from '@mui/material/Chip'
import Button from '@mui/material/Button'
import ClearIcon from '@mui/icons-material/Clear'
import FilterListIcon from '@mui/icons-material/FilterList'
import {formatDate} from '@/lib/format.js'
export default function VersionFilters({data, onFiltersChange}) {
const [filters, setFilters] = useState({
author: '',
dateFrom: '',
dateTo: '',
status: ''
})
// Extract unique authors from data
const authors = useMemo(() => {
const authorSet = new Set()
for (const version of data) {
if (version.user_created) {
const authorName = version.user_created.split('-')[0]
authorSet.add(authorName)
}
}
return [...authorSet].sort()
}, [data])
// Extract date range from data
const dateRange = useMemo(() => {
if (data.length === 0) {
return {min: '', max: ''}
}
const dates = data.map(v => new Date(v.date_created))
const minDate = new Date(Math.min(...dates))
const maxDate = new Date(Math.max(...dates))
return {
min: minDate.toISOString().split('T')[0],
max: maxDate.toISOString().split('T')[0]
}
}, [data])
const handleFilterChange = (filterKey, value) => {
const newFilters = {...filters, [filterKey]: value}
setFilters(newFilters)
onFiltersChange(newFilters)
}
const clearAllFilters = () => {
const emptyFilters = {
author: '',
dateFrom: '',
dateTo: '',
status: ''
}
setFilters(emptyFilters)
onFiltersChange(emptyFilters)
}
const hasActiveFilters = Object.values(filters).some(value => value !== '')
return (
<Box sx={{mb: 2}}>
<Box sx={{
display: 'flex',
alignItems: 'center',
gap: 2,
mb: 2,
flexWrap: 'wrap'
}}
>
<FilterListIcon color='action' />
<FormControl size='small' sx={{minWidth: 120}}>
<InputLabel>Auteur</InputLabel>
<Select
value={filters.author}
label='Auteur'
onChange={event => handleFilterChange('author', event.target.value)}
>
<MenuItem value=''>Tous les auteurs</MenuItem>
{authors.map(author => (
<MenuItem key={author} value={author}>
@{author}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
size='small'
label='Du'
type='date'
value={filters.dateFrom}
InputLabelProps={{shrink: true}}
inputProps={{
min: dateRange.min,
max: dateRange.max
}}
sx={{width: 160}}
onChange={event => handleFilterChange('dateFrom', event.target.value)}
/>
<TextField
size='small'
label='Au'
type='date'
value={filters.dateTo}
InputLabelProps={{shrink: true}}
inputProps={{
min: filters.dateFrom || dateRange.min,
max: dateRange.max
}}
sx={{width: 160}}
onChange={event => handleFilterChange('dateTo', event.target.value)}
/>
<FormControl size='small' sx={{minWidth: 120}}>
<InputLabel>Statut</InputLabel>
<Select
value={filters.status}
label='Statut'
onChange={event => handleFilterChange('status', event.target.value)}
>
<MenuItem value=''>Tous les statuts</MenuItem>
<MenuItem value='current'>En cours</MenuItem>
<MenuItem value='archived'>Archivé</MenuItem>
<MenuItem value='outdated'>Obsolète</MenuItem>
</Select>
</FormControl>
{hasActiveFilters && (
<Button
size='small'
variant='outlined'
startIcon={<ClearIcon />}
onClick={clearAllFilters}
>
Effacer filtres
</Button>
)}
</Box>
{/* Active filters display */}
{hasActiveFilters && (
<Box sx={{display: 'flex', gap: 1, flexWrap: 'wrap'}}>
{filters.author && (
<Chip
label={`Auteur: @${filters.author}`}
size='small'
color='primary'
variant='outlined'
onDelete={() => handleFilterChange('author', '')}
/>
)}
{filters.dateFrom && (
<Chip
label={`Du: ${formatDate(filters.dateFrom, 'dd/MM/yyyy')}`}
size='small'
color='primary'
variant='outlined'
onDelete={() => handleFilterChange('dateFrom', '')}
/>
)}
{filters.dateTo && (
<Chip
label={`Au: ${formatDate(filters.dateTo, 'dd/MM/yyyy')}`}
size='small'
color='primary'
variant='outlined'
onDelete={() => handleFilterChange('dateTo', '')}
/>
)}
{filters.status && (
<Chip
label={`Statut: ${(
filters.status === 'current' ? 'En cours'
: (filters.status === 'archived' ? 'Archivé'
: 'Obsolète')
)}`}
size='small'
color='primary'
variant='outlined'
onDelete={() => handleFilterChange('status', '')}
/>
)}
</Box>
)}
</Box>
)
}
VersionFilters.propTypes = {
data: PropTypes.array.isRequired,
onFiltersChange: PropTypes.func.isRequired
}