232 lines
6.3 KiB
TypeScript
232 lines
6.3 KiB
TypeScript
import {
|
|
Box,
|
|
TextField,
|
|
Button,
|
|
Typography,
|
|
Autocomplete,
|
|
} from "@mui/material";
|
|
import { Edit } from "@refinedev/mui";
|
|
import { useForm } from "@refinedev/react-hook-form";
|
|
import { useEffect } from "react";
|
|
import { useShow } from "@refinedev/core";
|
|
import { Controller } from "react-hook-form";
|
|
|
|
import { TOKEN_KEY } from "@providers";
|
|
import { MEDIA_TYPES } from "@lib";
|
|
import {
|
|
ALLOWED_IMAGE_TYPES,
|
|
ALLOWED_VIDEO_TYPES,
|
|
ALLOWED_ICON_TYPES,
|
|
ALLOWED_WATERMARK_TYPES,
|
|
ALLOWED_PANORAMA_TYPES,
|
|
ALLOWED_3D_MODEL_TYPES,
|
|
useMediaFileUpload,
|
|
} from "../../components/media/MediaFormUtils";
|
|
import { languageStore, META_LANGUAGE } from "@stores";
|
|
import { observer } from "mobx-react-lite";
|
|
import { LanguageSelector, MediaData, MediaView } from "@ui";
|
|
|
|
type MediaFormValues = {
|
|
media_name: string;
|
|
media_type: number;
|
|
file?: File;
|
|
};
|
|
|
|
export const MediaEdit = observer(() => {
|
|
const { language } = languageStore;
|
|
const {
|
|
saveButtonProps,
|
|
refineCore: { onFinish },
|
|
register,
|
|
formState: { errors },
|
|
setValue,
|
|
handleSubmit,
|
|
watch,
|
|
setError,
|
|
clearErrors,
|
|
control,
|
|
} = useForm<MediaFormValues>({
|
|
defaultValues: {
|
|
media_name: "",
|
|
media_type: "",
|
|
file: undefined,
|
|
},
|
|
refineCoreProps: META_LANGUAGE(language)
|
|
});
|
|
|
|
const { query } = useShow();
|
|
const { data } = query;
|
|
const record = data?.data;
|
|
|
|
const selectedMediaType = watch("media_type");
|
|
|
|
const {
|
|
selectedFile,
|
|
previewUrl,
|
|
setPreviewUrl,
|
|
handleFileChange,
|
|
handleMediaTypeChange,
|
|
} = useMediaFileUpload({
|
|
selectedMediaType,
|
|
setError,
|
|
clearErrors,
|
|
setValue,
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (record?.id) {
|
|
setPreviewUrl(
|
|
`${import.meta.env.VITE_KRBL_MEDIA}${
|
|
record.id
|
|
}/download?token=${localStorage.getItem(TOKEN_KEY)}`
|
|
);
|
|
setValue("media_name", record?.media_name || "");
|
|
setValue("media_type", record?.media_type);
|
|
}
|
|
}, [record, setValue, setPreviewUrl]);
|
|
|
|
return (
|
|
<Edit
|
|
saveButtonProps={{
|
|
...saveButtonProps,
|
|
disabled: !!errors.file,
|
|
onClick: handleSubmit((data) => {
|
|
const formData = {
|
|
media_name: data.media_name,
|
|
filename: selectedFile?.name || record?.filename,
|
|
type: Number(data.media_type),
|
|
};
|
|
onFinish(formData);
|
|
}),
|
|
}}
|
|
>
|
|
<Box
|
|
component="form"
|
|
sx={{ display: "flex", flexDirection: "column" }}
|
|
autoComplete="off"
|
|
>
|
|
<LanguageSelector />
|
|
<Controller
|
|
control={control}
|
|
name="media_type"
|
|
rules={{
|
|
required: "Это поле является обязательным",
|
|
}}
|
|
defaultValue={null}
|
|
render={({ field }) => (
|
|
<Autocomplete
|
|
options={MEDIA_TYPES}
|
|
value={
|
|
MEDIA_TYPES.find((option) => option.value === field.value) ||
|
|
null
|
|
}
|
|
onChange={(_, value) => {
|
|
field.onChange(value?.value || null);
|
|
handleMediaTypeChange(value?.value || null);
|
|
}}
|
|
getOptionLabel={(item) => {
|
|
return item ? item.label : "";
|
|
}}
|
|
isOptionEqualToValue={(option, value) => {
|
|
return option.value === value?.value;
|
|
}}
|
|
renderInput={(params) => (
|
|
<TextField
|
|
{...params}
|
|
label="Тип"
|
|
margin="normal"
|
|
variant="outlined"
|
|
error={!!errors.media_type}
|
|
helperText={(errors as any)?.media_type?.message}
|
|
required
|
|
/>
|
|
)}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<TextField
|
|
{...register("media_name", {
|
|
required: "Это поле является обязательным",
|
|
})}
|
|
error={!!(errors as any)?.media_name}
|
|
helperText={(errors as any)?.media_name?.message}
|
|
margin="normal"
|
|
fullWidth
|
|
slotProps={{inputLabel: {shrink: true}}}
|
|
type="text"
|
|
label="Название *"
|
|
name="media_name"
|
|
/>
|
|
|
|
<Box
|
|
display="flex"
|
|
flexDirection="column-reverse"
|
|
alignItems="center"
|
|
gap={4}
|
|
style={{ marginTop: 10 }}
|
|
>
|
|
<Box
|
|
display="flex"
|
|
flexDirection="column"
|
|
alignItems="center"
|
|
gap={2}
|
|
>
|
|
<Button
|
|
variant="contained"
|
|
component="label"
|
|
disabled={!selectedMediaType}
|
|
>
|
|
{selectedFile ? "Изменить файл" : "Загрузить файл"}
|
|
<input
|
|
type="file"
|
|
hidden
|
|
onChange={handleFileChange}
|
|
accept={
|
|
selectedMediaType === 1
|
|
? ALLOWED_IMAGE_TYPES.join(",")
|
|
: selectedMediaType === 2
|
|
? ALLOWED_VIDEO_TYPES.join(",")
|
|
: selectedMediaType === 3
|
|
? ALLOWED_ICON_TYPES.join(",")
|
|
: selectedMediaType === 4
|
|
? ALLOWED_WATERMARK_TYPES.join(",")
|
|
: selectedMediaType === 5
|
|
? ALLOWED_PANORAMA_TYPES.join(",")
|
|
: selectedMediaType === 6
|
|
? ALLOWED_3D_MODEL_TYPES.join(",")
|
|
: ""
|
|
}
|
|
/>
|
|
</Button>
|
|
|
|
{selectedFile && (
|
|
<Typography variant="body2" color="text.secondary">
|
|
{selectedFile.name}
|
|
</Typography>
|
|
)}
|
|
|
|
{errors.file && (
|
|
<Typography variant="caption" color="error">
|
|
{(errors as any)?.file?.message}
|
|
</Typography>
|
|
)}
|
|
</Box>
|
|
|
|
|
|
<MediaView media={record as MediaData} />
|
|
{/* {previewUrl && selectedMediaType === 1 && (
|
|
<Box mt={2} display="flex" justifyContent="center">
|
|
<img
|
|
src={previewUrl}
|
|
alt="Preview"
|
|
style={{ maxWidth: "200px", borderRadius: 8 }}
|
|
/>
|
|
</Box>
|
|
)} */}
|
|
</Box>
|
|
</Box>
|
|
</Edit>
|
|
);
|
|
});
|