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

@@ -13,28 +13,27 @@ import {
languageStore,
SelectArticleModal,
TabPanel,
SelectMediaDialog, // Import
SelectMediaDialog,
UploadMediaDialog,
Media, // Import
Media,
} from "@shared";
import {
LanguageSwitcher,
MediaArea, // Import
MediaAreaForSight, // Import
MediaArea,
MediaAreaForSight,
ReactMarkdownComponent,
ReactMarkdownEditor,
DeleteModal,
} from "@widgets";
import { ImagePlus, Plus, Save, Trash2, Unlink, X } from "lucide-react"; // Import X
import { ImagePlus, Plus, Save, Trash2, Unlink, X } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useState, useEffect } from "react"; // Added useEffect
import { useState, useEffect } from "react";
import { MediaViewer } from "../../MediaViewer/index";
import { toast } from "react-toastify";
import { authInstance } from "@shared";
import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
type MediaItemShared = {
// Define if not already available from @shared
id: string;
filename: string;
media_name?: string;
@@ -52,14 +51,14 @@ export const CreateRightTab = observer(
unlinkPreviewMedia,
createLinkWithRightArticle,
deleteRightArticleMedia,
setFileToUpload, // From store
setUploadMediaOpen, // From store
uploadMediaOpen, // From store
unlinkRightAritcle, // Corrected spelling
setFileToUpload,
setUploadMediaOpen,
uploadMediaOpen,
unlinkRightAritcle,
deleteRightArticle,
linkExistingRightArticle,
createSight,
clearCreateSight, // For resetting form
clearCreateSight,
updateRightArticles,
} = createSightStore;
const { language } = languageStore;
@@ -78,7 +77,7 @@ export const CreateRightTab = observer(
>(null);
const [previewMedia, setPreviewMedia] = useState<Media | null>(null);
// Reset activeArticleIndex if language changes and index is out of bounds
useEffect(() => {
if (sight.preview_media) {
const fetchMedia = async () => {
@@ -97,7 +96,7 @@ export const CreateRightTab = observer(
activeArticleIndex >= sight[language].right.length
) {
setActiveArticleIndex(null);
setType("media"); // Default back to media preview if selected article disappears
setType("media");
}
}, [language, sight[language].right, activeArticleIndex]);
@@ -113,10 +112,9 @@ export const CreateRightTab = observer(
try {
await createSight(language);
toast.success("Достопримечательность успешно создана!");
clearCreateSight(); // Reset form
clearCreateSight();
setActiveArticleIndex(null);
setType("media");
// Potentially navigate away: history.push('/sights-list');
} catch (error) {
console.error("Failed to save sight:", error);
toast.error("Ошибка при создании достопримечательности.");
@@ -132,7 +130,7 @@ export const CreateRightTab = observer(
handleCloseMenu();
try {
const newArticleId = await createNewRightArticle();
// Automatically select the new article if ID is returned
const newIndex = sight[language].right.findIndex(
(a) => a.id === newArticleId
);
@@ -140,7 +138,6 @@ export const CreateRightTab = observer(
setActiveArticleIndex(newIndex);
setType("article");
} else {
// Fallback if findIndex fails (should not happen if store updates correctly)
setActiveArticleIndex(sight[language].right.length - 1);
setType("article");
}
@@ -156,7 +153,7 @@ export const CreateRightTab = observer(
const linkedArticleId = await linkExistingRightArticle(
selectedArticleId
);
setSelectArticleDialogOpen(false); // Close dialog
setSelectArticleDialogOpen(false);
const newIndex = sight[language].right.findIndex(
(a) => a.id === linkedArticleId
);
@@ -174,7 +171,6 @@ export const CreateRightTab = observer(
? sight[language].right[activeArticleIndex]
: null;
// Media Handling for Dialogs
const handleOpenUploadMedia = () => {
setUploadMediaOpen(true);
};
@@ -203,7 +199,6 @@ export const CreateRightTab = observer(
};
const handleMediaUploaded = async (media: MediaItemShared) => {
// After UploadMediaDialog finishes
setUploadMediaOpen(false);
setFileToUpload(null);
if (mediaTarget === "sightPreview") {
@@ -211,36 +206,25 @@ export const CreateRightTab = observer(
} else if (mediaTarget === "rightArticle" && currentRightArticle) {
await createLinkWithRightArticle(media, currentRightArticle.id);
}
setMediaTarget(null); // Reset target
setMediaTarget(null);
};
const handleDragEnd = (result: any) => {
const { source, destination } = result;
// 1. Guard clause: If dropped outside any droppable area, do nothing.
if (!destination) return;
// Extract source and destination indices
const sourceIndex = source.index;
const destinationIndex = destination.index;
// 2. Guard clause: If dropped in the same position, do nothing.
if (sourceIndex === destinationIndex) return;
// 3. Create a new array with reordered articles:
// - Create a shallow copy of the current articles array.
// This is important for immutability and triggering re-renders.
const newRightArticles = [...sight[language].right];
// - Remove the dragged article from its original position.
// `splice` returns an array of removed items, so we destructure the first (and only) one.
const [movedArticle] = newRightArticles.splice(sourceIndex, 1);
// - Insert the moved article into its new position.
newRightArticles.splice(destinationIndex, 0, movedArticle);
// 4. Update the store with the new order:
// This will typically trigger a re-render of the component with the updated list.
updateRightArticles(newRightArticles);
};
@@ -254,7 +238,7 @@ export const CreateRightTab = observer(
height: "100%",
minHeight: "calc(100vh - 200px)",
gap: 2,
paddingBottom: "70px", // Space for the save button
paddingBottom: "70px",
position: "relative",
}}
>
@@ -264,7 +248,6 @@ export const CreateRightTab = observer(
</div>
<Box sx={{ display: "flex", flexGrow: 1, gap: 2.5 }}>
{/* Left Column: Navigation & Article List */}
<Box className="flex flex-col w-[75%] gap-2">
<Box className="w-full flex gap-2 ">
<Box className="relative w-[20%] h-[70vh] flex flex-col rounded-2xl overflow-y-auto gap-3 border border-gray-300 p-3">
@@ -272,7 +255,6 @@ export const CreateRightTab = observer(
<Box
onClick={() => {
setType("media");
// setActiveArticleIndex(null); // Optional: deselect article when switching to general media view
}}
className={`w-full p-4 rounded-2xl cursor-pointer text-sm hover:bg-gray-300 transition-all duration-300 ${
type === "media"
@@ -364,7 +346,6 @@ export const CreateRightTab = observer(
</Menu>
</Box>
{/* Main content area: Article Editor or Sight Media Preview */}
{type === "article" && currentRightArticle ? (
<Box className="w-[80%] border border-gray-300 p-3 flex flex-col gap-2 overflow-hidden">
<Box className="flex justify-end gap-2 mb-1 flex-shrink-0">
@@ -375,7 +356,7 @@ export const CreateRightTab = observer(
startIcon={<Unlink color="white" size={18} />}
onClick={() => {
if (currentRightArticle) {
unlinkRightAritcle(currentRightArticle.id); // Corrected function name
unlinkRightAritcle(currentRightArticle.id);
setActiveArticleIndex(null);
setType("media");
}
@@ -435,7 +416,7 @@ export const CreateRightTab = observer(
/>
</Box>
<MediaArea
articleId={currentRightArticle.id} // Needs a real ID
articleId={currentRightArticle.id}
mediaIds={currentRightArticle.media || []}
onFilesDrop={(files) => {
if (files.length > 0) {
@@ -507,7 +488,6 @@ export const CreateRightTab = observer(
</Box>
</Box>
{/* Right Column: Live Preview */}
<Box className="w-[25%] mr-10">
{type === "article" && activeArticleIndex !== null && (
<Paper
@@ -662,12 +642,11 @@ export const CreateRightTab = observer(
</Box>
</Box>
{/* Sticky Save Button Footer */}
<Box
sx={{
position: "absolute",
bottom: "-20px",
left: 0, // ensure it spans from left
left: 0,
right: 0,
padding: 2,
backgroundColor: "background.paper",
@@ -689,19 +668,17 @@ export const CreateRightTab = observer(
</Box>
</Box>
{/* Modals */}
<SelectArticleModal
open={selectArticleDialogOpen}
onClose={() => setSelectArticleDialogOpen(false)}
onSelectArticle={handleSelectExistingArticleAndLink}
// Pass IDs of already linked/added right articles to exclude them from selection
linkedArticleIds={sight[language].right.map((article) => article.id)}
/>
<UploadMediaDialog
open={uploadMediaOpen} // From store
open={uploadMediaOpen}
onClose={() => {
setUploadMediaOpen(false);
setFileToUpload(null); // Clear file if dialog is closed without upload
setFileToUpload(null);
setMediaTarget(null);
}}
contextObjectName={sight[language].name}
@@ -712,7 +689,7 @@ export const CreateRightTab = observer(
? sight[language].right[activeArticleIndex].heading
: undefined
}
afterUpload={handleMediaUploaded} // This will use the mediaTarget
afterUpload={handleMediaUploaded}
/>
<SelectMediaDialog
open={isSelectMediaDialogOpen}