feat(client): complete AdminGalleryPage with new upload and resize UI
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useRef } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import Box from '@mui/material/Box'
|
import Box from '@mui/material/Box'
|
||||||
import Button from '@mui/material/Button'
|
import Button from '@mui/material/Button'
|
||||||
import Divider from '@mui/material/Divider'
|
import Divider from '@mui/material/Divider'
|
||||||
@@ -6,8 +6,13 @@ import Stack from '@mui/material/Stack'
|
|||||||
import Typography from '@mui/material/Typography'
|
import Typography from '@mui/material/Typography'
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||||
import { fetchAdminCatalogSlider } from '@/entities/catalog-slider'
|
import { fetchAdminCatalogSlider } from '@/entities/catalog-slider'
|
||||||
import { deleteGalleryImage, fetchAdminGallery, GalleryGrid, resizeGalleryImage } from '@/entities/gallery'
|
import {
|
||||||
import { uploadAdminProductImages } from '@/entities/product/api/product-api'
|
deleteGalleryImage,
|
||||||
|
fetchAdminGallery,
|
||||||
|
GalleryGrid,
|
||||||
|
resizeGalleryImage,
|
||||||
|
uploadGalleryImages,
|
||||||
|
} from '@/entities/gallery'
|
||||||
import { formatAdminImageMaxSizeHint } from '@/shared/constants/upload-limits'
|
import { formatAdminImageMaxSizeHint } from '@/shared/constants/upload-limits'
|
||||||
import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys'
|
import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys'
|
||||||
import { GallerySliderSection } from './GallerySliderSection'
|
import { GallerySliderSection } from './GallerySliderSection'
|
||||||
@@ -22,6 +27,7 @@ function getApiErrorMessage(error: unknown): string | null {
|
|||||||
export function AdminGalleryPage() {
|
export function AdminGalleryPage() {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||||
|
const [resizingId, setResizingId] = useState<string | null>(null)
|
||||||
|
|
||||||
const sliderQuery = useQuery({
|
const sliderQuery = useQuery({
|
||||||
queryKey: ['admin', 'catalog-slider'],
|
queryKey: ['admin', 'catalog-slider'],
|
||||||
@@ -34,7 +40,7 @@ export function AdminGalleryPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const uploadMut = useMutation({
|
const uploadMut = useMutation({
|
||||||
mutationFn: (files: File[]) => uploadAdminProductImages(files),
|
mutationFn: (files: File[]) => uploadGalleryImages(files),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
void invalidateQueryKeys(queryClient, [['admin', 'gallery']])
|
void invalidateQueryKeys(queryClient, [['admin', 'gallery']])
|
||||||
if (fileInputRef.current) {
|
if (fileInputRef.current) {
|
||||||
@@ -51,7 +57,14 @@ export function AdminGalleryPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const resizeMut = useMutation({
|
const resizeMut = useMutation({
|
||||||
mutationFn: (id: string) => resizeGalleryImage(id),
|
mutationFn: async (id: string) => {
|
||||||
|
setResizingId(id)
|
||||||
|
try {
|
||||||
|
return await resizeGalleryImage(id)
|
||||||
|
} finally {
|
||||||
|
setResizingId(null)
|
||||||
|
}
|
||||||
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
void invalidateQueryKeys(queryClient, [['admin', 'gallery'], ['admin', 'catalog-slider'], ['catalog-slider']])
|
void invalidateQueryKeys(queryClient, [['admin', 'gallery'], ['admin', 'catalog-slider'], ['catalog-slider']])
|
||||||
},
|
},
|
||||||
@@ -65,8 +78,8 @@ export function AdminGalleryPage() {
|
|||||||
Галерея
|
Галерея
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
|
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
|
||||||
Изображения без привязки к товару можно загружать здесь; их же можно добавить в карточку товара через «Из
|
Изображения загружаются без обработки. После загрузки нажмите «Resize» для подготовки к публикации. Обработанные
|
||||||
галереи». Удаление из списка стирает файл с диска, если оно не используется в товаре.
|
изображения доступны для добавления в карточку товара и слайдер.
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{sliderQuery.isError && (
|
{sliderQuery.isError && (
|
||||||
@@ -121,6 +134,9 @@ export function AdminGalleryPage() {
|
|||||||
{deleteMut.isError && (
|
{deleteMut.isError && (
|
||||||
<Typography color="error">{getApiErrorMessage(deleteMut.error) ?? 'Ошибка удаления'}</Typography>
|
<Typography color="error">{getApiErrorMessage(deleteMut.error) ?? 'Ошибка удаления'}</Typography>
|
||||||
)}
|
)}
|
||||||
|
{resizeMut.isError && (
|
||||||
|
<Typography color="error">{getApiErrorMessage(resizeMut.error) ?? 'Ошибка обработки'}</Typography>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
{galleryQuery.isError && (
|
{galleryQuery.isError && (
|
||||||
@@ -132,7 +148,7 @@ export function AdminGalleryPage() {
|
|||||||
<GalleryGrid
|
<GalleryGrid
|
||||||
items={items}
|
items={items}
|
||||||
deleting={deleteMut.isPending}
|
deleting={deleteMut.isPending}
|
||||||
resizing={resizeMut.isPending ? (resizeMut.variables ?? null) : null}
|
resizing={resizingId}
|
||||||
onDelete={(id) => deleteMut.mutate(id)}
|
onDelete={(id) => deleteMut.mutate(id)}
|
||||||
onResize={(id) => resizeMut.mutate(id)}
|
onResize={(id) => resizeMut.mutate(id)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user