WhiteNightsAdminPanel/src/shared/modals/SelectMediaDialog/index.tsx
2025-06-01 23:18:21 +03:00

167 lines
5.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { mediaStore } from "@shared";
import { observer } from "mobx-react-lite";
import { useEffect, useState } from "react";
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
TextField,
List,
ListItemButton,
ListItemText,
Paper,
Typography,
InputAdornment,
} from "@mui/material";
import { Search } from "lucide-react";
import { MediaViewer } from "@widgets";
interface SelectMediaDialogProps {
open: boolean; // Corrected prop name
onClose: () => void;
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
}
export const SelectMediaDialog = observer(
({
open, // Corrected prop name
onClose,
onSelectMedia, // Renamed prop
linkedMediaIds = [], // Default to empty array if not provided, renamed
}: SelectMediaDialogProps) => {
const { media, getMedia } = mediaStore;
const [searchQuery, setSearchQuery] = useState("");
const [hoveredMediaId, setHoveredMediaId] = useState<string | null>(null);
// Fetch media on component mount
useEffect(() => {
getMedia();
}, [getMedia]);
// Keyboard event listener for "Enter" key to select hovered media
useEffect(() => {
const handleKeyPress = (event: KeyboardEvent) => {
if (event.key === "Enter") {
event.preventDefault(); // Prevent browser default action (e.g., form submission)
if (hoveredMediaId) {
const mediaItem = media.find((m) => m.id === hoveredMediaId);
if (mediaItem) {
onSelectMedia(mediaItem);
}
onClose();
}
}
};
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [hoveredMediaId, onSelectMedia, onClose]); // Dependencies for keyboard listener
const filteredMedia = media
.filter((mediaItem) => !linkedMediaIds.includes(mediaItem.id)) // Use mediaItem to avoid name collision
.filter((mediaItem) =>
mediaItem.media_name.toLowerCase().includes(searchQuery.toLowerCase())
);
// Find the currently hovered media object for MediaViewer
const currentHoveredMedia = hoveredMediaId
? media.find((m) => m.id === hoveredMediaId)
: null;
return (
<Dialog open={open} onClose={onClose} maxWidth="lg" fullWidth>
<DialogTitle>Выберите существующее медиа</DialogTitle>
<DialogContent
className="flex gap-4"
dividers // Adds a divider below the title and above the actions
sx={{ height: "600px", display: "flex", flexDirection: "row" }} // Fixed height for DialogContent
>
<Paper className="w-[66%] flex flex-col" sx={{ p: 2 }}>
{" "}
{/* Added padding for consistency */}
<TextField
fullWidth
placeholder="Поиск медиа..." // Changed placeholder for clarity
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
sx={{ mb: 2, mt: 1 }}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search size={20} />
</InputAdornment>
),
}}
/>
<List sx={{ flexGrow: 1, overflowY: "auto" }}>
{filteredMedia.length > 0 ? (
filteredMedia.map(
(
mediaItem // Use mediaItem to avoid confusion
) => (
<ListItemButton
key={mediaItem.id}
onClick={() => setHoveredMediaId(mediaItem.id)} // Call onSelectMedia
onDoubleClick={() => {
onSelectMedia(mediaItem);
onClose();
}}
sx={{
borderRadius: 1,
mb: 0.5,
"&:hover": {
backgroundColor: "action.hover",
},
}}
>
<ListItemText primary={mediaItem.media_name} />
</ListItemButton>
)
)
) : (
<Typography
sx={{ mt: 2, textAlign: "center" }}
color="text.secondary"
>
Медиа не найдено или все медиа уже прикреплены.
</Typography>
)}
</List>
</Paper>
{currentHoveredMedia ? ( // Only render MediaViewer if currentHoveredMedia is found
<Paper className="w-[33%] h-[100%] flex justify-center items-center">
<MediaViewer
media={{
id: currentHoveredMedia.id,
media_type: currentHoveredMedia.media_type ?? 1, // Provide a default if media_type can be undefined
filename: currentHoveredMedia.filename,
}}
/>
</Paper>
) : (
<Paper className="w-[33%] h-[100%] flex justify-center items-center">
<Typography variant="body2" color="text.secondary">
Наведите на медиа в списке для предпросмотра.
</Typography>
</Paper>
)}
</DialogContent>
<DialogActions>
<Button onClick={onClose}>Отмена</Button>
</DialogActions>
</Dialog>
);
}
);