feat: Add translation on 3 languages for sight page

This commit is contained in:
2025-06-01 00:34:59 +03:00
parent 0d9bbb140f
commit 87386c6a73
22 changed files with 768 additions and 732 deletions

View File

@@ -1,15 +1,16 @@
// @shared/stores/editSightStore.ts
import { Language } from "@shared";
import { makeAutoObservable } from "mobx";
import { authInstance, Language } from "@shared";
import { makeAutoObservable, runInAction } from "mobx";
export interface MediaObject {
id: string;
filename: string;
media_type: number;
}
type SightBaseInfo = {
export type SightLanguageInfo = {
id: number;
name: string;
address: string;
left: { heading: string; body: string };
right: { heading: string; body: string }[];
};
export type SightCommonInfo = {
city_id: number;
city: string;
latitude: number;
@@ -22,103 +23,14 @@ type SightBaseInfo = {
video_preview: string;
};
export interface RightArticleBlock {
id: string;
type: "article" | "preview_media";
name: string;
linkedArticleId?: string;
heading: string;
body: string;
media: MediaObject | null;
}
type SightInfo = SightBaseInfo & {
[key in Language]: {
info: {
name: string;
address: string;
};
left: {
loaded: boolean; // Означает, что данные для этого языка были инициализированы/загружены
heading: string;
body: string;
media: MediaObject | null;
};
right: RightArticleBlock[];
};
export type SightBaseInfo = {
common: SightCommonInfo;
} & {
[key in Language]: SightLanguageInfo;
};
class EditSightStore {
sightInfo: SightInfo = {
id: 0,
city_id: 0,
city: "",
latitude: 0,
longitude: 0,
thumbnail: "",
watermark_lu: "",
watermark_rd: "",
left_article: 0,
preview_media: "",
video_preview: "",
ru: {
info: { name: "", address: "" },
left: { loaded: false, heading: "", body: "", media: null },
right: [],
},
en: {
info: { name: "", address: "" },
left: { loaded: false, heading: "", body: "", media: null },
right: [],
},
zh: {
info: { name: "", address: "" },
left: { loaded: false, heading: "", body: "", media: null },
right: [],
},
};
constructor() {
makeAutoObservable(this);
}
// loadSightInfo: Используется для первоначальной загрузки данных для ЯЗЫКА.
// Она устанавливает loaded: true, чтобы в будущем не перезатирать данные.
loadSightInfo = (
language: Language,
heading: string,
body: string,
media: MediaObject | null
) => {
// Важно: если данные уже были загружены или изменены, не перезаписывайте их.
// Это предотвращает потерю пользовательского ввода при переключении языков.
// Если хотите принудительную загрузку, добавьте другой метод или параметр.
if (!this.sightInfo[language].left.loaded) {
// <--- Только если еще не загружено
this.sightInfo[language].left.heading = heading;
this.sightInfo[language].left.body = body;
this.sightInfo[language].left.media = media;
this.sightInfo[language].left.loaded = true; // <--- Устанавливаем loaded только при загрузке
}
};
// updateSightInfo: Используется для сохранения ЛЮБЫХ пользовательских изменений.
// Она НЕ должна влиять на флаг 'loaded', который управляется 'loadSightInfo'.
updateSightInfo = (
language: Language,
heading: string,
body: string,
media: MediaObject | null
) => {
this.sightInfo[language].left.heading = heading;
this.sightInfo[language].left.body = body;
this.sightInfo[language].left.media = media;
// this.sightInfo[language].left.loaded = true; // <-- УДАЛИТЕ эту строку
};
clearSightInfo = () => {
this.sightInfo = {
id: 0,
sight: SightBaseInfo = {
common: {
city_id: 0,
city: "",
latitude: 0,
@@ -129,23 +41,123 @@ class EditSightStore {
left_article: 0,
preview_media: "",
video_preview: "",
},
ru: {
id: 0,
name: "",
address: "",
left: { heading: "", body: "" },
right: [],
},
en: {
id: 0,
name: "",
address: "",
left: { heading: "", body: "" },
right: [],
},
zh: {
id: 0,
name: "",
address: "",
left: { heading: "", body: "" },
right: [],
},
};
constructor() {
makeAutoObservable(this);
}
hasLoadedCommon = false;
getSightInfo = async (id: number, language: Language) => {
if (this.sight[language].id === id) {
return;
}
const response = await authInstance.get(`/sight/${id}`);
const data = response.data;
runInAction(() => {
// Обновляем языковую часть
this.sight[language] = {
...this.sight[language],
...data,
};
// Только при первом запросе обновляем общую часть
if (!this.hasLoadedCommon) {
this.sight.common = {
...this.sight.common,
...data,
};
this.hasLoadedCommon = true;
}
});
};
updateLeftInfo = (language: Language, heading: string, body: string) => {
this.sight[language].left.heading = heading;
this.sight[language].left.body = body;
};
clearSightInfo = () => {
this.sight = {
common: {
city_id: 0,
city: "",
latitude: 0,
longitude: 0,
thumbnail: "",
watermark_lu: "",
watermark_rd: "",
left_article: 0,
preview_media: "",
video_preview: "",
},
ru: {
info: { name: "", address: "" },
left: { loaded: false, heading: "", body: "", media: null },
id: 0,
name: "",
address: "",
left: { heading: "", body: "" },
right: [],
},
en: {
info: { name: "", address: "" },
left: { loaded: false, heading: "", body: "", media: null },
id: 0,
name: "",
address: "",
left: { heading: "", body: "" },
right: [],
},
zh: {
info: { name: "", address: "" },
left: { loaded: false, heading: "", body: "", media: null },
id: 0,
name: "",
address: "",
left: { heading: "", body: "" },
right: [],
},
};
};
updateSightInfo = (
language: Language,
content: Partial<SightLanguageInfo | SightCommonInfo>,
common: boolean = false
) => {
if (common) {
this.sight.common = {
...this.sight.common,
...content,
};
} else {
this.sight[language] = {
...this.sight[language],
...content,
};
}
};
}
export const editSightStore = new EditSightStore();