sight edit page update
This commit is contained in:
parent
0d325a3aa6
commit
a1a2264758
@ -80,7 +80,7 @@ import { KBarProvider, RefineKbar } from "@refinedev/kbar";
|
|||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<LoadingProvider>
|
<LoadingProvider>
|
||||||
<HashRouter>
|
<BrowserRouter>
|
||||||
<ColorModeContextProvider>
|
<ColorModeContextProvider>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<GlobalStyles styles={{ html: { WebkitFontSmoothing: "auto" } }} />
|
<GlobalStyles styles={{ html: { WebkitFontSmoothing: "auto" } }} />
|
||||||
@ -425,7 +425,7 @@ function App() {
|
|||||||
</DevtoolsProvider>
|
</DevtoolsProvider>
|
||||||
</RefineSnackbarProvider>
|
</RefineSnackbarProvider>
|
||||||
</ColorModeContextProvider>
|
</ColorModeContextProvider>
|
||||||
</HashRouter>
|
</BrowserRouter>
|
||||||
</LoadingProvider>
|
</LoadingProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ type LinkedItemsProps<T> = {
|
|||||||
parentResource: string;
|
parentResource: string;
|
||||||
childResource: string;
|
childResource: string;
|
||||||
fields: Field<T>[];
|
fields: Field<T>[];
|
||||||
|
setItemsParent?: (items: T[]) => void;
|
||||||
title: string;
|
title: string;
|
||||||
type: "show" | "edit";
|
type: "show" | "edit";
|
||||||
extraField?: ExtraFieldConfig;
|
extraField?: ExtraFieldConfig;
|
||||||
@ -74,6 +75,7 @@ export const LinkedItems = <T extends { id: number; [key: string]: any }>({
|
|||||||
parentId,
|
parentId,
|
||||||
parentResource,
|
parentResource,
|
||||||
childResource,
|
childResource,
|
||||||
|
setItemsParent,
|
||||||
fields,
|
fields,
|
||||||
title,
|
title,
|
||||||
dragAllowed = false,
|
dragAllowed = false,
|
||||||
@ -135,6 +137,12 @@ export const LinkedItems = <T extends { id: number; [key: string]: any }>({
|
|||||||
}
|
}
|
||||||
}, [childResource, availableItems]);
|
}, [childResource, availableItems]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (setItemsParent) {
|
||||||
|
setItemsParent(linkedItems);
|
||||||
|
}
|
||||||
|
}, [linkedItems, setItemsParent]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// При загрузке linkedItems можно запросить текущие языки для статей
|
// При загрузке linkedItems можно запросить текущие языки для статей
|
||||||
if (childResource === "article" && linkedItems.length > 0) {
|
if (childResource === "article" && linkedItems.length > 0) {
|
||||||
@ -315,9 +323,7 @@ export const LinkedItems = <T extends { id: number; [key: string]: any }>({
|
|||||||
{field.label}
|
{field.label}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
{childResource === "article" && (
|
|
||||||
<TableCell key="language">Язык</TableCell>
|
|
||||||
)}
|
|
||||||
{type === "edit" && (
|
{type === "edit" && (
|
||||||
<TableCell width="120px">Действие</TableCell>
|
<TableCell width="120px">Действие</TableCell>
|
||||||
)}
|
)}
|
||||||
@ -366,96 +372,7 @@ export const LinkedItems = <T extends { id: number; [key: string]: any }>({
|
|||||||
: item[field.data]}
|
: item[field.data]}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
{childResource === "article" && (
|
|
||||||
<TableCell>
|
|
||||||
<Box
|
|
||||||
display="flex"
|
|
||||||
justifyContent="center"
|
|
||||||
alignItems="center"
|
|
||||||
flexDirection="column"
|
|
||||||
gap={1}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
padding: "4px",
|
|
||||||
cursor: "pointer",
|
|
||||||
background:
|
|
||||||
articleLanguages[item.id] === "RU"
|
|
||||||
? theme.palette.primary.main
|
|
||||||
: "transparent",
|
|
||||||
color:
|
|
||||||
articleLanguages[item.id] === "RU"
|
|
||||||
? theme.palette.primary.contrastText
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
border:
|
|
||||||
articleLanguages[item.id] !== "RU"
|
|
||||||
? `1px solid ${theme.palette.primary.main}`
|
|
||||||
: "none",
|
|
||||||
}}
|
|
||||||
onClick={() =>
|
|
||||||
handleArticleLanguageChange(
|
|
||||||
item.id,
|
|
||||||
"RU"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
RU
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
padding: "4px",
|
|
||||||
cursor: "pointer",
|
|
||||||
background:
|
|
||||||
articleLanguages[item.id] === "EN"
|
|
||||||
? theme.palette.primary.main
|
|
||||||
: "transparent",
|
|
||||||
color:
|
|
||||||
articleLanguages[item.id] === "EN"
|
|
||||||
? theme.palette.primary.contrastText
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
border:
|
|
||||||
articleLanguages[item.id] !== "EN"
|
|
||||||
? `1px solid ${theme.palette.primary.main}`
|
|
||||||
: "none",
|
|
||||||
}}
|
|
||||||
onClick={() =>
|
|
||||||
handleArticleLanguageChange(
|
|
||||||
item.id,
|
|
||||||
"EN"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
EN
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
padding: "4px",
|
|
||||||
cursor: "pointer",
|
|
||||||
background:
|
|
||||||
articleLanguages[item.id] === "ZH"
|
|
||||||
? theme.palette.primary.main
|
|
||||||
: "transparent",
|
|
||||||
color:
|
|
||||||
articleLanguages[item.id] === "ZH"
|
|
||||||
? theme.palette.primary.contrastText
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
border:
|
|
||||||
articleLanguages[item.id] !== "ZH"
|
|
||||||
? `1px solid ${theme.palette.primary.main}`
|
|
||||||
: "none",
|
|
||||||
}}
|
|
||||||
onClick={() =>
|
|
||||||
handleArticleLanguageChange(
|
|
||||||
item.id,
|
|
||||||
"ZH"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
ZN
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</TableCell>
|
|
||||||
)}
|
|
||||||
{type === "edit" && (
|
{type === "edit" && (
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Button
|
<Button
|
||||||
|
@ -2,8 +2,8 @@ import { Box, TextField, Typography, Paper } from "@mui/material";
|
|||||||
import { Edit } from "@refinedev/mui";
|
import { Edit } from "@refinedev/mui";
|
||||||
import { useForm } from "@refinedev/react-hook-form";
|
import { useForm } from "@refinedev/react-hook-form";
|
||||||
import { Controller } from "react-hook-form";
|
import { Controller } from "react-hook-form";
|
||||||
import { useLocation, useParams } from "react-router";
|
import { useParams } from "react-router";
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useMemo } from "react";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import { useList } from "@refinedev/core";
|
import { useList } from "@refinedev/core";
|
||||||
|
|
||||||
@ -12,17 +12,13 @@ import { LinkedItems } from "../../components/LinkedItems";
|
|||||||
import { MediaItem, mediaFields } from "./types";
|
import { MediaItem, mediaFields } from "./types";
|
||||||
import { TOKEN_KEY } from "../../authProvider";
|
import { TOKEN_KEY } from "../../authProvider";
|
||||||
import "easymde/dist/easymde.min.css";
|
import "easymde/dist/easymde.min.css";
|
||||||
import Cookies from "js-cookie";
|
import { languageStore } from "../../store/LanguageStore";
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
const MemoizedSimpleMDE = React.memo(MarkdownEditor);
|
const MemoizedSimpleMDE = React.memo(MarkdownEditor);
|
||||||
|
|
||||||
export const ArticleEdit = () => {
|
export const ArticleEdit = observer(() => {
|
||||||
// const [initialLanguage] = useState(Cookies.get("lang")!);
|
const { language, setLanguageAction } = languageStore;
|
||||||
// const { pathname } = useLocation();
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// Cookies.set("lang", initialLanguage);
|
|
||||||
// }, [pathname]);
|
|
||||||
const [language, setLanguage] = useState(Cookies.get("lang") || "ru");
|
|
||||||
const [articleData, setArticleData] = useState<{
|
const [articleData, setArticleData] = useState<{
|
||||||
ru: { heading: string; body: string };
|
ru: { heading: string; body: string };
|
||||||
en: { heading: string; body: string };
|
en: { heading: string; body: string };
|
||||||
@ -35,7 +31,7 @@ export const ArticleEdit = () => {
|
|||||||
const { id: articleId } = useParams<{ id: string }>();
|
const { id: articleId } = useParams<{ id: string }>();
|
||||||
const [preview, setPreview] = useState("");
|
const [preview, setPreview] = useState("");
|
||||||
const [headingPreview, setHeadingPreview] = useState("");
|
const [headingPreview, setHeadingPreview] = useState("");
|
||||||
const simpleMDEOptions = React.useMemo(
|
const simpleMDEOptions = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
placeholder: "Введите контент в формате Markdown...",
|
placeholder: "Введите контент в формате Markdown...",
|
||||||
spellChecker: false,
|
spellChecker: false,
|
||||||
@ -51,7 +47,7 @@ export const ArticleEdit = () => {
|
|||||||
watch,
|
watch,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
setValue,
|
setValue,
|
||||||
} = useForm({
|
} = useForm<{ heading: string; body: string }>({
|
||||||
refineCoreProps: {
|
refineCoreProps: {
|
||||||
meta: {
|
meta: {
|
||||||
headers: {
|
headers: {
|
||||||
@ -61,14 +57,6 @@ export const ArticleEdit = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const lang = Cookies.get("lang")!;
|
|
||||||
Cookies.set("lang", language);
|
|
||||||
return () => {
|
|
||||||
Cookies.set("lang", lang);
|
|
||||||
};
|
|
||||||
}, [language]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setValue(
|
setValue(
|
||||||
"heading",
|
"heading",
|
||||||
@ -88,12 +76,11 @@ export const ArticleEdit = () => {
|
|||||||
setArticleData((prevData) => ({
|
setArticleData((prevData) => ({
|
||||||
...prevData,
|
...prevData,
|
||||||
[language]: {
|
[language]: {
|
||||||
heading: watch("heading") || "",
|
heading: watch("heading") ?? "",
|
||||||
body: watch("body") || "",
|
body: watch("body") ?? "",
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
setLanguage(lang);
|
setLanguageAction(lang);
|
||||||
Cookies.set("lang", lang);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const bodyContent = watch("body");
|
const bodyContent = watch("body");
|
||||||
@ -107,17 +94,16 @@ export const ArticleEdit = () => {
|
|||||||
setHeadingPreview(headingContent || "");
|
setHeadingPreview(headingContent || "");
|
||||||
}, [headingContent]);
|
}, [headingContent]);
|
||||||
|
|
||||||
const onSubmit = (data: { heading: string; body: string }) => {
|
|
||||||
// Здесь вы будете отправлять данные на сервер,
|
|
||||||
// учитывая текущий язык (language)
|
|
||||||
console.log("Данные для сохранения:", data, language);
|
|
||||||
// ... ваша логика сохранения ...
|
|
||||||
};
|
|
||||||
|
|
||||||
const { data: mediaData } = useList<MediaItem>({
|
const { data: mediaData } = useList<MediaItem>({
|
||||||
resource: `article/${articleId}/media`,
|
resource: `article/${articleId}/media`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
setLanguageAction("ru");
|
||||||
|
};
|
||||||
|
}, [setLanguageAction]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Edit saveButtonProps={saveButtonProps}>
|
<Edit saveButtonProps={saveButtonProps}>
|
||||||
<Box sx={{ display: "flex", gap: 2 }}>
|
<Box sx={{ display: "flex", gap: 2 }}>
|
||||||
@ -186,8 +172,8 @@ export const ArticleEdit = () => {
|
|||||||
{...register("heading", {
|
{...register("heading", {
|
||||||
required: "Это поле является обязательным",
|
required: "Это поле является обязательным",
|
||||||
})}
|
})}
|
||||||
error={!!(errors as any)?.heading}
|
error={!!errors?.heading}
|
||||||
helperText={(errors as any)?.heading?.message}
|
helperText={errors?.heading?.message as string}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
fullWidth
|
fullWidth
|
||||||
InputLabelProps={{ shrink: true }}
|
InputLabelProps={{ shrink: true }}
|
||||||
@ -347,4 +333,4 @@ export const ArticleEdit = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Edit>
|
</Edit>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
@ -390,7 +390,7 @@ export const SightCreate = observer(() => {
|
|||||||
renderInput={(params) => (
|
renderInput={(params) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...params}
|
{...params}
|
||||||
label="Выберите обложку"
|
label="Выберите логотип достопримечательности"
|
||||||
margin="normal"
|
margin="normal"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
error={!!errors.thumbnail}
|
error={!!errors.thumbnail}
|
||||||
@ -559,7 +559,7 @@ export const SightCreate = observer(() => {
|
|||||||
renderInput={(params) => (
|
renderInput={(params) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...params}
|
{...params}
|
||||||
label="Cтатья-предпросмотр"
|
label="Медиа-предпросмотр"
|
||||||
margin="normal"
|
margin="normal"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
error={!!errors.preview_article}
|
error={!!errors.preview_article}
|
||||||
@ -661,12 +661,12 @@ export const SightCreate = observer(() => {
|
|||||||
gutterBottom
|
gutterBottom
|
||||||
sx={{ color: "text.secondary" }}
|
sx={{ color: "text.secondary" }}
|
||||||
>
|
>
|
||||||
Обложка:
|
Логотип достопримечательности:
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
component="img"
|
component="img"
|
||||||
src={thumbnailPreview}
|
src={thumbnailPreview}
|
||||||
alt="Обложка"
|
alt="Логотип"
|
||||||
sx={{
|
sx={{
|
||||||
maxWidth: "100%",
|
maxWidth: "100%",
|
||||||
height: "40vh",
|
height: "40vh",
|
||||||
|
@ -104,6 +104,11 @@ export const SightEdit = observer(() => {
|
|||||||
operator: "contains",
|
operator: "contains",
|
||||||
value,
|
value,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: "media_type",
|
||||||
|
operator: "contains",
|
||||||
|
value,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -134,6 +139,7 @@ export const SightEdit = observer(() => {
|
|||||||
latitude: "",
|
latitude: "",
|
||||||
longitude: "",
|
longitude: "",
|
||||||
});
|
});
|
||||||
|
const [selectedArticleIndex, setSelectedArticleIndex] = useState(0);
|
||||||
const [cityPreview, setCityPreview] = useState("");
|
const [cityPreview, setCityPreview] = useState("");
|
||||||
const [thumbnailPreview, setThumbnailPreview] = useState<string | null>(null);
|
const [thumbnailPreview, setThumbnailPreview] = useState<string | null>(null);
|
||||||
const [watermarkLUPreview, setWatermarkLUPreview] = useState<string | null>(
|
const [watermarkLUPreview, setWatermarkLUPreview] = useState<string | null>(
|
||||||
@ -144,9 +150,10 @@ export const SightEdit = observer(() => {
|
|||||||
);
|
);
|
||||||
const [leftArticlePreview, setLeftArticlePreview] = useState("");
|
const [leftArticlePreview, setLeftArticlePreview] = useState("");
|
||||||
const [previewArticlePreview, setPreviewArticlePreview] = useState("");
|
const [previewArticlePreview, setPreviewArticlePreview] = useState("");
|
||||||
|
const [linkedArticles, setLinkedArticles] = useState<ArticleItem[]>([]);
|
||||||
// Следим за изменениями во всех полях
|
// Следим за изменениями во всех полях
|
||||||
const coordinatesContent = watch("coordinates");
|
const selectedArticle = linkedArticles[selectedArticleIndex];
|
||||||
|
|
||||||
const addressContent = watch("address");
|
const addressContent = watch("address");
|
||||||
const nameContent = watch("name");
|
const nameContent = watch("name");
|
||||||
const latitudeContent = watch("latitude");
|
const latitudeContent = watch("latitude");
|
||||||
@ -163,6 +170,12 @@ export const SightEdit = observer(() => {
|
|||||||
setNamePreview(nameContent || "");
|
setNamePreview(nameContent || "");
|
||||||
}, [nameContent]);
|
}, [nameContent]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
setLanguageAction("ru");
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCoordinatesPreview({
|
setCoordinatesPreview({
|
||||||
latitude: latitudeContent || "",
|
latitude: latitudeContent || "",
|
||||||
@ -245,13 +258,22 @@ export const SightEdit = observer(() => {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<CustomTabPanel value={tabValue} index={0}>
|
<CustomTabPanel value={tabValue} index={0}>
|
||||||
<Edit saveButtonProps={saveButtonProps}>
|
<Edit
|
||||||
<Box sx={{ display: "flex", gap: 2 }}>
|
saveButtonProps={saveButtonProps}
|
||||||
|
footerButtonProps={{
|
||||||
|
sx: {
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ display: "flex", gap: 2, position: "relative" }}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
maxWidth: "50%",
|
||||||
gap: 10,
|
gap: 10,
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
}}
|
}}
|
||||||
@ -330,17 +352,7 @@ export const SightEdit = observer(() => {
|
|||||||
label={"Название *"}
|
label={"Название *"}
|
||||||
name="name"
|
name="name"
|
||||||
/>
|
/>
|
||||||
<TextField
|
|
||||||
value={`${coordinatesPreview.latitude}, ${coordinatesPreview.longitude}`}
|
|
||||||
onChange={handleCoordinatesChange}
|
|
||||||
error={!!(errors as any)?.latitude}
|
|
||||||
helperText={(errors as any)?.latitude?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
type="text"
|
|
||||||
label={"Координаты *"}
|
|
||||||
/>
|
|
||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
{...register("longitude", {
|
{...register("longitude", {
|
||||||
@ -469,16 +481,18 @@ export const SightEdit = observer(() => {
|
|||||||
return option.id === value?.id;
|
return option.id === value?.id;
|
||||||
}}
|
}}
|
||||||
filterOptions={(options, { inputValue }) => {
|
filterOptions={(options, { inputValue }) => {
|
||||||
return options.filter((option) =>
|
return options.filter(
|
||||||
option.media_name
|
(option) =>
|
||||||
.toLowerCase()
|
option.media_name
|
||||||
.includes(inputValue.toLowerCase())
|
.toLowerCase()
|
||||||
|
.includes(inputValue.toLowerCase()) &&
|
||||||
|
option.media_type === 3
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
renderInput={(params) => (
|
renderInput={(params) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...params}
|
{...params}
|
||||||
label="Выберите обложку"
|
label="Выберите логотип достопримечательности"
|
||||||
margin="normal"
|
margin="normal"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
error={!!errors.arms}
|
error={!!errors.arms}
|
||||||
@ -490,91 +504,94 @@ export const SightEdit = observer(() => {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Controller
|
<Box sx={{ display: "none" }}>
|
||||||
control={control}
|
<Controller
|
||||||
name="watermark_lu"
|
control={control}
|
||||||
defaultValue={null}
|
name="watermark_lu"
|
||||||
render={({ field }) => (
|
defaultValue={null}
|
||||||
<Autocomplete
|
render={({ field }) => (
|
||||||
{...mediaAutocompleteProps}
|
<Autocomplete
|
||||||
value={
|
{...mediaAutocompleteProps}
|
||||||
mediaAutocompleteProps.options.find(
|
value={
|
||||||
(option) => option.id === field.value
|
mediaAutocompleteProps.options.find(
|
||||||
) || null
|
(option) => option.id === field.value
|
||||||
}
|
) || null
|
||||||
onChange={(_, value) => {
|
}
|
||||||
field.onChange(value?.id || "");
|
onChange={(_, value) => {
|
||||||
}}
|
field.onChange(value?.id || "");
|
||||||
getOptionLabel={(item) => {
|
}}
|
||||||
return item ? item.media_name : "";
|
getOptionLabel={(item) => {
|
||||||
}}
|
return item ? item.media_name : "";
|
||||||
isOptionEqualToValue={(option, value) => {
|
}}
|
||||||
return option.id === value?.id;
|
isOptionEqualToValue={(option, value) => {
|
||||||
}}
|
return option.id === value?.id;
|
||||||
filterOptions={(options, { inputValue }) => {
|
}}
|
||||||
return options.filter((option) =>
|
filterOptions={(options, { inputValue }) => {
|
||||||
option.media_name
|
return options.filter((option) =>
|
||||||
.toLowerCase()
|
option.media_name
|
||||||
.includes(inputValue.toLowerCase())
|
.toLowerCase()
|
||||||
);
|
.includes(inputValue.toLowerCase())
|
||||||
}}
|
);
|
||||||
renderInput={(params) => (
|
}}
|
||||||
<TextField
|
renderInput={(params) => (
|
||||||
{...params}
|
<TextField
|
||||||
label="Выберите водный знак (Левый верх)"
|
{...params}
|
||||||
margin="normal"
|
label="Выберите водный знак (Левый верх)"
|
||||||
variant="outlined"
|
margin="normal"
|
||||||
error={!!errors.arms}
|
variant="outlined"
|
||||||
helperText={(errors as any)?.arms?.message}
|
error={!!errors.arms}
|
||||||
required
|
helperText={(errors as any)?.arms?.message}
|
||||||
/>
|
required
|
||||||
)}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
/>
|
||||||
/>
|
)}
|
||||||
|
/>
|
||||||
<Controller
|
</Box>
|
||||||
control={control}
|
<Box sx={{ display: "none" }}>
|
||||||
name="watermark_rd"
|
<Controller
|
||||||
defaultValue={null}
|
control={control}
|
||||||
render={({ field }) => (
|
name="watermark_rd"
|
||||||
<Autocomplete
|
defaultValue={null}
|
||||||
{...mediaAutocompleteProps}
|
render={({ field }) => (
|
||||||
value={
|
<Autocomplete
|
||||||
mediaAutocompleteProps.options.find(
|
{...mediaAutocompleteProps}
|
||||||
(option) => option.id === field.value
|
value={
|
||||||
) || null
|
mediaAutocompleteProps.options.find(
|
||||||
}
|
(option) => option.id === field.value
|
||||||
onChange={(_, value) => {
|
) || null
|
||||||
field.onChange(value?.id || "");
|
}
|
||||||
}}
|
onChange={(_, value) => {
|
||||||
getOptionLabel={(item) => {
|
field.onChange(value?.id || "");
|
||||||
return item ? item.media_name : "";
|
}}
|
||||||
}}
|
getOptionLabel={(item) => {
|
||||||
isOptionEqualToValue={(option, value) => {
|
return item ? item.media_name : "";
|
||||||
return option.id === value?.id;
|
}}
|
||||||
}}
|
isOptionEqualToValue={(option, value) => {
|
||||||
filterOptions={(options, { inputValue }) => {
|
return option.id === value?.id;
|
||||||
return options.filter((option) =>
|
}}
|
||||||
option.media_name
|
filterOptions={(options, { inputValue }) => {
|
||||||
.toLowerCase()
|
return options.filter((option) =>
|
||||||
.includes(inputValue.toLowerCase())
|
option.media_name
|
||||||
);
|
.toLowerCase()
|
||||||
}}
|
.includes(inputValue.toLowerCase())
|
||||||
renderInput={(params) => (
|
);
|
||||||
<TextField
|
}}
|
||||||
{...params}
|
renderInput={(params) => (
|
||||||
label="Выберите водный знак (Правый вверх)"
|
<TextField
|
||||||
margin="normal"
|
{...params}
|
||||||
variant="outlined"
|
label="Выберите водный знак (Правый вверх)"
|
||||||
error={!!errors.arms}
|
margin="normal"
|
||||||
helperText={(errors as any)?.arms?.message}
|
variant="outlined"
|
||||||
required
|
error={!!errors.arms}
|
||||||
/>
|
helperText={(errors as any)?.arms?.message}
|
||||||
)}
|
required
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
@ -650,7 +667,7 @@ export const SightEdit = observer(() => {
|
|||||||
renderInput={(params) => (
|
renderInput={(params) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...params}
|
{...params}
|
||||||
label="Cтатья-предпросмотр"
|
label="Медиа-предпросмотр"
|
||||||
margin="normal"
|
margin="normal"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
error={!!errors.arms}
|
error={!!errors.arms}
|
||||||
@ -667,11 +684,14 @@ export const SightEdit = observer(() => {
|
|||||||
{/* Блок предпросмотра */}
|
{/* Блок предпросмотра */}
|
||||||
<Paper
|
<Paper
|
||||||
sx={{
|
sx={{
|
||||||
flex: 1,
|
position: "fixed",
|
||||||
p: 2,
|
p: 2,
|
||||||
|
width: "30%",
|
||||||
|
|
||||||
position: "sticky",
|
top: "179px",
|
||||||
top: 16,
|
|
||||||
|
right: 50,
|
||||||
|
zIndex: 1000,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
border: "1px solid",
|
border: "1px solid",
|
||||||
borderColor: "primary.main",
|
borderColor: "primary.main",
|
||||||
@ -686,8 +706,8 @@ export const SightEdit = observer(() => {
|
|||||||
{/* Название достопримечательности */}
|
{/* Название достопримечательности */}
|
||||||
<Typography
|
<Typography
|
||||||
variant="h4"
|
variant="h4"
|
||||||
gutterBottom
|
|
||||||
sx={{
|
sx={{
|
||||||
|
wordWrap: "break-word",
|
||||||
color: (theme) =>
|
color: (theme) =>
|
||||||
theme.palette.mode === "dark" ? "grey.300" : "grey.800",
|
theme.palette.mode === "dark" ? "grey.300" : "grey.800",
|
||||||
mb: 3,
|
mb: 3,
|
||||||
@ -728,22 +748,6 @@ export const SightEdit = observer(() => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{/* Координаты */}
|
|
||||||
<Typography variant="body1" sx={{ mb: 2 }}>
|
|
||||||
<Box component="span" sx={{ color: "text.secondary" }}>
|
|
||||||
Координаты:{" "}
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
component="span"
|
|
||||||
sx={{
|
|
||||||
color: (theme) =>
|
|
||||||
theme.palette.mode === "dark" ? "grey.300" : "grey.800",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{`${coordinatesPreview.latitude}, ${coordinatesPreview.longitude}`}
|
|
||||||
</Box>
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
{/* Обложка */}
|
{/* Обложка */}
|
||||||
{thumbnailPreview && (
|
{thumbnailPreview && (
|
||||||
<Box sx={{ mb: 2 }}>
|
<Box sx={{ mb: 2 }}>
|
||||||
@ -752,12 +756,12 @@ export const SightEdit = observer(() => {
|
|||||||
gutterBottom
|
gutterBottom
|
||||||
sx={{ color: "text.secondary" }}
|
sx={{ color: "text.secondary" }}
|
||||||
>
|
>
|
||||||
Обложка:
|
Логотип достопримечательности:
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
component="img"
|
component="img"
|
||||||
src={thumbnailPreview}
|
src={thumbnailPreview}
|
||||||
alt="Обложка"
|
alt="Логотип"
|
||||||
sx={{
|
sx={{
|
||||||
maxWidth: "100%",
|
maxWidth: "100%",
|
||||||
height: "40vh",
|
height: "40vh",
|
||||||
@ -768,6 +772,282 @@ export const SightEdit = observer(() => {
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Edit>
|
||||||
|
</CustomTabPanel>
|
||||||
|
<CustomTabPanel value={tabValue} index={1}>
|
||||||
|
<Edit
|
||||||
|
saveButtonProps={saveButtonProps}
|
||||||
|
footerButtonProps={{
|
||||||
|
sx: {
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
maxWidth: "50%",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: 2,
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
component="form"
|
||||||
|
sx={{ flex: 1, 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"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<LinkedItems<ArticleItem>
|
||||||
|
type="edit"
|
||||||
|
parentId={sightId!}
|
||||||
|
setItemsParent={setLinkedArticles}
|
||||||
|
parentResource="sight"
|
||||||
|
fields={articleFields}
|
||||||
|
childResource="article"
|
||||||
|
title="статьи"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CreateSightArticle
|
||||||
|
parentId={sightId!}
|
||||||
|
parentResource="sight"
|
||||||
|
childResource="article"
|
||||||
|
title="статью"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Edit>
|
||||||
|
<Paper
|
||||||
|
sx={{
|
||||||
|
position: "fixed",
|
||||||
|
p: 2,
|
||||||
|
|
||||||
|
width: "30%",
|
||||||
|
|
||||||
|
top: "178px",
|
||||||
|
|
||||||
|
right: 50,
|
||||||
|
zIndex: 1000,
|
||||||
|
borderRadius: 2,
|
||||||
|
border: "1px solid",
|
||||||
|
borderColor: "primary.main",
|
||||||
|
bgcolor: (theme) =>
|
||||||
|
theme.palette.mode === "dark" ? "background.paper" : "#fff",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="h6" gutterBottom color="primary">
|
||||||
|
Предпросмотр
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
{/* Водяные знаки */}
|
||||||
|
<Box sx={{ mb: 2 }}>
|
||||||
|
<Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
|
||||||
|
{selectedArticle && (
|
||||||
|
<Typography
|
||||||
|
variant="h4"
|
||||||
|
gutterBottom
|
||||||
|
sx={{ color: "text.primary" }}
|
||||||
|
>
|
||||||
|
{selectedArticle.heading}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{selectedArticle && (
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
gutterBottom
|
||||||
|
sx={{ color: "text.primary" }}
|
||||||
|
>
|
||||||
|
{selectedArticle.body}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
{/* Координаты */}
|
||||||
|
<Box sx={{ display: "flex", gap: 1, mt: 2 }}>
|
||||||
|
{linkedArticles.map((article, index) => (
|
||||||
|
<Box
|
||||||
|
key={article.id}
|
||||||
|
onClick={() => setSelectedArticleIndex(index)}
|
||||||
|
sx={{
|
||||||
|
cursor: "pointer",
|
||||||
|
bgcolor:
|
||||||
|
selectedArticleIndex === index
|
||||||
|
? "primary.main"
|
||||||
|
: "transparent",
|
||||||
|
color: selectedArticleIndex === index ? "white" : "inherit",
|
||||||
|
p: 1,
|
||||||
|
borderRadius: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="body1" gutterBottom>
|
||||||
|
{article.heading}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Paper>
|
||||||
|
</CustomTabPanel>
|
||||||
|
<CustomTabPanel value={tabValue} index={2}>
|
||||||
|
<Edit
|
||||||
|
saveButtonProps={saveButtonProps}
|
||||||
|
footerButtonProps={{
|
||||||
|
sx: {
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
maxWidth: "50%",
|
||||||
|
display: "flex",
|
||||||
|
gap: 2,
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
component="form"
|
||||||
|
sx={{ flex: 1, display: "flex", flexDirection: "column" }}
|
||||||
|
autoComplete="off"
|
||||||
|
>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="watermark_lu"
|
||||||
|
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.arms}
|
||||||
|
helperText={(errors as any)?.arms?.message}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="watermark_rd"
|
||||||
|
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.arms}
|
||||||
|
helperText={(errors as any)?.arms?.message}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
value={`${coordinatesPreview.latitude}, ${coordinatesPreview.longitude}`}
|
||||||
|
onChange={handleCoordinatesChange}
|
||||||
|
error={!!(errors as any)?.latitude}
|
||||||
|
helperText={(errors as any)?.latitude?.message}
|
||||||
|
margin="normal"
|
||||||
|
fullWidth
|
||||||
|
InputLabelProps={{ shrink: true }}
|
||||||
|
type="text"
|
||||||
|
label={"Координаты *"}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Paper
|
||||||
|
sx={{
|
||||||
|
position: "fixed",
|
||||||
|
p: 2,
|
||||||
|
|
||||||
|
width: "30%",
|
||||||
|
|
||||||
|
top: "178px",
|
||||||
|
|
||||||
|
right: 50,
|
||||||
|
zIndex: 1000,
|
||||||
|
borderRadius: 2,
|
||||||
|
border: "1px solid",
|
||||||
|
borderColor: "primary.main",
|
||||||
|
bgcolor: (theme) =>
|
||||||
|
theme.palette.mode === "dark" ? "background.paper" : "#fff",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="h6" gutterBottom color="primary">
|
||||||
|
Предпросмотр
|
||||||
|
</Typography>
|
||||||
|
|
||||||
{/* Водяные знаки */}
|
{/* Водяные знаки */}
|
||||||
<Box sx={{ mb: 2 }}>
|
<Box sx={{ mb: 2 }}>
|
||||||
@ -828,87 +1108,29 @@ export const SightEdit = observer(() => {
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
{/* Координаты */}
|
||||||
|
<Typography
|
||||||
{/* Связанные статьи */}
|
variant="body1"
|
||||||
<Box>
|
sx={{ display: "flex", flexDirection: "column", mb: 2 }}
|
||||||
{/* <Typography variant="body1" gutterBottom sx={{color: 'text.secondary'}}>
|
>
|
||||||
Связанные статьи:
|
<Box component="span" sx={{ color: "text.secondary" }}>
|
||||||
</Typography> */}
|
Координаты:{" "}
|
||||||
{leftArticlePreview && (
|
</Box>
|
||||||
<Typography variant="body1" gutterBottom>
|
<Box
|
||||||
<Box component="span" sx={{ color: "text.secondary" }}>
|
component="span"
|
||||||
Левая статья:{" "}
|
sx={{
|
||||||
</Box>
|
color: (theme) =>
|
||||||
<Box
|
theme.palette.mode === "dark" ? "grey.300" : "grey.800",
|
||||||
component={Link}
|
}}
|
||||||
to={`/article/show/${watch("left_article")}`}
|
>
|
||||||
sx={{
|
{`${coordinatesPreview.latitude}, ${coordinatesPreview.longitude}`}
|
||||||
color: (theme) =>
|
</Box>
|
||||||
theme.palette.mode === "dark"
|
</Typography>
|
||||||
? "grey.300"
|
|
||||||
: "grey.800",
|
|
||||||
textDecoration: "none",
|
|
||||||
"&:hover": {
|
|
||||||
textDecoration: "underline",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{leftArticlePreview}
|
|
||||||
</Box>
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
{previewArticlePreview && (
|
|
||||||
<Typography variant="body1" gutterBottom>
|
|
||||||
<Box component="span" sx={{ color: "text.secondary" }}>
|
|
||||||
Статья-предпросмотр:{" "}
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
component={Link}
|
|
||||||
to={`/article/show/${watch("preview_article")}`}
|
|
||||||
sx={{
|
|
||||||
color: (theme) =>
|
|
||||||
theme.palette.mode === "dark"
|
|
||||||
? "grey.300"
|
|
||||||
: "grey.800",
|
|
||||||
textDecoration: "none",
|
|
||||||
"&:hover": {
|
|
||||||
textDecoration: "underline",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{previewArticlePreview}
|
|
||||||
</Box>
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ mt: 3 }}>
|
|
||||||
<LinkedItems<ArticleItem>
|
|
||||||
type="edit"
|
|
||||||
parentId={sightId!}
|
|
||||||
parentResource="sight"
|
|
||||||
childResource="article"
|
|
||||||
fields={articleFields}
|
|
||||||
title="статьи"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<CreateSightArticle
|
|
||||||
parentId={sightId!}
|
|
||||||
parentResource="sight"
|
|
||||||
childResource="article"
|
|
||||||
title="статью"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Edit>
|
</Edit>
|
||||||
</CustomTabPanel>
|
</CustomTabPanel>
|
||||||
<CustomTabPanel value={tabValue} index={1}>
|
|
||||||
1
|
|
||||||
</CustomTabPanel>
|
|
||||||
<CustomTabPanel value={tabValue} index={2}>
|
|
||||||
2
|
|
||||||
</CustomTabPanel>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -195,58 +195,6 @@ export const StationEdit = () => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextField
|
|
||||||
{...register("offset_x", {
|
|
||||||
// required: 'Это поле является обязательным',
|
|
||||||
})}
|
|
||||||
error={!!(errors as any)?.offset_x}
|
|
||||||
helperText={(errors as any)?.offset_x?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
type="number"
|
|
||||||
label={"Смещение (X)"}
|
|
||||||
name="offset_x"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
{...register("offset_y", {
|
|
||||||
// required: 'Это поле является обязательным',
|
|
||||||
})}
|
|
||||||
error={!!(errors as any)?.offset_y}
|
|
||||||
helperText={(errors as any)?.offset_y?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
type="number"
|
|
||||||
label={"Смещение (Y)"}
|
|
||||||
name="offset_y"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Группа полей пересадок */}
|
|
||||||
<Paper sx={{ p: 2, mt: 2 }}>
|
|
||||||
<Typography variant="h6" gutterBottom>
|
|
||||||
Пересадки
|
|
||||||
</Typography>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
{TRANSFER_FIELDS.map((field) => (
|
|
||||||
<Grid item xs={12} sm={6} md={4} key={field.name}>
|
|
||||||
<TextField
|
|
||||||
{...register(`transfers.${field.name}`)}
|
|
||||||
error={!!(errors as any)?.transfers?.[field.name]}
|
|
||||||
helperText={(errors as any)?.transfers?.[field.name]?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
type="text"
|
|
||||||
label={field.label}
|
|
||||||
name={`transfers.${field.name}`}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
</Paper>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{stationId && (
|
{stationId && (
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
ShowButton,
|
ShowButton,
|
||||||
useDataGrid,
|
useDataGrid,
|
||||||
} from "@refinedev/mui";
|
} from "@refinedev/mui";
|
||||||
import { Stack } from "@mui/material";
|
import { Stack, Typography } from "@mui/material";
|
||||||
import { CustomDataGrid } from "../../components/CustomDataGrid";
|
import { CustomDataGrid } from "../../components/CustomDataGrid";
|
||||||
import { localeText } from "../../locales/ru/localeText";
|
import { localeText } from "../../locales/ru/localeText";
|
||||||
import { cityStore } from "../../store/CityStore";
|
import { cityStore } from "../../store/CityStore";
|
||||||
@ -58,6 +58,19 @@ export const StationList = observer(() => {
|
|||||||
align: "left",
|
align: "left",
|
||||||
headerAlign: "left",
|
headerAlign: "left",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: "direction",
|
||||||
|
headerName: "Направление",
|
||||||
|
type: "boolean",
|
||||||
|
minWidth: 200,
|
||||||
|
display: "flex",
|
||||||
|
|
||||||
|
renderCell: ({ value }) => (
|
||||||
|
<Typography style={{ color: value ? "#48989f" : "#7f6b58" }}>
|
||||||
|
{value ? "прямой" : "обратный"}
|
||||||
|
</Typography>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: "latitude",
|
field: "latitude",
|
||||||
headerName: "Широта",
|
headerName: "Широта",
|
||||||
|
@ -29,6 +29,7 @@ export const stationFields: Array<FieldType<StationItem>> = [
|
|||||||
// {label: 'ID', data: 'id'},
|
// {label: 'ID', data: 'id'},
|
||||||
{ label: "Название", data: "name" },
|
{ label: "Название", data: "name" },
|
||||||
{ label: "Системное название", data: "system_name" },
|
{ label: "Системное название", data: "system_name" },
|
||||||
|
// { label: "Направление", data: "direction" },
|
||||||
{ label: "Адрес", data: "address" },
|
{ label: "Адрес", data: "address" },
|
||||||
// {label: 'Широта', data: 'latitude'},
|
// {label: 'Широта', data: 'latitude'},
|
||||||
// {label: 'Долгота', data: 'longitude'},
|
// {label: 'Долгота', data: 'longitude'},
|
||||||
|
@ -17,7 +17,7 @@ axiosInstance.interceptors.request.use((config) => {
|
|||||||
|
|
||||||
// Добавляем язык в кастомный заголовок
|
// Добавляем язык в кастомный заголовок
|
||||||
|
|
||||||
config.headers["X-Language"] = "ru";
|
config.headers["X-Language"] = languageStore.language;
|
||||||
|
|
||||||
console.log("Request headers:", config.headers);
|
console.log("Request headers:", config.headers);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { makeAutoObservable } from "mobx";
|
import { makeAutoObservable } from "mobx";
|
||||||
|
|
||||||
class CityStore {
|
class CityStore {
|
||||||
city_id: string = "";
|
city_id: string = "0";
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
@ -9,7 +9,12 @@ class CityStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
this.city_id = localStorage.getItem("city_id") ?? "";
|
const id = localStorage.getItem("city_id");
|
||||||
|
if (id) {
|
||||||
|
this.city_id = id;
|
||||||
|
} else {
|
||||||
|
this.city_id = "0";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCityIdAction = (city_id: string) => {
|
setCityIdAction = (city_id: string) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user