WhiteNightsAdminPanel/src/pages/route/create.tsx
2025-04-06 18:59:20 +03:00

218 lines
7.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {Autocomplete, Box, TextField, FormControlLabel, Checkbox, Typography} from '@mui/material'
import {Create, useAutocomplete} from '@refinedev/mui'
import {useForm} from '@refinedev/react-hook-form'
import {Controller} from 'react-hook-form'
export const RouteCreate = () => {
const {
saveButtonProps,
refineCore: {formLoading},
register,
control,
formState: {errors},
} = useForm({
refineCoreProps: {
resource: 'route/',
},
})
const {autocompleteProps: carrierAutocompleteProps} = useAutocomplete({
resource: 'carrier',
onSearch: (value) => [
{
field: 'short_name',
operator: 'contains',
value,
},
],
})
return (
<Create isLoading={formLoading} saveButtonProps={saveButtonProps}>
<Box component="form" sx={{display: 'flex', flexDirection: 'column'}} autoComplete="off">
<Controller
control={control}
name="carrier_id"
rules={{required: 'Это поле является обязательным'}}
defaultValue={null}
render={({field}) => (
<Autocomplete
{...carrierAutocompleteProps}
value={carrierAutocompleteProps.options.find((option) => option.id === field.value) || null}
onChange={(_, value) => {
field.onChange(value?.id || '')
}}
getOptionLabel={(item) => {
return item ? item.short_name : ''
}}
isOptionEqualToValue={(option, value) => {
return option.id === value?.id
}}
filterOptions={(options, {inputValue}) => {
return options.filter((option) => option.short_name.toLowerCase().includes(inputValue.toLowerCase()))
}}
renderInput={(params) => <TextField {...params} label="Выберите перевозчика" margin="normal" variant="outlined" error={!!errors.carrier_id} helperText={(errors as any)?.carrier_id?.message} required />}
/>
)}
/>
<TextField
{...register('route_number', {
required: 'Это поле является обязательным',
setValueAs: (value) => String(value),
})}
error={!!(errors as any)?.route_number}
helperText={(errors as any)?.route_number?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
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>
<TextField
{...register('path', {
required: 'Это поле является обязательным',
setValueAs: (value: string) => {
try {
// Парсим строку в массив массивов
return JSON.parse(value)
} catch {
return []
}
},
validate: (value: unknown) => {
if (!Array.isArray(value)) return 'Неверный формат'
if (!value.every((point: unknown) => Array.isArray(point) && point.length === 2)) {
return 'Каждая точка должна быть массивом из двух координат'
}
if (!value.every((point: unknown[]) => point.every((coord: unknown) => !isNaN(Number(coord)) && typeof coord === 'number'))) {
return 'Координаты должны быть числами'
}
return true
},
})}
error={!!(errors as any)?.path}
helperText={(errors as any)?.path?.message} // 'Формат: [[lat1,lon1], [lat2,lon2], ...]'
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
label={'Координаты маршрута *'}
name="path"
placeholder="[[1.1, 2.2], [2.1, 4.5]]"
/>
<TextField
{...register('route_sys_number', {
required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.route_sys_number}
helperText={(errors as any)?.route_sys_number?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="number"
label={'Системный номер маршрута *'}
name="route_sys_number"
/>
<TextField
{...register('governor_appeal', {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.governor_appeal}
helperText={(errors as any)?.governor_appeal?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="number"
label={'Обращение губернатора'}
name="governor_appeal"
/>
<TextField
{...register('scale_min', {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.scale_min}
helperText={(errors as any)?.scale_min?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="number"
label={'Масштаб (мин)'}
name="scale_min"
/>
<TextField
{...register('scale_max', {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.scale_max}
helperText={(errors as any)?.scale_max?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="number"
label={'Масштаб (макс)'}
name="scale_max"
/>
<TextField
{...register('rotate', {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.rotate}
helperText={(errors as any)?.rotate?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="number"
label={'Поворот'}
name="rotate"
/>
<TextField
{...register('center_latitude', {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.center_latitude}
helperText={(errors as any)?.center_latitude?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="number"
label={'Центр. широта'}
name="center_latitude"
/>
<TextField
{...register('center_longitude', {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.center_longitude}
helperText={(errors as any)?.center_longitude?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="number"
label={'Центр. долгота'}
name="center_longitude"
/>
</Box>
</Create>
)
}