Refactor UserTypeFilter component to use Chips for selection and update user type filtering logic

This commit is contained in:
AshAnand34
2025-07-21 21:22:05 -07:00
parent b29845c2d3
commit 1cae1c9fda
4 changed files with 38 additions and 60 deletions

View File

@@ -1,23 +1,11 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { import { Box, Chip, Typography } from '@mui/material';
Box,
Chip,
FormControl,
InputLabel,
MenuItem,
OutlinedInput,
Select,
SelectChangeEvent,
Typography,
useTheme
} from '@mui/material';
import { UserType } from '@tools/defineTool'; import { UserType } from '@tools/defineTool';
const userTypes: UserType[] = [ const userTypes: UserType[] = [
'General Users', 'General Users',
'Developers', 'Developers',
'Designers', 'Designers',
'Students',
'CyberSec' 'CyberSec'
]; ];
@@ -32,54 +20,28 @@ export default function UserTypeFilter({
onUserTypesChange, onUserTypesChange,
label = 'Filter by User Type' label = 'Filter by User Type'
}: UserTypeFilterProps) { }: UserTypeFilterProps) {
const theme = useTheme();
const handleChange = (event: SelectChangeEvent<UserType[]>) => {
const {
target: { value }
} = event;
const newUserTypes =
typeof value === 'string' ? (value.split(',') as UserType[]) : value;
onUserTypesChange(newUserTypes);
};
return ( return (
<Box sx={{ minWidth: 200 }}> <Box sx={{ minWidth: 200 }}>
<FormControl fullWidth> <Typography variant="subtitle2" sx={{ mb: 1 }}>
<InputLabel id="user-type-filter-label">{label}</InputLabel> {label}
<Select </Typography>
labelId="user-type-filter-label" <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
id="user-type-filter" {userTypes.map((userType) => (
multiple <Chip
value={selectedUserTypes} key={userType}
onChange={handleChange} label={userType}
input={<OutlinedInput label={label} />} color={selectedUserTypes.includes(userType) ? 'primary' : 'default'}
renderValue={(selected) => ( onClick={() => {
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}> const isSelected = selectedUserTypes.includes(userType);
{selected.map((value) => ( const newUserTypes = isSelected
<Chip ? selectedUserTypes.filter((ut) => ut !== userType)
key={value} : [...selectedUserTypes, userType];
label={value} onUserTypesChange(newUserTypes);
size="small" }}
sx={{ sx={{ cursor: 'pointer' }}
backgroundColor: theme.palette.primary.main, />
color: 'white', ))}
'& .MuiChip-deleteIcon': { </Box>
color: 'white'
}
}}
/>
))}
</Box>
)}
>
{userTypes.map((userType) => (
<MenuItem key={userType} value={userType}>
{userType}
</MenuItem>
))}
</Select>
</FormControl>
</Box> </Box>
); );
} }

View File

@@ -2,9 +2,17 @@ import { Box, useTheme } from '@mui/material';
import Hero from 'components/Hero'; import Hero from 'components/Hero';
import Categories from './Categories'; import Categories from './Categories';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import UserTypeFilter, { useUserTypeFilter } from 'components/UserTypeFilter';
import { UserType } from '@tools/defineTool';
export default function Home() { export default function Home() {
const theme = useTheme(); const theme = useTheme();
const { selectedUserTypes, setSelectedUserTypes } = useUserTypeFilter();
const handleUserTypesChange = (userTypes: UserType[]) => {
setSelectedUserTypes(userTypes);
};
return ( return (
<Box <Box
padding={{ padding={{
@@ -28,6 +36,11 @@ export default function Home() {
> >
<Helmet title={'OmniTools'} /> <Helmet title={'OmniTools'} />
<Hero /> <Hero />
<UserTypeFilter
selectedUserTypes={selectedUserTypes}
onUserTypesChange={handleUserTypesChange}
label="Filter by User Type"
/>
<Categories /> <Categories />
</Box> </Box>
); );

View File

@@ -8,7 +8,6 @@ export type UserType =
| 'General Users' | 'General Users'
| 'Developers' | 'Developers'
| 'Designers' | 'Designers'
| 'Students'
| 'CyberSec'; | 'CyberSec';
export interface ToolMeta { export interface ToolMeta {

View File

@@ -145,6 +145,10 @@ export const filterToolsByUserTypes = (
if (userTypes.length === 0) return tools; if (userTypes.length === 0) return tools;
return tools.filter((tool) => { return tools.filter((tool) => {
// Always treat xml tools as dev-only
if (tool.type === 'xml') {
return userTypes.includes('Developers');
}
// If tool has no userTypes defined, show it to all users // If tool has no userTypes defined, show it to all users
if (!tool.userTypes || tool.userTypes.length === 0) return true; if (!tool.userTypes || tool.userTypes.length === 0) return true;