feat: Add translation on 3 languages for sight page
This commit is contained in:
@@ -14,79 +14,44 @@ import {
|
||||
ReactMarkdownEditor,
|
||||
} from "@widgets";
|
||||
import { Unlink, Trash2, ImagePlus } from "lucide-react";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useState, useCallback } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
|
||||
export const LeftWidgetTab = observer(
|
||||
({ value, index }: { value: number; index: number }) => {
|
||||
const { sightInfo, updateSightInfo, loadSightInfo } = editSightStore;
|
||||
const { articleLoading, getArticleByArticleId } = articlesStore;
|
||||
const { language } = languageStore;
|
||||
const { sight, updateSightInfo } = editSightStore;
|
||||
const { getArticleByArticleId } = articlesStore;
|
||||
|
||||
const linkedArticle = getArticleByArticleId.get(); // Получаем связанную статью
|
||||
const data = sightInfo[languageStore.language]; // Получаем данные для текущего языка
|
||||
|
||||
useEffect(() => {
|
||||
// Этот useEffect должен загружать данные ИЗ СВЯЗАННОЙ СТАТЬИ
|
||||
// ТОЛЬКО ЕСЛИ данные для ТЕКУЩЕГО ЯЗЫКА еще не были загружены
|
||||
// или если sightInfo.left_article изменился (т.е. привязали новую статью).
|
||||
|
||||
// Мы также должны учитывать, что linkedArticle может измениться (т.е. новую статью привязали)
|
||||
// или language изменился.
|
||||
// Если для текущего языка данные еще не "загружены" (`loaded: false`),
|
||||
// тогда мы берем их из `linkedArticle` и инициализируем.
|
||||
console.log("data.left.loaded", data.left.loaded);
|
||||
if (!data.left.loaded) {
|
||||
// <--- КЛЮЧЕВОЕ УСЛОВИЕ
|
||||
if (linkedArticle && !articleLoading) {
|
||||
console.log("loadSightInfo", linkedArticle, language);
|
||||
loadSightInfo(
|
||||
languageStore.language,
|
||||
linkedArticle.heading,
|
||||
linkedArticle.body || "",
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
// Зависимости: linkedArticle (для реакции на изменение привязанной статьи),
|
||||
// languageStore.language (для реакции на изменение языка),
|
||||
// loadSightInfo (чтобы useEffect знал об изменениях в функции),
|
||||
// data.left.loaded (чтобы useEffect перепроверил условие, когда этот флаг изменится).
|
||||
// Важно: если data.left.loaded становится true, то этот эффект не будет
|
||||
// перезапускаться для того же языка.
|
||||
}, [
|
||||
linkedArticle?.heading,
|
||||
language,
|
||||
loadSightInfo,
|
||||
data.left.loaded,
|
||||
articleLoading,
|
||||
]);
|
||||
const data = sight[languageStore.language]; // Получаем данные для текущего языка
|
||||
|
||||
const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
|
||||
useState(false);
|
||||
|
||||
const handleOpenMediaDialog = useCallback(() => {
|
||||
setIsSelectMediaDialogOpen(true);
|
||||
}, []);
|
||||
|
||||
const handleMediaSelected = useCallback(
|
||||
(selectedMedia: any) => {
|
||||
// При выборе медиа, обновляем данные для ТЕКУЩЕГО ЯЗЫКА
|
||||
// сохраняя текущие heading и body.
|
||||
updateSightInfo(
|
||||
languageStore.language,
|
||||
data.left.heading,
|
||||
data.left.body,
|
||||
selectedMedia
|
||||
);
|
||||
setIsSelectMediaDialogOpen(false);
|
||||
},
|
||||
[
|
||||
const handleMediaSelected = useCallback(() => {
|
||||
// При выборе медиа, обновляем данные для ТЕКУЩЕГО ЯЗЫКА
|
||||
// сохраняя текущие heading и body.
|
||||
updateSightInfo(
|
||||
languageStore.language,
|
||||
data.left.heading,
|
||||
data.left.body,
|
||||
updateSightInfo,
|
||||
]
|
||||
);
|
||||
{
|
||||
left: {
|
||||
heading: data.left.heading,
|
||||
body: data.left.body,
|
||||
},
|
||||
},
|
||||
false
|
||||
);
|
||||
setIsSelectMediaDialogOpen(false);
|
||||
}, [
|
||||
languageStore.language,
|
||||
{
|
||||
left: {
|
||||
heading: data.left.heading,
|
||||
body: data.left.body,
|
||||
},
|
||||
},
|
||||
false,
|
||||
]);
|
||||
|
||||
const handleCloseMediaDialog = useCallback(() => {
|
||||
setIsSelectMediaDialogOpen(false);
|
||||
@@ -150,13 +115,17 @@ export const LeftWidgetTab = observer(
|
||||
>
|
||||
<TextField
|
||||
label="Название информации"
|
||||
value={data.left.heading}
|
||||
value={data?.left?.heading}
|
||||
onChange={(e) =>
|
||||
updateSightInfo(
|
||||
languageStore.language,
|
||||
e.target.value,
|
||||
data.left.body,
|
||||
data.left.media
|
||||
{
|
||||
left: {
|
||||
heading: e.target.value,
|
||||
body: data.left.body,
|
||||
},
|
||||
},
|
||||
false
|
||||
)
|
||||
}
|
||||
variant="outlined"
|
||||
@@ -164,19 +133,23 @@ export const LeftWidgetTab = observer(
|
||||
/>
|
||||
|
||||
<ReactMarkdownEditor
|
||||
value={data.left.body}
|
||||
value={data?.left?.body}
|
||||
onChange={(value) =>
|
||||
updateSightInfo(
|
||||
languageStore.language,
|
||||
data.left.heading,
|
||||
value,
|
||||
data.left.media
|
||||
{
|
||||
left: {
|
||||
heading: data.left.heading,
|
||||
body: value,
|
||||
},
|
||||
},
|
||||
false
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
{/* Блок МЕДИА для статьи */}
|
||||
<Paper elevation={1} sx={{ padding: 2, mt: 1 }}>
|
||||
{/* <Paper elevation={1} sx={{ padding: 2, mt: 1 }}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
МЕДИА
|
||||
</Typography>
|
||||
@@ -226,16 +199,21 @@ export const LeftWidgetTab = observer(
|
||||
onClick={() =>
|
||||
updateSightInfo(
|
||||
languageStore.language,
|
||||
data.left.heading,
|
||||
data.left.body,
|
||||
null
|
||||
{
|
||||
left: {
|
||||
heading: data.left.heading,
|
||||
body: data.left.body,
|
||||
media: null,
|
||||
},
|
||||
},
|
||||
false
|
||||
)
|
||||
}
|
||||
>
|
||||
Удалить медиа
|
||||
</Button>
|
||||
)}
|
||||
</Paper>
|
||||
</Paper> */}
|
||||
</Box>
|
||||
|
||||
{/* Правая колонка: Предпросмотр */}
|
||||
@@ -247,7 +225,6 @@ export const LeftWidgetTab = observer(
|
||||
gap: 1.5,
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6">Предпросмотр</Typography>
|
||||
<Paper
|
||||
elevation={3}
|
||||
sx={{
|
||||
@@ -263,8 +240,7 @@ export const LeftWidgetTab = observer(
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
{/* Медиа в превью (если есть) */}
|
||||
{data.left.media ? (
|
||||
{/* {data.left.media?.filename ? (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
@@ -276,7 +252,7 @@ export const LeftWidgetTab = observer(
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={data.left.media.filename}
|
||||
src={data.left.media?.filename ?? ""}
|
||||
alt="Превью медиа"
|
||||
style={{
|
||||
objectFit: "cover",
|
||||
@@ -286,19 +262,21 @@ export const LeftWidgetTab = observer(
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: 200,
|
||||
backgroundColor: "grey.300",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<ImagePlus size={48} color="grey" />
|
||||
</Box>
|
||||
)}
|
||||
|
||||
)} */}
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: 200,
|
||||
backgroundColor: "grey.300",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<ImagePlus size={48} color="grey" />
|
||||
</Box>
|
||||
|
||||
{/* Заголовок в превью */}
|
||||
<Box
|
||||
@@ -313,7 +291,7 @@ export const LeftWidgetTab = observer(
|
||||
component="h2"
|
||||
sx={{ wordBreak: "break-word" }}
|
||||
>
|
||||
{data.left.heading || "Название информации"}
|
||||
{data?.left?.heading || "Название информации"}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
@@ -324,7 +302,7 @@ export const LeftWidgetTab = observer(
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<ReactMarkdownComponent value={data.left.body} />
|
||||
<ReactMarkdownComponent value={data?.left?.body} />
|
||||
</Box>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user