mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-09-24 16:39:31 +02:00
Refactor UserTypeFilter component to use Chips for selection and update user type filtering logic
This commit is contained in:
@@ -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
|
|
||||||
value={selectedUserTypes}
|
|
||||||
onChange={handleChange}
|
|
||||||
input={<OutlinedInput label={label} />}
|
|
||||||
renderValue={(selected) => (
|
|
||||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
|
|
||||||
{selected.map((value) => (
|
|
||||||
<Chip
|
<Chip
|
||||||
key={value}
|
key={userType}
|
||||||
label={value}
|
label={userType}
|
||||||
size="small"
|
color={selectedUserTypes.includes(userType) ? 'primary' : 'default'}
|
||||||
sx={{
|
onClick={() => {
|
||||||
backgroundColor: theme.palette.primary.main,
|
const isSelected = selectedUserTypes.includes(userType);
|
||||||
color: 'white',
|
const newUserTypes = isSelected
|
||||||
'& .MuiChip-deleteIcon': {
|
? selectedUserTypes.filter((ut) => ut !== userType)
|
||||||
color: 'white'
|
: [...selectedUserTypes, userType];
|
||||||
}
|
onUserTypesChange(newUserTypes);
|
||||||
}}
|
}}
|
||||||
|
sx={{ cursor: 'pointer' }}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
|
||||||
>
|
|
||||||
{userTypes.map((userType) => (
|
|
||||||
<MenuItem key={userType} value={userType}>
|
|
||||||
{userType}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -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>
|
||||||
);
|
);
|
||||||
|
@@ -8,7 +8,6 @@ export type UserType =
|
|||||||
| 'General Users'
|
| 'General Users'
|
||||||
| 'Developers'
|
| 'Developers'
|
||||||
| 'Designers'
|
| 'Designers'
|
||||||
| 'Students'
|
|
||||||
| 'CyberSec';
|
| 'CyberSec';
|
||||||
|
|
||||||
export interface ToolMeta {
|
export interface ToolMeta {
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user