import { Autocomplete, Box, TextField, Paper, Typography, Tab, Tabs, } from "@mui/material"; import { Edit, useAutocomplete } from "@refinedev/mui"; import { useForm } from "@refinedev/react-hook-form"; import { Controller } from "react-hook-form"; import { useParams, Link } from "react-router"; import React, { useState, useEffect } from "react"; import { LinkedItems } from "../../components/LinkedItems"; import { CreateSightArticle } from "../../components/CreateSightArticle"; import { ArticleItem, articleFields } from "./types"; import { TOKEN_KEY } from "../../authProvider"; import { observer } from "mobx-react-lite"; import { languageStore } from "../../store/LanguageStore"; function a11yProps(index: number) { return { id: `simple-tab-${index}`, "aria-controls": `simple-tabpanel-${index}`, }; } interface TabPanelProps { children?: React.ReactNode; index: number; value: number; } function CustomTabPanel(props: TabPanelProps) { const { children, value, index, ...other } = props; return ( ); } export const SightEdit = observer(() => { const { id: sightId } = useParams<{ id: string }>(); const { language, setLanguageAction } = languageStore; const { saveButtonProps, register, control, watch, getValues, setValue, formState: { errors }, } = useForm({ refineCoreProps: { meta: { headers: { "Accept-Language": language, }, }, }, }); const { autocompleteProps: cityAutocompleteProps } = useAutocomplete({ resource: "city", onSearch: (value) => [ { field: "name", operator: "contains", value, }, ], }); const [tabValue, setTabValue] = useState(0); const { autocompleteProps: mediaAutocompleteProps } = useAutocomplete({ resource: "media", onSearch: (value) => [ { field: "media_name", operator: "contains", value, }, ], }); const { autocompleteProps: articleAutocompleteProps } = useAutocomplete({ resource: "article", queryOptions: { queryKey: ["article", language], }, onSearch: (value) => [ { field: "heading", operator: "contains", value, }, ], }); useEffect(() => { const latitude = getValues("latitude"); const longitude = getValues("longitude"); if (latitude && longitude) { setCoordinatesPreview({ latitude: latitude, longitude: longitude, }); } }, [getValues]); const handleCoordinatesChange = (e: React.ChangeEvent) => { const [lat, lon] = e.target.value.split(",").map((s) => s.trim()); setCoordinatesPreview({ latitude: lat, longitude: lon, }); setValue("latitude", lat); setValue("longitude", lon); }; // Состояния для предпросмотра const [namePreview, setNamePreview] = useState(""); const [coordinatesPreview, setCoordinatesPreview] = useState({ latitude: "", longitude: "", }); const [cityPreview, setCityPreview] = useState(""); const [thumbnailPreview, setThumbnailPreview] = useState(null); const [watermarkLUPreview, setWatermarkLUPreview] = useState( null ); const [watermarkRDPreview, setWatermarkRDPreview] = useState( null ); const [leftArticlePreview, setLeftArticlePreview] = useState(""); const [previewArticlePreview, setPreviewArticlePreview] = useState(""); // Следим за изменениями во всех полях const coordinatesContent = watch("coordinates"); const addressContent = watch("address"); const nameContent = watch("name"); const latitudeContent = watch("latitude"); const longitudeContent = watch("longitude"); const cityContent = watch("city_id"); const thumbnailContent = watch("thumbnail"); const watermarkLUContent = watch("watermark_lu"); const watermarkRDContent = watch("watermark_rd"); const leftArticleContent = watch("left_article"); const previewArticleContent = watch("preview_article"); // Обновляем состояния при изменении полей useEffect(() => { setNamePreview(nameContent || ""); }, [nameContent]); useEffect(() => { setCoordinatesPreview({ latitude: latitudeContent || "", longitude: longitudeContent || "", }); }, [latitudeContent, longitudeContent]); useEffect(() => { const selectedCity = cityAutocompleteProps.options.find( (option) => option.id === cityContent ); setCityPreview(selectedCity?.name || ""); }, [cityContent, cityAutocompleteProps.options]); useEffect(() => { const selectedThumbnail = mediaAutocompleteProps.options.find( (option) => option.id === thumbnailContent ); setThumbnailPreview( selectedThumbnail ? `${import.meta.env.VITE_KRBL_MEDIA}${ selectedThumbnail.id }/download?token=${localStorage.getItem(TOKEN_KEY)}` : null ); }, [thumbnailContent, mediaAutocompleteProps.options]); useEffect(() => { const selectedWatermarkLU = mediaAutocompleteProps.options.find( (option) => option.id === watermarkLUContent ); setWatermarkLUPreview( selectedWatermarkLU ? `${import.meta.env.VITE_KRBL_MEDIA}${ selectedWatermarkLU.id }/download?token=${localStorage.getItem(TOKEN_KEY)}` : null ); }, [watermarkLUContent, mediaAutocompleteProps.options]); useEffect(() => { const selectedWatermarkRD = mediaAutocompleteProps.options.find( (option) => option.id === watermarkRDContent ); setWatermarkRDPreview( selectedWatermarkRD ? `${import.meta.env.VITE_KRBL_MEDIA}${ selectedWatermarkRD.id }/download?token=${localStorage.getItem(TOKEN_KEY)}` : null ); }, [watermarkRDContent, mediaAutocompleteProps.options]); useEffect(() => { const selectedLeftArticle = articleAutocompleteProps.options.find( (option) => option.id === leftArticleContent ); setLeftArticlePreview(selectedLeftArticle?.heading || ""); }, [leftArticleContent, articleAutocompleteProps.options]); useEffect(() => { const selectedPreviewArticle = articleAutocompleteProps.options.find( (option) => option.id === previewArticleContent ); setPreviewArticlePreview(selectedPreviewArticle?.heading || ""); }, [previewArticleContent, articleAutocompleteProps.options]); return ( setTabValue(newValue)} aria-label="basic tabs example" > {/* Language Selection */} setLanguageAction("ru")} > RU setLanguageAction("en")} > EN setLanguageAction("zh")} > ZH {/* Форма редактирования */} {/* */} {/* */} ( 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) => ( )} /> )} /> ( 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) => ( )} /> )} /> ( 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) => ( )} /> )} /> ( 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) => ( )} /> )} /> ( option.id === field.value ) || null } onChange={(_, value) => { field.onChange(value?.id || ""); }} getOptionLabel={(item) => { return item ? item.heading : ""; }} isOptionEqualToValue={(option, value) => { return option.id === value?.id; }} filterOptions={(options, { inputValue }) => { return options.filter((option) => option.heading .toLowerCase() .includes(inputValue.toLowerCase()) ); }} renderInput={(params) => ( )} /> )} /> ( option.id === field.value ) || null } onChange={(_, value) => { field.onChange(value?.id || ""); }} getOptionLabel={(item) => { return item ? item.heading : ""; }} isOptionEqualToValue={(option, value) => { return option.id === value?.id; }} filterOptions={(options, { inputValue }) => { return options.filter((option) => option.heading .toLowerCase() .includes(inputValue.toLowerCase()) ); }} renderInput={(params) => ( )} /> )} /> {/* Блок предпросмотра */} theme.palette.mode === "dark" ? "background.paper" : "#fff", }} > Предпросмотр {/* Название достопримечательности */} theme.palette.mode === "dark" ? "grey.300" : "grey.800", mb: 3, }} > {namePreview} {/* Город */} Город:{" "} theme.palette.mode === "dark" ? "grey.300" : "grey.800", }} > {cityPreview} {/* Адрес */} Адрес:{" "} theme.palette.mode === "dark" ? "grey.300" : "grey.800", }} > {addressContent} {/* Координаты */} Координаты:{" "} theme.palette.mode === "dark" ? "grey.300" : "grey.800", }} > {`${coordinatesPreview.latitude}, ${coordinatesPreview.longitude}`} {/* Обложка */} {thumbnailPreview && ( Обложка: )} {/* Водяные знаки */} Водяные знаки: {watermarkLUPreview && ( Левый верхний: )} {watermarkRDPreview && ( Правый верхний: )} {/* Связанные статьи */} {/* Связанные статьи: */} {leftArticlePreview && ( Левая статья:{" "} theme.palette.mode === "dark" ? "grey.300" : "grey.800", textDecoration: "none", "&:hover": { textDecoration: "underline", }, }} > {leftArticlePreview} )} {previewArticlePreview && ( Статья-предпросмотр:{" "} theme.palette.mode === "dark" ? "grey.300" : "grey.800", textDecoration: "none", "&:hover": { textDecoration: "underline", }, }} > {previewArticlePreview} )} type="edit" parentId={sightId!} parentResource="sight" childResource="article" fields={articleFields} title="статьи" /> 1 2 ); });