fix: lint and type errors in ToggleCartIcon, AdminLayout, ProductFilters, use-product-filters

This commit is contained in:
Kirill
2026-05-14 21:36:00 +05:00
parent 8632601490
commit d5075813a2
15 changed files with 105 additions and 24 deletions
+1 -1
View File
@@ -1,5 +1,4 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Menu, Package } from 'lucide-react'
import AppBar from '@mui/material/AppBar' import AppBar from '@mui/material/AppBar'
import Badge from '@mui/material/Badge' import Badge from '@mui/material/Badge'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
@@ -12,6 +11,7 @@ import Typography from '@mui/material/Typography'
import useMediaQuery from '@mui/material/useMediaQuery' import useMediaQuery from '@mui/material/useMediaQuery'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { useUnit } from 'effector-react' import { useUnit } from 'effector-react'
import { Menu, Package } from 'lucide-react'
import { Link as RouterLink, useNavigate } from 'react-router-dom' import { Link as RouterLink, useNavigate } from 'react-router-dom'
import { useThemeController } from '@/app/providers/theme-controller' import { useThemeController } from '@/app/providers/theme-controller'
import { fetchMyCart } from '@/entities/cart/api/cart-api' import { fetchMyCart } from '@/entities/cart/api/cart-api'
+1 -1
View File
@@ -4,8 +4,8 @@ import Container from '@mui/material/Container'
import Divider from '@mui/material/Divider' import Divider from '@mui/material/Divider'
import Grid from '@mui/material/Grid' import Grid from '@mui/material/Grid'
import Link from '@mui/material/Link' import Link from '@mui/material/Link'
import SvgIcon from '@mui/material/SvgIcon'
import Stack from '@mui/material/Stack' import Stack from '@mui/material/Stack'
import SvgIcon from '@mui/material/SvgIcon'
import Typography from '@mui/material/Typography' import Typography from '@mui/material/Typography'
import { Link as RouterLink } from 'react-router-dom' import { Link as RouterLink } from 'react-router-dom'
import { AppHeader } from '@/app/layout/AppHeader' import { AppHeader } from '@/app/layout/AppHeader'
@@ -1,8 +1,6 @@
import { apiClient } from '@/shared/api/client' import { apiClient } from '@/shared/api/client'
import type { InfoPageBlock } from '../model/types' import type { InfoPageBlock } from '../model/types'
export async function fetchPublicInfoBlocks(): Promise<{ items: InfoPageBlock[] }> { export async function fetchPublicInfoBlocks(): Promise<{ items: InfoPageBlock[] }> {
const { data } = await apiClient.get<{ items: InfoPageBlock[] }>('info-page/blocks') const { data } = await apiClient.get<{ items: InfoPageBlock[] }>('info-page/blocks')
return data return data
@@ -1,7 +1,7 @@
import { ShoppingCart } from 'lucide-react'
import Badge from '@mui/material/Badge' import Badge from '@mui/material/Badge'
import IconButton from '@mui/material/IconButton' import IconButton from '@mui/material/IconButton'
import Tooltip from '@mui/material/Tooltip' import Tooltip from '@mui/material/Tooltip'
import { ShoppingCart } from 'lucide-react'
import type { AuthUser } from '@/shared/model/auth' import type { AuthUser } from '@/shared/model/auth'
type Props = { type Props = {
@@ -1,8 +1,8 @@
import { ShoppingCart, ShoppingCartOff } from 'lucide-react'
import IconButton from '@mui/material/IconButton' import IconButton from '@mui/material/IconButton'
import Tooltip from '@mui/material/Tooltip' import Tooltip from '@mui/material/Tooltip'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useUnit } from 'effector-react' import { useUnit } from 'effector-react'
import { ShoppingCart } from 'lucide-react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { addToCart, fetchMyCart, removeCartItem } from '@/entities/cart/api/cart-api' import { addToCart, fetchMyCart, removeCartItem } from '@/entities/cart/api/cart-api'
import { $user } from '@/shared/model/auth' import { $user } from '@/shared/model/auth'
@@ -63,7 +63,7 @@ export function ToggleCartIcon(props: {
<Tooltip title={tooltip}> <Tooltip title={tooltip}>
<span> <span>
<IconButton size={size} onClick={onClick} disabled={disabled || busy} aria-label={tooltip} type="button"> <IconButton size={size} onClick={onClick} disabled={disabled || busy} aria-label={tooltip} type="button">
{user ? inCart ? <ShoppingCart /> : <ShoppingCartOff /> : <ShoppingCart /> {user ? inCart ? <ShoppingCart /> : <ShoppingCart /> : <ShoppingCart />}
</IconButton> </IconButton>
</span> </span>
</Tooltip> </Tooltip>
@@ -1,10 +1,10 @@
import { useState } from 'react' import { useState } from 'react'
import { User } from 'lucide-react'
import Badge from '@mui/material/Badge' import Badge from '@mui/material/Badge'
import IconButton from '@mui/material/IconButton' import IconButton from '@mui/material/IconButton'
import ListItemText from '@mui/material/ListItemText' import ListItemText from '@mui/material/ListItemText'
import Menu from '@mui/material/Menu' import Menu from '@mui/material/Menu'
import MenuItem from '@mui/material/MenuItem' import MenuItem from '@mui/material/MenuItem'
import { User } from 'lucide-react'
import type { AuthUser } from '@/shared/model/auth' import type { AuthUser } from '@/shared/model/auth'
type Props = { type Props = {
@@ -1,6 +1,5 @@
import type { ReactNode } from 'react' import type { ReactNode } from 'react'
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import { FileText, Image, LayoutGrid, ListOrdered, MessageSquare, People, Store } from 'lucide-react'
import Badge from '@mui/material/Badge' import Badge from '@mui/material/Badge'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import Divider from '@mui/material/Divider' import Divider from '@mui/material/Divider'
@@ -16,6 +15,7 @@ import Typography from '@mui/material/Typography'
import useMediaQuery from '@mui/material/useMediaQuery' import useMediaQuery from '@mui/material/useMediaQuery'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { useUnit } from 'effector-react' import { useUnit } from 'effector-react'
import { FileText, Image, LayoutGrid, ListOrdered, MessageSquare, Store, Users } from 'lucide-react'
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom' import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom'
import { fetchAdminOrdersSummary } from '@/entities/order/api/admin-order-api' import { fetchAdminOrdersSummary } from '@/entities/order/api/admin-order-api'
import { AdminCategoriesPage } from '@/pages/admin-categories' import { AdminCategoriesPage } from '@/pages/admin-categories'
@@ -59,7 +59,7 @@ export function AdminLayoutPage() {
{ to: '/admin/gallery', label: 'Галерея', icon: <Image /> }, { to: '/admin/gallery', label: 'Галерея', icon: <Image /> },
{ to: '/admin/orders', label: 'Заказы', icon: <ListOrdered /> }, { to: '/admin/orders', label: 'Заказы', icon: <ListOrdered /> },
{ to: '/admin/reviews', label: 'Отзывы', icon: <MessageSquare /> }, { to: '/admin/reviews', label: 'Отзывы', icon: <MessageSquare /> },
{ to: '/admin/users', label: 'Пользователи', icon: <People /> }, { to: '/admin/users', label: 'Пользователи', icon: <Users /> },
{ to: '/admin/info', label: 'Инфо-страница', icon: <FileText /> }, { to: '/admin/info', label: 'Инфо-страница', icon: <FileText /> },
], ],
[], [],
+1 -1
View File
@@ -1,4 +1,3 @@
import { Minus, Plus, Trash2 } from 'lucide-react'
import Alert from '@mui/material/Alert' import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import Button from '@mui/material/Button' import Button from '@mui/material/Button'
@@ -9,6 +8,7 @@ import Tooltip from '@mui/material/Tooltip'
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 { useUnit } from 'effector-react' import { useUnit } from 'effector-react'
import { Minus, Plus, Trash2 } from 'lucide-react'
import { Link as RouterLink } from 'react-router-dom' import { Link as RouterLink } from 'react-router-dom'
import { fetchMyCart, removeCartItem, setCartQty } from '@/entities/cart/api/cart-api' import { fetchMyCart, removeCartItem, setCartQty } from '@/entities/cart/api/cart-api'
import { formatPriceRub } from '@/shared/lib/format-price' import { formatPriceRub } from '@/shared/lib/format-price'
@@ -24,8 +24,8 @@ export function useProductFilters() {
return () => window.clearTimeout(t) return () => window.clearTimeout(t)
}, [qInput]) }, [qInput])
const handleCategoryChange = (e: SelectChangeEvent<string>) => { const handleCategoryChange = (slug: string) => {
setCategorySlug(e.target.value) setCategorySlug(slug)
setPage(1) setPage(1)
} }
+45 -7
View File
@@ -83,9 +83,26 @@ export function ProductFilters({
<Paper <Paper
variant="outlined" variant="outlined"
sx={{ p: 1.5, borderRadius: 3, bgcolor: 'background.paper', display: 'flex', flexDirection: { xs: 'column', sm: 'row' }, gap: 1.5, alignItems: { sm: 'center' }, justifyContent: 'space-between' }} sx={{
p: 1.5,
borderRadius: 3,
bgcolor: 'background.paper',
display: 'flex',
flexDirection: { xs: 'column', sm: 'row' },
gap: 1.5,
alignItems: { sm: 'center' },
justifyContent: 'space-between',
}}
>
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', sm: 'row' },
alignItems: { sm: 'center' },
gap: 1.5,
flexGrow: 1,
}}
> >
<Box sx={{ display: 'flex', flexDirection: { xs: 'column', sm: 'row' }, alignItems: { sm: 'center' }, gap: 1.5, flexGrow: 1 }}>
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75, alignItems: 'center' }}> <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75, alignItems: 'center' }}>
<Chip <Chip
label="Все" label="Все"
@@ -149,11 +166,17 @@ export function ProductFilters({
<Collapse in={moreOpen} unmountOnExit> <Collapse in={moreOpen} unmountOnExit>
<Paper variant="outlined" sx={{ p: 2, borderRadius: 3, display: 'flex', flexDirection: 'column', gap: 2 }}> <Paper variant="outlined" sx={{ p: 2, borderRadius: 3, display: 'flex', flexDirection: 'column', gap: 2 }}>
<Stack direction={{ xs: 'column', md: 'row' }} spacing={2} sx={{ alignItems: { md: 'center' }, flexWrap: { md: 'wrap' } }}> <Stack
direction={{ xs: 'column', md: 'row' }}
spacing={2}
sx={{ alignItems: { md: 'center' }, flexWrap: { md: 'wrap' } }}
>
<FormControl sx={{ minWidth: 200 }} size="small"> <FormControl sx={{ minWidth: 200 }} size="small">
<InputLabel id="sort-label">Сортировка</InputLabel> <InputLabel id="sort-label">Сортировка</InputLabel>
<Select<string> labelId="sort-label" label="Сортировка" value={sort} onChange={handleSortChange}> <Select<string> labelId="sort-label" label="Сортировка" value={sort} onChange={handleSortChange}>
<MenuItem value=""><em>Сначала новые</em></MenuItem> <MenuItem value="">
<em>Сначала новые</em>
</MenuItem>
<MenuItem value="price_asc">Цена: по возрастанию</MenuItem> <MenuItem value="price_asc">Цена: по возрастанию</MenuItem>
<MenuItem value="price_desc">Цена: по убыванию</MenuItem> <MenuItem value="price_desc">Цена: по убыванию</MenuItem>
</Select> </Select>
@@ -176,9 +199,16 @@ export function ProductFilters({
<FormControl sx={{ minWidth: 160 }} size="small"> <FormControl sx={{ minWidth: 160 }} size="small">
<InputLabel id="page-size-label">На странице</InputLabel> <InputLabel id="page-size-label">На странице</InputLabel>
<Select<string> labelId="page-size-label" label="На странице" value={String(pageSize)} onChange={handlePageSizeChange}> <Select<string>
labelId="page-size-label"
label="На странице"
value={String(pageSize)}
onChange={handlePageSizeChange}
>
{[6, 12, 18, 24].map((n) => ( {[6, 12, 18, 24].map((n) => (
<MenuItem key={n} value={String(n)}>{n}</MenuItem> <MenuItem key={n} value={String(n)}>
{n}
</MenuItem>
))} ))}
</Select> </Select>
</FormControl> </FormControl>
@@ -186,7 +216,15 @@ export function ProductFilters({
<Divider /> <Divider />
<Box sx={{ display: 'flex', flexDirection: { xs: 'column', sm: 'row' }, gap: 1.5, alignItems: { sm: 'center' }, justifyContent: 'space-between' }}> <Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', sm: 'row' },
gap: 1.5,
alignItems: { sm: 'center' },
justifyContent: 'space-between',
}}
>
<Typography variant="subtitle2">Масштаб карточек</Typography> <Typography variant="subtitle2">Масштаб карточек</Typography>
<ToggleButtonGroup <ToggleButtonGroup
exclusive exclusive
+1 -1
View File
@@ -1,6 +1,5 @@
import type { ReactNode } from 'react' import type { ReactNode } from 'react'
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import { MapPin, MessageCircle, Settings, SlidersHorizontal, Truck } from 'lucide-react'
import Alert from '@mui/material/Alert' import Alert from '@mui/material/Alert'
import Badge from '@mui/material/Badge' import Badge from '@mui/material/Badge'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
@@ -17,6 +16,7 @@ import Typography from '@mui/material/Typography'
import useMediaQuery from '@mui/material/useMediaQuery' import useMediaQuery from '@mui/material/useMediaQuery'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { useUnit } from 'effector-react' import { useUnit } from 'effector-react'
import { MapPin, MessageCircle, Settings, SlidersHorizontal, Truck } from 'lucide-react'
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom' import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom'
import { fetchUnreadMessageCount } from '@/entities/user/api/messages-api' import { fetchUnreadMessageCount } from '@/entities/user/api/messages-api'
import { AddressesPage } from '@/pages/me/ui/sections/AddressesPage' import { AddressesPage } from '@/pages/me/ui/sections/AddressesPage'
+1 -1
View File
@@ -1,5 +1,4 @@
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import { Star, X } from 'lucide-react'
import Alert from '@mui/material/Alert' import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import Chip from '@mui/material/Chip' import Chip from '@mui/material/Chip'
@@ -13,6 +12,7 @@ import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography' import Typography from '@mui/material/Typography'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { useUnit } from 'effector-react' import { useUnit } from 'effector-react'
import { Star, X } from 'lucide-react'
import { useParams } from 'react-router-dom' import { useParams } from 'react-router-dom'
import { Navigation } from 'swiper/modules' import { Navigation } from 'swiper/modules'
import { Swiper, SwiperSlide } from 'swiper/react' import { Swiper, SwiperSlide } from 'swiper/react'
@@ -1,6 +1,6 @@
import { Monitor, Moon, Sun } from 'lucide-react'
import IconButton from '@mui/material/IconButton' import IconButton from '@mui/material/IconButton'
import Tooltip from '@mui/material/Tooltip' import Tooltip from '@mui/material/Tooltip'
import { Monitor, Moon, Sun } from 'lucide-react'
import type { ThemeModePreference } from '@/shared/model/theme' import type { ThemeModePreference } from '@/shared/model/theme'
type Props = { type Props = {
@@ -1,11 +1,11 @@
import { useEffect } from 'react' import { useEffect } from 'react'
import { Bold, Italic, List } from 'lucide-react'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import IconButton from '@mui/material/IconButton' import IconButton from '@mui/material/IconButton'
import Stack from '@mui/material/Stack' import Stack from '@mui/material/Stack'
import Placeholder from '@tiptap/extension-placeholder' import Placeholder from '@tiptap/extension-placeholder'
import { EditorContent, useEditor } from '@tiptap/react' import { EditorContent, useEditor } from '@tiptap/react'
import TiptapStarterKit from '@tiptap/starter-kit' import TiptapStarterKit from '@tiptap/starter-kit'
import { Bold, Italic, List } from 'lucide-react'
type RichTextMessageEditorProps = { type RichTextMessageEditorProps = {
value: string value: string
@@ -0,0 +1,45 @@
# UI Style Refresh — Implementation Plan
**Goal:** Замена иконок MUI→Lucide, редизайн темы/слайдера/фильтров/кнопок, VK в футер.
**Architecture:** 6 независимых этапов: подготовка (package.json, config), замена иконок в ~12 файлах, визуальный редизайн 3 компонентов.
**Tech Stack:** React, MUI, Lucide React
---
### Task A1: package.json + shared/config
- Удалить `@mui/icons-material` из package.json
- Заменить `STORE_SOCIAL_NOTE` на `VK_URL` в config
### Task A2: MUI-тема (AppProviders)
- Добавить `components.MuiButton` styleOverrides (тени, hover)
- Добавить `components.MuiIconButton` styleOverrides (scale)
### Task B3: Хедер + меню
- `AppHeader.tsx``Menu`, `Package` (lucide)
- `CartBadge.tsx``ShoppingCart` (lucide)
- `UserMenu.tsx``User` (lucide)
- `ToggleCartIcon.tsx``ShoppingCart`, `ShoppingCartOff` (lucide)
### Task B4: Админка
- `AdminLayoutPage.tsx``Store`, `LayoutGrid`, `Image`, `ListOrdered`, `MessageSquare`, `People`, `FileText` (lucide)
### Task B5: Личный кабинет
- `MeLayoutPage.tsx``Truck`, `MessageCircle`, `Settings`, `MapPin`, `SlidersHorizontal` (lucide)
### Task B6: Остальные иконки
- `ProductPage.tsx``Star`, `X` (lucide)
- `CartPage.tsx``Plus`, `Minus`, `Trash2` (lucide)
- `ModeSwitcher.tsx``Sun`, `Moon`, `Monitor` (lucide, 3 режима)
- `SchemeSwitcher.tsx` — без bgcolor, цветная обводка
- `RichTextMessageEditor.tsx``Bold`, `Italic`, `List` (lucide)
### Task C7: VK в футер
- `MainLayout.tsx` — кастомный SvgIcon VK, удалить SOCIAL_NOTE
### Task C8: ProductFilters (каталог)
- Search с иконкой, Chips категорий, компактные фильтры
### Task C9: CatalogSlider (слайдер)
- Подложка с градиентом, новый стиль текста