init project
This commit is contained in:
@@ -0,0 +1 @@
|
||||
export { HomePage } from './ui/HomePage'
|
||||
@@ -0,0 +1,97 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
import Alert from '@mui/material/Alert'
|
||||
import Box from '@mui/material/Box'
|
||||
import FormControl from '@mui/material/FormControl'
|
||||
import Grid from '@mui/material/Grid'
|
||||
import InputLabel from '@mui/material/InputLabel'
|
||||
import MenuItem from '@mui/material/MenuItem'
|
||||
import Select from '@mui/material/Select'
|
||||
import type { SelectChangeEvent } from '@mui/material/Select'
|
||||
import Skeleton from '@mui/material/Skeleton'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { fetchCategories, fetchPublicProducts } from '@/entities/product/api/product-api'
|
||||
import { ProductCard } from '@/entities/product/ui/ProductCard'
|
||||
|
||||
export function HomePage() {
|
||||
const [categorySlug, setCategorySlug] = useState<string>('')
|
||||
|
||||
const categoriesQuery = useQuery({
|
||||
queryKey: ['categories'],
|
||||
queryFn: () => fetchCategories(),
|
||||
})
|
||||
|
||||
const productsQuery = useQuery({
|
||||
queryKey: ['products', 'public', categorySlug || 'all'],
|
||||
queryFn: () => fetchPublicProducts(categorySlug || undefined),
|
||||
})
|
||||
|
||||
const handleCategoryChange = (e: SelectChangeEvent<string>) => {
|
||||
setCategorySlug(e.target.value)
|
||||
}
|
||||
|
||||
const title = useMemo(
|
||||
() =>
|
||||
categorySlug ? `Категория: ${categoriesQuery.data?.find((c) => c.slug === categorySlug)?.name ?? ''}` : 'Каталог',
|
||||
[categorySlug, categoriesQuery.data],
|
||||
)
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="h4" component="h1" gutterBottom>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
|
||||
Игрушки, сувениры и другие изделия ручной работы.
|
||||
</Typography>
|
||||
|
||||
<FormControl sx={{ minWidth: 220, mb: 3 }} size="small">
|
||||
<InputLabel id="category-filter-label">Категория</InputLabel>
|
||||
<Select<string>
|
||||
labelId="category-filter-label"
|
||||
label="Категория"
|
||||
value={categorySlug}
|
||||
onChange={handleCategoryChange}
|
||||
disabled={categoriesQuery.isLoading}
|
||||
>
|
||||
<MenuItem value="">
|
||||
<em>Все</em>
|
||||
</MenuItem>
|
||||
{(categoriesQuery.data ?? []).map((c) => (
|
||||
<MenuItem key={c.id} value={c.slug}>
|
||||
{c.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
{productsQuery.isLoading && (
|
||||
<Grid container spacing={2}>
|
||||
{[1, 2, 3].map((i) => (
|
||||
<Grid size={{ xs: 12, sm: 6, md: 4 }} key={i}>
|
||||
<Skeleton variant="rectangular" height={360} />
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{productsQuery.isError && (
|
||||
<Alert severity="error">Не удалось загрузить товары. Проверьте, что API запущен.</Alert>
|
||||
)}
|
||||
|
||||
{productsQuery.isSuccess && productsQuery.data.length === 0 && (
|
||||
<Typography color="text.secondary">Пока нет опубликованных товаров.</Typography>
|
||||
)}
|
||||
|
||||
{productsQuery.isSuccess && productsQuery.data.length > 0 && (
|
||||
<Grid container spacing={2}>
|
||||
{productsQuery.data.map((p) => (
|
||||
<Grid size={{ xs: 12, sm: 6, md: 4 }} key={p.id}>
|
||||
<ProductCard product={p} />
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
)}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user