WhiteNightsAdminPanel/src/pages/carrier/create.tsx
Alexander Lazarenko cf2a116ecb
All checks were successful
release-tag / release-image (push) Successful in 2m17s
Latest version (#12)
Co-authored-by: itoshi <kkzemeow@gmail.com>
Co-authored-by: Spynder <19329095+Spynder@users.noreply.github.com>
Reviewed-on: #12
Co-authored-by: Alexander Lazarenko <kerblif@unprism.ru>
Co-committed-by: Alexander Lazarenko <kerblif@unprism.ru>
2025-05-29 10:12:00 +00:00

292 lines
9.1 KiB
TypeScript

import { Autocomplete, Box, TextField } from "@mui/material";
import { Create, useAutocomplete } from "@refinedev/mui";
import { useForm } from "@refinedev/react-hook-form";
import { Controller } from "react-hook-form";
import { observer } from "mobx-react-lite";
import { META_LANGUAGE } from "../../store/LanguageStore";
import { LanguageSwitch } from "@/components/LanguageSwitch";
import { useEffect, useState } from "react";
import { EVERY_LANGUAGE, Languages, languageStore } from "@stores";
export const CarrierCreate = observer(() => {
const { language, setLanguageAction } = languageStore;
const {
saveButtonProps,
refineCore: { formLoading },
register,
control,
setValue,
watch,
formState: { errors },
} = useForm({
refineCoreProps: META_LANGUAGE(language),
});
const [carrierData, setCarrierData] = useState({
full_name: EVERY_LANGUAGE(""),
short_name: EVERY_LANGUAGE(""),
slogan: EVERY_LANGUAGE(""),
});
useEffect(() => {
setValue("full_name", carrierData.full_name[language]);
setValue("short_name", carrierData.short_name[language]);
setValue("slogan", carrierData.slogan[language]);
}, [carrierData, language, setValue]);
function updateTranslations(update: boolean = true) {
const newCarrierData = {
...carrierData,
full_name: {
...carrierData.full_name,
[language]: watch("full_name") ?? "",
},
short_name: {
...carrierData.short_name,
[language]: watch("short_name") ?? "",
},
slogan: {
...carrierData.slogan,
[language]: watch("slogan") ?? "",
},
};
if (update) setCarrierData(newCarrierData);
return newCarrierData;
}
const handleLanguageChange = (lang: Languages) => {
updateTranslations();
setLanguageAction(lang);
};
const { autocompleteProps: cityAutocompleteProps } = useAutocomplete({
resource: "city",
onSearch: (value) => [
{
field: "name",
operator: "contains",
value,
},
],
});
const { autocompleteProps: mediaAutocompleteProps } = useAutocomplete({
resource: "media",
onSearch: (value) => [
{
field: "media_name",
operator: "contains",
value,
},
],
});
return (
<Create isLoading={formLoading} saveButtonProps={saveButtonProps}>
<Box
component="form"
sx={{ display: "flex", flexDirection: "column" }}
autoComplete="off"
>
<LanguageSwitch action={handleLanguageChange} />
<Controller
control={control}
name="city_id"
rules={{ required: "Это поле является обязательным" }}
defaultValue={null}
render={({ field }) => (
<Autocomplete
{...cityAutocompleteProps}
value={
cityAutocompleteProps.options.find(
(option) => option.id === field.value
) ?? null
}
onChange={(_, value) => {
field.onChange(value?.id ?? "");
}}
getOptionLabel={(item) => {
return item ? item.name : "";
}}
isOptionEqualToValue={(option, value) => {
return option.id === value?.id;
}}
filterOptions={(options, { inputValue }) => {
return options.filter((option) =>
option.name.toLowerCase().includes(inputValue.toLowerCase())
);
}}
renderInput={(params) => (
<TextField
{...params}
label="Выберите город"
margin="normal"
variant="outlined"
error={!!errors.city_id}
helperText={(errors as any)?.city_id?.message}
required
/>
)}
/>
)}
/>
<TextField
{...register("full_name", {
required: "Это поле является обязательным",
})}
error={!!(errors as any)?.full_name}
helperText={(errors as any)?.full_name?.message}
margin="normal"
fullWidth
slotProps={{ inputLabel: { shrink: true } }}
type="text"
label={"Полное имя *"}
name="full_name"
/>
<TextField
{...register("short_name", {
//required: "Это поле является обязательным",
})}
error={!!(errors as any)?.short_name}
helperText={(errors as any)?.short_name?.message}
margin="normal"
fullWidth
slotProps={{ inputLabel: { shrink: true } }}
type="text"
label={"Короткое имя"}
name="short_name"
/>
<Box component="form" sx={{ display: "flex" }} autoComplete="off">
<TextField
{...register("main_color", {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.main_color}
helperText={(errors as any)?.main_color?.message}
margin="normal"
fullWidth
slotProps={{ inputLabel: { shrink: true } }}
type="color"
label={"Основной цвет"}
name="main_color"
sx={{
"& input": {
height: "50px",
paddingBlock: "14px",
paddingInline: "14px",
cursor: "pointer",
},
}}
/>
<TextField
{...register("left_color", {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.left_color}
helperText={(errors as any)?.left_color?.message}
margin="normal"
fullWidth
slotProps={{ inputLabel: { shrink: true } }}
type="color"
label={"Цвет левого виджета"}
name="left_color"
sx={{
marginLeft: "16px",
marginRight: "16px",
"& input": {
height: "50px",
paddingBlock: "14px",
paddingInline: "14px",
cursor: "pointer",
},
}}
/>
<TextField
{...register("right_color", {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.right_color}
helperText={(errors as any)?.right_color?.message}
margin="normal"
fullWidth
slotProps={{ inputLabel: { shrink: true } }}
type="color"
label={"Цвет правого виджета"}
name="right_color"
sx={{
"& input": {
height: "50px",
paddingBlock: "14px",
paddingInline: "14px",
cursor: "pointer",
},
}}
/>
</Box>
<TextField
{...register("slogan", {
// required: 'Это поле является обязательным',
})}
error={!!(errors as any)?.slogan}
helperText={(errors as any)?.slogan?.message}
margin="normal"
fullWidth
slotProps={{ inputLabel: { shrink: true } }}
type="text"
label={"Слоган"}
name="slogan"
/>
<Controller
control={control}
name="logo"
// rules={{required: 'Это поле является обязательным'}}
defaultValue={null}
render={({ field }) => (
<Autocomplete
{...mediaAutocompleteProps}
value={
mediaAutocompleteProps.options.find(
(option) => option.id === field.value
) ?? null
}
onChange={(_, value) => {
field.onChange(value?.id ?? "");
}}
getOptionLabel={(item) => {
return item ? item.media_name : "";
}}
isOptionEqualToValue={(option, value) => {
return option.id === value?.id;
}}
filterOptions={(options, { inputValue }) => {
return options.filter((option) =>
option.media_name
.toLowerCase()
.includes(inputValue.toLowerCase())
);
}}
renderInput={(params) => (
<TextField
{...params}
label="Выберите логотип"
margin="normal"
variant="outlined"
error={!!errors.logo}
helperText={(errors as any)?.logo?.message}
/>
)}
/>
)}
/>
</Box>
</Create>
);
});