feat(client): add resize button and status badge to GalleryGrid

This commit is contained in:
Kirill
2026-05-17 18:09:12 +05:00
parent cf6b5da4fc
commit 5411f8ae24
2 changed files with 71 additions and 20 deletions
+42 -4
View File
@@ -1,5 +1,8 @@
import AutoFixHighOutlinedIcon from '@mui/icons-material/AutoFixHighOutlined'
import CheckCircleOutlineOutlinedIcon from '@mui/icons-material/CheckCircleOutlineOutlined'
import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined'
import Box from '@mui/material/Box'
import Chip from '@mui/material/Chip'
import IconButton from '@mui/material/IconButton'
import Tooltip from '@mui/material/Tooltip'
import { OptimizedImage } from '@/shared/ui/OptimizedImage'
@@ -8,10 +11,12 @@ import type { GalleryImageItem } from '../model/types'
type Props = {
items: GalleryImageItem[]
deleting?: boolean
resizing?: string | null
onDelete: (id: string) => void
onResize: (id: string) => void
}
export function GalleryGrid({ items, deleting, onDelete }: Props) {
export function GalleryGrid({ items, deleting, resizing, onDelete, onResize }: Props) {
return (
<Box
sx={{
@@ -38,14 +43,46 @@ export function GalleryGrid({ items, deleting, onDelete }: Props) {
sizes="140px"
sx={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
/>
<Box sx={{ position: 'absolute', top: 4, left: 4 }}>
{item.isResized ? (
<Chip
label="Готово"
size="small"
color="success"
icon={<CheckCircleOutlineOutlinedIcon fontSize="small" />}
sx={{ height: 24, '& .MuiChip-label': { px: 0.75 }, '& .MuiChip-icon': { fontSize: 14, ml: 0.5 } }}
/>
) : (
<Chip
label="Не обработано"
size="small"
color="warning"
sx={{ height: 24, '& .MuiChip-label': { px: 0.75 } }}
/>
)}
</Box>
<Box sx={{ position: 'absolute', top: 4, right: 4, display: 'flex', gap: 0.5 }}>
{!item.isResized && (
<Tooltip title="Обработать (resize)">
<IconButton
size="small"
color="primary"
sx={{
bgcolor: 'background.paper',
'&:hover': { bgcolor: 'primary.light', color: 'primary.contrastText' },
}}
disabled={resizing === item.id}
onClick={() => onResize(item.id)}
>
<AutoFixHighOutlinedIcon fontSize="small" />
</IconButton>
</Tooltip>
)}
<Tooltip title="Удалить из галереи">
<IconButton
size="small"
color="error"
sx={{
position: 'absolute',
top: 4,
right: 4,
bgcolor: 'background.paper',
'&:hover': { bgcolor: 'error.light', color: 'error.contrastText' },
}}
@@ -56,6 +93,7 @@ export function GalleryGrid({ items, deleting, onDelete }: Props) {
</IconButton>
</Tooltip>
</Box>
</Box>
))}
</Box>
)
@@ -6,7 +6,7 @@ import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { fetchAdminCatalogSlider } from '@/entities/catalog-slider'
import { deleteGalleryImage, fetchAdminGallery, GalleryGrid } from '@/entities/gallery'
import { deleteGalleryImage, fetchAdminGallery, GalleryGrid, resizeGalleryImage } from '@/entities/gallery'
import { uploadAdminProductImages } from '@/entities/product/api/product-api'
import { formatAdminImageMaxSizeHint } from '@/shared/constants/upload-limits'
import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys'
@@ -50,6 +50,13 @@ export function AdminGalleryPage() {
},
})
const resizeMut = useMutation({
mutationFn: (id: string) => resizeGalleryImage(id),
onSuccess: () => {
void invalidateQueryKeys(queryClient, [['admin', 'gallery'], ['admin', 'catalog-slider'], ['catalog-slider']])
},
})
const items = galleryQuery.data?.items ?? []
return (
@@ -122,7 +129,13 @@ export function AdminGalleryPage() {
</Typography>
)}
<GalleryGrid items={items} deleting={deleteMut.isPending} onDelete={(id) => deleteMut.mutate(id)} />
<GalleryGrid
items={items}
deleting={deleteMut.isPending}
resizing={resizeMut.isPending ? (resizeMut.variables ?? null) : null}
onDelete={(id) => deleteMut.mutate(id)}
onResize={(id) => resizeMut.mutate(id)}
/>
{!galleryQuery.isLoading && items.length === 0 && (
<Typography color="text.secondary">Пока нет загруженных изображений.</Typography>