fix: Delete ai comments

This commit is contained in:
2025-11-06 00:58:10 +03:00
parent 5298fb9f60
commit 1917b2cf5a
41 changed files with 203 additions and 1107 deletions

View File

@@ -1,4 +1,3 @@
// @shared/stores/createSightStore.ts
import {
articlesStore,
Language,
@@ -27,7 +26,6 @@ type SightLanguageInfo = {
};
type SightCommonInfo = {
// id: number; // ID is 0 until created
city_id: number;
city: string;
latitude: number;
@@ -35,13 +33,11 @@ type SightCommonInfo = {
thumbnail: string | null;
watermark_lu: string | null;
watermark_rd: string | null;
left_article: number; // Can be 0 or a real ID, or placeholder like 10000000
left_article: number;
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;
};
@@ -78,7 +74,7 @@ const initialSightState: SightBaseInfo = {
};
class CreateSightStore {
sight: SightBaseInfo = JSON.parse(JSON.stringify(initialSightState)); // Deep copy for reset
sight: SightBaseInfo = JSON.parse(JSON.stringify(initialSightState));
uploadMediaOpen = false;
setUploadMediaOpen = (open: boolean) => {
@@ -93,9 +89,7 @@ class CreateSightStore {
makeAutoObservable(this);
}
// --- Right Article Management ---
createNewRightArticle = async () => {
// Create article in DB for all languages
const articleRuData = {
heading: "Новый заголовок (RU)",
body: "Новый текст (RU)",
@@ -125,7 +119,7 @@ class CreateSightStore {
},
},
});
const { id } = articleRes.data; // New article's ID
const { id } = articleRes.data;
runInAction(() => {
const newArticleEntry = { id, media: [] };
@@ -133,7 +127,7 @@ class CreateSightStore {
this.sight.en.right.push({ ...newArticleEntry, ...articleEnData });
this.sight.zh.right.push({ ...newArticleEntry, ...articleZhData });
});
return id; // Return ID for potential immediate use
return id;
} catch (error) {
console.error("Error creating new right article:", error);
throw error;
@@ -169,7 +163,7 @@ class CreateSightStore {
});
});
return articleId; // Return the linked article ID
return articleId;
} catch (error) {
console.error("Error linking existing right article:", error);
throw error;
@@ -188,9 +182,7 @@ class CreateSightStore {
}
};
// "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
@@ -202,16 +194,12 @@ class CreateSightStore {
(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
await authInstance.delete(`/article/${articleId}`);
runInAction(() => {
// Remove from local store for all languages
this.sight.ru.right = this.sight.ru.right.filter(
(article) => article.id !== articleId
);
@@ -228,12 +216,11 @@ class CreateSightStore {
}
};
// --- 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
media_order: 1,
});
runInAction(() => {
(["ru", "en", "zh"] as Language[]).forEach((lang) => {
@@ -242,7 +229,7 @@ class CreateSightStore {
);
if (article) {
if (!article.media) article.media = [];
article.media.unshift(media); // Add to the beginning
article.media.unshift(media);
}
});
});
@@ -273,7 +260,6 @@ class CreateSightStore {
}
};
// --- 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;
@@ -323,7 +309,7 @@ class CreateSightStore {
deleteLeftArticle = async (articleId: number) => {
/* ... your existing logic ... */
await authInstance.delete(`/article/${articleId}`);
// articlesStore.getArticles(languageStore.language); // If still neede
runInAction(() => {
articlesStore.articles.ru = articlesStore.articles.ru.filter(
(article) => article.id !== articleId
@@ -344,7 +330,6 @@ class CreateSightStore {
const enName = (this.sight.en.name || "").trim();
const zhName = (this.sight.zh.name || "").trim();
// If all names are empty, skip defaulting and use empty headings
const hasAnyName = !!(ruName || enName || zhName);
const response = await languageInstance("ru").post("/article", {
@@ -363,7 +348,7 @@ class CreateSightStore {
});
runInAction(() => {
this.sight.left_article = newLeftArticleId; // Store the actual ID
this.sight.left_article = newLeftArticleId;
this.sight.ru.left = {
heading: hasAnyName ? ruName : "",
body: "",
@@ -402,9 +387,8 @@ class CreateSightStore {
return newLeftArticleId;
};
// Placeholder for a "new" unsaved left article
setNewLeftArticlePlaceholder = () => {
this.sight.left_article = 10000000; // Special placeholder ID
this.sight.left_article = 10000000;
this.sight.ru.left = {
heading: "Новая левая статья",
body: "Заполните контентом",
@@ -422,7 +406,6 @@ class CreateSightStore {
};
};
// --- Sight Preview Media ---
linkPreviewMedia = (mediaId: string) => {
this.sight.preview_media = mediaId;
};
@@ -431,32 +414,27 @@ class CreateSightStore {
this.sight.preview_media = null;
};
// --- General Store Methods ---
clearCreateSight = () => {
this.needLeaveAgree = false;
this.sight = JSON.parse(JSON.stringify(initialSightState)); // Reset to initial
this.sight = JSON.parse(JSON.stringify(initialSightState));
};
updateSightInfo = (
content: Partial<SightLanguageInfo | SightCommonInfo>, // Corrected types
content: Partial<SightLanguageInfo | SightCommonInfo>,
language?: Language
) => {
this.needLeaveAgree = true;
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,
@@ -474,7 +452,6 @@ class CreateSightStore {
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 }
@@ -488,10 +465,7 @@ class CreateSightStore {
{ 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) {
@@ -501,14 +475,12 @@ class CreateSightStore {
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,
@@ -528,9 +500,8 @@ class CreateSightStore {
"/sight",
sightPayload
);
const newSightId = response.data.id; // ID of the newly created sight
const newSightId = response.data.id;
// 4. Update other languages for the sight
const otherLanguages = (["ru", "en", "zh"] as Language[]).filter(
(l) => l !== primaryLanguage
);
@@ -551,20 +522,17 @@ class CreateSightStore {
});
}
// 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
page_num: i + 1,
});
}
// Optionally: this.clearCreateSight(); // To reset form after successful creation
this.needLeaveAgree = false;
return newSightId;
};
// --- Media Upload (Generic, used by dialogs) ---
uploadMedia = async (
filename: string,
type: number,
@@ -583,12 +551,12 @@ class CreateSightStore {
this.fileToUpload = null;
this.uploadMediaOpen = false;
});
mediaStore.getMedia(); // Refresh global media list
mediaStore.getMedia();
return {
id: response.data.id,
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
filename: filename,
media_name: media_name,
media_type: type,
};
} catch (error) {
console.error("Error uploading media:", error);
@@ -596,15 +564,12 @@ class CreateSightStore {
}
};
// 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 {
@@ -663,7 +628,7 @@ class CreateSightStore {
this.sight.ru.right = sortArticles(this.sight.ru.right);
this.sight.en.right = sortArticles(this.sight.en.right);
this.sight.zh.right = sortArticles(this.sight.zh.right); // теперь zh тоже сортируется одинаково
this.sight.zh.right = sortArticles(this.sight.zh.right);
this.needLeaveAgree = true;
};