init /user route only for admin user

This commit is contained in:
maxim
2025-03-28 03:54:15 +03:00
parent 3eb56a27ae
commit b4afcdfa3b
11 changed files with 338 additions and 6 deletions

View File

@ -70,13 +70,13 @@ export const RouteCreate = () => {
label={'Номер маршрута *'}
name="route_number"
/>
<Controller
name="route_direction" // boolean
control={control}
defaultValue={false}
render={({field}: {field: any}) => <FormControlLabel label="Прямой маршрут? *" control={<Checkbox {...field} checked={field.value} onChange={(e) => field.onChange(e.target.checked)} />} />}
/>
<Typography variant="caption" color="textSecondary" sx={{mt: 0, mb: 1}}>
(Прямой / Обратный)
</Typography>

68
src/pages/user/create.tsx Normal file
View File

@ -0,0 +1,68 @@
import {Box, TextField, FormControlLabel, Checkbox} from '@mui/material'
import {Create} from '@refinedev/mui'
import {useForm} from '@refinedev/react-hook-form'
import {Controller} from 'react-hook-form'
export const UserCreate = () => {
const {
saveButtonProps,
refineCore: {formLoading},
register,
control,
formState: {errors},
} = useForm({})
return (
<Create isLoading={formLoading} saveButtonProps={saveButtonProps}>
<Box component="form" sx={{display: 'flex', flexDirection: 'column'}} autoComplete="off">
<TextField
{...register('name', {
required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.name}
helperText={(errors as any)?.name?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
label={'Имя *'}
name="name"
/>
<TextField
{...register('email', {
required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.email}
helperText={(errors as any)?.email?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="email"
label={'Электронная почта *'}
name="email"
/>
<TextField
{...register('password', {
required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.password}
helperText={(errors as any)?.password?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
label={'Пароль *'}
name="password"
/>
<Controller
name="is_admin" // boolean
control={control}
defaultValue={false}
render={({field}: {field: any}) => <FormControlLabel label="Администратор *" control={<Checkbox {...field} checked={field.value} onChange={(e) => field.onChange(e.target.checked)} />} />}
/>
</Box>
</Create>
)
}

67
src/pages/user/edit.tsx Normal file
View File

@ -0,0 +1,67 @@
import {Box, TextField, FormControlLabel, Checkbox} from '@mui/material'
import {Edit} from '@refinedev/mui'
import {useForm} from '@refinedev/react-hook-form'
import {Controller} from 'react-hook-form'
export const UserEdit = () => {
const {
saveButtonProps,
register,
control,
formState: {errors},
} = useForm({})
return (
<Edit saveButtonProps={saveButtonProps}>
<Box component="form" sx={{display: 'flex', flexDirection: 'column'}} autoComplete="off">
<TextField
{...register('name', {
required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.name}
helperText={(errors as any)?.name?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
label={'Имя *'}
name="name"
/>
<TextField
{...register('email', {
required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.email}
helperText={(errors as any)?.email?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="email"
label={'Электронная почта *'}
name="email"
/>
<TextField
{...register('password', {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.password}
helperText={(errors as any)?.password?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
label={'Пароль *'}
name="password"
/>
<Controller
name="is_admin" // boolean
control={control}
defaultValue={false}
render={({field}: {field: any}) => <FormControlLabel label="Администратор *" control={<Checkbox {...field} checked={field.value} onChange={(e) => field.onChange(e.target.checked)} />} />}
/>
</Box>
</Edit>
)
}

4
src/pages/user/index.tsx Normal file
View File

@ -0,0 +1,4 @@
export * from './create'
export * from './edit'
export * from './list'
export * from './show'

77
src/pages/user/list.tsx Normal file
View File

@ -0,0 +1,77 @@
import React from 'react'
import {type GridColDef} from '@mui/x-data-grid'
import {DeleteButton, EditButton, List, ShowButton, useDataGrid} from '@refinedev/mui'
import {CustomDataGrid} from '../../components/CustomDataGrid'
import {localeText} from '../../locales/ru/localeText'
import {Typography} from '@mui/material'
export const UserList = () => {
const {dataGridProps} = useDataGrid({})
const columns = React.useMemo<GridColDef[]>(
() => [
{
field: 'id',
headerName: 'ID',
type: 'number',
minWidth: 50,
align: 'left',
headerAlign: 'left',
},
{
field: 'name',
headerName: 'Имя',
type: 'string',
minWidth: 250,
align: 'left',
headerAlign: 'left',
},
{
field: 'email',
headerName: 'Email',
type: 'string',
minWidth: 250,
align: 'left',
headerAlign: 'left',
},
{
field: 'is_admin',
headerName: 'Роль',
type: 'boolean',
align: 'left',
headerAlign: 'left',
minWidth: 150,
flex: 1,
// renderCell: ({value}) => <Chip label={value ? 'Да' : 'Нет'} color={value ? 'primary' : 'default'} size="small" />,
renderCell: ({value}) => <Typography style={{color: value ? '#48989f' : '#7f6b58'}}>{value ? 'администратор' : 'пользователь'}</Typography>,
},
{
field: 'actions',
headerName: 'Действия',
minWidth: 120,
display: 'flex',
align: 'right',
headerAlign: 'center',
sortable: false,
filterable: false,
disableColumnMenu: true,
renderCell: function render({row}) {
return (
<>
<EditButton hideText recordItemId={row.id} />
<ShowButton hideText recordItemId={row.id} />
<DeleteButton hideText confirmTitle="Вы уверены?" recordItemId={row.id} />
</>
)
},
},
],
[],
)
return (
<List>
<CustomDataGrid {...dataGridProps} columns={columns} localeText={localeText} getRowId={(row: any) => row.id} />
</List>
)
}

34
src/pages/user/show.tsx Normal file
View File

@ -0,0 +1,34 @@
import {Stack, Typography} from '@mui/material'
import {useShow} from '@refinedev/core'
import {Show, TextFieldComponent as TextField} from '@refinedev/mui'
export const UserShow = () => {
const {query} = useShow({})
const {data, isLoading} = query
const record = data?.data
const fields = [
{label: 'Имя', data: 'name'},
{label: 'Электронная почта', data: 'email'},
{
label: 'Администратор',
data: 'is_admin',
render: (value: number[][]) => <Typography style={{color: value ? '#48989f' : '#7f6b58'}}>{value ? 'администратор' : 'пользователь'}</Typography>,
},
]
return (
<Show isLoading={isLoading}>
<Stack gap={4}>
{fields.map(({label, data, render}) => (
<Stack key={data} gap={1}>
<Typography variant="body1" fontWeight="bold">
{label}
</Typography>
{render ? render(record?.[data]) : <TextField value={record?.[data]} />}
</Stack>
))}
</Stack>
</Show>
)
}