init project

This commit is contained in:
@kirill.komarov
2026-04-28 11:02:08 +05:00
commit 55480d4aa5
50 changed files with 9241 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
export { HomePage } from './ui/HomePage'
+97
View File
@@ -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>
)
}