diff --git a/package.json b/package.json
index 54bdc7f..ae27d52 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
     "path": "^0.12.7",
     "react": "^19.1.0",
     "react-dom": "^19.1.0",
+    "react-dropzone": "^14.3.8",
     "react-markdown": "^10.1.0",
     "react-photo-sphere-viewer": "^6.2.3",
     "react-router-dom": "^7.6.1",
diff --git a/src/app/router/index.tsx b/src/app/router/index.tsx
index 8eabdb9..8afce23 100644
--- a/src/app/router/index.tsx
+++ b/src/app/router/index.tsx
@@ -6,8 +6,9 @@ import {
   MainPage,
   SightPage,
 } from "@pages";
-import { authStore, editSightStore, sightsStore } from "@shared";
+import { authStore, createSightStore, editSightStore } from "@shared";
 import { Layout } from "@widgets";
+import { runInAction } from "mobx";
 import { useEffect } from "react";
 
 import { Navigate, Outlet, Route, Routes, useLocation } from "react-router-dom";
@@ -34,10 +35,15 @@ const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
 
 export const Router = () => {
   const pathname = useLocation();
+
   useEffect(() => {
     editSightStore.clearSightInfo();
-    sightsStore.clearCreateSight();
+    createSightStore.clearCreateSight();
+    runInAction(() => {
+      editSightStore.hasLoadedCommon = false;
+    });
   }, [pathname]);
+
   return (
     <Routes>
       <Route
diff --git a/src/pages/CreateSightPage/index.tsx b/src/pages/CreateSightPage/index.tsx
index 38ed3a0..e5f0bfb 100644
--- a/src/pages/CreateSightPage/index.tsx
+++ b/src/pages/CreateSightPage/index.tsx
@@ -1,7 +1,6 @@
 import { Box, Tab, Tabs } from "@mui/material";
 import { articlesStore, cityStore, languageStore } from "@shared";
-import { InformationTab, RightWidgetTab } from "@widgets";
-import { LeftWidgetTab } from "@widgets";
+import { CreateInformationTab, CreateLeftTab, CreateRightTab } from "@widgets";
 import { useEffect, useState } from "react";
 import { observer } from "mobx-react-lite";
 
@@ -21,8 +20,11 @@ export const CreateSightPage = observer(() => {
   };
 
   useEffect(() => {
-    getCities();
-    getArticles(languageStore.language);
+    const fetchData = async () => {
+      await getCities();
+      await getArticles(languageStore.language);
+    };
+    fetchData();
   }, []);
 
   return (
@@ -60,9 +62,9 @@ export const CreateSightPage = observer(() => {
       </Box>
 
       <div className="flex-1">
-        <InformationTab value={value} index={0} />
-        <LeftWidgetTab value={value} index={1} />
-        <RightWidgetTab value={value} index={2} />
+        <CreateInformationTab value={value} index={0} />
+        <CreateLeftTab value={value} index={1} />
+        <CreateRightTab value={value} index={2} />
       </div>
     </Box>
   );
diff --git a/src/pages/EditSightPage/index.tsx b/src/pages/EditSightPage/index.tsx
index 73c104c..cd1f932 100644
--- a/src/pages/EditSightPage/index.tsx
+++ b/src/pages/EditSightPage/index.tsx
@@ -20,7 +20,7 @@ function a11yProps(index: number) {
 
 export const EditSightPage = observer(() => {
   const [value, setValue] = useState(0);
-  const { getSightInfo } = editSightStore;
+  const { sight, getSightInfo } = editSightStore;
   const { getArticles } = articlesStore;
   const { language } = languageStore;
   const { id } = useParams();
@@ -75,11 +75,13 @@ export const EditSightPage = observer(() => {
         </Tabs>
       </Box>
 
-      <div className="flex-1">
-        <InformationTab value={value} index={0} />
-        <LeftWidgetTab value={value} index={1} />
-        <RightWidgetTab value={value} index={2} />
-      </div>
+      {sight.common.id !== 0 && (
+        <div className="flex-1">
+          <InformationTab value={value} index={0} />
+          <LeftWidgetTab value={value} index={1} />
+          <RightWidgetTab value={value} index={2} />
+        </div>
+      )}
     </Box>
   );
 });
diff --git a/src/shared/modals/SelectArticleDialog/index.tsx b/src/shared/modals/SelectArticleDialog/index.tsx
index 8c0e831..0c709d6 100644
--- a/src/shared/modals/SelectArticleDialog/index.tsx
+++ b/src/shared/modals/SelectArticleDialog/index.tsx
@@ -1,4 +1,4 @@
-import { articlesStore } from "@shared";
+import { articlesStore, authInstance, languageStore } from "@shared";
 import { observer } from "mobx-react-lite";
 import { useEffect, useState } from "react";
 import {
@@ -22,8 +22,13 @@ import { ReactMarkdownComponent } from "@widgets";
 interface SelectArticleModalProps {
   open: boolean;
   onClose: () => void;
-  onSelectArticle: (articleId: string) => void;
-  linkedArticleIds?: string[]; // Add optional prop for linked articles
+  onSelectArticle: (
+    articleId: number,
+    heading: string,
+    body: string,
+    media: { id: string; media_type: number; filename: string }[]
+  ) => void;
+  linkedArticleIds?: number[]; // Add optional prop for linked articles
 }
 
 export const SelectArticleModal = observer(
@@ -35,7 +40,7 @@ export const SelectArticleModal = observer(
   }: SelectArticleModalProps) => {
     const { articles, getArticle, getArticleMedia } = articlesStore;
     const [searchQuery, setSearchQuery] = useState("");
-    const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
+    const [selectedArticleId, setSelectedArticleId] = useState<number | null>(
       null
     );
     const [isLoading, setIsLoading] = useState(false);
@@ -50,12 +55,21 @@ export const SelectArticleModal = observer(
     }, [open]);
 
     useEffect(() => {
-      const handleKeyPress = (event: KeyboardEvent) => {
+      const handleKeyPress = async (event: KeyboardEvent) => {
         if (event.key.toLowerCase() === "enter") {
           event.preventDefault();
           if (selectedArticleId) {
-            onSelectArticle(selectedArticleId);
+            const media = await authInstance.get(
+              `/article/${selectedArticleId}/media`
+            );
+            onSelectArticle(
+              selectedArticleId,
+              articlesStore.articleData?.heading || "",
+              articlesStore.articleData?.body || "",
+              media.data || []
+            );
             onClose();
+            setSelectedArticleId(null);
           }
         }
       };
@@ -66,9 +80,7 @@ export const SelectArticleModal = observer(
       };
     }, [selectedArticleId, onSelectArticle, onClose]);
 
-    const handleArticleClick = async (articleId: string) => {
-      if (selectedArticleId === articleId) return;
-
+    const handleArticleClick = async (articleId: number) => {
       setSelectedArticleId(articleId);
       setIsLoading(true);
 
@@ -86,14 +98,13 @@ export const SelectArticleModal = observer(
         setIsLoading(false);
       }
     };
-    // @ts-ignore
-    const filteredArticles = articles
-      // @ts-ignore
-      .filter((article) => !linkedArticleIds.includes(article.id))
-      // @ts-ignore
-      .filter((article) =>
-        article.service_name.toLowerCase().includes(searchQuery.toLowerCase())
-      );
+
+    const filteredArticles = articles[languageStore.language].filter(
+      (article) => !linkedArticleIds.includes(article.id)
+    );
+    // .filter((article) =>
+    //   article.service_name.toLowerCase().includes(searchQuery.toLowerCase())
+    // );
 
     const token = localStorage.getItem("token");
     return (
@@ -150,7 +161,17 @@ export const SelectArticleModal = observer(
                   <ListItemButton
                     key={article.id}
                     onClick={() => handleArticleClick(article.id)}
-                    onDoubleClick={() => onSelectArticle(article.id)}
+                    onDoubleClick={async () => {
+                      const media = await authInstance.get(
+                        `/article/${article.id}/media`
+                      );
+                      onSelectArticle(
+                        article.id,
+                        article.heading,
+                        article.body,
+                        media.data
+                      );
+                    }}
                     selected={selectedArticleId === article.id}
                     disabled={isLoading}
                     sx={{
@@ -288,9 +309,22 @@ export const SelectArticleModal = observer(
           <Button onClick={onClose}>Отмена</Button>
           <Button
             variant="contained"
-            onClick={() =>
-              selectedArticleId && onSelectArticle(selectedArticleId)
-            }
+            onClick={async () => {
+              if (selectedArticleId) {
+                const media = await authInstance.get(
+                  `/article/${selectedArticleId}/media`
+                );
+
+                onSelectArticle(
+                  selectedArticleId,
+                  articlesStore.articleData?.heading || "",
+                  articlesStore.articleData?.body || "",
+                  media.data
+                );
+                onClose();
+                setSelectedArticleId(null);
+              }
+            }}
             disabled={!selectedArticleId || isLoading}
           >
             Выбрать
diff --git a/src/shared/modals/SelectMediaDialog/index.tsx b/src/shared/modals/SelectMediaDialog/index.tsx
index 82cb785..75f7a93 100644
--- a/src/shared/modals/SelectMediaDialog/index.tsx
+++ b/src/shared/modals/SelectMediaDialog/index.tsx
@@ -1,6 +1,6 @@
 import { mediaStore } from "@shared";
 import { observer } from "mobx-react-lite";
-import { useEffect, useRef, useState } from "react";
+import { useEffect, useState } from "react";
 import {
   Dialog,
   DialogTitle,
@@ -21,7 +21,12 @@ import { MediaViewer } from "@widgets";
 interface SelectMediaDialogProps {
   open: boolean; // Corrected prop name
   onClose: () => void;
-  onSelectMedia: (mediaId: string) => void; // Renamed from onSelectArticle
+  onSelectMedia: (media: {
+    id: string;
+    filename: string;
+    media_name?: string;
+    media_type: number;
+  }) => void; // Renamed from onSelectArticle
   linkedMediaIds?: string[]; // Renamed from linkedArticleIds, assuming it refers to media already in use
 }
 
@@ -32,15 +37,14 @@ export const SelectMediaDialog = observer(
     onSelectMedia, // Renamed prop
     linkedMediaIds = [], // Default to empty array if not provided, renamed
   }: SelectMediaDialogProps) => {
-    const { media, getMedia } = mediaStore; // Confirmed: using mediaStore for media
+    const { media, getMedia } = mediaStore;
     const [searchQuery, setSearchQuery] = useState("");
     const [hoveredMediaId, setHoveredMediaId] = useState<string | null>(null);
-    const hoverTimerRef = useRef<NodeJS.Timeout | null>(null);
 
     // Fetch media on component mount
     useEffect(() => {
       getMedia();
-    }, [getMedia]); // getMedia should be a dependency to avoid lint warnings if it's not stable
+    }, [getMedia]);
 
     // Keyboard event listener for "Enter" key to select hovered media
     useEffect(() => {
@@ -49,7 +53,10 @@ export const SelectMediaDialog = observer(
           event.preventDefault(); // Prevent browser default action (e.g., form submission)
 
           if (hoveredMediaId) {
-            onSelectMedia(hoveredMediaId); // Call onSelectMedia
+            const mediaItem = media.find((m) => m.id === hoveredMediaId);
+            if (mediaItem) {
+              onSelectMedia(mediaItem);
+            }
             onClose();
           }
         }
@@ -61,26 +68,6 @@ export const SelectMediaDialog = observer(
       };
     }, [hoveredMediaId, onSelectMedia, onClose]); // Dependencies for keyboard listener
 
-    // Effect for handling hover timeout (if you want to clear the preview after a delay)
-    // Based on the original code, it seemed like you wanted a delay for showing,
-    // but typically for a preview, it's immediate on hover and cleared on mouse leave.
-    // I've removed the 5-second timeout for setting the ID as it's counter-intuitive for a live preview.
-    // If you intend for the preview to disappear after a short while *after* the mouse leaves,
-    // you would implement a mouseleave timer. For now, it will clear on mouseleave.
-
-    const handleMouseEnter = (mediaId: string) => {
-      if (hoverTimerRef.current) {
-        clearTimeout(hoverTimerRef.current);
-      }
-      setHoveredMediaId(mediaId);
-    };
-
-    const handleMouseLeave = () => {
-      // You can add a small delay here if you want the preview to linger for a moment
-      // before disappearing, e.g., setTimeout(() => setHoveredMediaId(null), 200);
-      setHoveredMediaId(null);
-    };
-
     const filteredMedia = media
       .filter((mediaItem) => !linkedMediaIds.includes(mediaItem.id)) // Use mediaItem to avoid name collision
       .filter((mediaItem) =>
@@ -125,9 +112,11 @@ export const SelectMediaDialog = observer(
                   ) => (
                     <ListItemButton
                       key={mediaItem.id}
-                      onClick={() => onSelectMedia(mediaItem.id)} // Call onSelectMedia
-                      onMouseEnter={() => handleMouseEnter(mediaItem.id)}
-                      onMouseLeave={handleMouseLeave}
+                      onClick={() => setHoveredMediaId(mediaItem.id)} // Call onSelectMedia
+                      onDoubleClick={() => {
+                        onSelectMedia(mediaItem);
+                        onClose();
+                      }}
                       sx={{
                         borderRadius: 1,
                         mb: 0.5,
diff --git a/src/shared/modals/UploadMediaDialog/index.tsx b/src/shared/modals/UploadMediaDialog/index.tsx
new file mode 100644
index 0000000..8b35bb8
--- /dev/null
+++ b/src/shared/modals/UploadMediaDialog/index.tsx
@@ -0,0 +1,259 @@
+import { MEDIA_TYPE_LABELS, editSightStore } from "@shared";
+import { observer } from "mobx-react-lite";
+import { useEffect, useState } from "react";
+import {
+  Dialog,
+  DialogTitle,
+  DialogContent,
+  DialogActions,
+  Button,
+  TextField,
+  Paper,
+  Box,
+  CircularProgress,
+  Alert,
+  Snackbar,
+  Select,
+  MenuItem,
+  FormControl,
+  InputLabel,
+} from "@mui/material";
+import { Save } from "lucide-react";
+import { ModelViewer3D } from "@widgets";
+
+interface UploadMediaDialogProps {
+  open: boolean;
+  onClose: () => void;
+  afterUpload: (media: {
+    id: string;
+    filename: string;
+    media_name?: string;
+    media_type: number;
+  }) => void;
+}
+
+export const UploadMediaDialog = observer(
+  ({ open, onClose, afterUpload }: UploadMediaDialogProps) => {
+    const [isLoading, setIsLoading] = useState(false);
+    const [error, setError] = useState<string | null>(null);
+    const [success, setSuccess] = useState(false);
+    const [mediaName, setMediaName] = useState("");
+    const [mediaFilename, setMediaFilename] = useState("");
+    const [mediaType, setMediaType] = useState(0);
+    const [mediaFile, setMediaFile] = useState<File | null>(null);
+    const { fileToUpload, uploadMedia } = editSightStore;
+    const [mediaUrl, setMediaUrl] = useState<string | null>(null);
+    const [availableMediaTypes, setAvailableMediaTypes] = useState<number[]>(
+      []
+    );
+
+    useEffect(() => {
+      if (fileToUpload) {
+        setMediaFile(fileToUpload);
+        setMediaFilename(fileToUpload.name);
+        // Try to determine media type from file extension
+        const extension = fileToUpload.name.split(".").pop()?.toLowerCase();
+        if (extension) {
+          if (["glb", "gltf"].includes(extension)) {
+            setAvailableMediaTypes([6]);
+            setMediaType(6);
+          }
+          if (["jpg", "jpeg", "png", "gif"].includes(extension)) {
+            // Для изображений доступны все типы кроме видео
+            setAvailableMediaTypes([1, 3, 4, 5]); // Фото, Иконка, Водяной знак, Панорама, 3Д-модель
+            setMediaType(1); // По умолчанию Фото
+          } else if (["mp4", "webm", "mov"].includes(extension)) {
+            // Для видео только тип Видео
+            setAvailableMediaTypes([2]);
+            setMediaType(2);
+          }
+        }
+      }
+    }, [fileToUpload]);
+
+    useEffect(() => {
+      if (mediaFile) {
+        setMediaUrl(URL.createObjectURL(mediaFile as Blob));
+      }
+    }, [mediaFile]);
+
+    // const fileFormat = useEffect(() => {
+    //   const handleKeyPress = (event: KeyboardEvent) => {
+    //     if (event.key.toLowerCase() === "enter" && !event.ctrlKey) {
+    //       event.preventDefault();
+    //       onClose();
+    //     }
+    //   };
+
+    //   window.addEventListener("keydown", handleKeyPress);
+    //   return () => window.removeEventListener("keydown", handleKeyPress);
+    // }, [onClose]);
+
+    const handleSave = async () => {
+      if (!mediaFile) return;
+
+      setIsLoading(true);
+      setError(null);
+
+      try {
+        const media = await uploadMedia(
+          mediaFilename,
+          mediaType,
+          mediaFile,
+          mediaName
+        );
+        if (media) {
+          await afterUpload(media);
+        }
+        setSuccess(true);
+      } catch (err) {
+        setError(err instanceof Error ? err.message : "Failed to save media");
+      } finally {
+        setIsLoading(false);
+      }
+    };
+
+    const handleClose = () => {
+      setError(null);
+      setSuccess(false);
+      onClose();
+    };
+
+    return (
+      <>
+        <Dialog open={open} onClose={handleClose} maxWidth="md" fullWidth>
+          <DialogTitle>Просмотр медиа</DialogTitle>
+          <DialogContent
+            className="flex gap-4"
+            dividers
+            sx={{
+              height: "600px",
+              display: "flex",
+              flexDirection: "column",
+              gap: 2,
+              pt: 2,
+            }}
+          >
+            <Box className="flex flex-col gap-4">
+              <Box className="flex gap-2">
+                <TextField
+                  fullWidth
+                  value={mediaName}
+                  onChange={(e) => setMediaName(e.target.value)}
+                  label="Название медиа"
+                  disabled={isLoading}
+                />
+                <TextField
+                  fullWidth
+                  value={mediaFilename}
+                  onChange={(e) => setMediaFilename(e.target.value)}
+                  label="Название файла"
+                  disabled={isLoading}
+                />
+              </Box>
+
+              <FormControl fullWidth sx={{ width: "50%" }}>
+                <InputLabel>Тип медиа</InputLabel>
+                <Select
+                  value={mediaType}
+                  label="Тип медиа"
+                  onChange={(e) => setMediaType(Number(e.target.value))}
+                  disabled={isLoading}
+                >
+                  {availableMediaTypes.map((type) => (
+                    <MenuItem key={type} value={type}>
+                      {
+                        MEDIA_TYPE_LABELS[
+                          type as keyof typeof MEDIA_TYPE_LABELS
+                        ]
+                      }
+                    </MenuItem>
+                  ))}
+                </Select>
+              </FormControl>
+
+              <Box className="flex gap-4 h-full">
+                <Paper
+                  elevation={2}
+                  sx={{
+                    flex: 1,
+                    p: 2,
+                    display: "flex",
+                    alignItems: "center",
+                    justifyContent: "center",
+                    minHeight: 400,
+                  }}
+                >
+                  {/* <MediaViewer
+                    media={{
+                      id: "",
+                      media_type: mediaType,
+                      filename: mediaFilename,
+                    }}
+                  /> */}
+                  {mediaType === 6 && mediaUrl && (
+                    <ModelViewer3D fileUrl={mediaUrl} height="100%" />
+                  )}
+                  {mediaType !== 6 && mediaType !== 2 && mediaUrl && (
+                    <img
+                      src={mediaUrl ?? ""}
+                      alt="Uploaded media"
+                      style={{
+                        maxWidth: "100%",
+                        maxHeight: "100%",
+                        objectFit: "contain",
+                      }}
+                    />
+                  )}
+                </Paper>
+
+                <Box className="flex flex-col gap-2 self-end">
+                  <Button
+                    variant="contained"
+                    color="success"
+                    startIcon={
+                      isLoading ? (
+                        <CircularProgress size={16} />
+                      ) : (
+                        <Save size={16} />
+                      )
+                    }
+                    onClick={handleSave}
+                    disabled={isLoading || (!mediaName && !mediaFilename)}
+                  >
+                    Сохранить
+                  </Button>
+                </Box>
+              </Box>
+            </Box>
+          </DialogContent>
+          <DialogActions>
+            <Button onClick={handleClose} disabled={isLoading}>
+              Отмена
+            </Button>
+          </DialogActions>
+        </Dialog>
+
+        <Snackbar
+          open={!!error}
+          autoHideDuration={6000}
+          onClose={() => setError(null)}
+        >
+          <Alert severity="error" onClose={() => setError(null)}>
+            {error}
+          </Alert>
+        </Snackbar>
+
+        <Snackbar
+          open={success}
+          autoHideDuration={3000}
+          onClose={() => setSuccess(false)}
+        >
+          <Alert severity="success" onClose={() => setSuccess(false)}>
+            Медиа успешно сохранено
+          </Alert>
+        </Snackbar>
+      </>
+    );
+  }
+);
diff --git a/src/shared/modals/index.ts b/src/shared/modals/index.ts
index 22df340..378cd4f 100644
--- a/src/shared/modals/index.ts
+++ b/src/shared/modals/index.ts
@@ -1,3 +1,4 @@
 export * from "./SelectArticleDialog";
 export * from "./SelectMediaDialog";
 export * from "./PreviewMediaDialog";
+export * from "./UploadMediaDialog";
diff --git a/src/shared/store/CityStore/index.tsx b/src/shared/store/CityStore/index.tsx
index 154d96d..4f87be0 100644
--- a/src/shared/store/CityStore/index.tsx
+++ b/src/shared/store/CityStore/index.tsx
@@ -17,6 +17,8 @@ class CityStore {
   }
 
   getCities = async () => {
+    if (this.cities.length !== 0) return;
+
     const response = await authInstance.get("/city");
     runInAction(() => {
       this.cities = response.data;
diff --git a/src/shared/store/CreateSightStore/index.tsx b/src/shared/store/CreateSightStore/index.tsx
new file mode 100644
index 0000000..227fcb4
--- /dev/null
+++ b/src/shared/store/CreateSightStore/index.tsx
@@ -0,0 +1,449 @@
+// @shared/stores/createSightStore.ts
+import {
+  Language,
+  authInstance,
+  languageInstance,
+  articlesStore,
+  languageStore,
+  mediaStore,
+} from "@shared";
+import { makeAutoObservable } from "mobx";
+
+type SightLanguageInfo = {
+  name: string;
+  address: string;
+  left: {
+    heading: string;
+    body: string;
+    media: {
+      id: string;
+      filename: string;
+      media_name?: string;
+      media_type: number;
+    }[];
+  };
+  right: { heading: string; body: string }[];
+};
+
+type SightCommonInfo = {
+  id: number;
+  city_id: number;
+  city: string;
+  latitude: number;
+  longitude: number;
+  thumbnail: string | null;
+  watermark_lu: string | null;
+  watermark_rd: string | null;
+  left_article: number;
+  preview_media: string | null;
+  video_preview: string | null;
+};
+
+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,
+
+    ru: {
+      name: "",
+      address: "",
+      left: { heading: "", body: "", media: [] },
+      right: [],
+    },
+    en: {
+      name: "",
+      address: "",
+      left: { heading: "", body: "", media: [] },
+      right: [],
+    },
+    zh: {
+      name: "",
+      address: "",
+      left: { heading: "", body: "", media: [] },
+      right: [],
+    },
+  };
+
+  uploadMediaOpen = false;
+  setUploadMediaOpen = (open: boolean) => {
+    this.uploadMediaOpen = open;
+  };
+  fileToUpload: File | null = null;
+  setFileToUpload = (file: File | null) => {
+    this.fileToUpload = file;
+  };
+
+  constructor() {
+    makeAutoObservable(this);
+  }
+
+  createNewRightArticle = () => {
+    this.sight.ru.right.push({
+      heading: "Введите русский заголовок",
+      body: "Введите русский текст",
+    });
+    this.sight.en.right.push({
+      heading: "Enter the English heading",
+      body: "Enter the English text",
+    });
+    this.sight.zh.right.push({
+      heading: "Введите китайский заголовок",
+      body: "Введите китайский текст",
+    });
+  };
+
+  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: [],
+      },
+    };
+  };
+
+  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}`
+      );
+
+      this.sight.ru.left.heading = ruArticleData.data.heading;
+      this.sight.en.left.heading = enArticleData.data.heading;
+      this.sight.zh.left.heading = zhArticleData.data.heading;
+
+      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,
+      });
+    });
+    console.log("created");
+  };
+
+  updateRightArticleInfo = (
+    index: number,
+    language: Language,
+    heading: string,
+    body: string
+  ) => {
+    this.sight[language].right[index].heading = heading;
+    this.sight[language].right[index].body = body;
+  };
+
+  uploadMedia = async (
+    filename: string,
+    type: number,
+    file: File,
+    media_name?: string
+  ) => {
+    const formData = new FormData();
+    formData.append("file", file);
+    formData.append("filename", filename);
+    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();
+      return {
+        id: response.data.id,
+        filename: filename,
+        media_name: media_name,
+        media_type: type,
+      };
+    } catch (error) {
+      console.log(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,
+    });
+  };
+}
+
+export const createSightStore = new CreateSightStore();
diff --git a/src/shared/store/EditSightStore/index.tsx b/src/shared/store/EditSightStore/index.tsx
index 19b8c8b..37af665 100644
--- a/src/shared/store/EditSightStore/index.tsx
+++ b/src/shared/store/EditSightStore/index.tsx
@@ -1,26 +1,31 @@
 // @shared/stores/editSightStore.ts
-import { authInstance, Language } from "@shared";
+import { authInstance, Language, languageInstance, mediaStore } from "@shared";
 import { makeAutoObservable, runInAction } from "mobx";
 
 export type SightLanguageInfo = {
   id: number;
   name: string;
   address: string;
-  left: { heading: string; body: string };
+  left: {
+    heading: string;
+    body: string;
+    media: { id: string; media_type: number; filename: string }[];
+  };
   right: { heading: string; body: string }[];
 };
 
 export type SightCommonInfo = {
+  id: number;
   city_id: number;
   city: string;
   latitude: number;
   longitude: number;
-  thumbnail: string;
-  watermark_lu: string;
-  watermark_rd: string;
+  thumbnail: string | null;
+  watermark_lu: string | null;
+  watermark_rd: string | null;
   left_article: number;
-  preview_media: string;
-  video_preview: string;
+  preview_media: string | null;
+  video_preview: string | null;
 };
 
 export type SightBaseInfo = {
@@ -31,36 +36,37 @@ export type SightBaseInfo = {
 class EditSightStore {
   sight: SightBaseInfo = {
     common: {
+      id: 0,
       city_id: 0,
       city: "",
       latitude: 0,
       longitude: 0,
-      thumbnail: "",
-      watermark_lu: "",
-      watermark_rd: "",
+      thumbnail: null,
+      watermark_lu: null,
+      watermark_rd: null,
       left_article: 0,
-      preview_media: "",
-      video_preview: "",
+      preview_media: null,
+      video_preview: null,
     },
     ru: {
       id: 0,
       name: "",
       address: "",
-      left: { heading: "", body: "" },
+      left: { heading: "", body: "", media: [] },
       right: [],
     },
     en: {
       id: 0,
       name: "",
       address: "",
-      left: { heading: "", body: "" },
+      left: { heading: "", body: "", media: [] },
       right: [],
     },
     zh: {
       id: 0,
       name: "",
       address: "",
-      left: { heading: "", body: "" },
+      left: { heading: "", body: "", media: [] },
       right: [],
     },
   };
@@ -77,6 +83,9 @@ class EditSightStore {
 
     const response = await authInstance.get(`/sight/${id}`);
     const data = response.data;
+    if (data.left_article != 0) {
+      await this.getLeftArticle(data.left_article);
+    }
 
     runInAction(() => {
       // Обновляем языковую часть
@@ -101,25 +110,62 @@ class EditSightStore {
     this.sight[language].left.body = body;
   };
 
+  getRightArticles = async (id: number) => {
+    const responseRu = await languageInstance("ru").get(`/sight/${id}/article`);
+    const responseEn = await languageInstance("en").get(`/sight/${id}/article`);
+    const responseZh = await languageInstance("zh").get(`/sight/${id}/article`);
+
+    const data = {
+      ru: {
+        right: responseRu.data,
+      },
+      en: {
+        right: responseEn.data,
+      },
+      zh: {
+        right: responseZh.data,
+      },
+    };
+    runInAction(() => {
+      this.sight = {
+        ...this.sight,
+        ru: {
+          ...this.sight.ru,
+          right: data.ru.right,
+        },
+        en: {
+          ...this.sight.en,
+          right: data.en.right,
+        },
+
+        zh: {
+          ...this.sight.zh,
+          right: data.zh.right,
+        },
+      };
+    });
+  };
+
   clearSightInfo = () => {
     this.sight = {
       common: {
+        id: 0,
         city_id: 0,
         city: "",
         latitude: 0,
         longitude: 0,
-        thumbnail: "",
-        watermark_lu: "",
-        watermark_rd: "",
+        thumbnail: null,
+        watermark_lu: null,
+        watermark_rd: null,
         left_article: 0,
-        preview_media: "",
-        video_preview: "",
+        preview_media: null,
+        video_preview: null,
       },
       ru: {
         id: 0,
         name: "",
         address: "",
-        left: { heading: "", body: "" },
+        left: { heading: "", body: "", media: [] },
         right: [],
       },
 
@@ -127,7 +173,7 @@ class EditSightStore {
         id: 0,
         name: "",
         address: "",
-        left: { heading: "", body: "" },
+        left: { heading: "", body: "", media: [] },
         right: [],
       },
 
@@ -135,7 +181,7 @@ class EditSightStore {
         id: 0,
         name: "",
         address: "",
-        left: { heading: "", body: "" },
+        left: { heading: "", body: "", media: [] },
         right: [],
       },
     };
@@ -158,6 +204,244 @@ class EditSightStore {
       };
     }
   };
+
+  unlinkLeftArticle = async () => {
+    this.sight.common.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 = "";
+  };
+
+  updateSight = async () => {
+    let createdLeftArticleId = this.sight.common.left_article;
+
+    if (this.sight.common.left_article == 10000000) {
+      const response = await languageInstance("ru").post(`/article`, {
+        heading: this.sight.ru.left.heading,
+        body: this.sight.ru.left.body,
+      });
+      createdLeftArticleId = response.data.id;
+      await languageInstance("en").patch(`/article/${createdLeftArticleId}`, {
+        heading: this.sight.en.left.heading,
+        body: this.sight.en.left.body,
+      });
+
+      await languageInstance("zh").patch(`/article/${createdLeftArticleId}`, {
+        heading: this.sight.zh.left.heading,
+        body: this.sight.zh.left.body,
+      });
+
+      this.sight.common.left_article = createdLeftArticleId;
+    } else if (this.sight.common.left_article != 0) {
+      await languageInstance("ru").patch(
+        `/article/${this.sight.common.left_article}`,
+        {
+          heading: this.sight.ru.left.heading,
+          body: this.sight.ru.left.body,
+        }
+      );
+      await languageInstance("en").patch(
+        `/article/${this.sight.common.left_article}`,
+        {
+          heading: this.sight.en.left.heading,
+          body: this.sight.en.left.body,
+        }
+      );
+
+      await languageInstance("zh").patch(
+        `/article/${this.sight.common.left_article}`,
+        {
+          heading: this.sight.zh.left.heading,
+          body: this.sight.zh.left.body,
+        }
+      );
+    }
+
+    await languageInstance("ru").patch(`/sight/${this.sight.common.id}`, {
+      ...this.sight.common,
+      name: this.sight.ru.name,
+      address: this.sight.ru.address,
+      left_article: createdLeftArticleId,
+    });
+    await languageInstance("en").patch(`/sight/${this.sight.common.id}`, {
+      ...this.sight.common,
+      name: this.sight.en.name,
+      address: this.sight.en.address,
+      left_article: createdLeftArticleId,
+    });
+    await languageInstance("zh").patch(`/sight/${this.sight.common.id}`, {
+      ...this.sight.common,
+      name: this.sight.zh.name,
+      address: this.sight.zh.address,
+      left_article: createdLeftArticleId,
+    });
+
+    if (this.sight.common.left_article == 0) {
+      return;
+    }
+
+    // await languageInstance("ru").patch(
+    //   `/sight/${this.sight.common.left_article}/article`,
+    //   {
+    //     heading: this.sight.ru.left.heading,
+    //     body: this.sight.ru.left.body,
+    //   }
+    // );
+    // await languageInstance("en").patch(
+    //   `/sight/${this.sight.common.left_article}/article`,
+    //   {
+    //     heading: this.sight.en.left.heading,
+    //     body: this.sight.en.left.body,
+    //   }
+    // );
+    // await languageInstance("zh").patch(
+    //   `/sight/${this.sight.common.left_article}/article`,
+    //   {
+    //     heading: this.sight.zh.left.heading,
+    //     body: this.sight.zh.left.body,
+    //   }
+    // );
+  };
+
+  getLeftArticle = async (id: number) => {
+    const response = await languageInstance("ru").get(`/article/${id}`);
+    const responseEn = await languageInstance("en").get(`/article/${id}`);
+    const responseZh = await languageInstance("zh").get(`/article/${id}`);
+    const mediaIds = await authInstance.get(`/article/${id}/media`);
+    runInAction(() => {
+      this.sight.ru.left = {
+        heading: response.data.heading,
+        body: response.data.body,
+        media: mediaIds.data,
+      };
+      this.sight.en.left = {
+        heading: responseEn.data.heading,
+        body: responseEn.data.body,
+        media: mediaIds.data,
+      };
+      this.sight.zh.left = {
+        heading: responseZh.data.heading,
+        body: responseZh.data.body,
+        media: mediaIds.data,
+      };
+    });
+  };
+
+  deleteLeftArticle = async (id: number) => {
+    await authInstance.delete(`/article/${id}`);
+    this.sight.common.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 = "";
+  };
+
+  createLeftArticle = async () => {
+    const response = await languageInstance("ru").post(`/article`, {
+      heading: "",
+      body: "",
+    });
+
+    this.sight.common.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 = "";
+  };
+
+  deleteMedia = async (article_id: number, media_id: string) => {
+    await authInstance.delete(`/article/${article_id}/media`, {
+      data: {
+        media_id: media_id,
+      },
+    });
+
+    this.sight.ru.left.media = this.sight.ru.left.media.filter(
+      (media) => media.id !== media_id
+    );
+    this.sight.en.left.media = this.sight.en.left.media.filter(
+      (media) => media.id !== media_id
+    );
+    this.sight.zh.left.media = this.sight.zh.left.media.filter(
+      (media) => media.id !== media_id
+    );
+  };
+
+  uploadMediaOpen = false;
+  setUploadMediaOpen = (open: boolean) => {
+    this.uploadMediaOpen = open;
+  };
+  fileToUpload: File | null = null;
+  setFileToUpload = (file: File | null) => {
+    this.fileToUpload = file;
+  };
+  uploadMedia = async (
+    filename: string,
+    type: number,
+    file: File,
+    media_name?: string
+  ) => {
+    const formData = new FormData();
+    formData.append("file", file);
+    formData.append("filename", filename);
+    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();
+      return {
+        id: response.data.id,
+        filename: filename,
+        media_name: media_name,
+        media_type: type,
+      };
+    } catch (error) {
+      console.log(error);
+    }
+  };
+
+  createLinkWithArticle = async (media: {
+    id: string;
+    filename: string;
+    media_name?: string;
+    media_type: number;
+  }) => {
+    await authInstance.post(
+      `/article/${this.sight.common.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,
+    });
+  };
 }
 
 export const editSightStore = new EditSightStore();
diff --git a/src/shared/store/index.ts b/src/shared/store/index.ts
index cb82e5c..efa6fe6 100644
--- a/src/shared/store/index.ts
+++ b/src/shared/store/index.ts
@@ -8,3 +8,4 @@ export * from "./CityStore";
 export * from "./ArticlesStore";
 export * from "./EditSightStore";
 export * from "./MediaStore";
+export * from "./CreateSightStore";
diff --git a/src/widgets/MediaArea/index.tsx b/src/widgets/MediaArea/index.tsx
new file mode 100644
index 0000000..4b66d6d
--- /dev/null
+++ b/src/widgets/MediaArea/index.tsx
@@ -0,0 +1,135 @@
+import { Box, Button } from "@mui/material";
+import { MediaViewer } from "@widgets";
+import { PreviewMediaDialog } from "@shared";
+import { X, Upload } from "lucide-react";
+import { observer } from "mobx-react-lite";
+import { useState, DragEvent, useRef } from "react";
+
+export const MediaArea = observer(
+  ({
+    articleId,
+    mediaIds,
+    deleteMedia,
+    onFilesDrop, // 👈 Проп для обработки загруженных файлов
+    setSelectMediaDialogOpen,
+  }: {
+    articleId: number;
+    mediaIds: { id: string; media_type: number; filename: string }[];
+    deleteMedia: (id: number, media_id: string) => void;
+    onFilesDrop?: (files: File[]) => void;
+    setSelectMediaDialogOpen: (open: boolean) => void;
+  }) => {
+    const [mediaModal, setMediaModal] = useState<boolean>(false);
+    const [mediaId, setMediaId] = useState<string>("");
+    const [isDragging, setIsDragging] = useState(false);
+    const fileInputRef = useRef<HTMLInputElement>(null);
+
+    const handleMediaModal = (mediaId: string) => {
+      setMediaModal(true);
+      setMediaId(mediaId);
+    };
+
+    const handleDrop = (e: DragEvent<HTMLDivElement>) => {
+      e.preventDefault();
+      e.stopPropagation();
+      setIsDragging(false);
+
+      const files = Array.from(e.dataTransfer.files);
+      if (files.length && onFilesDrop) {
+        onFilesDrop(files);
+      }
+    };
+
+    const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
+      e.preventDefault();
+      setIsDragging(true);
+    };
+
+    const handleDragLeave = () => {
+      setIsDragging(false);
+    };
+
+    const handleClick = () => {
+      fileInputRef.current?.click();
+    };
+
+    const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
+      const files = Array.from(event.target.files || []);
+      if (files.length && onFilesDrop) {
+        onFilesDrop(files);
+      }
+      // Сбрасываем значение input, чтобы можно было выбрать тот же файл снова
+      event.target.value = "";
+    };
+
+    return (
+      <>
+        <input
+          type="file"
+          ref={fileInputRef}
+          onChange={handleFileSelect}
+          accept="image/*,video/*,.glb,.gltf"
+          multiple
+          style={{ display: "none" }}
+        />
+        <Box className="w-full flex flex-col items-center justify-center border rounded-md p-4">
+          <div className="w-full flex flex-col items-center justify-center">
+            <div
+              className={`w-full h-40 flex flex-col justify-center items-center text-gray-400 border-dashed border-2 rounded-md border-gray-400 p-4 cursor-pointer hover:bg-gray-50 ${
+                isDragging ? "bg-blue-100 border-blue-400" : ""
+              }`}
+              onDrop={handleDrop}
+              onDragOver={handleDragOver}
+              onDragLeave={handleDragLeave}
+              onClick={handleClick}
+            >
+              <Upload size={32} className="mb-2" />
+              Перетащите медиа файлы сюда или нажмите для выбора
+            </div>
+            <div>или</div>
+            <Button
+              variant="contained"
+              color="primary"
+              onClick={() => setSelectMediaDialogOpen(true)}
+            >
+              Выбрать существующие медиа файлы
+            </Button>
+          </div>
+
+          <div className="w-full flex flex-start flex-wrap gap-2 mt-4">
+            {mediaIds.map((m) => (
+              <button
+                className="relative w-40 h-40"
+                key={m.id}
+                onClick={() => handleMediaModal(m.id)}
+              >
+                <MediaViewer
+                  media={{
+                    id: m.id,
+                    media_type: m.media_type,
+                    filename: m.filename,
+                  }}
+                />
+                <button
+                  className="absolute top-2 right-2"
+                  onClick={(e) => {
+                    e.stopPropagation();
+                    deleteMedia(articleId, m.id);
+                  }}
+                >
+                  <X size={16} color="red" />
+                </button>
+              </button>
+            ))}
+          </div>
+        </Box>
+
+        <PreviewMediaDialog
+          open={mediaModal}
+          onClose={() => setMediaModal(false)}
+          mediaId={mediaId}
+        />
+      </>
+    );
+  }
+);
diff --git a/src/widgets/ModelViewer3D/index.tsx b/src/widgets/ModelViewer3D/index.tsx
new file mode 100644
index 0000000..5648efd
--- /dev/null
+++ b/src/widgets/ModelViewer3D/index.tsx
@@ -0,0 +1,24 @@
+import { Stage, useGLTF } from "@react-three/drei";
+import { Canvas } from "@react-three/fiber";
+import { OrbitControls } from "@react-three/drei";
+
+export const ModelViewer3D = ({
+  fileUrl,
+  height = "100%",
+}: {
+  fileUrl: string;
+  height: string;
+}) => {
+  const { scene } = useGLTF(fileUrl);
+
+  return (
+    <Canvas style={{ width: "100%", height: height }}>
+      <ambientLight />
+      <directionalLight />
+      <Stage environment="city" intensity={0.6}>
+        <primitive object={scene} />
+      </Stage>
+      <OrbitControls />
+    </Canvas>
+  );
+};
diff --git a/src/widgets/ReactMarkdownEditor/index.tsx b/src/widgets/ReactMarkdownEditor/index.tsx
index e4c498e..b695afa 100644
--- a/src/widgets/ReactMarkdownEditor/index.tsx
+++ b/src/widgets/ReactMarkdownEditor/index.tsx
@@ -24,6 +24,14 @@ const StyledMarkdownEditor = styled("div")(({ theme }) => ({
     backgroundColor: theme.palette.background.paper,
     color: theme.palette.text.primary,
     borderColor: theme.palette.divider,
+    height: "auto",
+    minHeight: "200px",
+    maxHeight: "500px",
+    overflow: "auto",
+  },
+  "& .CodeMirror-scroll": {
+    minHeight: "200px",
+    maxHeight: "500px",
   },
   // Стили для текста в редакторе
   "& .CodeMirror-selected": {
diff --git a/src/widgets/SightTabs/CreateInformationTab/MediaUploadBox.tsx b/src/widgets/SightTabs/CreateInformationTab/MediaUploadBox.tsx
new file mode 100644
index 0000000..a148144
--- /dev/null
+++ b/src/widgets/SightTabs/CreateInformationTab/MediaUploadBox.tsx
@@ -0,0 +1,158 @@
+// import { Box, Button, Paper, Typography } from "@mui/material";
+// import { X, Upload } from "lucide-react";
+// import { useCallback, useState } from "react";
+// import { useDropzone } from "react-dropzone";
+// import { UploadMediaDialog } from "@shared";
+// import { createSightStore } from "@shared";
+
+// interface MediaUploadBoxProps {
+//   title: string;
+//   tooltip?: string;
+//   mediaId: string | null;
+//   onMediaSelect: (mediaId: string) => void;
+//   onMediaRemove: () => void;
+//   onPreviewClick: (mediaId: string) => void;
+//   token: string;
+//   type: "thumbnail" | "watermark_lu" | "watermark_rd";
+// }
+
+// export const MediaUploadBox = ({
+//   title,
+//   tooltip,
+//   mediaId,
+//   onMediaSelect,
+//   onMediaRemove,
+//   onPreviewClick,
+//   token,
+//   type,
+// }: MediaUploadBoxProps) => {
+//   const [uploadMediaOpen, setUploadMediaOpen] = useState(false);
+//   const [fileToUpload, setFileToUpload] = useState<File | null>(null);
+
+//   const onDrop = useCallback((acceptedFiles: File[]) => {
+//     if (acceptedFiles.length > 0) {
+//       setFileToUpload(acceptedFiles[0]);
+//       setUploadMediaOpen(true);
+//     }
+//   }, []);
+
+//   const { getRootProps, getInputProps, isDragActive } = useDropzone({
+//     onDrop,
+//     accept: {
+//       "image/*": [".png", ".jpg", ".jpeg", ".gif"],
+//     },
+//     multiple: false,
+//   });
+
+//   const handleUploadComplete = async (media: {
+//     id: string;
+//     filename: string;
+//     media_name?: string;
+//     media_type: number;
+//   }) => {
+//     onMediaSelect(media.id);
+//   };
+
+//   return (
+//     <>
+//       <Paper
+//         elevation={2}
+//         sx={{
+//           padding: 2,
+//           display: "flex",
+//           flexDirection: "column",
+//           alignItems: "center",
+//           gap: 1,
+//           flex: 1,
+//           minWidth: 150,
+//         }}
+//       >
+//         <Box sx={{ display: "flex", alignItems: "center" }}>
+//           <Typography variant="subtitle2" gutterBottom sx={{ mb: 0, mr: 0.5 }}>
+//             {title}
+//           </Typography>
+//         </Box>
+//         <Box
+//           {...getRootProps()}
+//           sx={{
+//             position: "relative",
+//             width: "200px",
+//             height: "200px",
+//             display: "flex",
+//             alignItems: "center",
+//             justifyContent: "center",
+//             borderRadius: 1,
+//             mb: 1,
+//             cursor: mediaId ? "pointer" : "default",
+//             border: isDragActive ? "2px dashed #1976d2" : "none",
+//             backgroundColor: isDragActive
+//               ? "rgba(25, 118, 210, 0.04)"
+//               : "transparent",
+//             transition: "all 0.2s ease",
+//           }}
+//         >
+//           <input {...getInputProps()} />
+//           {mediaId && (
+//             <button
+//               className="absolute top-2 right-2 z-10"
+//               onClick={(e) => {
+//                 e.stopPropagation();
+//                 onMediaRemove();
+//               }}
+//             >
+//               <X color="red" />
+//             </button>
+//           )}
+//           {mediaId ? (
+//             <img
+//               src={`${
+//                 import.meta.env.VITE_KRBL_MEDIA
+//               }${mediaId}/download?token=${token}`}
+//               alt={title}
+//               style={{ maxWidth: "100%", maxHeight: "100%" }}
+//               onClick={(e) => {
+//                 e.stopPropagation();
+//                 onPreviewClick(mediaId);
+//               }}
+//             />
+//           ) : (
+//             <div className="w-full flex flex-col items-center justify-center gap-3">
+//               <div
+//                 className={`w-full h-20 border rounded-md flex flex-col items-center transition-all duration-300 justify-center border-dashed ${
+//                   isDragActive
+//                     ? "border-blue-500 bg-blue-50"
+//                     : "border-gray-300"
+//                 } cursor-pointer hover:bg-gray-100`}
+//               >
+//                 <Upload size={24} className="mb-2" />
+//                 <p>
+//                   {isDragActive ? "Отпустите файл здесь" : "Перетащите файл"}
+//                 </p>
+//               </div>
+//               <p>или</p>
+//               <Button
+//                 variant="contained"
+//                 color="primary"
+//                 onClick={(e) => {
+//                   e.stopPropagation();
+//                   onMediaSelect("");
+//                 }}
+//               >
+//                 Выбрать файл
+//               </Button>
+//             </div>
+//           )}
+//         </Box>
+//       </Paper>
+
+//       <UploadMediaDialog
+//         open={uploadMediaOpen}
+//         onClose={() => {
+//           setUploadMediaOpen(false);
+//           setFileToUpload(null);
+//         }}
+//         afterUpload={handleUploadComplete}
+//       />
+//     </>
+//   );
+// };
diff --git a/src/widgets/SightTabs/CreateInformationTab/index.tsx b/src/widgets/SightTabs/CreateInformationTab/index.tsx
new file mode 100644
index 0000000..3288ef4
--- /dev/null
+++ b/src/widgets/SightTabs/CreateInformationTab/index.tsx
@@ -0,0 +1,582 @@
+import {
+  Button,
+  TextField,
+  Box,
+  Autocomplete,
+  Typography,
+  Paper,
+  Tooltip,
+  MenuItem,
+  Menu as MuiMenu,
+} from "@mui/material";
+import {
+  BackButton,
+  TabPanel,
+  languageStore,
+  Language,
+  cityStore,
+  SelectMediaDialog,
+  PreviewMediaDialog,
+  SightLanguageInfo,
+  SightCommonInfo,
+  createSightStore,
+} from "@shared";
+import { LanguageSwitcher } from "@widgets";
+import { Info, X } from "lucide-react";
+
+import { observer } from "mobx-react-lite";
+import { useEffect, useState } from "react";
+import { toast } from "react-toastify";
+
+// Мокап для всплывающей подсказки
+
+export const CreateInformationTab = observer(
+  ({ value, index }: { value: number; index: number }) => {
+    const { cities } = cityStore;
+    const [, setIsMediaModalOpen] = useState(false);
+    const [mediaId, setMediaId] = useState<string>("");
+    const [isPreviewMediaOpen, setIsPreviewMediaOpen] = useState(false);
+
+    const { language } = languageStore;
+    const { sight, updateSightInfo, createSight } = createSightStore;
+
+    const data = sight[language];
+
+    const [, setCity] = useState<number>(sight.city_id ?? 0);
+    const [coordinates, setCoordinates] = useState<string>(`0 0`);
+
+    const token = localStorage.getItem("token");
+
+    // Menu state for each media button
+    const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);
+    const [activeMenuType, setActiveMenuType] = useState<
+      "thumbnail" | "watermark_lu" | "watermark_rd" | null
+    >(null);
+    const [isAddMediaOpen, setIsAddMediaOpen] = useState(false);
+
+    // const handleMenuOpen = (
+    //   event: React.MouseEvent<HTMLElement>,
+    //   type: "thumbnail" | "watermark_lu" | "watermark_rd"
+    // ) => {
+    //   setMenuAnchorEl(event.currentTarget);
+    //   setActiveMenuType(type);
+    // };
+
+    useEffect(() => {
+      // Показывать только при инициализации (не менять при ошибках пользователя)
+      if (sight.latitude !== 0 || sight.longitude !== 0) {
+        setCoordinates(`${sight.latitude} ${sight.longitude}`);
+      }
+      // если координаты обнулились — оставить поле как есть
+    }, [sight.latitude, sight.longitude]);
+
+    const handleMenuClose = () => {
+      setMenuAnchorEl(null);
+      setActiveMenuType(null);
+    };
+
+    const handleCreateNew = () => {
+      handleMenuClose();
+    };
+
+    const handleAddMedia = () => {
+      setIsAddMediaOpen(true);
+      handleMenuClose();
+    };
+
+    const handleChange = (
+      content: Partial<SightLanguageInfo | SightCommonInfo>,
+      language?: Language
+    ) => {
+      if (language) {
+        updateSightInfo(content, language);
+      } else {
+        updateSightInfo(content);
+      }
+    };
+
+    const handleMediaSelect = (
+      media: {
+        id: string;
+        filename: string;
+        media_name?: string;
+        media_type: number;
+      },
+      type: "thumbnail" | "watermark_lu" | "watermark_rd"
+    ) => {
+      handleChange({
+        [type]: media.id,
+      });
+      setActiveMenuType(null);
+    };
+    return (
+      <>
+        <TabPanel value={value} index={index}>
+          <Box
+            sx={{
+              display: "flex",
+              flexDirection: "column",
+              gap: 3,
+              position: "relative",
+              paddingBottom: "70px" /* Space for save button */,
+            }}
+          >
+            <BackButton />
+
+            <Box
+              sx={{
+                display: "flex",
+
+                gap: 4, // Added gap between the two main columns
+                width: "100%",
+                flexDirection: "column",
+              }}
+            >
+              {/* Left column with main fields */}
+              <Box
+                sx={{
+                  flexGrow: 1,
+                  display: "flex",
+                  width: "80%",
+                  flexDirection: "column",
+                  gap: 2.5,
+                }}
+              >
+                <TextField
+                  label={`Название (${language.toUpperCase()})`}
+                  value={data.name}
+                  onChange={(e) => {
+                    handleChange(
+                      {
+                        name: e.target.value,
+                      },
+                      language
+                    );
+                  }}
+                  fullWidth
+                  variant="outlined"
+                />
+
+                <TextField
+                  label="Адрес"
+                  value={data.address}
+                  onChange={(e) => {
+                    handleChange(
+                      {
+                        address: e.target.value,
+                      },
+                      language
+                    );
+                  }}
+                  fullWidth
+                  variant="outlined"
+                />
+
+                <Autocomplete
+                  options={cities ?? []}
+                  value={
+                    cities.find((city) => city.id === sight.city_id) ?? null
+                  }
+                  getOptionLabel={(option) => option.name}
+                  onChange={(_, value) => {
+                    setCity(value?.id ?? 0);
+                    handleChange({
+                      city_id: value?.id ?? 0,
+                    });
+                  }}
+                  renderInput={(params) => (
+                    <TextField {...params} label="Город" />
+                  )}
+                />
+
+                <TextField
+                  label="Координаты"
+                  value={coordinates}
+                  onChange={(e) => {
+                    const input = e.target.value;
+                    setCoordinates(input); // показываем как есть
+
+                    const [latStr, lonStr] = input.split(/\s+/); // учитываем любые пробелы
+
+                    const lat = parseFloat(latStr);
+                    const lon = parseFloat(lonStr);
+
+                    // Проверка, что обе координаты валидные числа
+                    const isValidLat = !isNaN(lat);
+                    const isValidLon = !isNaN(lon);
+
+                    if (isValidLat && isValidLon) {
+                      handleChange({
+                        latitude: lat,
+                        longitude: lon,
+                      });
+                    } else {
+                      handleChange(
+                        {
+                          latitude: 0,
+                          longitude: 0,
+                        },
+                        language
+                      );
+                    }
+                  }}
+                  fullWidth
+                  variant="outlined"
+                  placeholder="Введите координаты в формате: широта долгота"
+                />
+              </Box>
+
+              <Box
+                sx={{
+                  display: "flex",
+
+                  gap: 4,
+                }}
+              >
+                <Box
+                  sx={{
+                    display: "flex",
+                    justifyContent: "space-around",
+                    width: "80%",
+                    gap: 2,
+                    flexDirection: { xs: "column", sm: "row" }, // Stack on extra small, side-by-side on small and up
+                  }}
+                >
+                  <Paper
+                    elevation={2}
+                    sx={{
+                      padding: 2,
+                      display: "flex",
+                      flexDirection: "column",
+                      alignItems: "center",
+                      gap: 1,
+                      flex: 1,
+                      minWidth: 150, // Ensure a minimum width
+                    }}
+                  >
+                    <Box sx={{ display: "flex", alignItems: "center" }}>
+                      <Typography
+                        variant="subtitle2"
+                        gutterBottom
+                        sx={{ mb: 0, mr: 0.5 }}
+                      >
+                        Логотип
+                      </Typography>
+                    </Box>
+                    <Box
+                      sx={{
+                        position: "relative",
+                        width: "200px",
+                        height: "200px",
+
+                        display: "flex",
+                        alignItems: "center",
+                        justifyContent: "center",
+                        borderRadius: 1,
+                        mb: 1,
+                        cursor: sight.thumbnail ? "pointer" : "default",
+                      }}
+                      onClick={() => {
+                        setIsMediaModalOpen(true);
+                      }}
+                    >
+                      {sight.thumbnail && (
+                        <button
+                          className="absolute top-2 right-2"
+                          onClick={() => {
+                            handleChange({
+                              thumbnail: null,
+                            });
+                            setActiveMenuType(null);
+                          }}
+                        >
+                          <X color="red" />
+                        </button>
+                      )}
+                      {sight.thumbnail ? (
+                        <img
+                          src={`${import.meta.env.VITE_KRBL_MEDIA}${
+                            sight.thumbnail
+                          }/download?token=${token}`}
+                          alt="Логотип"
+                          style={{ maxWidth: "100%", maxHeight: "100%" }}
+                          onClick={() => {
+                            setIsPreviewMediaOpen(true);
+                            setMediaId(sight.thumbnail ?? "");
+                          }}
+                        />
+                      ) : (
+                        <div className="w-full flex flex-col items-center justify-center gap-3">
+                          <div className="w-full h-20 border rounded-md flex flex-col items-center transition-all duration-300 justify-center border-dashed border-gray-300 cursor-pointer hover:bg-gray-100">
+                            <p>Перетащите файл</p>
+                          </div>
+                          <p>или</p>
+                          <Button
+                            variant="contained"
+                            color="primary"
+                            onClick={() => {
+                              setIsAddMediaOpen(true);
+                              setActiveMenuType("thumbnail");
+                            }}
+                          >
+                            Выбрать файл
+                          </Button>
+                        </div>
+                      )}
+                    </Box>
+                  </Paper>
+                  <Paper
+                    elevation={2}
+                    sx={{
+                      padding: 2,
+                      display: "flex",
+                      flexDirection: "column",
+                      alignItems: "center",
+                      gap: 1,
+                      flex: 1,
+                      minWidth: 150, // Ensure a minimum width
+                    }}
+                  >
+                    <Box sx={{ display: "flex", alignItems: "center" }}>
+                      <Typography
+                        variant="subtitle2"
+                        gutterBottom
+                        sx={{ mb: 0, mr: 0.5 }}
+                      >
+                        Водяной знак (л.в)
+                      </Typography>
+                      <Tooltip title={"asf"}>
+                        <Info
+                          size={16}
+                          color="gray"
+                          style={{ cursor: "pointer" }}
+                        />
+                      </Tooltip>
+                    </Box>
+
+                    <Box
+                      sx={{
+                        position: "relative",
+                        width: "200px",
+                        height: "200px",
+
+                        display: "flex",
+                        alignItems: "center",
+                        justifyContent: "center",
+                        borderRadius: 1,
+                        mb: 1,
+                        cursor: sight.watermark_lu ? "pointer" : "default",
+                      }}
+                      onClick={() => {
+                        setIsMediaModalOpen(true);
+                      }}
+                    >
+                      {sight.watermark_lu && (
+                        <button
+                          className="absolute top-2 right-2"
+                          onClick={() => {
+                            handleChange({
+                              watermark_lu: null,
+                            });
+                            setActiveMenuType(null);
+                          }}
+                        >
+                          <X color="red" />
+                        </button>
+                      )}
+                      {sight.watermark_lu ? (
+                        <img
+                          src={`${import.meta.env.VITE_KRBL_MEDIA}${
+                            sight.watermark_lu
+                          }/download?token=${token}`}
+                          alt="Логотип"
+                          style={{ maxWidth: "100%", maxHeight: "100%" }}
+                          onClick={() => {
+                            setIsPreviewMediaOpen(true);
+                            setMediaId(sight.watermark_lu ?? "");
+                          }}
+                        />
+                      ) : (
+                        <div className="w-full flex flex-col items-center justify-center gap-3">
+                          <div className="w-full h-20 border rounded-md flex flex-col items-center transition-all duration-300 justify-center border-dashed border-gray-300 cursor-pointer hover:bg-gray-100">
+                            <p>Перетащите файл</p>
+                          </div>
+                          <p>или</p>
+                          <Button
+                            variant="contained"
+                            color="primary"
+                            onClick={() => {
+                              setActiveMenuType("watermark_lu");
+                              setIsAddMediaOpen(true);
+                            }}
+                          >
+                            Выбрать файл
+                          </Button>
+                        </div>
+                      )}
+                    </Box>
+                  </Paper>
+
+                  <Paper
+                    elevation={2}
+                    sx={{
+                      padding: 2,
+                      display: "flex",
+                      flexDirection: "column",
+                      alignItems: "center",
+                      gap: 1,
+                      flex: 1,
+                      minWidth: 150, // Ensure a minimum width
+                    }}
+                  >
+                    <Box sx={{ display: "flex", alignItems: "center" }}>
+                      <Typography
+                        variant="subtitle2"
+                        gutterBottom
+                        sx={{ mb: 0, mr: 0.5 }}
+                      >
+                        Водяной знак (п.в)
+                      </Typography>
+                      <Tooltip title={"asfaf"}>
+                        <Info
+                          size={16}
+                          color="gray"
+                          style={{ cursor: "pointer" }}
+                        />
+                      </Tooltip>
+                    </Box>
+                    <Box
+                      sx={{
+                        position: "relative",
+                        width: "200px",
+                        height: "200px",
+
+                        display: "flex",
+                        alignItems: "center",
+                        justifyContent: "center",
+                        borderRadius: 1,
+                        mb: 1,
+                        cursor: sight.watermark_rd ? "pointer" : "default",
+                      }}
+                      onClick={() => {
+                        setIsMediaModalOpen(true);
+                      }}
+                    >
+                      {sight.watermark_rd && (
+                        <button
+                          className="absolute top-2 right-2"
+                          onClick={() => {
+                            handleChange({
+                              watermark_rd: null,
+                            });
+                            setActiveMenuType(null);
+                          }}
+                        >
+                          <X color="red" />
+                        </button>
+                      )}
+                      {sight.watermark_rd ? (
+                        <img
+                          src={`${import.meta.env.VITE_KRBL_MEDIA}${
+                            sight.watermark_rd
+                          }/download?token=${token}`}
+                          alt="Логотип"
+                          style={{ maxWidth: "100%", maxHeight: "100%" }}
+                          onClick={() => {
+                            setIsPreviewMediaOpen(true);
+                            setMediaId(sight.watermark_rd ?? "");
+                          }}
+                        />
+                      ) : (
+                        <div className="w-full flex flex-col items-center justify-center gap-3">
+                          <div className="w-full h-20 border rounded-md flex flex-col items-center transition-all duration-300 justify-center border-dashed border-gray-300 cursor-pointer hover:bg-gray-100">
+                            <p>Перетащите файл</p>
+                          </div>
+                          <p>или</p>
+                          <Button
+                            variant="contained"
+                            color="primary"
+                            onClick={() => {
+                              setActiveMenuType("watermark_rd");
+                              setIsAddMediaOpen(true);
+                            }}
+                          >
+                            Выбрать файл
+                          </Button>
+                        </div>
+                      )}
+                    </Box>
+                  </Paper>
+                </Box>
+              </Box>
+            </Box>
+
+            {/* LanguageSwitcher positioned at the top right */}
+
+            <LanguageSwitcher />
+
+            {/* Save Button fixed at the bottom right */}
+            <Box
+              sx={{
+                position: "absolute",
+                bottom: 0,
+                right: 0,
+                padding: 2,
+                backgroundColor: "background.paper", // To ensure it stands out over content
+                width: "100%", // Take full width to cover content below it
+                display: "flex",
+                justifyContent: "flex-end", // Align to the right
+              }}
+            >
+              <Button
+                variant="contained"
+                color="success"
+                onClick={async () => {
+                  await createSight(language);
+                  toast.success("Достопримечательность создана");
+                }}
+              >
+                Сохранить
+              </Button>
+            </Box>
+          </Box>
+        </TabPanel>
+
+        {/* Media Menu */}
+        <MuiMenu
+          anchorEl={menuAnchorEl}
+          open={Boolean(menuAnchorEl)}
+          onClose={handleMenuClose}
+          anchorOrigin={{
+            vertical: "top",
+            horizontal: "right",
+          }}
+          transformOrigin={{
+            vertical: "bottom",
+            horizontal: "right",
+          }}
+        >
+          <MenuItem onClick={handleCreateNew}>Создать новую</MenuItem>
+          <MenuItem onClick={handleAddMedia}>Выбрать существующую</MenuItem>
+        </MuiMenu>
+
+        <SelectMediaDialog
+          open={isAddMediaOpen}
+          onClose={() => {
+            setIsAddMediaOpen(false);
+            setActiveMenuType(null);
+          }}
+          onSelectMedia={(media) => {
+            handleMediaSelect(media, activeMenuType ?? "thumbnail");
+          }}
+        />
+
+        <PreviewMediaDialog
+          open={isPreviewMediaOpen}
+          onClose={() => setIsPreviewMediaOpen(false)}
+          mediaId={mediaId}
+        />
+      </>
+    );
+  }
+);
diff --git a/src/widgets/SightTabs/CreateLeftTab/index.tsx b/src/widgets/SightTabs/CreateLeftTab/index.tsx
new file mode 100644
index 0000000..c180068
--- /dev/null
+++ b/src/widgets/SightTabs/CreateLeftTab/index.tsx
@@ -0,0 +1,451 @@
+// @widgets/LeftWidgetTab.tsx
+import { Box, Button, TextField, Paper, Typography } from "@mui/material";
+import {
+  BackButton,
+  TabPanel,
+  languageStore,
+  SelectMediaDialog,
+  editSightStore,
+  createSightStore,
+  SelectArticleModal,
+  UploadMediaDialog,
+} from "@shared";
+import {
+  LanguageSwitcher,
+  MediaArea,
+  ReactMarkdownComponent,
+  ReactMarkdownEditor,
+  MediaViewer,
+} from "@widgets";
+import { Trash2, ImagePlus } from "lucide-react";
+import { useState, useCallback } from "react";
+import { observer } from "mobx-react-lite";
+import { toast } from "react-toastify";
+
+export const CreateLeftTab = observer(
+  ({ value, index }: { value: number; index: number }) => {
+    const {
+      sight,
+      updateSightInfo,
+      updateLeftArticle,
+      createSight,
+      deleteLeftArticle,
+      createLeftArticle,
+      unlinkLeftArticle,
+      createLinkWithArticle,
+    } = createSightStore;
+    const {
+      deleteMedia,
+      setFileToUpload,
+      uploadMediaOpen,
+      setUploadMediaOpen,
+    } = editSightStore;
+
+    const { language } = languageStore;
+
+    const [isSelectArticleDialogOpen, setIsSelectArticleDialogOpen] =
+      useState(false);
+    const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
+      useState(false);
+
+    // const handleMediaSelected = useCallback(() => {
+    //   // При выборе медиа, обновляем данные для ТЕКУЩЕГО ЯЗЫКА
+    //   // сохраняя текущие heading и body.
+    //   updateSightInfo(language, {
+    //     left: {
+    //       heading: data.left.heading,
+    //       body: data.left.body,
+    //     },
+    //   });
+    //   setIsSelectMediaDialogOpen(false);
+    // }, [language, data.left.heading, data.left.body]);
+
+    const handleCloseArticleDialog = useCallback(() => {
+      setIsSelectArticleDialogOpen(false);
+    }, []);
+
+    const handleCloseMediaDialog = useCallback(() => {
+      setIsSelectMediaDialogOpen(false);
+    }, []);
+
+    const handleMediaSelected = useCallback(
+      async (media: {
+        id: string;
+        filename: string;
+        media_name?: string;
+        media_type: number;
+      }) => {
+        await createLinkWithArticle(media);
+        setIsSelectMediaDialogOpen(false);
+      },
+      [createLinkWithArticle]
+    );
+
+    const handleArticleSelect = useCallback(
+      (articleId: number) => {
+        updateLeftArticle(articleId);
+      },
+      [updateLeftArticle]
+    );
+
+    return (
+      <TabPanel value={value} index={index}>
+        <LanguageSwitcher />
+        <Box
+          sx={{
+            display: "flex",
+            flexDirection: "column",
+            gap: 3,
+            paddingBottom: "70px",
+            position: "relative",
+          }}
+        >
+          <BackButton />
+          <Paper
+            elevation={2}
+            sx={{
+              display: "flex",
+              alignItems: "center",
+              justifyContent: "space-between",
+              paddingX: 2.5,
+              paddingY: 1.5,
+              borderRadius: 2,
+              border: "1px solid",
+              borderColor: "divider",
+            }}
+          >
+            <Typography variant="h6">Левая статья</Typography>
+            <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
+              {sight.left_article ? (
+                <>
+                  <Button
+                    variant="contained"
+                    color="primary"
+                    size="small"
+                    style={{ transition: "0" }}
+                    onClick={() => {
+                      unlinkLeftArticle();
+                      toast.success("Статья откреплена");
+                    }}
+                  >
+                    Открепить
+                  </Button>
+                  <Button
+                    variant="outlined"
+                    color="error"
+                    style={{ transition: "0" }}
+                    startIcon={<Trash2 size={18} />}
+                    size="small"
+                    onClick={() => {
+                      deleteLeftArticle(sight.left_article);
+                      toast.success("Статья откреплена");
+                    }}
+                  >
+                    Удалить
+                  </Button>
+                </>
+              ) : (
+                <>
+                  <Button
+                    variant="contained"
+                    color="primary"
+                    size="small"
+                    onClick={() => setIsSelectArticleDialogOpen(true)}
+                  >
+                    Выбрать статью
+                  </Button>
+                  <Button
+                    variant="contained"
+                    color="primary"
+                    size="small"
+                    style={{ transition: "0" }}
+                    onClick={createLeftArticle}
+                  >
+                    Создать статью
+                  </Button>
+                </>
+              )}
+            </Box>
+          </Paper>
+          {sight.left_article > 0 && (
+            <>
+              <Box sx={{ display: "flex", gap: 3, flexGrow: 1 }}>
+                {/* Левая колонка: Редактирование */}
+
+                <Box
+                  sx={{
+                    flex: 2,
+                    display: "flex",
+                    flexDirection: "column",
+                    gap: 2,
+                  }}
+                >
+                  <TextField
+                    label="Название информации"
+                    value={sight[language].left.heading}
+                    onChange={(e) =>
+                      updateSightInfo(
+                        {
+                          left: {
+                            heading: e.target.value,
+                            body: sight[language].left.body,
+                            media: sight[language].left.media,
+                          },
+                        },
+                        language
+                      )
+                    }
+                    variant="outlined"
+                    fullWidth
+                  />
+
+                  <ReactMarkdownEditor
+                    value={sight[language].left.body}
+                    onChange={(value) =>
+                      updateSightInfo(
+                        {
+                          left: {
+                            heading: sight[language].left.heading,
+                            body: value,
+                            media: sight[language].left.media,
+                          },
+                        },
+                        language
+                      )
+                    }
+                  />
+
+                  <MediaArea
+                    articleId={sight.left_article}
+                    mediaIds={sight[language].left.media}
+                    deleteMedia={deleteMedia}
+                    setSelectMediaDialogOpen={setIsSelectMediaDialogOpen}
+                    onFilesDrop={(files) => {
+                      setFileToUpload(files[0]);
+                      setUploadMediaOpen(true);
+                    }}
+                  />
+
+                  {/* Блок МЕДИА для статьи */}
+                  {/* <Paper elevation={1} sx={{ padding: 2, mt: 1 }}>
+                <Typography variant="h6" gutterBottom>
+                  МЕДИА
+                </Typography>
+                {data.left.media ? (
+                  <Box sx={{ mb: 1 }}>
+                    <img
+                      src={data.left.media.filename}
+                      alt="Selected media"
+                      style={{
+                        maxWidth: "100%",
+                        maxHeight: "150px",
+                        objectFit: "contain",
+                      }}
+                    />
+                  </Box>
+                ) : (
+                  <Box
+                    sx={{
+                      width: "100%",
+                      height: 100,
+                      backgroundColor: "grey.100",
+                      display: "flex",
+                      alignItems: "center",
+                      justifyContent: "center",
+                      borderRadius: 1,
+                      mb: 1,
+                      border: "2px dashed",
+                      borderColor: "grey.300",
+                    }}
+                  >
+                    <Typography color="text.secondary">Нет медиа</Typography>
+                  </Box>
+                )}
+                <Button
+                  variant="contained"
+                  startIcon={<ImagePlus size={18} />}
+                  onClick={handleOpenMediaDialog}
+                >
+                  Выбрать/Загрузить медиа
+                </Button>
+                {data.left.media && (
+                  <Button
+                    variant="outlined"
+                    color="error"
+                    size="small"
+                    sx={{ ml: 1 }}
+                    onClick={() =>
+                      updateSightInfo(
+                        languageStore.language,
+                        {
+                          left: {
+                              heading:      data.left.heading,
+                            body: data.left.body,
+                            media: null,
+                          },
+                        },
+                        false
+                      )
+                    }
+                  >
+                    Удалить медиа
+                  </Button>
+                )}
+              </Paper> */}
+                </Box>
+
+                {/* Правая колонка: Предпросмотр */}
+                <Box
+                  sx={{
+                    flex: 1,
+                    display: "flex",
+                    flexDirection: "column",
+                    gap: 1.5,
+                  }}
+                >
+                  <Paper
+                    elevation={3}
+                    sx={{
+                      width: "100%",
+                      minWidth: 320,
+                      maxWidth: 400,
+                      height: "auto",
+                      minHeight: 500,
+                      backgroundColor: "#877361",
+                      overflowY: "auto",
+                      padding: 0,
+                      display: "flex",
+                      flexDirection: "column",
+                    }}
+                  >
+                    {/* {data.left.media?.filename ? (
+                  <Box
+                    sx={{
+                      width: "100%",
+                      height: 200,
+                      backgroundColor: "grey.300",
+                      display: "flex",
+                      alignItems: "center",
+                      justifyContent: "center",
+                    }}
+                  >
+                    <img
+                      src={data.left.media?.filename ?? ""}
+                      alt="Превью медиа"
+                      style={{
+                        objectFit: "cover",
+                        width: "100%",
+                        height: "100%",
+                      }}
+                    />
+                  </Box>
+                ) : (
+                  
+                )} */}
+
+                    <Box
+                      sx={{
+                        width: "100%",
+                        height: 200,
+                        backgroundColor: "grey.300",
+                        display: "flex",
+                        alignItems: "center",
+                        justifyContent: "center",
+                      }}
+                    >
+                      {sight[language].left.media.length > 0 ? (
+                        <MediaViewer
+                          media={{
+                            id: sight[language].left.media[0].id,
+                            media_type:
+                              sight[language].left.media[0].media_type,
+                            filename: sight[language].left.media[0].filename,
+                          }}
+                        />
+                      ) : (
+                        <ImagePlus size={48} color="grey" />
+                      )}
+                    </Box>
+
+                    {/* Заголовок в превью */}
+                    <Box
+                      sx={{
+                        backgroundColor: "#877361",
+                        color: "white",
+                        padding: 1.5,
+                      }}
+                    >
+                      <Typography
+                        variant="h5"
+                        component="h2"
+                        sx={{ wordBreak: "break-word" }}
+                      >
+                        {sight[language].left.heading || "Название информации"}
+                      </Typography>
+                    </Box>
+
+                    {/* Текст статьи в превью */}
+                    <Box
+                      sx={{
+                        padding: 2,
+                        flexGrow: 1,
+                      }}
+                    >
+                      <ReactMarkdownComponent
+                        value={sight[language].left.body}
+                      />
+                    </Box>
+                  </Paper>
+                </Box>
+              </Box>
+
+              <Box
+                sx={{ position: "absolute", bottom: 0, right: 0, padding: 2 }}
+              >
+                <Button
+                  variant="contained"
+                  color="success"
+                  onClick={async () => {
+                    try {
+                      await createSight(language);
+                      toast.success("Странца создана");
+                    } catch (error) {
+                      console.error(error);
+                    }
+                  }}
+                >
+                  Сохранить
+                </Button>
+              </Box>
+            </>
+          )}
+        </Box>
+
+        {/* <SelectMediaDialog
+          open={isSelectMediaDialogOpen}
+          onClose={handleCloseMediaDialog}
+          onSelectMedia={handleArticleSelect}
+        /> */}
+        <SelectMediaDialog
+          open={isSelectMediaDialogOpen}
+          onClose={handleCloseMediaDialog}
+          onSelectMedia={handleMediaSelected}
+        />
+        <UploadMediaDialog
+          open={uploadMediaOpen}
+          onClose={() => setUploadMediaOpen(false)}
+          afterUpload={async (media) => {
+            setUploadMediaOpen(false);
+            setFileToUpload(null);
+            await createLinkWithArticle(media);
+          }}
+        />
+        <SelectArticleModal
+          open={isSelectArticleDialogOpen}
+          onClose={handleCloseArticleDialog}
+          onSelectArticle={handleArticleSelect}
+        />
+      </TabPanel>
+    );
+  }
+);
diff --git a/src/widgets/SightTabs/CreateRightTab/index.tsx b/src/widgets/SightTabs/CreateRightTab/index.tsx
new file mode 100644
index 0000000..97b4723
--- /dev/null
+++ b/src/widgets/SightTabs/CreateRightTab/index.tsx
@@ -0,0 +1,374 @@
+import {
+  Box,
+  Button,
+  Paper,
+  Typography,
+  Menu,
+  MenuItem,
+  TextField,
+} from "@mui/material";
+import { BackButton, createSightStore, languageStore, TabPanel } from "@shared";
+import {
+  LanguageSwitcher,
+  ReactMarkdownComponent,
+  ReactMarkdownEditor,
+} from "@widgets";
+import { ImagePlus, Plus } from "lucide-react";
+import { observer } from "mobx-react-lite";
+import { useState } from "react";
+
+// --- RightWidgetTab (Parent) Component ---
+export const CreateRightTab = observer(
+  ({ value, index }: { value: number; index: number }) => {
+    const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
+    const { sight, createNewRightArticle, updateRightArticleInfo } =
+      createSightStore;
+    const { language } = languageStore;
+
+    const [activeArticleIndex, setActiveArticleIndex] = useState<number | null>(
+      null
+    );
+    const open = Boolean(anchorEl);
+    const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
+      setAnchorEl(event.currentTarget);
+    };
+    const handleClose = () => {
+      setAnchorEl(null);
+    };
+    const handleSave = () => {
+      console.log("Saving right widget...");
+    };
+
+    const handleSelectArticle = (index: number) => {
+      setActiveArticleIndex(index);
+    };
+
+    return (
+      <TabPanel value={value} index={index}>
+        <LanguageSwitcher />
+        <Box
+          sx={{
+            display: "flex",
+            flexDirection: "column",
+            height: "100%",
+            minHeight: "calc(100vh - 200px)", // Adjust as needed
+            gap: 2,
+            paddingBottom: "70px", // Space for the save button
+            position: "relative",
+          }}
+        >
+          <BackButton />
+
+          <Box sx={{ display: "flex", flexGrow: 1, gap: 2.5 }}>
+            <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">
+                  <Box className="flex flex-col gap-3 max-h-[60vh] overflow-y-auto">
+                    <Box
+                      onClick={() => {
+                        // setMediaType("preview");
+                      }}
+                      className="w-full  bg-gray-200 p-4 rounded-2xl cursor-pointer text-sm hover:bg-gray-300 transition-all duration-300"
+                    >
+                      <Typography>Предпросмотр медиа</Typography>
+                    </Box>
+
+                    {sight[language].right.map((article, index) => (
+                      <Box
+                        key={index}
+                        className="w-full  bg-gray-200 p-4 rounded-2xl  text-sm cursor-pointer hover:bg-gray-300 transition-all duration-300"
+                        onClick={() => {
+                          handleSelectArticle(index);
+                        }}
+                      >
+                        <Typography>{article.heading}</Typography>
+                      </Box>
+                    ))}
+                  </Box>
+                  <button
+                    className="w-10 h-10 bg-blue-500 rounded-full absolute bottom-5 left-5 flex items-center justify-center"
+                    onClick={handleClick}
+                  >
+                    <Plus size={20} color="white" />
+                  </button>
+                  <Menu
+                    id="basic-menu"
+                    anchorEl={anchorEl}
+                    open={open}
+                    onClose={handleClose}
+                    MenuListProps={{
+                      "aria-labelledby": "basic-button",
+                    }}
+                    sx={{
+                      mt: 1,
+                    }}
+                  >
+                    <MenuItem
+                      onClick={() => {
+                        createNewRightArticle();
+                        handleClose();
+                      }}
+                    >
+                      <Typography>Создать новую</Typography>
+                    </MenuItem>
+                    <MenuItem
+                      onClick={() => {
+                        handleClose();
+                      }}
+                    >
+                      <Typography>Выбрать существующую статью</Typography>
+                    </MenuItem>
+                  </Menu>
+                </Box>
+                <Box className="w-[80%] h-[70vh] border border-gray-300 rounded-2xl p-3">
+                  {activeArticleIndex !== null && (
+                    <>
+                      <Box className="flex justify-end gap-2 mb-3">
+                        <Button variant="contained" color="primary">
+                          Открепить
+                        </Button>
+
+                        <Button variant="contained" color="success">
+                          Удалить
+                        </Button>
+                      </Box>
+                      <Box sx={{ display: "flex", gap: 3, flexGrow: 1 }}>
+                        {/* Левая колонка: Редактирование */}
+
+                        <Box
+                          sx={{
+                            flex: 2,
+                            display: "flex",
+                            flexDirection: "column",
+                            gap: 2,
+                          }}
+                        >
+                          <TextField
+                            label="Название информации"
+                            value={
+                              sight[language].right[activeArticleIndex].heading
+                            }
+                            onChange={(e) =>
+                              updateRightArticleInfo(
+                                activeArticleIndex,
+                                language,
+                                e.target.value,
+                                sight[language].right[activeArticleIndex].body
+                              )
+                            }
+                            variant="outlined"
+                            fullWidth
+                          />
+
+                          <ReactMarkdownEditor
+                            value={
+                              sight[language].right[activeArticleIndex].body
+                            }
+                            onChange={(value) =>
+                              updateRightArticleInfo(
+                                activeArticleIndex,
+                                language,
+                                sight[language].right[activeArticleIndex]
+                                  .heading,
+                                value
+                              )
+                            }
+                          />
+                        </Box>
+                        {/* Блок МЕДИА для статьи */}
+                        {/* <Paper elevation={1} sx={{ padding: 2, mt: 1 }}>
+                    <Typography variant="h6" gutterBottom>
+                      МЕДИА
+                    </Typography>
+                    {data.left.media ? (
+                      <Box sx={{ mb: 1 }}>
+                        <img
+                          src={data.left.media.filename}
+                          alt="Selected media"
+                          style={{
+                            maxWidth: "100%",
+                            maxHeight: "150px",
+                            objectFit: "contain",
+                          }}
+                        />
+                      </Box>
+                    ) : (
+                      <Box
+                        sx={{
+                          width: "100%",
+                          height: 100,
+                          backgroundColor: "grey.100",
+                          display: "flex",
+                          alignItems: "center",
+                          justifyContent: "center",
+                          borderRadius: 1,
+                          mb: 1,
+                          border: "2px dashed",
+                          borderColor: "grey.300",
+                        }}
+                      >
+                        <Typography color="text.secondary">Нет медиа</Typography>
+                      </Box>
+                    )}
+                    <Button
+                      variant="contained"
+                      startIcon={<ImagePlus size={18} />}
+                      onClick={handleOpenMediaDialog}
+                    >
+                      Выбрать/Загрузить медиа
+                    </Button>
+                    {data.left.media && (
+                      <Button
+                        variant="outlined"
+                        color="error"
+                        size="small"
+                        sx={{ ml: 1 }}
+                        onClick={() =>
+                          updateSightInfo(
+                            languageStore.language,
+                            {
+                              left: {
+                                  heading:      data.left.heading,
+                                body: data.left.body,
+                                media: null,
+                              },
+                            },
+                            false
+                          )
+                        }
+                      >
+                        Удалить медиа
+                      </Button>
+                    )}
+                  </Paper> */}
+                      </Box>
+                    </>
+                  )}
+                </Box>
+              </Box>
+            </Box>
+            <Box className="w-[25%] mr-10">
+              {activeArticleIndex !== null && (
+                <Paper
+                  className="flex-1 flex flex-col rounded-2xl"
+                  elevation={2}
+                >
+                  <Box
+                    className="rounded-2xl overflow-hidden"
+                    sx={{
+                      width: "100%",
+                      height: "75vh",
+                      background: "#877361",
+                      borderColor: "grey.300",
+                      display: "flex",
+                      flexDirection: "column",
+                    }}
+                  >
+                    {false ? (
+                      <Box
+                        sx={{
+                          width: "100%",
+                          height: "100%",
+                          display: "flex",
+                          alignItems: "center",
+                          justifyContent: "center",
+                        }}
+                      >
+                        <Typography color="white">Загрузка...</Typography>
+                      </Box>
+                    ) : (
+                      <>
+                        <Box
+                          sx={{
+                            width: "100%",
+                            height: 200,
+                            flexShrink: 0,
+                            backgroundColor: "rgba(0,0,0,0.1)",
+                            display: "flex",
+                            alignItems: "center",
+                            justifyContent: "center",
+                          }}
+                        >
+                          <ImagePlus size={48} color="white" />
+                        </Box>
+
+                        <Box
+                          sx={{
+                            width: "100%",
+                            minHeight: "70px",
+                            background: "#877361",
+                            display: "flex",
+                            flexShrink: 0,
+                            alignItems: "center",
+                            borderBottom: "1px solid rgba(255,255,255,0.1)",
+                            px: 2,
+                          }}
+                        >
+                          <Typography variant="h6" color="white">
+                            {sight[language].right[activeArticleIndex]
+                              .heading || "Выберите статью"}
+                          </Typography>
+                        </Box>
+
+                        <Box
+                          sx={{
+                            px: 2,
+                            flexGrow: 1,
+
+                            overflowY: "auto",
+                            backgroundColor: "#877361",
+                            color: "white",
+                            py: 1,
+                          }}
+                        >
+                          {sight[language].right[activeArticleIndex].body ? (
+                            <ReactMarkdownComponent
+                              value={
+                                sight[language].right[activeArticleIndex].body
+                              }
+                            />
+                          ) : (
+                            <Typography
+                              color="rgba(255,255,255,0.7)"
+                              sx={{ textAlign: "center", mt: 4 }}
+                            >
+                              Предпросмотр статьи появится здесь
+                            </Typography>
+                          )}
+                        </Box>
+                      </>
+                    )}
+                  </Box>
+                </Paper>
+              )}
+            </Box>
+          </Box>
+
+          <Box
+            sx={{
+              position: "absolute",
+              bottom: 0,
+              right: 0,
+              padding: 2,
+              backgroundColor: "background.paper", // Ensure button is visible
+              width: "100%", // Cover the full width to make it a sticky footer
+              display: "flex",
+              justifyContent: "flex-end",
+            }}
+          >
+            <Button variant="contained" color="success" onClick={handleSave}>
+              Сохранить изменения
+            </Button>
+          </Box>
+        </Box>
+        {/* 
+        <SelectArticleModal
+            open={openedType === "article"}
+          onClose={handleCloseSelectModal}
+          onSelectArticle={handleSelectArticle}
+          linkedArticleIds={linkedArticleIds}
+        /> */}
+      </TabPanel>
+    );
+  }
+);
diff --git a/src/widgets/SightTabs/InformationTab/index.tsx b/src/widgets/SightTabs/InformationTab/index.tsx
index 3b771a5..cdcfcfb 100644
--- a/src/widgets/SightTabs/InformationTab/index.tsx
+++ b/src/widgets/SightTabs/InformationTab/index.tsx
@@ -27,6 +27,8 @@ import { Info, ImagePlus } from "lucide-react";
 import { observer } from "mobx-react-lite";
 import { useEffect, useState } from "react";
 
+import { toast } from "react-toastify";
+
 // Мокап для всплывающей подсказки
 
 export const InformationTab = observer(
@@ -37,12 +39,10 @@ export const InformationTab = observer(
     const [isPreviewMediaOpen, setIsPreviewMediaOpen] = useState(false);
 
     const { language } = languageStore;
-    const { sight, updateSightInfo } = editSightStore;
 
-    const data = sight[language];
-    const common = sight.common;
+    const { sight, updateSightInfo, updateSight } = editSightStore;
 
-    const [, setCity] = useState<number>(common.city_id ?? 0);
+    const [, setCity] = useState<number>(sight.common.city_id ?? 0);
     const [coordinates, setCoordinates] = useState<string>(`0 0`);
 
     const token = localStorage.getItem("token");
@@ -54,21 +54,13 @@ export const InformationTab = observer(
     >(null);
     const [isAddMediaOpen, setIsAddMediaOpen] = useState(false);
 
-    const handleMenuOpen = (
-      event: React.MouseEvent<HTMLElement>,
-      type: "thumbnail" | "watermark_lu" | "watermark_rd"
-    ) => {
-      setMenuAnchorEl(event.currentTarget);
-      setActiveMenuType(type);
-    };
-
     useEffect(() => {
       // Показывать только при инициализации (не менять при ошибках пользователя)
-      if (common.latitude !== 0 || common.longitude !== 0) {
-        setCoordinates(`${common.latitude} ${common.longitude}`);
+      if (sight.common.latitude !== 0 || sight.common.longitude !== 0) {
+        setCoordinates(`${sight.common.latitude} ${sight.common.longitude}`);
       }
       // если координаты обнулились — оставить поле как есть
-    }, [common.latitude, common.longitude]);
+    }, [sight.common.latitude, sight.common.longitude]);
 
     const handleMenuClose = () => {
       setMenuAnchorEl(null);
@@ -135,7 +127,7 @@ export const InformationTab = observer(
               >
                 <TextField
                   label={`Название (${language.toUpperCase()})`}
-                  value={data.name}
+                  value={sight[language].name}
                   onChange={(e) => {
                     handleChange(language as Language, {
                       name: e.target.value,
@@ -147,7 +139,7 @@ export const InformationTab = observer(
 
                 <TextField
                   label="Адрес"
-                  value={data.address}
+                  value={sight[language].address}
                   onChange={(e) => {
                     handleChange(language as Language, {
                       address: e.target.value,
@@ -160,18 +152,15 @@ export const InformationTab = observer(
                 <Autocomplete
                   options={cities ?? []}
                   value={
-                    cities.find((city) => city.id === common.city_id) ?? null
+                    cities.find((city) => city.id === sight.common.city_id) ??
+                    null
                   }
                   getOptionLabel={(option) => option.name}
                   onChange={(_, value) => {
                     setCity(value?.id ?? 0);
-                    handleChange(
-                      language as Language,
-                      {
-                        city_id: value?.id ?? 0,
-                      },
-                      true
-                    );
+                    handleChange(language as Language, {
+                      city_id: value?.id ?? 0,
+                    });
                   }}
                   renderInput={(params) => (
                     <TextField {...params} label="Город" />
@@ -195,15 +184,23 @@ export const InformationTab = observer(
                     const isValidLon = !isNaN(lon);
 
                     if (isValidLat && isValidLon) {
-                      handleChange(language as Language, {
-                        latitude: lat,
-                        longitude: lon,
-                      });
+                      handleChange(
+                        language as Language,
+                        {
+                          latitude: lat,
+                          longitude: lon,
+                        },
+                        true
+                      );
                     } else {
-                      handleChange(language as Language, {
-                        latitude: 0,
-                        longitude: 0,
-                      });
+                      handleChange(
+                        language as Language,
+                        {
+                          latitude: 0,
+                          longitude: 0,
+                        },
+                        true
+                      );
                     }
                   }}
                   fullWidth
@@ -251,17 +248,18 @@ export const InformationTab = observer(
                     </Box>
                     <Box
                       sx={{
-                        width: 80,
-                        height: 80,
+                        position: "relative",
+                        width: "200px",
+                        height: "200px",
                         backgroundColor: "grey.200",
                         display: "flex",
                         alignItems: "center",
                         justifyContent: "center",
                         borderRadius: 1,
                         mb: 1,
-                        cursor: common.thumbnail ? "pointer" : "default",
+                        cursor: sight.common.thumbnail ? "pointer" : "default",
                         "&:hover": {
-                          backgroundColor: common.thumbnail
+                          backgroundColor: sight.common.thumbnail
                             ? "red.300"
                             : "grey.200",
                         },
@@ -270,29 +268,22 @@ export const InformationTab = observer(
                         setIsMediaModalOpen(true);
                       }}
                     >
-                      {common.thumbnail ? (
+                      {sight.common.thumbnail ? (
                         <img
                           src={`${import.meta.env.VITE_KRBL_MEDIA}${
-                            common.thumbnail
+                            sight.common.thumbnail
                           }/download?token=${token}`}
                           alt="Логотип"
                           style={{ maxWidth: "100%", maxHeight: "100%" }}
                           onClick={() => {
                             setIsPreviewMediaOpen(true);
-                            setMediaId(common.thumbnail);
+                            setMediaId(sight.common.thumbnail ?? "");
                           }}
                         />
                       ) : (
                         <ImagePlus size={24} color="grey" />
                       )}
                     </Box>
-                    <Button
-                      variant="outlined"
-                      size="small"
-                      onClick={(e) => handleMenuOpen(e, "thumbnail")}
-                    >
-                      Выбрать
-                    </Button>
                   </Paper>
                   <Paper
                     elevation={2}
@@ -324,49 +315,45 @@ export const InformationTab = observer(
                     </Box>
                     <Box
                       sx={{
-                        width: 80,
-                        height: 80,
+                        position: "relative",
+                        width: "200px",
+                        height: "200px",
                         backgroundColor: "grey.200",
                         display: "flex",
                         alignItems: "center",
                         justifyContent: "center",
                         borderRadius: 1,
                         mb: 1,
-                        cursor: common.watermark_lu ? "pointer" : "default",
+                        cursor: sight.common.watermark_lu
+                          ? "pointer"
+                          : "default",
                         "&:hover": {
-                          backgroundColor: common.watermark_lu
+                          backgroundColor: sight.common.watermark_lu
                             ? "grey.300"
                             : "grey.200",
                         },
                       }}
                       onClick={() => {
                         setIsPreviewMediaOpen(true);
-                        setMediaId(common.watermark_lu);
+                        setMediaId(sight.common.watermark_lu ?? "");
                       }}
                     >
-                      {common.watermark_lu ? (
+                      {sight.common.watermark_lu ? (
                         <img
                           src={`${import.meta.env.VITE_KRBL_MEDIA}${
-                            common.watermark_lu
+                            sight.common.watermark_lu
                           }/download?token=${token}`}
                           alt="Знак л.в"
                           style={{ maxWidth: "100%", maxHeight: "100%" }}
                           onClick={() => {
                             setIsMediaModalOpen(true);
-                            setMediaId(common.watermark_lu);
+                            setMediaId(sight.common.watermark_lu ?? "");
                           }}
                         />
                       ) : (
                         <ImagePlus size={24} color="grey" />
                       )}
                     </Box>
-                    <Button
-                      variant="outlined"
-                      size="small"
-                      onClick={(e) => handleMenuOpen(e, "watermark_lu")}
-                    >
-                      Выбрать
-                    </Button>
                   </Paper>
 
                   <Paper
@@ -399,49 +386,45 @@ export const InformationTab = observer(
                     </Box>
                     <Box
                       sx={{
-                        width: 80,
-                        height: 80,
+                        position: "relative",
+                        width: "200px",
+                        height: "200px",
                         backgroundColor: "grey.200",
                         display: "flex",
                         alignItems: "center",
                         justifyContent: "center",
                         borderRadius: 1,
                         mb: 1,
-                        cursor: common.watermark_rd ? "pointer" : "default",
+                        cursor: sight.common.watermark_rd
+                          ? "pointer"
+                          : "default",
                         "&:hover": {
-                          backgroundColor: common.watermark_rd
+                          backgroundColor: sight.common.watermark_rd
                             ? "grey.300"
                             : "grey.200",
                         },
                       }}
                       onClick={() => {
                         setIsMediaModalOpen(true);
-                        setMediaId(common.watermark_rd);
+                        setMediaId(sight.common.watermark_rd ?? "");
                       }}
                     >
-                      {common.watermark_rd ? (
+                      {sight.common.watermark_rd ? (
                         <img
                           src={`${import.meta.env.VITE_KRBL_MEDIA}${
-                            common.watermark_rd
+                            sight.common.watermark_rd
                           }/download?token=${token}`}
                           alt="Знак п.в"
                           style={{ maxWidth: "100%", maxHeight: "100%" }}
                           onClick={() => {
                             setIsPreviewMediaOpen(true);
-                            setMediaId(common.watermark_rd);
+                            setMediaId(sight.common.watermark_rd ?? "");
                           }}
                         />
                       ) : (
                         <ImagePlus size={24} color="grey" />
                       )}
                     </Box>
-                    <Button
-                      variant="outlined"
-                      size="small"
-                      onClick={(e) => handleMenuOpen(e, "watermark_rd")}
-                    >
-                      Выбрать
-                    </Button>
                   </Paper>
                 </Box>
               </Box>
@@ -467,8 +450,9 @@ export const InformationTab = observer(
               <Button
                 variant="contained"
                 color="success"
-                onClick={() => {
-                  console.log(sight);
+                onClick={async () => {
+                  await updateSight();
+                  toast.success("Достопримечательность сохранена");
                 }}
               >
                 Сохранить
diff --git a/src/widgets/SightTabs/LeftWidgetTab/index.tsx b/src/widgets/SightTabs/LeftWidgetTab/index.tsx
index 4990c42..5576e4f 100644
--- a/src/widgets/SightTabs/LeftWidgetTab/index.tsx
+++ b/src/widgets/SightTabs/LeftWidgetTab/index.tsx
@@ -1,326 +1,345 @@
 // @widgets/LeftWidgetTab.tsx
 import { Box, Button, TextField, Paper, Typography } from "@mui/material";
 import {
-  articlesStore,
   BackButton,
   TabPanel,
   languageStore,
   SelectMediaDialog,
   editSightStore,
+  SelectArticleModal,
+  UploadMediaDialog,
 } from "@shared";
 import {
   LanguageSwitcher,
   ReactMarkdownComponent,
   ReactMarkdownEditor,
+  MediaArea,
+  MediaViewer,
 } from "@widgets";
-import { Unlink, Trash2, ImagePlus } from "lucide-react";
+import { Trash2, ImagePlus } from "lucide-react";
 import { useState, useCallback } from "react";
 import { observer } from "mobx-react-lite";
+import { toast } from "react-toastify";
 
 export const LeftWidgetTab = observer(
   ({ value, index }: { value: number; index: number }) => {
-    const { sight, updateSightInfo } = editSightStore;
-    const { getArticleByArticleId } = articlesStore;
+    const {
+      sight,
+      updateSightInfo,
+      unlinkLeftArticle,
+      updateSight,
+      deleteLeftArticle,
+      createLeftArticle,
+      deleteMedia,
+      uploadMediaOpen,
+      setUploadMediaOpen,
 
-    const linkedArticle = getArticleByArticleId.get(); // Получаем связанную статью
-    const data = sight[languageStore.language]; // Получаем данные для текущего языка
+      setFileToUpload,
+      createLinkWithArticle,
+    } = editSightStore;
+
+    const { language } = languageStore;
+    const data = sight[language];
 
     const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
       useState(false);
+    const [isSelectArticleDialogOpen, setIsSelectArticleDialogOpen] =
+      useState(false);
 
-    const handleMediaSelected = useCallback(() => {
-      // При выборе медиа, обновляем данные для ТЕКУЩЕГО ЯЗЫКА
-      // сохраняя текущие heading и body.
-      updateSightInfo(
-        languageStore.language,
-        {
-          left: {
-            heading: data.left.heading,
-            body: data.left.body,
-          },
-        },
-        false
-      );
-      setIsSelectMediaDialogOpen(false);
-    }, [
-      languageStore.language,
-      {
-        left: {
-          heading: data.left.heading,
-          body: data.left.body,
-        },
+    const handleMediaSelected = useCallback(
+      async (media: {
+        id: string;
+        filename: string;
+        media_name?: string;
+        media_type: number;
+      }) => {
+        await createLinkWithArticle(media);
+        setIsSelectMediaDialogOpen(false);
       },
-      false,
-    ]);
+      [createLinkWithArticle]
+    );
 
     const handleCloseMediaDialog = useCallback(() => {
       setIsSelectMediaDialogOpen(false);
     }, []);
 
-    // ... (остальной JSX код остался почти без изменений)
-    return (
-      <TabPanel value={value} index={index}>
-        <LanguageSwitcher />
-        <Box
-          sx={{
-            display: "flex",
-            flexDirection: "column",
-            gap: 3,
-            paddingBottom: "70px",
-            position: "relative",
-          }}
-        >
-          <BackButton />
+    const handleCloseArticleDialog = useCallback(() => {
+      setIsSelectArticleDialogOpen(false);
+    }, []);
 
-          <Paper
-            elevation={2}
+    const handleSelectArticle = useCallback(
+      (
+        articleId: number,
+        heading: string,
+        body: string,
+        media: { id: string; media_type: number; filename: string }[]
+      ) => {
+        setIsSelectArticleDialogOpen(false);
+        updateSightInfo(languageStore.language, {
+          left: {
+            heading,
+            body,
+            media,
+          },
+        });
+        updateSightInfo(
+          languageStore.language,
+          {
+            left_article: articleId,
+          },
+          true
+        );
+      },
+      []
+    );
+
+    return (
+      <>
+        <TabPanel value={value} index={index}>
+          <LanguageSwitcher />
+          <Box
             sx={{
               display: "flex",
-              alignItems: "center",
-              justifyContent: "space-between",
-              paddingX: 2.5,
-              paddingY: 1.5,
-              borderRadius: 2,
-              border: "1px solid",
-              borderColor: "divider",
+              flexDirection: "column",
+              gap: 3,
+              paddingBottom: "70px",
+              position: "relative",
             }}
           >
-            <Typography variant="h6">Левая статья</Typography>
-            <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
-              {linkedArticle && (
-                <Button
-                  variant="outlined"
-                  color="primary"
-                  startIcon={<Unlink size={18} />}
-                  size="small"
-                >
-                  Открепить
-                </Button>
-              )}
-              <Button
-                variant="outlined"
-                color="error"
-                startIcon={<Trash2 size={18} />}
-                size="small"
-              >
-                Удалить
-              </Button>
-            </Box>
-          </Paper>
+            <BackButton />
 
-          <Box sx={{ display: "flex", gap: 3, flexGrow: 1 }}>
-            {/* Левая колонка: Редактирование */}
-            <Box
-              sx={{ flex: 2, display: "flex", flexDirection: "column", gap: 2 }}
-            >
-              <TextField
-                label="Название информации"
-                value={data?.left?.heading}
-                onChange={(e) =>
-                  updateSightInfo(
-                    languageStore.language,
-                    {
-                      left: {
-                        heading: e.target.value,
-                        body: data.left.body,
-                      },
-                    },
-                    false
-                  )
-                }
-                variant="outlined"
-                fullWidth
-              />
-
-              <ReactMarkdownEditor
-                value={data?.left?.body}
-                onChange={(value) =>
-                  updateSightInfo(
-                    languageStore.language,
-                    {
-                      left: {
-                        heading: data.left.heading,
-                        body: value,
-                      },
-                    },
-                    false
-                  )
-                }
-              />
-
-              {/* Блок МЕДИА для статьи */}
-              {/* <Paper elevation={1} sx={{ padding: 2, mt: 1 }}>
-                <Typography variant="h6" gutterBottom>
-                  МЕДИА
-                </Typography>
-                {data.left.media ? (
-                  <Box sx={{ mb: 1 }}>
-                    <img
-                      src={data.left.media.filename}
-                      alt="Selected media"
-                      style={{
-                        maxWidth: "100%",
-                        maxHeight: "150px",
-                        objectFit: "contain",
-                      }}
-                    />
-                  </Box>
-                ) : (
-                  <Box
-                    sx={{
-                      width: "100%",
-                      height: 100,
-                      backgroundColor: "grey.100",
-                      display: "flex",
-                      alignItems: "center",
-                      justifyContent: "center",
-                      borderRadius: 1,
-                      mb: 1,
-                      border: "2px dashed",
-                      borderColor: "grey.300",
-                    }}
-                  >
-                    <Typography color="text.secondary">Нет медиа</Typography>
-                  </Box>
-                )}
-                <Button
-                  variant="contained"
-                  startIcon={<ImagePlus size={18} />}
-                  onClick={handleOpenMediaDialog}
-                >
-                  Выбрать/Загрузить медиа
-                </Button>
-                {data.left.media && (
-                  <Button
-                    variant="outlined"
-                    color="error"
-                    size="small"
-                    sx={{ ml: 1 }}
-                    onClick={() =>
-                      updateSightInfo(
-                        languageStore.language,
-                        {
-                          left: {
-                              heading:      data.left.heading,
-                            body: data.left.body,
-                            media: null,
-                          },
-                        },
-                        false
-                      )
-                    }
-                  >
-                    Удалить медиа
-                  </Button>
-                )}
-              </Paper> */}
-            </Box>
-
-            {/* Правая колонка: Предпросмотр */}
-            <Box
+            <Paper
+              elevation={2}
               sx={{
-                flex: 1,
                 display: "flex",
-                flexDirection: "column",
-                gap: 1.5,
+                alignItems: "center",
+                justifyContent: "space-between",
+                paddingX: 2.5,
+                paddingY: 1.5,
+                borderRadius: 2,
+                border: "1px solid",
+                borderColor: "divider",
               }}
             >
-              <Paper
-                elevation={3}
-                sx={{
-                  width: "100%",
-                  minWidth: 320,
-                  maxWidth: 400,
-                  height: "auto",
-                  minHeight: 500,
-                  backgroundColor: "#877361",
-                  overflowY: "auto",
-                  padding: 0,
-                  display: "flex",
-                  flexDirection: "column",
-                }}
-              >
-                {/* {data.left.media?.filename ? (
-                  <Box
+              <Typography variant="h6">Левая статья</Typography>
+              <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
+                {sight.common.left_article ? (
+                  <>
+                    <Button
+                      variant="contained"
+                      color="primary"
+                      size="small"
+                      style={{ transition: "0" }}
+                      onClick={() => {
+                        unlinkLeftArticle();
+                        toast.success("Статья откреплена");
+                      }}
+                    >
+                      Открепить
+                    </Button>
+                    <Button
+                      variant="outlined"
+                      color="error"
+                      style={{ transition: "0" }}
+                      startIcon={<Trash2 size={18} />}
+                      size="small"
+                      onClick={() => {
+                        deleteLeftArticle(sight.common.left_article);
+                        toast.success("Статья откреплена");
+                      }}
+                    >
+                      Удалить
+                    </Button>
+                  </>
+                ) : (
+                  <>
+                    <Button
+                      variant="contained"
+                      color="primary"
+                      size="small"
+                      onClick={() => setIsSelectArticleDialogOpen(true)}
+                    >
+                      Выбрать статью
+                    </Button>
+                    <Button
+                      variant="contained"
+                      color="primary"
+                      size="small"
+                      style={{ transition: "0" }}
+                      onClick={() => {
+                        createLeftArticle();
+                        toast.success("Статья создана");
+                      }}
+                    >
+                      Создать статью
+                    </Button>
+                  </>
+                )}
+              </Box>
+            </Paper>
+
+            {sight.common.left_article > 0 && (
+              <Box sx={{ display: "flex", gap: 3, flexGrow: 1 }}>
+                <Box
+                  sx={{
+                    flex: 2,
+                    display: "flex",
+                    flexDirection: "column",
+                    gap: 2,
+                  }}
+                >
+                  <TextField
+                    label="Название информации"
+                    value={data?.left?.heading}
+                    onChange={(e) =>
+                      updateSightInfo(languageStore.language, {
+                        left: {
+                          heading: e.target.value,
+                          body: sight[languageStore.language].left.body,
+                          media: data.left.media,
+                        },
+                      })
+                    }
+                    variant="outlined"
+                    fullWidth
+                  />
+
+                  <ReactMarkdownEditor
+                    value={data?.left?.body}
+                    onChange={(value) =>
+                      updateSightInfo(languageStore.language, {
+                        left: {
+                          heading: sight[languageStore.language].left.heading,
+                          body: value,
+                          media: data.left.media,
+                        },
+                      })
+                    }
+                  />
+
+                  <MediaArea
+                    articleId={sight.common.left_article}
+                    mediaIds={data.left.media}
+                    deleteMedia={deleteMedia}
+                    setSelectMediaDialogOpen={setIsSelectMediaDialogOpen}
+                    onFilesDrop={(files) => {
+                      setFileToUpload(files[0]);
+                      setUploadMediaOpen(true);
+                    }}
+                  />
+                </Box>
+
+                <Box
+                  sx={{
+                    flex: 1,
+                    display: "flex",
+                    flexDirection: "column",
+                    gap: 1.5,
+                  }}
+                >
+                  <Paper
+                    elevation={3}
                     sx={{
                       width: "100%",
-                      height: 200,
-                      backgroundColor: "grey.300",
+                      minWidth: 320,
+                      maxWidth: 400,
+                      height: "auto",
+                      minHeight: 500,
+                      backgroundColor: "#877361",
+                      overflowY: "auto",
+                      padding: 0,
                       display: "flex",
-                      alignItems: "center",
-                      justifyContent: "center",
+                      flexDirection: "column",
                     }}
                   >
-                    <img
-                      src={data.left.media?.filename ?? ""}
-                      alt="Превью медиа"
-                      style={{
-                        objectFit: "cover",
+                    <Box
+                      sx={{
                         width: "100%",
-                        height: "100%",
+                        height: 200,
+                        backgroundColor: "grey.300",
+                        display: "flex",
+                        alignItems: "center",
+                        justifyContent: "center",
                       }}
-                    />
-                  </Box>
-                ) : (
-                  
-                )} */}
+                    >
+                      {data.left.media.length > 0 ? (
+                        <MediaViewer
+                          media={{
+                            id: data.left.media[0].id,
+                            media_type: data.left.media[0].media_type,
+                            filename: data.left.media[0].filename,
+                          }}
+                        />
+                      ) : (
+                        <ImagePlus size={48} color="grey" />
+                      )}
+                    </Box>
 
-                <Box
-                  sx={{
-                    width: "100%",
-                    height: 200,
-                    backgroundColor: "grey.300",
-                    display: "flex",
-                    alignItems: "center",
-                    justifyContent: "center",
-                  }}
-                >
-                  <ImagePlus size={48} color="grey" />
-                </Box>
+                    <Box
+                      sx={{
+                        backgroundColor: "#877361",
+                        color: "white",
+                        padding: 1.5,
+                      }}
+                    >
+                      <Typography
+                        variant="h5"
+                        component="h2"
+                        sx={{ wordBreak: "break-word" }}
+                      >
+                        {data?.left?.heading || "Название информации"}
+                      </Typography>
+                    </Box>
 
-                {/* Заголовок в превью */}
-                <Box
-                  sx={{
-                    backgroundColor: "#877361",
-                    color: "white",
-                    padding: 1.5,
-                  }}
-                >
-                  <Typography
-                    variant="h5"
-                    component="h2"
-                    sx={{ wordBreak: "break-word" }}
-                  >
-                    {data?.left?.heading || "Название информации"}
-                  </Typography>
+                    {data?.left?.body && (
+                      <Box
+                        sx={{
+                          padding: 2,
+                          flexGrow: 1,
+                        }}
+                      >
+                        <ReactMarkdownComponent value={data?.left?.body} />
+                      </Box>
+                    )}
+                  </Paper>
                 </Box>
+              </Box>
+            )}
 
-                {/* Текст статьи в превью */}
-                <Box
-                  sx={{
-                    padding: 2,
-                    flexGrow: 1,
-                  }}
-                >
-                  <ReactMarkdownComponent value={data?.left?.body} />
-                </Box>
-              </Paper>
+            <Box sx={{ position: "absolute", bottom: 0, right: 0, padding: 2 }}>
+              <Button
+                variant="contained"
+                color="success"
+                onClick={async () => {
+                  await updateSight();
+                  toast.success("Достопримечательность сохранена");
+                }}
+              >
+                Сохранить
+              </Button>
             </Box>
           </Box>
-
-          <Box sx={{ position: "absolute", bottom: 0, right: 0, padding: 2 }}>
-            <Button variant="contained" color="success">
-              Сохранить
-            </Button>
-          </Box>
-        </Box>
-
+        </TabPanel>
+        <UploadMediaDialog
+          open={uploadMediaOpen}
+          onClose={() => setUploadMediaOpen(false)}
+          afterUpload={async (media) => {
+            setUploadMediaOpen(false);
+            setFileToUpload(null);
+            await createLinkWithArticle(media);
+          }}
+        />
         <SelectMediaDialog
           open={isSelectMediaDialogOpen}
           onClose={handleCloseMediaDialog}
           onSelectMedia={handleMediaSelected}
         />
-      </TabPanel>
+        <SelectArticleModal
+          open={isSelectArticleDialogOpen}
+          onClose={handleCloseArticleDialog}
+          onSelectArticle={handleSelectArticle}
+        />
+      </>
     );
   }
 );
diff --git a/src/widgets/SightTabs/RightWidgetTab/index.tsx b/src/widgets/SightTabs/RightWidgetTab/index.tsx
index c04442c..b8ab094 100644
--- a/src/widgets/SightTabs/RightWidgetTab/index.tsx
+++ b/src/widgets/SightTabs/RightWidgetTab/index.tsx
@@ -1,345 +1,288 @@
 import {
   Box,
   Button,
-  List,
-  ListItemButton,
-  ListItemText,
   Paper,
   Typography,
   Menu,
   MenuItem,
+  TextField,
 } from "@mui/material";
 import {
-  articlesStore,
   BackButton,
+  createSightStore,
+  editSightStore,
+  languageStore,
   SelectArticleModal,
   TabPanel,
 } from "@shared";
-import { SightEdit } from "@widgets";
-import { Plus } from "lucide-react";
+import {
+  LanguageSwitcher,
+  ReactMarkdownComponent,
+  ReactMarkdownEditor,
+} from "@widgets";
+import { ImagePlus, Plus } from "lucide-react";
 import { observer } from "mobx-react-lite";
-import { useState } from "react";
+import { useEffect, useState } from "react";
+import { toast } from "react-toastify";
 
-// --- Mock Data (can be moved to a separate file or fetched from an API) ---
-const mockRightWidgetBlocks = [
-  { id: "preview_media", name: "Превью-медиа", type: "special" },
-  { id: "article_1", name: "1. История", type: "article" },
-  { id: "article_2", name: "2. Факты", type: "article" },
-  {
-    id: "article_3",
-    name: "3. Блокада (Пример длинного названия)",
-    type: "article",
-  },
-];
-
-const mockSelectedBlockData = {
-  id: "article_1",
-  heading: "История основания Санкт-Петербурга",
-  body: "## Начало\nГород был основан 27 мая 1703 года Петром I...",
-  media: [],
-};
-
-// --- ArticleListSidebar Component ---
-interface ArticleBlock {
-  id: string;
-  name: string;
-  type: string;
-  linkedArticleId?: string; // Added for linked articles
-}
-
-interface ArticleListSidebarProps {
-  blocks: ArticleBlock[];
-  selectedBlockId: string | null;
-  onSelectBlock: (blockId: string) => void;
-  onCreateNew: () => void;
-  onSelectExisting: () => void;
-}
-
-const ArticleListSidebar = ({
-  blocks,
-  selectedBlockId,
-  onSelectBlock,
-  onCreateNew,
-  onSelectExisting,
-}: ArticleListSidebarProps) => {
-  const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);
-
-  const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
-    setMenuAnchorEl(event.currentTarget);
-  };
-
-  const handleMenuClose = () => {
-    setMenuAnchorEl(null);
-  };
-
-  return (
-    <Paper
-      elevation={2}
-      sx={{
-        width: 260,
-        minWidth: 240,
-        display: "flex",
-        flexDirection: "column",
-        justifyContent: "space-between",
-        padding: 1.5,
-        borderRadius: 2,
-        border: "1px solid",
-        borderColor: "divider",
-      }}
-    >
-      <List
-        dense
-        sx={{
-          overflowY: "auto",
-          flexGrow: 1,
-          maxHeight: "calc(100% - 60px)",
-        }}
-      >
-        {blocks.map((block) => (
-          <ListItemButton
-            key={block.id}
-            selected={selectedBlockId === block.id}
-            onClick={() => onSelectBlock(block.id)}
-            sx={{
-              borderRadius: 1,
-              mb: 0.5,
-              backgroundColor:
-                selectedBlockId === block.id ? "primary.light" : "transparent",
-              "&.Mui-selected": {
-                backgroundColor: "primary.main",
-                color: "primary.contrastText",
-                "&:hover": {
-                  backgroundColor: "primary.dark",
-                },
-              },
-              "&:hover": {
-                backgroundColor:
-                  selectedBlockId !== block.id ? "action.hover" : undefined,
-              },
-            }}
-          >
-            <ListItemText
-              primary={block.name}
-              primaryTypographyProps={{
-                fontWeight: selectedBlockId === block.id ? "bold" : "normal",
-                overflow: "hidden",
-                textOverflow: "ellipsis",
-                whiteSpace: "nowrap",
-              }}
-            />
-          </ListItemButton>
-        ))}
-      </List>
-
-      <button
-        className="w-8 h-8 rounded-full bg-blue-500 text-white flex items-center justify-center hover:bg-blue-600 transition-colors"
-        onClick={handleMenuOpen}
-      >
-        <Plus color="white" />
-      </button>
-      <Menu
-        anchorEl={menuAnchorEl}
-        open={Boolean(menuAnchorEl)}
-        onClose={handleMenuClose}
-        anchorOrigin={{
-          vertical: "top",
-          horizontal: "right",
-        }}
-        transformOrigin={{
-          vertical: "bottom",
-          horizontal: "right",
-        }}
-      >
-        <MenuItem onClick={onCreateNew}>Создать новую</MenuItem>
-        <MenuItem onClick={onSelectExisting}>Выбрать существующую</MenuItem>
-      </Menu>
-    </Paper>
-  );
-};
-
-// --- ArticleEditorPane Component ---
-interface ArticleData {
-  id: string;
-  heading: string;
-  body: string;
-  media: any[]; // Define a proper type for media if available
-}
-
-interface ArticleEditorPaneProps {
-  articleData: ArticleData | null;
-}
-
-const ArticleEditorPane = ({ articleData }: ArticleEditorPaneProps) => {
-  if (!articleData) {
-    return (
-      <Paper
-        elevation={2}
-        sx={{
-          flexGrow: 1,
-          padding: 2.5,
-          borderRadius: 2,
-          border: "1px solid",
-          borderColor: "divider",
-          display: "flex",
-          alignItems: "center",
-          justifyContent: "center",
-        }}
-      >
-        <Typography variant="h6" color="text.secondary">
-          Выберите блок для редактирования
-        </Typography>
-      </Paper>
-    );
-  }
-
-  return (
-    <Paper
-      elevation={2}
-      sx={{
-        flexGrow: 1,
-        padding: 2.5,
-        borderRadius: 2,
-        border: "1px solid",
-        borderColor: "divider",
-        overflowY: "auto",
-      }}
-    >
-      <SightEdit />
-      <Paper elevation={1} sx={{ padding: 2, mt: 1, width: "75%" }}>
-        <Typography variant="h6" gutterBottom>
-          МЕДИА
-        </Typography>
-        <Box
-          sx={{
-            width: "100%",
-            height: 100,
-            backgroundColor: "grey.100",
-            display: "flex",
-            alignItems: "center",
-            justifyContent: "center",
-            borderRadius: 1,
-            mb: 1,
-            border: "2px dashed",
-            borderColor: "grey.300",
-          }}
-        >
-          <Typography color="text.secondary">Нет медиа</Typography>
-        </Box>
-        <Button variant="contained">Выбрать/Загрузить медиа</Button>
-      </Paper>
-    </Paper>
-  );
-};
-
-// --- RightWidgetTab (Parent) Component ---
 export const RightWidgetTab = observer(
   ({ value, index }: { value: number; index: number }) => {
-    const [rightWidgetBlocks, setRightWidgetBlocks] = useState<ArticleBlock[]>(
-      mockRightWidgetBlocks
-    );
-    const [selectedBlockId, setSelectedBlockId] = useState<string | null>(
-      mockRightWidgetBlocks[1]?.id || null
+    const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
+    const { createNewRightArticle, updateRightArticleInfo } = createSightStore;
+    const { sight, getRightArticles, updateSight } = editSightStore;
+    const { language } = languageStore;
+
+    useEffect(() => {
+      if (sight.common.id) {
+        getRightArticles(sight.common.id);
+      }
+    }, [sight.common.id]);
+
+    const [activeArticleIndex, setActiveArticleIndex] = useState<number | null>(
+      null
     );
     const [isSelectModalOpen, setIsSelectModalOpen] = useState(false);
 
-    const handleSelectBlock = (blockId: string) => {
-      setSelectedBlockId(blockId);
-      console.log("Selected block:", blockId);
+    const open = Boolean(anchorEl);
+    const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
+      setAnchorEl(event.currentTarget);
+    };
+    const handleClose = () => {
+      setAnchorEl(null);
+    };
+
+    const handleSelectArticle = (index: number) => {
+      setActiveArticleIndex(index);
     };
 
     const handleCreateNew = () => {
-      const newBlockId = `article_${Date.now()}`;
-      setRightWidgetBlocks((prevBlocks) => [
-        ...prevBlocks,
-        {
-          id: newBlockId,
-          name: `${
-            prevBlocks.filter((b) => b.type === "article").length + 1
-          }. Новый блок`,
-          type: "article",
-        },
-      ]);
-      setSelectedBlockId(newBlockId);
+      createNewRightArticle();
+      handleClose();
     };
 
     const handleSelectExisting = () => {
       setIsSelectModalOpen(true);
+      handleClose();
     };
 
     const handleCloseSelectModal = () => {
       setIsSelectModalOpen(false);
     };
 
-    const handleSelectArticle = (articleId: string) => {
-      // @ts-ignore
-      const article = articlesStore.articles.find((a) => a.id === articleId);
-      if (article) {
-        const newBlockId = `article_linked_${article.id}_${Date.now()}`;
-        setRightWidgetBlocks((prevBlocks) => [
-          ...prevBlocks,
-          {
-            id: newBlockId,
-            name: `${
-              prevBlocks.filter((b) => b.type === "article").length + 1
-            }. ${article.service_name}`,
-            type: "article",
-            linkedArticleId: article.id,
-          },
-        ]);
-        setSelectedBlockId(newBlockId);
-      }
+    const handleArticleSelect = () => {
+      // TODO: Implement article selection logic
       handleCloseSelectModal();
     };
 
-    const handleSave = () => {
-      console.log("Saving right widget...");
-      // Implement save logic here, e.g., send data to an API
+    const handleSave = async () => {
+      await updateSight();
+      toast.success("Достопримечательность сохранена");
     };
 
-    // Determine the current block data to pass to the editor pane
-    const currentBlockToEdit = selectedBlockId
-      ? selectedBlockId === mockSelectedBlockData.id
-        ? mockSelectedBlockData
-        : {
-            id: selectedBlockId,
-            heading:
-              rightWidgetBlocks.find((b) => b.id === selectedBlockId)?.name ||
-              "Заголовок...",
-            body: "Содержимое...",
-            media: [],
-          }
-      : null;
-
-    // Get list of already linked article IDs
-    const linkedArticleIds = rightWidgetBlocks
-      .filter((block) => block.linkedArticleId)
-      .map((block) => block.linkedArticleId as string);
-
     return (
       <TabPanel value={value} index={index}>
+        <LanguageSwitcher />
         <Box
           sx={{
             display: "flex",
             flexDirection: "column",
             height: "100%",
-            minHeight: "calc(100vh - 200px)", // Adjust as needed
+            minHeight: "calc(100vh - 200px)",
             gap: 2,
-            paddingBottom: "70px", // Space for the save button
+            paddingBottom: "70px",
             position: "relative",
           }}
         >
           <BackButton />
 
           <Box sx={{ display: "flex", flexGrow: 1, gap: 2.5 }}>
-            <ArticleListSidebar
-              blocks={rightWidgetBlocks}
-              selectedBlockId={selectedBlockId}
-              onSelectBlock={handleSelectBlock}
-              onCreateNew={handleCreateNew}
-              onSelectExisting={handleSelectExisting}
-            />
+            <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">
+                  <Box className="flex flex-col gap-3 max-h-[60vh] overflow-y-auto">
+                    <Box
+                      // onClick={() => setMediaType("preview")}
+                      className="w-full bg-gray-200 p-4 rounded-2xl cursor-pointer text-sm hover:bg-gray-300 transition-all duration-300"
+                    >
+                      <Typography>Предпросмотр медиа</Typography>
+                    </Box>
 
-            <ArticleEditorPane articleData={currentBlockToEdit} />
+                    {sight[language].right.map((article, index) => (
+                      <Box
+                        key={index}
+                        className="w-full bg-gray-200 p-4 rounded-2xl text-sm cursor-pointer hover:bg-gray-300 transition-all duration-300"
+                        onClick={() => handleSelectArticle(index)}
+                      >
+                        <Typography>{article.heading}</Typography>
+                      </Box>
+                    ))}
+                  </Box>
+                  <button
+                    className="w-10 h-10 bg-blue-500 rounded-full absolute bottom-5 left-5 flex items-center justify-center"
+                    onClick={handleClick}
+                  >
+                    <Plus size={20} color="white" />
+                  </button>
+                  <Menu
+                    id="basic-menu"
+                    anchorEl={anchorEl}
+                    open={open}
+                    onClose={handleClose}
+                    MenuListProps={{
+                      "aria-labelledby": "basic-button",
+                    }}
+                    sx={{ mt: 1 }}
+                  >
+                    <MenuItem onClick={handleCreateNew}>
+                      <Typography>Создать новую</Typography>
+                    </MenuItem>
+                    <MenuItem onClick={handleSelectExisting}>
+                      <Typography>Выбрать существующую статью</Typography>
+                    </MenuItem>
+                  </Menu>
+                </Box>
+
+                <Box className="w-[80%] border border-gray-300 rounded-2xl p-3">
+                  {activeArticleIndex !== null && (
+                    <>
+                      <Box className="flex justify-end gap-2 mb-3">
+                        <Button variant="contained" color="primary">
+                          Открепить
+                        </Button>
+                        <Button variant="contained" color="success">
+                          Удалить
+                        </Button>
+                      </Box>
+                      <Box sx={{ display: "flex", gap: 3, flexGrow: 1 }}>
+                        <Box
+                          sx={{
+                            flex: 2,
+                            display: "flex",
+                            flexDirection: "column",
+                            gap: 2,
+                            maxHeight: "70%",
+                          }}
+                        >
+                          <TextField
+                            label="Название информации"
+                            value={
+                              sight[language].right[activeArticleIndex].heading
+                            }
+                            onChange={(e) =>
+                              updateRightArticleInfo(
+                                activeArticleIndex,
+                                language,
+                                e.target.value,
+                                sight[language].right[activeArticleIndex].body
+                              )
+                            }
+                            variant="outlined"
+                            fullWidth
+                          />
+
+                          <ReactMarkdownEditor
+                            value={
+                              sight[language].right[activeArticleIndex].body
+                            }
+                            onChange={(value) =>
+                              updateRightArticleInfo(
+                                activeArticleIndex,
+                                language,
+                                sight[language].right[activeArticleIndex]
+                                  .heading,
+                                value
+                              )
+                            }
+                          />
+                          {/* <MediaArea
+                            articleId={1}
+                            mediaIds={[]}
+                            deleteMedia={() => {}}
+                          /> */}
+                        </Box>
+                      </Box>
+                    </>
+                  )}
+                </Box>
+              </Box>
+            </Box>
+
+            <Box className="w-[25%] mr-10">
+              {activeArticleIndex !== null && (
+                <Paper
+                  className="flex-1 flex flex-col rounded-2xl"
+                  elevation={2}
+                >
+                  <Box
+                    className="rounded-2xl overflow-hidden"
+                    sx={{
+                      width: "100%",
+                      height: "75vh",
+                      background: "#877361",
+                      borderColor: "grey.300",
+                      display: "flex",
+                      flexDirection: "column",
+                    }}
+                  >
+                    <Box
+                      sx={{
+                        width: "100%",
+                        height: 200,
+                        flexShrink: 0,
+                        backgroundColor: "rgba(0,0,0,0.1)",
+                        display: "flex",
+                        alignItems: "center",
+                        justifyContent: "center",
+                      }}
+                    >
+                      <ImagePlus size={48} color="white" />
+                    </Box>
+
+                    <Box
+                      sx={{
+                        width: "100%",
+                        minHeight: "70px",
+                        background: "#877361",
+                        display: "flex",
+                        flexShrink: 0,
+                        alignItems: "center",
+                        borderBottom: "1px solid rgba(255,255,255,0.1)",
+                        px: 2,
+                      }}
+                    >
+                      <Typography variant="h6" color="white">
+                        {sight[language].right[activeArticleIndex].heading ||
+                          "Выберите статью"}
+                      </Typography>
+                    </Box>
+
+                    <Box
+                      sx={{
+                        px: 2,
+                        flexGrow: 1,
+                        overflowY: "auto",
+                        backgroundColor: "#877361",
+                        color: "white",
+                        py: 1,
+                      }}
+                    >
+                      {sight[language].right[activeArticleIndex].body ? (
+                        <ReactMarkdownComponent
+                          value={sight[language].right[activeArticleIndex].body}
+                        />
+                      ) : (
+                        <Typography
+                          color="rgba(255,255,255,0.7)"
+                          sx={{ textAlign: "center", mt: 4 }}
+                        >
+                          Предпросмотр статьи появится здесь
+                        </Typography>
+                      )}
+                    </Box>
+                  </Box>
+                </Paper>
+              )}
+            </Box>
           </Box>
 
           <Box
@@ -348,8 +291,8 @@ export const RightWidgetTab = observer(
               bottom: 0,
               right: 0,
               padding: 2,
-              backgroundColor: "background.paper", // Ensure button is visible
-              width: "100%", // Cover the full width to make it a sticky footer
+              backgroundColor: "background.paper",
+              width: "100%",
               display: "flex",
               justifyContent: "flex-end",
             }}
@@ -363,8 +306,7 @@ export const RightWidgetTab = observer(
         <SelectArticleModal
           open={isSelectModalOpen}
           onClose={handleCloseSelectModal}
-          onSelectArticle={handleSelectArticle}
-          linkedArticleIds={linkedArticleIds}
+          onSelectArticle={handleArticleSelect}
         />
       </TabPanel>
     );
diff --git a/src/widgets/SightTabs/index.ts b/src/widgets/SightTabs/index.ts
index 1866c7f..20dd419 100644
--- a/src/widgets/SightTabs/index.ts
+++ b/src/widgets/SightTabs/index.ts
@@ -1,3 +1,6 @@
 export * from "./InformationTab";
 export * from "./LeftWidgetTab";
 export * from "./RightWidgetTab";
+export * from "./CreateInformationTab";
+export * from "./CreateLeftTab";
+export * from "./CreateRightTab";
diff --git a/src/widgets/index.ts b/src/widgets/index.ts
index 5db03b3..4ca557b 100644
--- a/src/widgets/index.ts
+++ b/src/widgets/index.ts
@@ -8,3 +8,5 @@ export * from "./LanguageSwitcher";
 export * from "./DevicesTable";
 export * from "./SightsTable";
 export * from "./MediaViewer";
+export * from "./MediaArea";
+export * from "./ModelViewer3D";
diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo
index 1735a1a..089bd8d 100644
--- a/tsconfig.tsbuildinfo
+++ b/tsconfig.tsbuildinfo
@@ -1 +1 @@
-{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/index.tsx","./src/app/router/index.tsx","./src/entities/index.ts","./src/entities/navigation/index.ts","./src/entities/navigation/model/index.ts","./src/entities/navigation/ui/index.tsx","./src/features/index.ts","./src/features/navigation/index.ts","./src/features/navigation/ui/index.tsx","./src/pages/index.ts","./src/pages/createsightpage/index.tsx","./src/pages/devicespage/index.tsx","./src/pages/editsightpage/index.tsx","./src/pages/loginpage/index.tsx","./src/pages/mainpage/index.tsx","./src/pages/sightpage/index.tsx","./src/shared/index.tsx","./src/shared/api/index.tsx","./src/shared/config/constants.tsx","./src/shared/config/index.ts","./src/shared/const/index.ts","./src/shared/lib/index.ts","./src/shared/lib/decodejwt/index.ts","./src/shared/lib/mui/theme.ts","./src/shared/modals/index.ts","./src/shared/modals/previewmediadialog/index.tsx","./src/shared/modals/selectarticledialog/index.tsx","./src/shared/modals/selectmediadialog/index.tsx","./src/shared/store/index.ts","./src/shared/store/articlesstore/index.tsx","./src/shared/store/authstore/index.tsx","./src/shared/store/citystore/index.tsx","./src/shared/store/devicesstore/index.tsx","./src/shared/store/editsightstore/index.tsx","./src/shared/store/languagestore/index.tsx","./src/shared/store/mediastore/index.tsx","./src/shared/store/sightsstore/index.tsx","./src/shared/store/snapshotstore/index.ts","./src/shared/store/vehiclestore/index.ts","./src/shared/ui/index.ts","./src/shared/ui/backbutton/index.tsx","./src/shared/ui/coordinatesinput/index.tsx","./src/shared/ui/input/index.tsx","./src/shared/ui/modal/index.tsx","./src/shared/ui/tabpanel/index.tsx","./src/widgets/index.ts","./src/widgets/devicestable/index.tsx","./src/widgets/languageswitcher/index.tsx","./src/widgets/layout/index.tsx","./src/widgets/layout/ui/appbar.tsx","./src/widgets/layout/ui/drawer.tsx","./src/widgets/layout/ui/drawerheader.tsx","./src/widgets/mediaviewer/threeview.tsx","./src/widgets/mediaviewer/index.tsx","./src/widgets/reactmarkdown/index.tsx","./src/widgets/reactmarkdowneditor/index.tsx","./src/widgets/sightedit/index.tsx","./src/widgets/sightheader/index.ts","./src/widgets/sightheader/ui/index.tsx","./src/widgets/sighttabs/index.ts","./src/widgets/sighttabs/informationtab/index.tsx","./src/widgets/sighttabs/leftwidgettab/index.tsx","./src/widgets/sighttabs/rightwidgettab/index.tsx","./src/widgets/sightstable/index.tsx","./src/widgets/modals/index.ts","./src/widgets/modals/selectarticledialog/index.tsx"],"errors":true,"version":"5.8.3"}
\ No newline at end of file
+{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/index.tsx","./src/app/router/index.tsx","./src/entities/index.ts","./src/entities/navigation/index.ts","./src/entities/navigation/model/index.ts","./src/entities/navigation/ui/index.tsx","./src/features/index.ts","./src/features/navigation/index.ts","./src/features/navigation/ui/index.tsx","./src/pages/index.ts","./src/pages/createsightpage/index.tsx","./src/pages/devicespage/index.tsx","./src/pages/editsightpage/index.tsx","./src/pages/loginpage/index.tsx","./src/pages/mainpage/index.tsx","./src/pages/sightpage/index.tsx","./src/shared/index.tsx","./src/shared/api/index.tsx","./src/shared/config/constants.tsx","./src/shared/config/index.ts","./src/shared/const/index.ts","./src/shared/lib/index.ts","./src/shared/lib/decodejwt/index.ts","./src/shared/lib/mui/theme.ts","./src/shared/modals/index.ts","./src/shared/modals/previewmediadialog/index.tsx","./src/shared/modals/selectarticledialog/index.tsx","./src/shared/modals/selectmediadialog/index.tsx","./src/shared/modals/uploadmediadialog/index.tsx","./src/shared/store/index.ts","./src/shared/store/articlesstore/index.tsx","./src/shared/store/authstore/index.tsx","./src/shared/store/citystore/index.tsx","./src/shared/store/createsightstore/index.tsx","./src/shared/store/devicesstore/index.tsx","./src/shared/store/editsightstore/index.tsx","./src/shared/store/languagestore/index.tsx","./src/shared/store/mediastore/index.tsx","./src/shared/store/sightsstore/index.tsx","./src/shared/store/snapshotstore/index.ts","./src/shared/store/vehiclestore/index.ts","./src/shared/ui/index.ts","./src/shared/ui/backbutton/index.tsx","./src/shared/ui/coordinatesinput/index.tsx","./src/shared/ui/input/index.tsx","./src/shared/ui/modal/index.tsx","./src/shared/ui/tabpanel/index.tsx","./src/widgets/index.ts","./src/widgets/devicestable/index.tsx","./src/widgets/languageswitcher/index.tsx","./src/widgets/layout/index.tsx","./src/widgets/layout/ui/appbar.tsx","./src/widgets/layout/ui/drawer.tsx","./src/widgets/layout/ui/drawerheader.tsx","./src/widgets/mediaarea/index.tsx","./src/widgets/mediaviewer/threeview.tsx","./src/widgets/mediaviewer/index.tsx","./src/widgets/modelviewer3d/index.tsx","./src/widgets/reactmarkdown/index.tsx","./src/widgets/reactmarkdowneditor/index.tsx","./src/widgets/sightedit/index.tsx","./src/widgets/sightheader/index.ts","./src/widgets/sightheader/ui/index.tsx","./src/widgets/sighttabs/index.ts","./src/widgets/sighttabs/createinformationtab/mediauploadbox.tsx","./src/widgets/sighttabs/createinformationtab/index.tsx","./src/widgets/sighttabs/createlefttab/index.tsx","./src/widgets/sighttabs/createrighttab/index.tsx","./src/widgets/sighttabs/informationtab/index.tsx","./src/widgets/sighttabs/leftwidgettab/index.tsx","./src/widgets/sighttabs/rightwidgettab/index.tsx","./src/widgets/sightstable/index.tsx","./src/widgets/modals/index.ts","./src/widgets/modals/selectarticledialog/index.tsx"],"version":"5.8.3"}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 84388b2..d15ebca 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1323,6 +1323,11 @@ asynckit@^0.4.0:
   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
   integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
 
+attr-accept@^2.2.4:
+  version "2.2.5"
+  resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e"
+  integrity sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==
+
 axios@^1.9.0:
   version "1.9.0"
   resolved "https://registry.yarnpkg.com/axios/-/axios-1.9.0.tgz#25534e3b72b54540077d33046f77e3b8d7081901"
@@ -1908,6 +1913,13 @@ file-entry-cache@^8.0.0:
   dependencies:
     flat-cache "^4.0.0"
 
+file-selector@^2.1.0:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-2.1.2.tgz#fe7c7ee9e550952dfbc863d73b14dc740d7de8b4"
+  integrity sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==
+  dependencies:
+    tslib "^2.7.0"
+
 fill-range@^7.1.1:
   version "7.1.1"
   resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz"
@@ -3098,6 +3110,15 @@ react-dom@^19.1.0:
   dependencies:
     scheduler "^0.26.0"
 
+react-dropzone@^14.3.8:
+  version "14.3.8"
+  resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.3.8.tgz#a7eab118f8a452fe3f8b162d64454e81ba830582"
+  integrity sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==
+  dependencies:
+    attr-accept "^2.2.4"
+    file-selector "^2.1.0"
+    prop-types "^15.8.1"
+
 react-is@^16.13.1, react-is@^16.7.0:
   version "16.13.1"
   resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
@@ -3501,7 +3522,7 @@ ts-api-utils@^2.1.0:
   resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz"
   integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==
 
-tslib@^2.4.0, tslib@^2.8.0:
+tslib@^2.4.0, tslib@^2.7.0, tslib@^2.8.0:
   version "2.8.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
   integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==