Add correct edit right widget
This commit is contained in:
@ -13,37 +13,63 @@ import {
|
||||
editSightStore,
|
||||
languageStore,
|
||||
SelectArticleModal,
|
||||
SelectMediaDialog,
|
||||
TabPanel,
|
||||
UploadMediaDialog,
|
||||
} from "@shared";
|
||||
import {
|
||||
LanguageSwitcher,
|
||||
MediaArea,
|
||||
MediaAreaForSight,
|
||||
ReactMarkdownComponent,
|
||||
ReactMarkdownEditor,
|
||||
} from "@widgets";
|
||||
import { ImagePlus, Plus } from "lucide-react";
|
||||
import { ImagePlus, Plus, X } from "lucide-react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
import { MediaViewer } from "../../MediaViewer/index";
|
||||
|
||||
export const RightWidgetTab = observer(
|
||||
({ value, index }: { value: number; index: number }) => {
|
||||
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||
const { createNewRightArticle, updateRightArticleInfo } = createSightStore;
|
||||
const { sight, getRightArticles, updateSight } = editSightStore;
|
||||
const { language } = languageStore;
|
||||
|
||||
const {
|
||||
sight,
|
||||
updateRightArticleInfo,
|
||||
getRightArticles,
|
||||
updateSight,
|
||||
unlinkPreviewMedia,
|
||||
linkPreviewMedia,
|
||||
unlinkRightArticle,
|
||||
deleteRightArticle,
|
||||
linkArticle,
|
||||
deleteRightArticleMedia,
|
||||
createLinkWithRightArticle,
|
||||
setFileToUpload,
|
||||
createNewRightArticle,
|
||||
} = editSightStore;
|
||||
|
||||
const [uploadMediaOpen, setUploadMediaOpen] = useState(false);
|
||||
const { language } = languageStore;
|
||||
const [type, setType] = useState<"article" | "media">("media");
|
||||
useEffect(() => {
|
||||
if (sight.common.id) {
|
||||
getRightArticles(sight.common.id);
|
||||
}
|
||||
const fetchData = async () => {
|
||||
if (sight.common.id) {
|
||||
await getRightArticles(sight.common.id);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
console.log(sight[language].right);
|
||||
}, [sight.common.id]);
|
||||
|
||||
const [activeArticleIndex, setActiveArticleIndex] = useState<number | null>(
|
||||
null
|
||||
);
|
||||
const [isSelectModalOpen, setIsSelectModalOpen] = useState(false);
|
||||
|
||||
const [isSelectMediaModalOpen, setIsSelectMediaModalOpen] = useState(false);
|
||||
const open = Boolean(anchorEl);
|
||||
|
||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
@ -69,16 +95,32 @@ export const RightWidgetTab = observer(
|
||||
setIsSelectModalOpen(false);
|
||||
};
|
||||
|
||||
const handleArticleSelect = () => {
|
||||
// TODO: Implement article selection logic
|
||||
const handleArticleSelect = (id: number) => {
|
||||
linkArticle(id);
|
||||
handleCloseSelectModal();
|
||||
};
|
||||
|
||||
const handleMediaSelected = async (media: {
|
||||
id: string;
|
||||
filename: string;
|
||||
media_name?: string;
|
||||
media_type: number;
|
||||
}) => {
|
||||
await createLinkWithRightArticle(
|
||||
media,
|
||||
sight[language].right[activeArticleIndex || 0].id
|
||||
);
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
await updateSight();
|
||||
toast.success("Достопримечательность сохранена");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log(sight[language].right);
|
||||
}, [sight[language].right]);
|
||||
|
||||
return (
|
||||
<TabPanel value={value} index={index}>
|
||||
<LanguageSwitcher />
|
||||
@ -99,23 +141,26 @@ export const RightWidgetTab = observer(
|
||||
<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 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"
|
||||
onClick={() => setType("media")}
|
||||
className="w-full bg-green-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>
|
||||
))}
|
||||
{sight[language].right.length > 0 &&
|
||||
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);
|
||||
setType("article");
|
||||
}}
|
||||
>
|
||||
<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"
|
||||
@ -142,147 +187,225 @@ export const RightWidgetTab = observer(
|
||||
</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={() => {}}
|
||||
/> */}
|
||||
{type === "article" && (
|
||||
<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"
|
||||
onClick={() => {
|
||||
unlinkRightArticle(
|
||||
sight[language].right[activeArticleIndex].id
|
||||
);
|
||||
setActiveArticleIndex(null);
|
||||
}}
|
||||
>
|
||||
Открепить
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="success"
|
||||
onClick={() => {
|
||||
deleteRightArticle(
|
||||
sight[language].right[activeArticleIndex].id
|
||||
);
|
||||
setActiveArticleIndex(null);
|
||||
}}
|
||||
>
|
||||
Удалить
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</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={
|
||||
sight[language].right[activeArticleIndex].id
|
||||
}
|
||||
mediaIds={
|
||||
sight[language].right[activeArticleIndex].media
|
||||
}
|
||||
onFilesDrop={(files) => {
|
||||
setFileToUpload(files[0]);
|
||||
setUploadMediaOpen(true);
|
||||
}}
|
||||
deleteMedia={deleteRightArticleMedia}
|
||||
setSelectMediaDialogOpen={() => {
|
||||
setIsSelectMediaModalOpen(true);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
{type === "media" && (
|
||||
<Box className="w-[80%] border border-gray-300 rounded-2xl relative">
|
||||
{sight.common.preview_media && (
|
||||
<>
|
||||
<Box className="absolute top-4 right-4">
|
||||
<button
|
||||
className="w-10 h-10 flex items-center justify-center"
|
||||
onClick={unlinkPreviewMedia}
|
||||
>
|
||||
<X size={20} color="red" />
|
||||
</button>
|
||||
</Box>
|
||||
|
||||
<MediaViewer
|
||||
media={{
|
||||
id: sight.common.preview_media || "",
|
||||
media_type: 1,
|
||||
filename: sight.common.preview_media || "",
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{!sight.common.preview_media && (
|
||||
<MediaAreaForSight
|
||||
onFinishUpload={(mediaId) => {
|
||||
linkPreviewMedia(mediaId);
|
||||
}}
|
||||
onFilesDrop={() => {}}
|
||||
/>
|
||||
)}
|
||||
</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",
|
||||
}}
|
||||
{type === "article" && (
|
||||
<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: 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",
|
||||
height: "75vh",
|
||||
background: "#877361",
|
||||
borderColor: "grey.300",
|
||||
display: "flex",
|
||||
flexShrink: 0,
|
||||
alignItems: "center",
|
||||
borderBottom: "1px solid rgba(255,255,255,0.1)",
|
||||
px: 2,
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<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}
|
||||
{sight[language].right[activeArticleIndex].media.length >
|
||||
0 ? (
|
||||
<MediaViewer
|
||||
media={
|
||||
sight[language].right[activeArticleIndex].media[0]
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Typography
|
||||
color="rgba(255,255,255,0.7)"
|
||||
sx={{ textAlign: "center", mt: 4 }}
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: 200,
|
||||
flexShrink: 0,
|
||||
backgroundColor: "rgba(0,0,0,0.1)",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
Предпросмотр статьи появится здесь
|
||||
</Typography>
|
||||
<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>
|
||||
</Box>
|
||||
</Paper>
|
||||
)}
|
||||
</Box>
|
||||
</Paper>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
@ -303,11 +426,29 @@ export const RightWidgetTab = observer(
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<UploadMediaDialog
|
||||
open={uploadMediaOpen}
|
||||
onClose={() => setUploadMediaOpen(false)}
|
||||
afterUpload={async (media) => {
|
||||
setUploadMediaOpen(false);
|
||||
setFileToUpload(null);
|
||||
await createLinkWithRightArticle(
|
||||
media,
|
||||
sight[language].right[activeArticleIndex || 0].id
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
<SelectArticleModal
|
||||
open={isSelectModalOpen}
|
||||
onClose={handleCloseSelectModal}
|
||||
onSelectArticle={handleArticleSelect}
|
||||
/>
|
||||
<SelectMediaDialog
|
||||
open={isSelectMediaModalOpen}
|
||||
onClose={() => setIsSelectMediaModalOpen(false)}
|
||||
onSelectMedia={handleMediaSelected}
|
||||
/>
|
||||
</TabPanel>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user