import { useState } from 'react' import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward' import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward' import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined' import Box from '@mui/material/Box' import Button from '@mui/material/Button' import Dialog from '@mui/material/Dialog' import DialogActions from '@mui/material/DialogActions' import DialogContent from '@mui/material/DialogContent' import DialogTitle from '@mui/material/DialogTitle' import IconButton from '@mui/material/IconButton' import Paper from '@mui/material/Paper' import Stack from '@mui/material/Stack' import TextField from '@mui/material/TextField' import Typography from '@mui/material/Typography' import { useMutation, useQueryClient } from '@tanstack/react-query' import { putAdminCatalogSlider } from '@/entities/catalog-slider' import type { GalleryImageItem } from '@/entities/gallery' import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys' export type SlideDraft = { galleryImageId: string; caption: string } type Props = { initialSlides: SlideDraft[] galleryItems: GalleryImageItem[] } export function GallerySliderSection({ initialSlides, galleryItems }: Props) { const queryClient = useQueryClient() const [sliderDraft, setSliderDraft] = useState(initialSlides) const [pickOpen, setPickOpen] = useState(false) const usedIds = new Set(sliderDraft.map((s) => s.galleryImageId)) const pickCandidates = galleryItems.filter((i) => !usedIds.has(i.id) && i.isResized) const saveSliderMut = useMutation({ mutationFn: () => putAdminCatalogSlider({ slides: sliderDraft }), onSuccess: async () => { await invalidateQueryKeys(queryClient, [['admin', 'catalog-slider'], ['catalog-slider']]) }, }) const moveSlide = (idx: number, dir: -1 | 1) => { const next = idx + dir if (next < 0 || next >= sliderDraft.length) return setSliderDraft((prev) => { const copy = [...prev] const t = copy[idx]! copy[idx] = copy[next]! copy[next] = t return copy }) } return ( <> Слайдер главной (каталог) Сначала загрузите фото в галерею ниже, затем добавьте слайды, укажите подписи и сохраните. Порядок строк = порядок показа на витрине. {sliderDraft.map((row, idx) => { const img = galleryItems.find((g) => g.id === row.galleryImageId) return ( { const v = e.target.value setSliderDraft((prev) => { const copy = [...prev] copy[idx] = { ...copy[idx]!, caption: v } return copy }) }} /> moveSlide(idx, -1)} disabled={idx === 0}> moveSlide(idx, 1)} disabled={idx >= sliderDraft.length - 1} > setSliderDraft((prev) => prev.filter((_, i) => i !== idx))} > ) })} {saveSliderMut.isError && ( {saveSliderMut.error instanceof Error ? saveSliderMut.error.message : 'Ошибка сохранения'} )} setPickOpen(false)} fullWidth maxWidth="sm"> Выберите изображение {pickCandidates.length === 0 ? ( Нет доступных файлов (все уже в слайдере или галерея пуста). ) : ( {pickCandidates.map((item) => ( ))} )} ) }