Fix catalog filters in mobile version. Add accordion animations
parent
82fe5666d6
commit
8b4b7b505e
|
@ -1,7 +1,7 @@
|
||||||
import {
|
import {
|
||||||
CheckboxGroup,
|
CheckboxGroup,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Button, Skeleton
|
Button, Skeleton, Accordion, AccordionItem
|
||||||
} from "@nextui-org/react";
|
} from "@nextui-org/react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
|
@ -19,33 +19,44 @@ import {Img} from "react-image";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const FilterGenerator = ({filterPropertiesData}: Pick<InferGetStaticPropsType<typeof getStaticProps>, "filterPropertiesData">) => {
|
const CheckboxUI = (obj: {id: number, name: string, values: {id: number, value: string}[]}) => {
|
||||||
return (
|
return (
|
||||||
<form className={'filters mb-10'}>
|
<Accordion>
|
||||||
<h2 className={"text-lg mb-4"}>Фильтры</h2>
|
<AccordionItem title={obj.name}>
|
||||||
|
<CheckboxGroup>
|
||||||
{filterPropertiesData.map( obj => (
|
|
||||||
<CheckboxGroup label={obj.name} key={"FILTER_"+obj.id}>
|
|
||||||
{obj.values && obj.values.map(val => (
|
{obj.values && obj.values.map(val => (
|
||||||
<Checkbox value={String(val.id)} key={"VALUE_"+val.id}>{val.value}</Checkbox>
|
<Checkbox value={String(val.id)} key={"VALUE_" + val.id}>{val.value}</Checkbox>
|
||||||
))}
|
))}
|
||||||
</CheckboxGroup>
|
</CheckboxGroup>
|
||||||
|
</AccordionItem>
|
||||||
|
|
||||||
|
</Accordion>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const FilterGenerator = ({filterPropertiesData}: Pick<InferGetStaticPropsType<typeof getStaticProps>, "filterPropertiesData">) => {
|
||||||
|
return (
|
||||||
|
<Accordion className={'filters mb-10 mr-4 lg:w-1/4 w-full'} defaultExpandedKeys={['1']}>
|
||||||
|
<AccordionItem title={"Фильтры"} key={"1"} aria-label={"Фильтры"} classNames={{trigger:"bg-primary px-4", base: "border-1 rounded", title: "font-bold"}}>
|
||||||
|
{filterPropertiesData.map(obj => (
|
||||||
|
<CheckboxUI key={obj.id} {...obj} />
|
||||||
))}
|
))}
|
||||||
</form>
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type CardProps = InferGetStaticPropsType<typeof getStaticProps>['catalog'][0] & {isFavourite?: boolean}
|
type CardProps = InferGetStaticPropsType<typeof getStaticProps>['catalog'][0] & { isFavourite?: boolean }
|
||||||
|
|
||||||
|
|
||||||
const CatalogCard = (product: CardProps) => {
|
const CatalogCard = (product: CardProps) => {
|
||||||
const isClient = useClient()
|
const isClient = useClient()
|
||||||
const cartItems = useQuery({queryKey: ['cart'], queryFn: async () => {
|
const cartItems = useQuery({
|
||||||
|
queryKey: ['cart'], queryFn: async () => {
|
||||||
const service = new LocalAPI()
|
const service = new LocalAPI()
|
||||||
return await service.getCartItems()
|
return await service.getCartItems()
|
||||||
}})
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
const qs = useQueryClient()
|
const qs = useQueryClient()
|
||||||
|
@ -65,21 +76,29 @@ const CatalogCard = (product: CardProps) => {
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"bg-gray-card w-full h-fit min-h-[250px] py-4 px-7 rounded-[20px] hover:shadow-md transition-shadow hover:cursor-pointer"} key={product.id}>
|
<div
|
||||||
|
className={"bg-gray-card w-full h-fit min-h-[250px] py-4 px-7 rounded-[20px] hover:shadow-md transition-shadow hover:cursor-pointer"}
|
||||||
|
key={product.id}>
|
||||||
<div className={"grid grid-cols-1 sm:grid-cols-10 w-fit relative items-center"}>
|
<div className={"grid grid-cols-1 sm:grid-cols-10 w-fit relative items-center"}>
|
||||||
{
|
{
|
||||||
isClient && product.properties.main_image && <Img src={`https://relynolli.ru/upload/${product.properties.main_image[0]}`} alt={product.name} className={"col-auto mx-auto mb-4 sm:col-span-2 sm:row-span-2"} loader={<Skeleton className={"absolute top-0 left-0 right-3/4 rounded-[20px] h-full"} />}/>
|
isClient && product.properties.main_image &&
|
||||||
|
<Img src={`https://relynolli.ru/upload/${product.properties.main_image[0]}`} alt={product.name}
|
||||||
|
className={"col-auto mx-auto mb-4 sm:col-span-2 sm:row-span-2"}
|
||||||
|
loader={<Skeleton className={"absolute top-0 left-0 right-3/4 rounded-[20px] h-full"}/>}/>
|
||||||
}
|
}
|
||||||
<div className="col-auto sm:col-start-4 sm:col-span-6 h-full flex flex-col justify-center">
|
<div className="col-auto sm:col-start-4 sm:col-span-6 h-full flex flex-col justify-center">
|
||||||
<span className={"text-[#52525C] font-normal text-subtitle-4 mb-2 block"}>Стандарт API: {product.properties.api_standart} Тип: {product.properties.oil_type}</span>
|
<span
|
||||||
|
className={"text-[#52525C] font-normal text-subtitle-4 mb-2 block"}>Стандарт API: {product.properties.api_standart} Тип: {product.properties.oil_type}</span>
|
||||||
<h3 className={"font-bold text-lg uppercase text-black-3"}>{product.name}</h3>
|
<h3 className={"font-bold text-lg uppercase text-black-3"}>{product.name}</h3>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
isClient ?
|
isClient ?
|
||||||
<FavouriteIcon onClick={() => toggleFavourite(product.id)} className={`transition-colors absolute z-20 top-0 right-0 ${product.isFavourite ? "fill-primary" : "fill-[#E0E3E3]"}`}/> : null
|
<FavouriteIcon onClick={() => toggleFavourite(product.id)}
|
||||||
|
className={`transition-colors absolute z-20 top-0 right-0 ${product.isFavourite ? "fill-primary" : "fill-[#E0E3E3]"}`}/> : null
|
||||||
}
|
}
|
||||||
|
|
||||||
<div className="flex col-auto row-auto sm:row-start-2 sm:col-start-4 sm:col-span-7 justify-between w-full items-center pt-4">
|
<div
|
||||||
|
className="flex col-auto row-auto sm:row-start-2 sm:col-start-4 sm:col-span-7 justify-between w-full items-center pt-4">
|
||||||
<span className="font-bold text-xl text-black-3">
|
<span className="font-bold text-xl text-black-3">
|
||||||
{`${product.price.BASE}`.replace(/\B(?=(\d{3})+(?!\d))/g, ' ')} ₽
|
{`${product.price.BASE}`.replace(/\B(?=(\d{3})+(?!\d))/g, ' ')} ₽
|
||||||
</span>
|
</span>
|
||||||
|
@ -88,7 +107,8 @@ const CatalogCard = (product: CardProps) => {
|
||||||
<Button onClick={() => toggleCart.mutate({
|
<Button onClick={() => toggleCart.mutate({
|
||||||
productId: product.id,
|
productId: product.id,
|
||||||
quantity: 1
|
quantity: 1
|
||||||
})} className={"font-bold text-lg bg-green-2 uppercase italic text-black-3 relative z-20"}>{cartItems.data?.map(({id}) => id).includes(product.id) ? "В корзине" : "В корзину"}</Button> : null
|
})}
|
||||||
|
className={"font-bold text-lg bg-green-2 uppercase italic text-black-3 relative z-20"}>{cartItems.data?.map(({id}) => id).includes(product.id) ? "В корзине" : "В корзину"}</Button> : null
|
||||||
}
|
}
|
||||||
|
|
||||||
<Link href={'/catalog/' + product.code} className={'absolute top-0 left-0 z-10 w-full h-full'}/>
|
<Link href={'/catalog/' + product.code} className={'absolute top-0 left-0 z-10 w-full h-full'}/>
|
||||||
|
@ -112,7 +132,8 @@ const Catalog = (props: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||||
{
|
{
|
||||||
props.catalog.map(product =>
|
props.catalog.map(product =>
|
||||||
<>
|
<>
|
||||||
<CatalogCard key={product.id} {...product} isFavourite={favourites.includes(product.id)} />
|
<CatalogCard key={product.id} {...product}
|
||||||
|
isFavourite={favourites.includes(product.id)}/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -126,7 +147,11 @@ export default Catalog;
|
||||||
|
|
||||||
export const getStaticProps = async () => {
|
export const getStaticProps = async () => {
|
||||||
const service = new LocalAPI()
|
const service = new LocalAPI()
|
||||||
const filterData = await service.getFilters() as {id: number, name: string, values: {id: number, value: string}[]}[]
|
const filterData = await service.getFilters() as {
|
||||||
|
id: number,
|
||||||
|
name: string,
|
||||||
|
values: { id: number, value: string }[]
|
||||||
|
}[]
|
||||||
const catalogData = await service.getCatalogItems() as {
|
const catalogData = await service.getCatalogItems() as {
|
||||||
id: number
|
id: number
|
||||||
code: string,
|
code: string,
|
||||||
|
|
Loading…
Reference in New Issue