feat: Refactor old code with delete
modal and icons
for buttons
This commit is contained in:
@ -14,7 +14,8 @@ import {
|
||||
SelectArticleModal,
|
||||
TabPanel,
|
||||
SelectMediaDialog, // Import
|
||||
UploadMediaDialog, // Import
|
||||
UploadMediaDialog,
|
||||
Media, // Import
|
||||
} from "@shared";
|
||||
import {
|
||||
LanguageSwitcher,
|
||||
@ -22,12 +23,14 @@ import {
|
||||
MediaAreaForSight, // Import
|
||||
ReactMarkdownComponent,
|
||||
ReactMarkdownEditor,
|
||||
DeleteModal,
|
||||
} from "@widgets";
|
||||
import { ImagePlus, Plus, X } from "lucide-react"; // Import X
|
||||
import { ImagePlus, Plus, Save, Trash2, Unlink, X } from "lucide-react"; // Import X
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useState, useEffect } from "react"; // Added useEffect
|
||||
import { MediaViewer } from "../../MediaViewer/index";
|
||||
import { toast } from "react-toastify";
|
||||
import { authInstance } from "@shared";
|
||||
|
||||
type MediaItemShared = {
|
||||
// Define if not already available from @shared
|
||||
@ -65,14 +68,27 @@ export const CreateRightTab = observer(
|
||||
null
|
||||
);
|
||||
const [type, setType] = useState<"article" | "media">("media");
|
||||
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
|
||||
useState(false);
|
||||
const [mediaTarget, setMediaTarget] = useState<
|
||||
"sightPreview" | "rightArticle" | null
|
||||
>(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 () => {
|
||||
const response = await authInstance.get(
|
||||
`/media/${sight.preview_media}`
|
||||
);
|
||||
setPreviewMedia(response.data);
|
||||
};
|
||||
fetchMedia();
|
||||
}
|
||||
}, [sight.preview_media]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
activeArticleIndex !== null &&
|
||||
@ -168,6 +184,7 @@ export const CreateRightTab = observer(
|
||||
|
||||
const handleMediaSelectedFromDialog = async (media: MediaItemShared) => {
|
||||
setIsSelectMediaDialogOpen(false);
|
||||
|
||||
if (mediaTarget === "sightPreview") {
|
||||
await linkPreviewMedia(media.id);
|
||||
} else if (mediaTarget === "rightArticle" && currentRightArticle) {
|
||||
@ -176,6 +193,11 @@ export const CreateRightTab = observer(
|
||||
setMediaTarget(null);
|
||||
};
|
||||
|
||||
const handleUnlinkPreviewMedia = async () => {
|
||||
await unlinkPreviewMedia();
|
||||
setPreviewMedia(null);
|
||||
};
|
||||
|
||||
const handleMediaUploaded = async (media: MediaItemShared) => {
|
||||
// After UploadMediaDialog finishes
|
||||
setUploadMediaOpen(false);
|
||||
@ -273,12 +295,13 @@ export const CreateRightTab = observer(
|
||||
|
||||
{/* Main content area: Article Editor or Sight Media Preview */}
|
||||
{type === "article" && currentRightArticle ? (
|
||||
<Box className="w-[80%] border border-gray-300 rounded-2xl p-3 flex flex-col gap-2 overflow-hidden">
|
||||
<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">
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="warning"
|
||||
color="primary"
|
||||
size="small"
|
||||
startIcon={<Unlink color="white" size={18} />}
|
||||
onClick={() => {
|
||||
if (currentRightArticle) {
|
||||
unlinkRightAritcle(currentRightArticle.id); // Corrected function name
|
||||
@ -293,22 +316,9 @@ export const CreateRightTab = observer(
|
||||
variant="contained"
|
||||
color="error"
|
||||
size="small"
|
||||
startIcon={<Trash2 size={18} />}
|
||||
onClick={async () => {
|
||||
if (
|
||||
currentRightArticle &&
|
||||
window.confirm(
|
||||
`Удалить статью "${currentRightArticle.heading}" окончательно?`
|
||||
)
|
||||
) {
|
||||
try {
|
||||
await deleteRightArticle(currentRightArticle.id);
|
||||
setActiveArticleIndex(null);
|
||||
setType("media");
|
||||
toast.success("Статья удалена");
|
||||
} catch {
|
||||
toast.error("Не удалось удалить статью");
|
||||
}
|
||||
}
|
||||
setIsDeleteModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Удалить
|
||||
@ -373,28 +383,30 @@ export const CreateRightTab = observer(
|
||||
) : type === "media" ? (
|
||||
<Box className="w-[80%] h-[70vh] border border-gray-300 rounded-2xl p-3 relative flex justify-center items-center">
|
||||
{type === "media" && (
|
||||
<Box className="w-[80%] border border-gray-300 rounded-2xl relative">
|
||||
{sight.preview_media && (
|
||||
<Box className="w-[80%] border border-gray-300 rounded-2xl relative flex items-center justify-center">
|
||||
{previewMedia && (
|
||||
<>
|
||||
<Box className="absolute top-4 right-4">
|
||||
<Box className="absolute top-4 right-4 z-10">
|
||||
<button
|
||||
className="w-10 h-10 flex items-center justify-center"
|
||||
onClick={unlinkPreviewMedia}
|
||||
className="w-10 h-10 flex items-center justify-center z-10"
|
||||
onClick={handleUnlinkPreviewMedia}
|
||||
>
|
||||
<X size={20} color="red" />
|
||||
</button>
|
||||
</Box>
|
||||
|
||||
<MediaViewer
|
||||
media={{
|
||||
id: sight.preview_media || "",
|
||||
media_type: 1,
|
||||
filename: sight.preview_media || "",
|
||||
}}
|
||||
/>
|
||||
<Box sx={{}}>
|
||||
<MediaViewer
|
||||
media={{
|
||||
id: previewMedia.id || "",
|
||||
media_type: previewMedia.media_type,
|
||||
filename: previewMedia.filename || "",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
{!sight.preview_media && (
|
||||
{!previewMedia && (
|
||||
<MediaAreaForSight
|
||||
onFinishUpload={(mediaId) => {
|
||||
linkPreviewMedia(mediaId);
|
||||
@ -505,33 +517,6 @@ export const CreateRightTab = observer(
|
||||
</Box>
|
||||
</Paper>
|
||||
)}
|
||||
{/* Optional: Preview for sight.preview_media when type === "media" */}
|
||||
{type === "media" && sight.preview_media && (
|
||||
<Paper
|
||||
className="flex-1 flex flex-col rounded-2xl"
|
||||
elevation={2}
|
||||
sx={{ height: "75vh", overflow: "hidden" }}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
background: "#877361",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<MediaViewer
|
||||
media={{
|
||||
id: sight.preview_media,
|
||||
filename: sight.preview_media,
|
||||
media_type: 1,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Paper>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@ -539,17 +524,15 @@ export const CreateRightTab = observer(
|
||||
<Box
|
||||
sx={{
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
bottom: "-20px",
|
||||
left: 0, // ensure it spans from left
|
||||
right: 0,
|
||||
padding: 2,
|
||||
backgroundColor: "background.paper",
|
||||
borderTop: "1px solid", // Add a subtle top border
|
||||
borderColor: "divider", // Use theme's divider color
|
||||
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
boxShadow: "0 -2px 5px rgba(0,0,0,0.1)", // Optional shadow
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
@ -557,8 +540,9 @@ export const CreateRightTab = observer(
|
||||
color="success"
|
||||
onClick={handleSave}
|
||||
size="large"
|
||||
startIcon={<Save color="white" size={18} />}
|
||||
>
|
||||
Сохранить достопримечательность
|
||||
Сохранить
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
@ -588,6 +572,20 @@ export const CreateRightTab = observer(
|
||||
}}
|
||||
onSelectMedia={handleMediaSelectedFromDialog}
|
||||
/>
|
||||
<DeleteModal
|
||||
open={isDeleteModalOpen}
|
||||
onDelete={async () => {
|
||||
try {
|
||||
await deleteRightArticle(currentRightArticle?.id || 0);
|
||||
setActiveArticleIndex(null);
|
||||
setType("media");
|
||||
toast.success("Статья удалена");
|
||||
} catch {
|
||||
toast.error("Не удалось удалить статью");
|
||||
}
|
||||
}}
|
||||
onCancel={() => setIsDeleteModalOpen(false)}
|
||||
/>
|
||||
</TabPanel>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user