import { Box, Button, Typography, TextField, Slider, Stack, } from "@mui/material"; import { authInstance, BackButton, editSightStore, languageStore, SelectMediaDialog, TabPanel, UploadMediaDialog, } from "@shared"; import { DeleteModal, LanguageSwitcher, MediaArea, MediaAreaForSight, ReactMarkdownEditor, } from "@widgets"; import { Plus, Save, Trash2, Unlink, X } from "lucide-react"; import { observer } from "mobx-react-lite"; import { useEffect, useRef, useState } from "react"; import { toast } from "react-toastify"; import { MediaViewer } from "../../MediaViewer/index"; import { DragDropContext, Droppable, Draggable, DropResult, } from "@hello-pangea/dnd"; import { SightFramePreview } from "./SightFramePreview"; export const RightWidgetTab = observer( ({ value, index }: { value: number; index: number }) => { const { sight, updateRightArticleInfo, getRightArticles, updateSight, updateSightInfo, unlinkPreviewMedia, linkPreviewMedia, unlinkRightArticle, deleteRightArticle, deleteRightArticleMedia, createLinkWithRightArticle, setFileToUpload, createNewRightArticle, updateRightArticles, } = editSightStore; const [previewMedia, setPreviewMedia] = useState(null); const shortNameRef = useRef(null); const insertNewline = () => { const input = shortNameRef.current; const currentValue = sight[language].name || ""; if (!input) { updateSightInfo(language, { name: currentValue + "\n" }); return; } const start = input.selectionStart ?? currentValue.length; const end = input.selectionEnd ?? start; const newValue = currentValue.slice(0, start) + "\n" + currentValue.slice(end); updateSightInfo(language, { name: newValue }); requestAnimationFrame(() => { if (shortNameRef.current) { shortNameRef.current.selectionStart = start + 1; shortNameRef.current.selectionEnd = start + 1; shortNameRef.current.focus(); } }); }; useEffect(() => { const fetchPreviewMedia = async () => { if (sight.common.preview_media) { const response = await authInstance.get( `/media/${sight.common.preview_media}` ); setPreviewMedia(response.data); } }; fetchPreviewMedia(); }, [sight.common.preview_media]); const handleUnlinkPreviewMedia = () => { unlinkPreviewMedia(); setPreviewMedia(null); }; const [uploadMediaOpen, setUploadMediaOpen] = useState(false); const { language } = languageStore; const [type, setType] = useState<"article" | "media">("media"); useEffect(() => { const fetchData = async () => { if (sight.common.id) { await getRightArticles(sight.common.id); } }; fetchData(); }, [sight.common.id]); const [activeArticleIndex, setActiveArticleIndex] = useState( null ); const [previewSection, setPreviewSection] = useState(-1); const [isSelectMediaModalOpen, setIsSelectMediaModalOpen] = useState(false); const [isDeleteArticleModalOpen, setIsDeleteArticleModalOpen] = useState(false); const handleDeleteArticle = () => { const idx = activeArticleIndex || 0; deleteRightArticle(sight[language].right[idx].id); if (idx > 0) { setActiveArticleIndex(idx - 1); setPreviewSection(idx - 1); setType("article"); } else { setActiveArticleIndex(null); setPreviewSection(-1); setType("media"); } }; const handleSelectArticle = (index: number) => { setActiveArticleIndex(index); }; const handleCreateNew = async () => { try { const newArticleId = await createNewRightArticle(); const newIndex = sight[language].right.findIndex( (article) => article.id === newArticleId ); if (newIndex > -1) { setActiveArticleIndex(newIndex); setType("article"); setPreviewSection(newIndex); } } catch (error) { console.error("Error creating new article:", error); } }; const handleMediaSelected = async (media: { id: string; filename: string; media_name?: string; media_type: number; }) => { await createLinkWithRightArticle( media, sight[language].right[activeArticleIndex || 0].id ); }; const handleSave = async () => { await updateSight(); toast.success("Достопримечательность сохранена"); }; const handleDragEnd = (result: DropResult) => { const { source, destination } = result; if (!destination) return; const sourceIndex = source.index; const destinationIndex = destination.index; if (sourceIndex === destinationIndex) return; const newRightArticles = [...sight[language].right]; const [movedArticle] = newRightArticles.splice(sourceIndex, 1); newRightArticles.splice(destinationIndex, 0, movedArticle); updateRightArticles(newRightArticles); }; return (

{sight[language].name}

{ setType("media"); setPreviewSection(-1); }} className={`w-full p-4 rounded-2xl cursor-pointer text-sm transition-all duration-300 ${ type === "media" ? "bg-blue-400 text-white" : "bg-gray-200 hover:bg-gray-300" }`} > Предпросмотр медиа {(provided) => ( {sight[language].right.length > 0 ? sight[language].right.map( (article, index) => ( {(provided, snapshot) => ( { handleSelectArticle(index); setType("article"); setPreviewSection(index); }} > {article.heading} )} ) ) : null} {provided.placeholder} )} {type === "article" && ( {activeArticleIndex !== null && ( <> updateRightArticleInfo( activeArticleIndex, language, e.target.value, sight[language].right[activeArticleIndex].body ) } variant="outlined" fullWidth /> updateRightArticleInfo( activeArticleIndex, language, sight[language].right[activeArticleIndex] .heading, value ) } /> { setFileToUpload(files[0]); setUploadMediaOpen(true); }} deleteMedia={deleteRightArticleMedia} setSelectMediaDialogOpen={() => { setIsSelectMediaModalOpen(true); }} /> )} )} {type === "media" && ( {sight.common.preview_media && ( <> {type === "media" && ( {previewMedia && ( <> )} )} )} {!sight.common.preview_media && ( { linkPreviewMedia(mediaId); }} onFilesDrop={() => {}} contextObjectName={sight[language].name} contextType="sight" isArticle={false} /> )} )} {type === "media" && ( { const raw = e.target.value; if (raw === "") { updateSightInfo(language, { preview_font_size: undefined }, true); return; } const val = Math.max(1, Math.min(300, Math.round(Number(raw)))); if (Number.isFinite(val)) { updateSightInfo(language, { preview_font_size: val }, true); } }} slotProps={{ input: { min: 1, max: 300 } }} sx={{ width: "200px" }} /> { if (typeof newValue === "number") { updateSightInfo(language, { preview_font_size: newValue }, true); } }} sx={{ flexGrow: 1 }} /> )} updateSightInfo(language, { name: e.target.value })} inputRef={shortNameRef} sx={{ flexGrow: 1 }} /> { handleSelectArticle(idx); setType("article"); setPreviewSection(idx); }} previewFontSize={sight.common.preview_font_size} selectedSection={previewSection} onSectionChange={(section) => { setPreviewSection(section); if (section === -1) { setType("media"); } else { handleSelectArticle(section); setType("article"); } }} />
setUploadMediaOpen(false)} contextObjectName={sight[language].name} contextType="sight" isArticle={true} articleName={ activeArticleIndex !== null ? sight[language].right[activeArticleIndex].heading : "Правая статья" } afterUpload={async (media) => { setUploadMediaOpen(false); setFileToUpload(null); await createLinkWithRightArticle( media, sight[language].right[activeArticleIndex || 0].id ); }} /> setIsDeleteArticleModalOpen(false)} onDelete={() => { handleDeleteArticle(); setIsDeleteArticleModalOpen(false); }} /> setIsSelectMediaModalOpen(false)} onSelectMedia={handleMediaSelected} />
); } );