Update media
select in EditSightPage
and CreateSightPage
This commit is contained in:
@ -1,13 +1,13 @@
|
||||
// @shared/stores/createSightStore.ts
|
||||
import {
|
||||
Language,
|
||||
authInstance,
|
||||
languageInstance,
|
||||
articlesStore,
|
||||
languageStore,
|
||||
mediaStore,
|
||||
} from "@shared";
|
||||
import { makeAutoObservable } from "mobx";
|
||||
import { Language, authInstance, languageInstance, mediaStore } from "@shared";
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
|
||||
type MediaItem = {
|
||||
id: string;
|
||||
filename: string;
|
||||
media_name?: string;
|
||||
media_type: number;
|
||||
};
|
||||
|
||||
type SightLanguageInfo = {
|
||||
name: string;
|
||||
@ -15,18 +15,13 @@ type SightLanguageInfo = {
|
||||
left: {
|
||||
heading: string;
|
||||
body: string;
|
||||
media: {
|
||||
id: string;
|
||||
filename: string;
|
||||
media_name?: string;
|
||||
media_type: number;
|
||||
}[];
|
||||
media: MediaItem[];
|
||||
};
|
||||
right: { id: number; heading: string; body: string; media: [] }[];
|
||||
right: { id: number; heading: string; body: string; media: MediaItem[] }[];
|
||||
};
|
||||
|
||||
type SightCommonInfo = {
|
||||
id: number;
|
||||
// id: number; // ID is 0 until created
|
||||
city_id: number;
|
||||
city: string;
|
||||
latitude: number;
|
||||
@ -34,48 +29,50 @@ type SightCommonInfo = {
|
||||
thumbnail: string | null;
|
||||
watermark_lu: string | null;
|
||||
watermark_rd: string | null;
|
||||
left_article: number;
|
||||
left_article: number; // Can be 0 or a real ID, or placeholder like 10000000
|
||||
preview_media: string | null;
|
||||
video_preview: string | null;
|
||||
};
|
||||
|
||||
// SightBaseInfo combines common info with language-specific info
|
||||
// The 'id' for the sight itself will be assigned upon creation by the backend.
|
||||
type SightBaseInfo = SightCommonInfo & {
|
||||
[key in Language]: SightLanguageInfo;
|
||||
};
|
||||
|
||||
class CreateSightStore {
|
||||
sight: SightBaseInfo = {
|
||||
id: 0,
|
||||
city_id: 0,
|
||||
city: "",
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
thumbnail: null,
|
||||
watermark_lu: null,
|
||||
watermark_rd: null,
|
||||
left_article: 0,
|
||||
preview_media: null,
|
||||
video_preview: null,
|
||||
const initialSightState: SightBaseInfo = {
|
||||
city_id: 0,
|
||||
city: "",
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
thumbnail: null,
|
||||
watermark_lu: null,
|
||||
watermark_rd: null,
|
||||
left_article: 0,
|
||||
preview_media: null,
|
||||
video_preview: null,
|
||||
ru: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
en: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
zh: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
};
|
||||
|
||||
ru: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
en: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
zh: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
};
|
||||
class CreateSightStore {
|
||||
sight: SightBaseInfo = JSON.parse(JSON.stringify(initialSightState)); // Deep copy for reset
|
||||
|
||||
uploadMediaOpen = false;
|
||||
setUploadMediaOpen = (open: boolean) => {
|
||||
@ -90,313 +87,74 @@ class CreateSightStore {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
// --- Right Article Management ---
|
||||
createNewRightArticle = async () => {
|
||||
const articleId = await languageInstance("ru").post("/article", {
|
||||
heading: "Введите русский заголовок",
|
||||
body: "Введите русский текст",
|
||||
});
|
||||
const { id } = articleId.data;
|
||||
await languageInstance("en").patch(`/article/${id}`, {
|
||||
heading: "Enter the English heading",
|
||||
body: "Enter the English text",
|
||||
});
|
||||
await languageInstance("zh").patch(`/article/${id}`, {
|
||||
heading: "Введите китайский заголовок",
|
||||
body: "Введите китайский текст",
|
||||
});
|
||||
await authInstance.post(`/sight/${this.sight.id}/article`, {
|
||||
article_id: id,
|
||||
page_num: this.sight.ru.right.length + 1,
|
||||
});
|
||||
|
||||
this.sight.ru.right.push({
|
||||
id: id,
|
||||
heading: "Введите русский заголовок",
|
||||
body: "Введите русский текст",
|
||||
media: [],
|
||||
});
|
||||
this.sight.en.right.push({
|
||||
id: id,
|
||||
heading: "Enter the English heading",
|
||||
body: "Enter the English text",
|
||||
media: [],
|
||||
});
|
||||
this.sight.zh.right.push({
|
||||
id: id,
|
||||
heading: "Введите китайский заголовок",
|
||||
body: "Введите китайский текст",
|
||||
media: [],
|
||||
});
|
||||
};
|
||||
|
||||
updateLeftInfo = (language: Language, heading: string, body: string) => {
|
||||
this.sight[language].left.heading = heading;
|
||||
this.sight[language].left.body = body;
|
||||
};
|
||||
|
||||
clearCreateSight = () => {
|
||||
this.sight = {
|
||||
id: 0,
|
||||
city_id: 0,
|
||||
city: "",
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
thumbnail: null,
|
||||
watermark_lu: null,
|
||||
watermark_rd: null,
|
||||
left_article: 0,
|
||||
preview_media: null,
|
||||
video_preview: null,
|
||||
|
||||
ru: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
|
||||
en: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
|
||||
zh: {
|
||||
name: "",
|
||||
address: "",
|
||||
left: { heading: "", body: "", media: [] },
|
||||
right: [],
|
||||
},
|
||||
// Create article in DB for all languages
|
||||
const articleRuData = {
|
||||
heading: "Новый заголовок (RU)",
|
||||
body: "Новый текст (RU)",
|
||||
};
|
||||
};
|
||||
const articleEnData = {
|
||||
heading: "New Heading (EN)",
|
||||
body: "New Text (EN)",
|
||||
};
|
||||
const articleZhData = { heading: "新标题 (ZH)", body: "新文本 (ZH)" };
|
||||
|
||||
updateSightInfo = (
|
||||
content: Partial<SightLanguageInfo | SightCommonInfo>,
|
||||
language?: Language
|
||||
) => {
|
||||
if (language) {
|
||||
this.sight[language] = {
|
||||
...this.sight[language],
|
||||
...content,
|
||||
};
|
||||
} else {
|
||||
this.sight = {
|
||||
...this.sight,
|
||||
...content,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
unlinkLeftArticle = () => {
|
||||
this.sight.left_article = 0;
|
||||
this.sight.ru.left.heading = "";
|
||||
this.sight.en.left.heading = "";
|
||||
this.sight.zh.left.heading = "";
|
||||
this.sight.ru.left.body = "";
|
||||
this.sight.en.left.body = "";
|
||||
this.sight.zh.left.body = "";
|
||||
};
|
||||
|
||||
updateLeftArticle = async (articleId: number) => {
|
||||
this.sight.left_article = articleId;
|
||||
|
||||
if (articleId) {
|
||||
const ruArticleData = await languageInstance("ru").get(
|
||||
`/article/${articleId}`
|
||||
);
|
||||
const enArticleData = await languageInstance("en").get(
|
||||
`/article/${articleId}`
|
||||
);
|
||||
const zhArticleData = await languageInstance("zh").get(
|
||||
`/article/${articleId}`
|
||||
try {
|
||||
const articleRes = await languageInstance("ru").post(
|
||||
"/article",
|
||||
articleRuData
|
||||
);
|
||||
const { id } = articleRes.data; // New article's ID
|
||||
|
||||
this.sight.ru.left.heading = ruArticleData.data.heading;
|
||||
this.sight.en.left.heading = enArticleData.data.heading;
|
||||
this.sight.zh.left.heading = zhArticleData.data.heading;
|
||||
await languageInstance("en").patch(`/article/${id}`, articleEnData);
|
||||
await languageInstance("zh").patch(`/article/${id}`, articleZhData);
|
||||
|
||||
this.sight.ru.left.body = ruArticleData.data.body;
|
||||
this.sight.en.left.body = enArticleData.data.body;
|
||||
this.sight.zh.left.body = zhArticleData.data.body;
|
||||
} else {
|
||||
this.sight.left_article = 0;
|
||||
this.sight.ru.left.heading = "";
|
||||
this.sight.en.left.heading = "";
|
||||
this.sight.zh.left.heading = "";
|
||||
this.sight.ru.left.body = "";
|
||||
this.sight.en.left.body = "";
|
||||
this.sight.zh.left.body = "";
|
||||
}
|
||||
};
|
||||
|
||||
deleteLeftArticle = async (articleId: number) => {
|
||||
await authInstance.delete(`/article/${articleId}`);
|
||||
articlesStore.getArticles(languageStore.language);
|
||||
this.sight.left_article = 0;
|
||||
this.sight.ru.left.heading = "";
|
||||
this.sight.en.left.heading = "";
|
||||
this.sight.zh.left.heading = "";
|
||||
this.sight.ru.left.body = "";
|
||||
};
|
||||
|
||||
createLeftArticle = async () => {
|
||||
const response = await languageInstance("ru").post("/article", {
|
||||
heading: "Новая статья",
|
||||
body: "Заполните статью контентом",
|
||||
});
|
||||
|
||||
this.sight.left_article = response.data.id;
|
||||
|
||||
this.sight.ru.left.heading = "Новая статья ";
|
||||
this.sight.en.left.heading = "";
|
||||
this.sight.zh.left.heading = "";
|
||||
this.sight.ru.left.body = "Заполните статью контентом";
|
||||
this.sight.en.left.body = "";
|
||||
this.sight.zh.left.body = "";
|
||||
};
|
||||
|
||||
createSight = async (language: Language) => {
|
||||
const rightArticles: number[] = [];
|
||||
|
||||
if (this.sight.left_article !== 0) {
|
||||
if (this.sight.left_article == 10000000) {
|
||||
const response = await languageInstance("ru").post("/article", {
|
||||
heading: this.sight.ru.left.heading,
|
||||
body: this.sight.ru.left.body,
|
||||
});
|
||||
const { id } = response.data;
|
||||
await languageInstance("en").patch(`/article/${id}`, {
|
||||
heading: this.sight.en.left.heading,
|
||||
body: this.sight.en.left.body,
|
||||
});
|
||||
|
||||
await languageInstance("zh").patch(`/article/${id}`, {
|
||||
heading: this.sight.zh.left.heading,
|
||||
body: this.sight.zh.left.body,
|
||||
});
|
||||
this.sight.left_article = id;
|
||||
} else {
|
||||
await languageInstance("ru").patch(
|
||||
`/article/${this.sight.left_article}`,
|
||||
{
|
||||
heading: this.sight.ru.left.heading,
|
||||
body: this.sight.ru.left.body,
|
||||
}
|
||||
);
|
||||
|
||||
await languageInstance("en").patch(
|
||||
`/article/${this.sight.left_article}`,
|
||||
{
|
||||
heading: this.sight.en.left.heading,
|
||||
body: this.sight.en.left.body,
|
||||
}
|
||||
);
|
||||
|
||||
await languageInstance("zh").patch(
|
||||
`/article/${this.sight.left_article}`,
|
||||
{
|
||||
heading: this.sight.zh.left.heading,
|
||||
body: this.sight.zh.left.body,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.sight[language].right.map(async (article, index) => {
|
||||
try {
|
||||
const response = await languageInstance(language).post("/article", {
|
||||
heading: article.heading,
|
||||
body: article.body,
|
||||
});
|
||||
const { id } = response.data;
|
||||
const anotherLanguages = ["en", "zh", "ru"].filter(
|
||||
(lang) => lang !== language
|
||||
);
|
||||
await languageInstance(anotherLanguages[0] as Language).patch(
|
||||
`/article/${id}`,
|
||||
{
|
||||
heading:
|
||||
this.sight[anotherLanguages[0] as Language].right[index].heading,
|
||||
body: this.sight[anotherLanguages[0] as Language].right[index].body,
|
||||
}
|
||||
);
|
||||
await languageInstance(anotherLanguages[1] as Language).patch(
|
||||
`/article/${id}`,
|
||||
{
|
||||
heading:
|
||||
this.sight[anotherLanguages[1] as Language].right[index].heading,
|
||||
body: this.sight[anotherLanguages[1] as Language].right[index].body,
|
||||
}
|
||||
);
|
||||
rightArticles.push(id);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
const response = await languageInstance(language).post("/sight", {
|
||||
city_id: this.sight.city_id,
|
||||
city: this.sight.city,
|
||||
latitude: this.sight.latitude,
|
||||
longitude: this.sight.longitude,
|
||||
name: this.sight[language].name,
|
||||
address: this.sight[language].address,
|
||||
thumbnail: this.sight.thumbnail ?? null,
|
||||
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,
|
||||
});
|
||||
|
||||
const { id } = response.data;
|
||||
const anotherLanguages = ["en", "zh", "ru"].filter(
|
||||
(lang) => lang !== language
|
||||
);
|
||||
|
||||
await languageInstance(anotherLanguages[0] as Language).patch(
|
||||
`/sight/${id}`,
|
||||
{
|
||||
city_id: this.sight.city_id,
|
||||
city: this.sight.city,
|
||||
latitude: this.sight.latitude,
|
||||
longitude: this.sight.longitude,
|
||||
name: this.sight[anotherLanguages[0] as Language as Language].name,
|
||||
address:
|
||||
this.sight[anotherLanguages[0] as Language as Language].address,
|
||||
thumbnail: this.sight.thumbnail ?? null,
|
||||
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,
|
||||
}
|
||||
);
|
||||
await languageInstance(anotherLanguages[1] as Language).patch(
|
||||
`/sight/${id}`,
|
||||
{
|
||||
city_id: this.sight.city_id,
|
||||
city: this.sight.city,
|
||||
latitude: this.sight.latitude,
|
||||
longitude: this.sight.longitude,
|
||||
name: this.sight[anotherLanguages[1] as Language].name,
|
||||
address: this.sight[anotherLanguages[1] as Language].address,
|
||||
thumbnail: this.sight.thumbnail ?? null,
|
||||
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,
|
||||
}
|
||||
);
|
||||
|
||||
rightArticles.map(async (article, index) => {
|
||||
await authInstance.post(`/sight/${id}/article`, {
|
||||
article_id: article,
|
||||
page_num: index + 1,
|
||||
runInAction(() => {
|
||||
const newArticleEntry = { id, media: [] };
|
||||
this.sight.ru.right.push({ ...newArticleEntry, ...articleRuData });
|
||||
this.sight.en.right.push({ ...newArticleEntry, ...articleEnData });
|
||||
this.sight.zh.right.push({ ...newArticleEntry, ...articleZhData });
|
||||
});
|
||||
});
|
||||
console.log("created");
|
||||
return id; // Return ID for potential immediate use
|
||||
} catch (error) {
|
||||
console.error("Error creating new right article:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
linkExistingRightArticle = async (articleId: number) => {
|
||||
try {
|
||||
const ruData = await languageInstance("ru").get(`/article/${articleId}`);
|
||||
const enData = await languageInstance("en").get(`/article/${articleId}`);
|
||||
const zhData = await languageInstance("zh").get(`/article/${articleId}`);
|
||||
const mediaRes = await authInstance.get(`/article/${articleId}/media`);
|
||||
const mediaData: MediaItem[] = mediaRes.data || [];
|
||||
|
||||
runInAction(() => {
|
||||
this.sight.ru.right.push({
|
||||
id: articleId,
|
||||
heading: ruData.data.heading,
|
||||
body: ruData.data.body,
|
||||
media: mediaData,
|
||||
});
|
||||
this.sight.en.right.push({
|
||||
id: articleId,
|
||||
heading: enData.data.heading,
|
||||
body: enData.data.body,
|
||||
media: mediaData,
|
||||
});
|
||||
this.sight.zh.right.push({
|
||||
id: articleId,
|
||||
heading: zhData.data.heading,
|
||||
body: zhData.data.body,
|
||||
media: mediaData,
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error linking existing right article:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
updateRightArticleInfo = (
|
||||
@ -405,94 +163,428 @@ class CreateSightStore {
|
||||
heading: string,
|
||||
body: string
|
||||
) => {
|
||||
this.sight[language].right[index].heading = heading;
|
||||
this.sight[language].right[index].body = body;
|
||||
if (this.sight[language].right[index]) {
|
||||
this.sight[language].right[index].heading = heading;
|
||||
this.sight[language].right[index].body = body;
|
||||
}
|
||||
};
|
||||
|
||||
// "Unlink" in create mode means just removing from the list to be created with the sight
|
||||
unlinkRightAritcle = (articleId: number) => {
|
||||
// Changed from 'unlinkRightAritcle' spelling
|
||||
runInAction(() => {
|
||||
this.sight.ru.right = this.sight.ru.right.filter(
|
||||
(article) => article.id !== articleId
|
||||
);
|
||||
this.sight.en.right = this.sight.en.right.filter(
|
||||
(article) => article.id !== articleId
|
||||
);
|
||||
this.sight.zh.right = this.sight.zh.right.filter(
|
||||
(article) => article.id !== articleId
|
||||
);
|
||||
});
|
||||
// Note: If this article was created via createNewRightArticle, it still exists in the DB.
|
||||
// Consider if an orphaned article should be deleted here or managed separately.
|
||||
// For now, it just removes it from the list associated with *this specific sight creation process*.
|
||||
};
|
||||
|
||||
deleteRightArticle = async (articleId: number) => {
|
||||
try {
|
||||
await authInstance.delete(`/article/${articleId}`); // Delete from backend
|
||||
runInAction(() => {
|
||||
// Remove from local store for all languages
|
||||
this.sight.ru.right = this.sight.ru.right.filter(
|
||||
(article) => article.id !== articleId
|
||||
);
|
||||
this.sight.en.right = this.sight.en.right.filter(
|
||||
(article) => article.id !== articleId
|
||||
);
|
||||
this.sight.zh.right = this.sight.zh.right.filter(
|
||||
(article) => article.id !== articleId
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error deleting right article:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// --- Right Article Media Management ---
|
||||
createLinkWithRightArticle = async (media: MediaItem, articleId: number) => {
|
||||
try {
|
||||
await authInstance.post(`/article/${articleId}/media`, {
|
||||
media_id: media.id,
|
||||
media_order: 1, // Or calculate based on existing media.length + 1
|
||||
});
|
||||
runInAction(() => {
|
||||
(["ru", "en", "zh"] as Language[]).forEach((lang) => {
|
||||
const article = this.sight[lang].right.find(
|
||||
(a) => a.id === articleId
|
||||
);
|
||||
if (article) {
|
||||
if (!article.media) article.media = [];
|
||||
article.media.unshift(media); // Add to the beginning
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error linking media to right article:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteRightArticleMedia = async (articleId: number, mediaId: string) => {
|
||||
try {
|
||||
await authInstance.delete(`/article/${articleId}/media`, {
|
||||
data: { media_id: mediaId },
|
||||
});
|
||||
runInAction(() => {
|
||||
(["ru", "en", "zh"] as Language[]).forEach((lang) => {
|
||||
const article = this.sight[lang].right.find(
|
||||
(a) => a.id === articleId
|
||||
);
|
||||
if (article && article.media) {
|
||||
article.media = article.media.filter((m) => m.id !== mediaId);
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error deleting media from right article:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// --- Left Article Management (largely unchanged from your provided store) ---
|
||||
updateLeftInfo = (language: Language, heading: string, body: string) => {
|
||||
this.sight[language].left.heading = heading;
|
||||
this.sight[language].left.body = body;
|
||||
};
|
||||
|
||||
unlinkLeftArticle = () => {
|
||||
/* ... your existing logic ... */
|
||||
this.sight.left_article = 0;
|
||||
this.sight.ru.left = { heading: "", body: "", media: [] };
|
||||
this.sight.en.left = { heading: "", body: "", media: [] };
|
||||
this.sight.zh.left = { heading: "", body: "", media: [] };
|
||||
};
|
||||
|
||||
updateLeftArticle = async (articleId: number) => {
|
||||
/* ... your existing logic ... */
|
||||
this.sight.left_article = articleId;
|
||||
if (articleId) {
|
||||
const [ruArticleData, enArticleData, zhArticleData, mediaData] =
|
||||
await Promise.all([
|
||||
languageInstance("ru").get(`/article/${articleId}`),
|
||||
languageInstance("en").get(`/article/${articleId}`),
|
||||
languageInstance("zh").get(`/article/${articleId}`),
|
||||
authInstance.get(`/article/${articleId}/media`),
|
||||
]);
|
||||
runInAction(() => {
|
||||
this.sight.ru.left = {
|
||||
heading: ruArticleData.data.heading,
|
||||
body: ruArticleData.data.body,
|
||||
media: mediaData.data || [],
|
||||
};
|
||||
this.sight.en.left = {
|
||||
heading: enArticleData.data.heading,
|
||||
body: enArticleData.data.body,
|
||||
media: mediaData.data || [],
|
||||
};
|
||||
this.sight.zh.left = {
|
||||
heading: zhArticleData.data.heading,
|
||||
body: zhArticleData.data.body,
|
||||
media: mediaData.data || [],
|
||||
};
|
||||
});
|
||||
} else {
|
||||
this.unlinkLeftArticle();
|
||||
}
|
||||
};
|
||||
|
||||
deleteLeftArticle = async (articleId: number) => {
|
||||
/* ... your existing logic ... */
|
||||
await authInstance.delete(`/article/${articleId}`);
|
||||
// articlesStore.getArticles(languageStore.language); // If still needed
|
||||
this.unlinkLeftArticle();
|
||||
};
|
||||
|
||||
createLeftArticle = async () => {
|
||||
/* ... your existing logic to create a new left article (placeholder or DB) ... */
|
||||
const response = await languageInstance("ru").post("/article", {
|
||||
heading: "Новая левая статья",
|
||||
body: "Заполните контентом",
|
||||
});
|
||||
const newLeftArticleId = response.data.id;
|
||||
await languageInstance("en").patch(`/article/${newLeftArticleId}`, {
|
||||
heading: "New Left Article",
|
||||
body: "Fill with content",
|
||||
});
|
||||
await languageInstance("zh").patch(`/article/${newLeftArticleId}`, {
|
||||
heading: "新的左侧文章",
|
||||
body: "填写内容",
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.sight.left_article = newLeftArticleId; // Store the actual ID
|
||||
this.sight.ru.left = {
|
||||
heading: "Новая левая статья",
|
||||
body: "Заполните контентом",
|
||||
media: [],
|
||||
};
|
||||
this.sight.en.left = {
|
||||
heading: "New Left Article",
|
||||
body: "Fill with content",
|
||||
media: [],
|
||||
};
|
||||
this.sight.zh.left = {
|
||||
heading: "新的左侧文章",
|
||||
body: "填写内容",
|
||||
media: [],
|
||||
};
|
||||
});
|
||||
return newLeftArticleId;
|
||||
};
|
||||
|
||||
// Placeholder for a "new" unsaved left article
|
||||
setNewLeftArticlePlaceholder = () => {
|
||||
this.sight.left_article = 10000000; // Special placeholder ID
|
||||
this.sight.ru.left = {
|
||||
heading: "Новая левая статья",
|
||||
body: "Заполните контентом",
|
||||
media: [],
|
||||
};
|
||||
this.sight.en.left = {
|
||||
heading: "New Left Article",
|
||||
body: "Fill with content",
|
||||
media: [],
|
||||
};
|
||||
this.sight.zh.left = {
|
||||
heading: "新的左侧文章",
|
||||
body: "填写内容",
|
||||
media: [],
|
||||
};
|
||||
};
|
||||
|
||||
// --- Sight Preview Media ---
|
||||
linkPreviewMedia = (mediaId: string) => {
|
||||
this.sight.preview_media = mediaId;
|
||||
};
|
||||
|
||||
unlinkPreviewMedia = () => {
|
||||
this.sight.preview_media = null;
|
||||
};
|
||||
|
||||
// --- General Store Methods ---
|
||||
clearCreateSight = () => {
|
||||
this.sight = JSON.parse(JSON.stringify(initialSightState)); // Reset to initial
|
||||
};
|
||||
|
||||
updateSightInfo = (
|
||||
content: Partial<SightLanguageInfo | SightCommonInfo>, // Corrected types
|
||||
language?: Language
|
||||
) => {
|
||||
if (language) {
|
||||
this.sight[language] = { ...this.sight[language], ...content };
|
||||
} else {
|
||||
// Assuming content here is for SightCommonInfo
|
||||
this.sight = { ...this.sight, ...(content as Partial<SightCommonInfo>) };
|
||||
}
|
||||
};
|
||||
|
||||
// --- Main Sight Creation Logic ---
|
||||
createSight = async (primaryLanguage: Language) => {
|
||||
let finalLeftArticleId = this.sight.left_article;
|
||||
|
||||
// 1. Handle Left Article (Create if new, or use existing ID)
|
||||
if (this.sight.left_article === 10000000) {
|
||||
// Placeholder for new
|
||||
const res = await languageInstance("ru").post("/article", {
|
||||
heading: this.sight.ru.left.heading,
|
||||
body: this.sight.ru.left.body,
|
||||
});
|
||||
finalLeftArticleId = res.data.id;
|
||||
await languageInstance("en").patch(`/article/${finalLeftArticleId}`, {
|
||||
heading: this.sight.en.left.heading,
|
||||
body: this.sight.en.left.body,
|
||||
});
|
||||
await languageInstance("zh").patch(`/article/${finalLeftArticleId}`, {
|
||||
heading: this.sight.zh.left.heading,
|
||||
body: this.sight.zh.left.body,
|
||||
});
|
||||
} else if (
|
||||
this.sight.left_article !== 0 &&
|
||||
this.sight.left_article !== null
|
||||
) {
|
||||
// Existing, ensure it's up-to-date
|
||||
await languageInstance("ru").patch(
|
||||
`/article/${this.sight.left_article}`,
|
||||
{ heading: this.sight.ru.left.heading, body: this.sight.ru.left.body }
|
||||
);
|
||||
await languageInstance("en").patch(
|
||||
`/article/${this.sight.left_article}`,
|
||||
{ heading: this.sight.en.left.heading, body: this.sight.en.left.body }
|
||||
);
|
||||
await languageInstance("zh").patch(
|
||||
`/article/${this.sight.left_article}`,
|
||||
{ heading: this.sight.zh.left.heading, body: this.sight.zh.left.body }
|
||||
);
|
||||
}
|
||||
// else: left_article is 0, so no left article
|
||||
|
||||
// 2. Right articles are already created in DB and their IDs are in this.sight[lang].right.
|
||||
// We just need to update their content if changed before saving the sight.
|
||||
for (const lang of ["ru", "en", "zh"] as Language[]) {
|
||||
for (const article of this.sight[lang].right) {
|
||||
if (article.id == 0 || article.id == null) {
|
||||
continue;
|
||||
}
|
||||
await languageInstance(lang).patch(`/article/${article.id}`, {
|
||||
heading: article.heading,
|
||||
body: article.body,
|
||||
});
|
||||
// Media for these articles are already linked via createLinkWithRightArticle
|
||||
}
|
||||
}
|
||||
const rightArticleIdsForLink = this.sight[primaryLanguage].right.map(
|
||||
(a) => a.id
|
||||
);
|
||||
|
||||
// 3. Create Sight object in DB
|
||||
const sightPayload = {
|
||||
city_id: this.sight.city_id,
|
||||
city: this.sight.city,
|
||||
latitude: this.sight.latitude,
|
||||
longitude: this.sight.longitude,
|
||||
name: this.sight[primaryLanguage].name,
|
||||
address: this.sight[primaryLanguage].address,
|
||||
thumbnail: this.sight.thumbnail,
|
||||
watermark_lu: this.sight.watermark_lu,
|
||||
watermark_rd: this.sight.watermark_rd,
|
||||
left_article: finalLeftArticleId === 0 ? null : finalLeftArticleId,
|
||||
preview_media: this.sight.preview_media,
|
||||
video_preview: this.sight.video_preview,
|
||||
};
|
||||
|
||||
const response = await languageInstance(primaryLanguage).post(
|
||||
"/sight",
|
||||
sightPayload
|
||||
);
|
||||
const newSightId = response.data.id; // ID of the newly created sight
|
||||
|
||||
// 4. Update other languages for the sight
|
||||
const otherLanguages = (["ru", "en", "zh"] as Language[]).filter(
|
||||
(l) => l !== primaryLanguage
|
||||
);
|
||||
for (const lang of otherLanguages) {
|
||||
await languageInstance(lang).patch(`/sight/${newSightId}`, {
|
||||
city_id: this.sight.city_id,
|
||||
city: this.sight.city,
|
||||
latitude: this.sight.latitude,
|
||||
longitude: this.sight.longitude,
|
||||
name: this.sight[lang].name,
|
||||
address: this.sight[lang].address,
|
||||
thumbnail: this.sight.thumbnail,
|
||||
watermark_lu: this.sight.watermark_lu,
|
||||
watermark_rd: this.sight.watermark_rd,
|
||||
left_article: finalLeftArticleId === 0 ? null : finalLeftArticleId,
|
||||
preview_media: this.sight.preview_media,
|
||||
video_preview: this.sight.video_preview,
|
||||
});
|
||||
}
|
||||
|
||||
// 5. Link Right Articles to the new Sight
|
||||
for (let i = 0; i < rightArticleIdsForLink.length; i++) {
|
||||
await authInstance.post(`/sight/${newSightId}/article`, {
|
||||
article_id: rightArticleIdsForLink[i],
|
||||
page_num: i + 1, // Or other logic for page_num
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Sight created with ID:", newSightId);
|
||||
// Optionally: this.clearCreateSight(); // To reset form after successful creation
|
||||
return newSightId;
|
||||
};
|
||||
|
||||
// --- Media Upload (Generic, used by dialogs) ---
|
||||
uploadMedia = async (
|
||||
filename: string,
|
||||
type: number,
|
||||
file: File,
|
||||
media_name?: string
|
||||
) => {
|
||||
): Promise<MediaItem> => {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
formData.append("filename", filename);
|
||||
if (media_name) {
|
||||
formData.append("media_name", media_name);
|
||||
}
|
||||
if (media_name) formData.append("media_name", media_name);
|
||||
formData.append("type", type.toString());
|
||||
|
||||
try {
|
||||
const response = await authInstance.post(`/media`, formData);
|
||||
this.fileToUpload = null;
|
||||
this.uploadMediaOpen = false;
|
||||
mediaStore.getMedia();
|
||||
runInAction(() => {
|
||||
this.fileToUpload = null;
|
||||
this.uploadMediaOpen = false;
|
||||
});
|
||||
mediaStore.getMedia(); // Refresh global media list
|
||||
return {
|
||||
id: response.data.id,
|
||||
filename: filename,
|
||||
media_name: media_name,
|
||||
media_type: type,
|
||||
filename: filename, // Or response.data.filename if backend returns it
|
||||
media_name: media_name, // Or response.data.media_name
|
||||
media_type: type, // Or response.data.type
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.error("Error uploading media:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createLinkWithArticle = async (media: {
|
||||
id: string;
|
||||
filename: string;
|
||||
media_name?: string;
|
||||
media_type: number;
|
||||
}) => {
|
||||
await authInstance.post(`/article/${this.sight.left_article}/media`, {
|
||||
media_id: media.id,
|
||||
media_order: 1,
|
||||
});
|
||||
|
||||
this.sight.ru.left.media.unshift({
|
||||
id: media.id,
|
||||
media_type: media.media_type,
|
||||
filename: media.filename,
|
||||
});
|
||||
|
||||
this.sight.en.left.media.unshift({
|
||||
id: media.id,
|
||||
media_type: media.media_type,
|
||||
filename: media.filename,
|
||||
});
|
||||
|
||||
this.sight.zh.left.media.unshift({
|
||||
id: media.id,
|
||||
media_type: media.media_type,
|
||||
filename: media.filename,
|
||||
});
|
||||
// For Left Article Media
|
||||
createLinkWithLeftArticle = async (media: MediaItem) => {
|
||||
if (!this.sight.left_article || this.sight.left_article === 10000000) {
|
||||
console.warn(
|
||||
"Left article not selected or is a placeholder. Cannot link media yet."
|
||||
);
|
||||
// If it's a placeholder, we could store the media temporarily and link it after the article is created.
|
||||
// For simplicity, we'll assume the article must exist.
|
||||
// A more robust solution might involve creating the article first if it's a placeholder.
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await authInstance.post(`/article/${this.sight.left_article}/media`, {
|
||||
media_id: media.id,
|
||||
media_order: (this.sight.ru.left.media?.length || 0) + 1,
|
||||
});
|
||||
runInAction(() => {
|
||||
(["ru", "en", "zh"] as Language[]).forEach((lang) => {
|
||||
if (!this.sight[lang].left.media) this.sight[lang].left.media = [];
|
||||
this.sight[lang].left.media.unshift(media);
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error linking media to left article:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
unlinkRightAritcle = async (id: number) => {
|
||||
this.sight.ru.right = this.sight.ru.right.filter(
|
||||
(article) => article.id !== id
|
||||
);
|
||||
this.sight.en.right = this.sight.en.right.filter(
|
||||
(article) => article.id !== id
|
||||
);
|
||||
this.sight.zh.right = this.sight.zh.right.filter(
|
||||
(article) => article.id !== id
|
||||
);
|
||||
};
|
||||
|
||||
deleteRightArticle = async (id: number) => {
|
||||
await authInstance.delete(`/article/${id}`);
|
||||
|
||||
this.sight.ru.right = this.sight.ru.right.filter(
|
||||
(article) => article.id !== id
|
||||
);
|
||||
this.sight.en.right = this.sight.en.right.filter(
|
||||
(article) => article.id !== id
|
||||
);
|
||||
this.sight.zh.right = this.sight.zh.right.filter(
|
||||
(article) => article.id !== id
|
||||
);
|
||||
deleteLeftArticleMedia = async (mediaId: string) => {
|
||||
if (!this.sight.left_article || this.sight.left_article === 10000000)
|
||||
return;
|
||||
try {
|
||||
await authInstance.delete(`/article/${this.sight.left_article}/media`, {
|
||||
data: { media_id: mediaId },
|
||||
});
|
||||
runInAction(() => {
|
||||
(["ru", "en", "zh"] as Language[]).forEach((lang) => {
|
||||
if (this.sight[lang].left.media) {
|
||||
this.sight[lang].left.media = this.sight[lang].left.media.filter(
|
||||
(m) => m.id !== mediaId
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error deleting media from left article:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,8 @@ class EditSightStore {
|
||||
|
||||
const response = await authInstance.get(`/sight/${id}`);
|
||||
const data = response.data;
|
||||
if (data.left_article != 0) {
|
||||
|
||||
if (data.left_article != 0 && data.left_article != null) {
|
||||
await this.getLeftArticle(data.left_article);
|
||||
}
|
||||
|
||||
@ -260,7 +261,10 @@ class EditSightStore {
|
||||
});
|
||||
|
||||
this.sight.common.left_article = createdLeftArticleId;
|
||||
} else if (this.sight.common.left_article != 0) {
|
||||
} else if (
|
||||
this.sight.common.left_article != 0 &&
|
||||
this.sight.common.left_article != null
|
||||
) {
|
||||
await languageInstance("ru").patch(
|
||||
`/article/${this.sight.common.left_article}`,
|
||||
{
|
||||
@ -306,6 +310,9 @@ class EditSightStore {
|
||||
|
||||
for (const language of ["ru", "en", "zh"] as Language[]) {
|
||||
for (const article of this.sight[language].right) {
|
||||
if (article.id == 0 || article.id == null) {
|
||||
continue;
|
||||
}
|
||||
await languageInstance(language).patch(`/article/${article.id}`, {
|
||||
heading: article.heading,
|
||||
body: article.body,
|
||||
|
Reference in New Issue
Block a user