fix: Language cache sight
This commit is contained in:
@ -1,36 +1,78 @@
|
||||
import { authInstance } from "@shared";
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
import { authInstance, editSightStore, Language, languageStore } from "@shared";
|
||||
import { computed, makeAutoObservable, runInAction } from "mobx";
|
||||
|
||||
export type Article = {
|
||||
id: string;
|
||||
id: number;
|
||||
heading: string;
|
||||
body: string;
|
||||
service_name: string;
|
||||
};
|
||||
|
||||
type Media = {
|
||||
id: string;
|
||||
filename: string;
|
||||
media_name: string;
|
||||
media_type: number;
|
||||
};
|
||||
|
||||
class ArticlesStore {
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
articles: Article[] = [];
|
||||
articles: { [key in Language]: Article[] } = {
|
||||
ru: [],
|
||||
en: [],
|
||||
zh: [],
|
||||
};
|
||||
articleData: Article | null = null;
|
||||
articleMedia: Media | null = null;
|
||||
articleLoading: boolean = false;
|
||||
|
||||
getArticles = async () => {
|
||||
getArticles = async (language: Language) => {
|
||||
this.articleLoading = true;
|
||||
const response = await authInstance.get("/article");
|
||||
|
||||
runInAction(() => {
|
||||
this.articles = response.data;
|
||||
this.articles[language] = response.data;
|
||||
});
|
||||
this.articleLoading = false;
|
||||
};
|
||||
|
||||
getArticle = async (id: string) => {
|
||||
getArticle = async (id: number) => {
|
||||
this.articleLoading = true;
|
||||
const response = await authInstance.get(`/article/${id}`);
|
||||
|
||||
runInAction(() => {
|
||||
this.articleData = response.data;
|
||||
});
|
||||
this.articleLoading = false;
|
||||
};
|
||||
|
||||
getSightArticles = async (id: number) => {
|
||||
const response = await authInstance.get(`/sight/${id}/article`);
|
||||
|
||||
runInAction(() => {
|
||||
editSightStore.sightInfo[languageStore.language].right = response.data;
|
||||
});
|
||||
};
|
||||
|
||||
getArticleMedia = async (id: number) => {
|
||||
const response = await authInstance.get(`/article/${id}/media`);
|
||||
|
||||
runInAction(() => {
|
||||
this.articleMedia = response.data[0];
|
||||
});
|
||||
};
|
||||
|
||||
getArticleByArticleId = computed(() => {
|
||||
if (editSightStore.sightInfo.left_article) {
|
||||
return this.articles[languageStore.language].find(
|
||||
(a) => a.id == editSightStore.sightInfo.left_article
|
||||
);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
export const articlesStore = new ArticlesStore();
|
||||
|
151
src/shared/store/EditSightStore/index.tsx
Normal file
151
src/shared/store/EditSightStore/index.tsx
Normal file
@ -0,0 +1,151 @@
|
||||
// @shared/stores/editSightStore.ts
|
||||
import { Language } from "@shared";
|
||||
import { makeAutoObservable } from "mobx";
|
||||
|
||||
export interface MediaObject {
|
||||
id: string;
|
||||
filename: string;
|
||||
media_type: number;
|
||||
}
|
||||
|
||||
type SightBaseInfo = {
|
||||
id: number;
|
||||
city_id: number;
|
||||
city: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
thumbnail: string;
|
||||
watermark_lu: string;
|
||||
watermark_rd: string;
|
||||
left_article: number;
|
||||
preview_media: string;
|
||||
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[];
|
||||
};
|
||||
};
|
||||
|
||||
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,
|
||||
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: [],
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const editSightStore = new EditSightStore();
|
27
src/shared/store/MediaStore/index.tsx
Normal file
27
src/shared/store/MediaStore/index.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
import { authInstance } from "@shared";
|
||||
|
||||
type Media = {
|
||||
id: string;
|
||||
filename: string;
|
||||
media_name: string;
|
||||
media_type: number;
|
||||
};
|
||||
|
||||
class MediaStore {
|
||||
media: Media[] = [];
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
getMedia = async () => {
|
||||
const response = await authInstance.get("/media");
|
||||
|
||||
runInAction(() => {
|
||||
this.media = [...response.data];
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export const mediaStore = new MediaStore();
|
@ -1,12 +1,17 @@
|
||||
import { authInstance, languageInstance, languageStore } from "@shared";
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
import {
|
||||
articlesStore,
|
||||
authInstance,
|
||||
languageInstance,
|
||||
languageStore,
|
||||
editSightStore,
|
||||
} from "@shared";
|
||||
import { computed, makeAutoObservable, runInAction } from "mobx";
|
||||
|
||||
export type Language = "ru" | "en" | "zh";
|
||||
|
||||
export type MultilingualContent = {
|
||||
[key in Language]: {
|
||||
name: string;
|
||||
description: string;
|
||||
address: string;
|
||||
};
|
||||
};
|
||||
@ -30,7 +35,6 @@ export type Sight = {
|
||||
export type CreateSight = {
|
||||
[key in Language]: {
|
||||
name: string;
|
||||
description: string;
|
||||
address: string;
|
||||
};
|
||||
};
|
||||
@ -39,9 +43,9 @@ class SightsStore {
|
||||
sights: Sight[] = [];
|
||||
sight: Sight | null = null;
|
||||
createSight: CreateSight = {
|
||||
ru: { name: "", description: "", address: "" },
|
||||
en: { name: "", description: "", address: "" },
|
||||
zh: { name: "", description: "", address: "" },
|
||||
ru: { name: "", address: "" },
|
||||
en: { name: "", address: "" },
|
||||
zh: { name: "", address: "" },
|
||||
};
|
||||
|
||||
constructor() {
|
||||
@ -60,6 +64,41 @@ class SightsStore {
|
||||
|
||||
runInAction(() => {
|
||||
this.sight = response.data;
|
||||
editSightStore.sightInfo = {
|
||||
...editSightStore.sightInfo,
|
||||
id: response.data.id,
|
||||
city_id: response.data.city_id,
|
||||
city: response.data.city,
|
||||
latitude: response.data.latitude,
|
||||
longitude: response.data.longitude,
|
||||
thumbnail: response.data.thumbnail,
|
||||
watermark_lu: response.data.watermark_lu,
|
||||
watermark_rd: response.data.watermark_rd,
|
||||
left_article: response.data.left_article,
|
||||
preview_media: response.data.preview_media,
|
||||
video_preview: response.data.video_preview,
|
||||
[languageStore.language]: {
|
||||
info: {
|
||||
name: response.data.name,
|
||||
address: response.data.address,
|
||||
description: response.data.description,
|
||||
},
|
||||
left: {
|
||||
heading: editSightStore.sightInfo[languageStore.language].left
|
||||
.loaded
|
||||
? editSightStore.sightInfo[languageStore.language].left.heading
|
||||
: articlesStore.articles[languageStore.language].find(
|
||||
(article) => article.id === response.data.left_article
|
||||
)?.heading,
|
||||
body: editSightStore.sightInfo[languageStore.language].left.loaded
|
||||
? editSightStore.sightInfo[languageStore.language].left.body
|
||||
: articlesStore.articles[languageStore.language].find(
|
||||
(article) => article.id === response.data.left_article
|
||||
)?.body,
|
||||
},
|
||||
},
|
||||
};
|
||||
console.log(editSightStore.sightInfo);
|
||||
});
|
||||
};
|
||||
|
||||
@ -70,7 +109,6 @@ class SightsStore {
|
||||
const id = (
|
||||
await authInstance.post("/sight", {
|
||||
name: this.createSight[languageStore.language].name,
|
||||
description: this.createSight[languageStore.language].description,
|
||||
address: this.createSight[languageStore.language].address,
|
||||
city_id: city,
|
||||
latitude: coordinates.latitude,
|
||||
@ -86,8 +124,6 @@ class SightsStore {
|
||||
`/sight/${id}`,
|
||||
{
|
||||
name: this.createSight[anotherLanguages[0] as Language].name,
|
||||
description:
|
||||
this.createSight[anotherLanguages[0] as Language].description,
|
||||
address: this.createSight[anotherLanguages[0] as Language].address,
|
||||
city_id: city,
|
||||
latitude: coordinates.latitude,
|
||||
@ -99,8 +135,6 @@ class SightsStore {
|
||||
`/sight/${id}`,
|
||||
{
|
||||
name: this.createSight[anotherLanguages[1] as Language].name,
|
||||
description:
|
||||
this.createSight[anotherLanguages[1] as Language].description,
|
||||
address: this.createSight[anotherLanguages[1] as Language].address,
|
||||
city_id: city,
|
||||
latitude: coordinates.latitude,
|
||||
@ -110,9 +144,9 @@ class SightsStore {
|
||||
|
||||
runInAction(() => {
|
||||
this.createSight = {
|
||||
ru: { name: "", description: "", address: "" },
|
||||
en: { name: "", description: "", address: "" },
|
||||
zh: { name: "", description: "", address: "" },
|
||||
ru: { name: "", address: "" },
|
||||
en: { name: "", address: "" },
|
||||
zh: { name: "", address: "" },
|
||||
};
|
||||
});
|
||||
};
|
||||
@ -139,22 +173,41 @@ class SightsStore {
|
||||
this.createSight = {
|
||||
ru: {
|
||||
name: "",
|
||||
description: "",
|
||||
address: "",
|
||||
},
|
||||
en: {
|
||||
name: "",
|
||||
description: "",
|
||||
address: "",
|
||||
},
|
||||
zh: {
|
||||
name: "",
|
||||
description: "",
|
||||
address: "",
|
||||
},
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
sightData = computed(() => {
|
||||
return {
|
||||
name: this.sight?.name,
|
||||
address: this.sight?.address,
|
||||
city_id: this.sight?.city_id,
|
||||
latitude: this.sight?.latitude,
|
||||
longitude: this.sight?.longitude,
|
||||
thumbnail: this.sight?.thumbnail,
|
||||
watermark_lu: this.sight?.watermark_lu,
|
||||
watermark_rd: this.sight?.watermark_rd,
|
||||
left_article: this.sight?.left_article,
|
||||
preview_media: this.sight?.preview_media,
|
||||
video_preview: this.sight?.video_preview,
|
||||
[languageStore.language]: {
|
||||
info: {
|
||||
name: this.sight?.name,
|
||||
address: this.sight?.address,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export const sightsStore = new SightsStore();
|
||||
|
@ -6,3 +6,5 @@ export * from "./SnapshotStore";
|
||||
export * from "./SightsStore";
|
||||
export * from "./CityStore";
|
||||
export * from "./ArticlesStore";
|
||||
export * from "./EditSightStore";
|
||||
export * from "./MediaStore";
|
||||
|
Reference in New Issue
Block a user