mirror of
https://github.com/vercel/commerce.git
synced 2025-05-20 16:36:59 +00:00
Add categories into all products page and complete translation of that page
This commit is contained in:
parent
59f6c63ce3
commit
c211bff2ad
84
site/components/common/Category/CategoryListItem.tsx
Normal file
84
site/components/common/Category/CategoryListItem.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
Text,
|
||||
IconButton,
|
||||
Button,
|
||||
Stack,
|
||||
Collapse,
|
||||
Icon,
|
||||
Link,
|
||||
Popover,
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
useColorModeValue,
|
||||
useBreakpointValue,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
HamburgerIcon,
|
||||
CloseIcon,
|
||||
ChevronDownIcon,
|
||||
ChevronRightIcon,
|
||||
} from '@chakra-ui/icons';
|
||||
|
||||
const CategoryListItem = ({ label, children, href, enabled }: CategoryItem) => {
|
||||
const { isOpen, onToggle } = useDisclosure();
|
||||
|
||||
return (
|
||||
<Stack spacing={4} onClick={children && onToggle} className={"block text-sm leading-5 text-accent-4 hover:bg-accent-1 lg:hover:bg-transparent hover:text-accent-8 focus:outline-none focus:bg-accent-1 focus:text-accent-8"}>
|
||||
<Flex
|
||||
py={2}
|
||||
as={Link}
|
||||
className={"block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4"}
|
||||
href={enabled ? href : '#'}
|
||||
justify={'space-between'}
|
||||
align={'center'}
|
||||
_hover={{
|
||||
textDecoration: 'none',
|
||||
}}>
|
||||
<Text
|
||||
fontWeight={600}
|
||||
color={useColorModeValue('gray.600', 'gray.200')}>
|
||||
{label}
|
||||
</Text>
|
||||
{children && (
|
||||
<Icon
|
||||
as={ChevronDownIcon}
|
||||
transition={'all .25s ease-in-out'}
|
||||
transform={isOpen ? 'rotate(180deg)' : ''}
|
||||
w={6}
|
||||
h={6}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
<Collapse in={isOpen} animateOpacity style={{ marginTop: '0!important' }}>
|
||||
<Stack
|
||||
mt={2}
|
||||
pl={4}
|
||||
borderLeft={1}
|
||||
borderStyle={'solid'}
|
||||
borderColor={useColorModeValue('gray.200', 'gray.700')}
|
||||
align={'start'}>
|
||||
{children &&
|
||||
children.map((child) => (
|
||||
<Link key={child.label} py={2} href={enabled ? child.href : '#'}>
|
||||
{child.label}
|
||||
</Link>
|
||||
))}
|
||||
</Stack>
|
||||
</Collapse>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
interface CategoryItem {
|
||||
label: string;
|
||||
subLabel?: string;
|
||||
children?: Array<CategoryItem>;
|
||||
href?: string;
|
||||
enabled: boolean;
|
||||
};
|
||||
|
||||
export default CategoryListItem;
|
@ -18,20 +18,11 @@ interface NavbarProps {
|
||||
}
|
||||
|
||||
const Navbar: FC<NavbarProps> = ({ links }) => {
|
||||
const {
|
||||
isOpen: isOpenDrawer,
|
||||
onOpen: onOpenDrawer,
|
||||
onClose: onCloseDrawer,
|
||||
} = useDisclosure()
|
||||
|
||||
const { locale, pathname } = useRouter()
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavBarFiltersDrawer
|
||||
onClose={onCloseDrawer}
|
||||
isOpen={isOpenDrawer}
|
||||
></NavBarFiltersDrawer>
|
||||
<NavbarRoot>
|
||||
<Container clean className="mx-auto max-w-8xl px-6">
|
||||
<div className={s.nav}>
|
||||
@ -49,13 +40,7 @@ const Navbar: FC<NavbarProps> = ({ links }) => {
|
||||
</Link>
|
||||
{links?.map((l) => (
|
||||
<Link href={l.href} key={l.href}>
|
||||
{l.label === 'Categories' || l.label === 'Categorie' ? (
|
||||
<a onClick={onOpenDrawer} className={s.link}>
|
||||
{l.label}
|
||||
</a>
|
||||
) : (
|
||||
<a className={s.link}>{l.label}</a>
|
||||
)}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
|
@ -43,7 +43,7 @@ const ProductCard: FC<Props> = ({
|
||||
|
||||
return (
|
||||
<Link href={`/product/${product.slug}`}>
|
||||
<a className={rootClassName} aria-label={product.name} onMouseLeave={() => setIsHover(false)} onMouseEnter={() => setIsHover(true)}>
|
||||
<a className={rootClassName} aria-label={product.name} onMouseOut={() => setIsHover(false)} onMouseOver={() => setIsHover(true)}>
|
||||
{variant === 'slim' && !isHover && (
|
||||
<>
|
||||
<div className={s.header}>
|
||||
@ -128,9 +128,6 @@ const ProductCard: FC<Props> = ({
|
||||
p={6}
|
||||
w={'full'}
|
||||
bg={useColorModeValue('white', 'gray.800')}
|
||||
boxShadow={'2xl'}
|
||||
rounded={'lg'}
|
||||
pos={'relative'}
|
||||
zIndex={1}>
|
||||
{process.env.COMMERCE_WISHLIST_ENABLED && (
|
||||
<WishlistButton
|
||||
|
@ -1,84 +0,0 @@
|
||||
import {
|
||||
Flex,
|
||||
Box,
|
||||
Image,
|
||||
useColorModeValue,
|
||||
Stack,
|
||||
Heading,
|
||||
Text,
|
||||
Center
|
||||
} from '@chakra-ui/react';
|
||||
import usePrice from '@framework/product/use-price'
|
||||
|
||||
import type { Product } from '@commerce/types/product'
|
||||
import { ImageProps } from 'next/image'
|
||||
import ProductTag from '../ProductTag'
|
||||
import { FC } from 'react';
|
||||
|
||||
interface Props {
|
||||
product: Product
|
||||
imgProps?: Omit<ImageProps, 'src' | 'layout' | 'placeholder' | 'blurDataURL'>
|
||||
}
|
||||
|
||||
const ProductCardExtended: FC<Props> =({
|
||||
product,
|
||||
imgProps
|
||||
}) => {
|
||||
|
||||
const { price } = usePrice({
|
||||
amount: product.price.value,
|
||||
baseAmount: product.price.retailPrice,
|
||||
currencyCode: product.price.currencyCode!,
|
||||
})
|
||||
|
||||
const placeholderImg = '/product-img-placeholder.svg';
|
||||
const IMAGE = product.images[0]?.url || placeholderImg
|
||||
|
||||
return (
|
||||
<Center>
|
||||
<Box
|
||||
role={'group'}
|
||||
p={6}
|
||||
maxW={'330px'}
|
||||
w={'full'}
|
||||
bg={useColorModeValue('white', 'gray.800')}
|
||||
boxShadow={'2xl'}
|
||||
rounded={'lg'}
|
||||
pos={'relative'}
|
||||
zIndex={1}>
|
||||
<Box
|
||||
rounded={'lg'}
|
||||
mt={-12}
|
||||
pos={'relative'}
|
||||
height={'230px'}
|
||||
>
|
||||
<Image
|
||||
rounded={'lg'}
|
||||
height={230}
|
||||
width={282}
|
||||
objectFit={'cover'}
|
||||
src={IMAGE}
|
||||
/>
|
||||
</Box>
|
||||
<Stack pt={10} align={'center'}>
|
||||
<Text color={'gray.500'} fontSize={'sm'} textTransform={'uppercase'}>
|
||||
Brand
|
||||
</Text>
|
||||
<Heading fontSize={'2xl'} fontFamily={'body'} fontWeight={500}>
|
||||
Nice Chair, pink
|
||||
</Heading>
|
||||
<Stack direction={'row'} align={'center'}>
|
||||
<Text fontWeight={800} fontSize={'xl'}>
|
||||
$57
|
||||
</Text>
|
||||
<Text textDecoration={'line-through'} color={'gray.600'}>
|
||||
$199
|
||||
</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProductCardExtended;
|
@ -9,18 +9,11 @@ import type { Product } from '@commerce/types/product'
|
||||
|
||||
import { Layout } from '@components/common'
|
||||
import { ProductCard } from '@components/product'
|
||||
import { Container, Skeleton } from '@components/ui'
|
||||
import { Collapse, Container, Skeleton } from '@components/ui'
|
||||
|
||||
import useSearch from '@framework/product/use-search'
|
||||
import rangeMap from '@lib/range-map'
|
||||
|
||||
const SORT = {
|
||||
'trending-desc': 'Trending',
|
||||
'latest-desc': 'Latest arrivals',
|
||||
'price-asc': 'Price: Low to high',
|
||||
'price-desc': 'Price: High to low',
|
||||
}
|
||||
|
||||
import {
|
||||
filterQuery,
|
||||
getCategoryPath,
|
||||
@ -28,6 +21,11 @@ import {
|
||||
useSearchMeta,
|
||||
} from '@lib/search'
|
||||
import ErrorMessage from './ui/ErrorMessage'
|
||||
import NavBarFiltersItem from './common/Navbar/NavBarFiltersItem'
|
||||
import filtersData from '../static_data/navBarMenuData.json'
|
||||
import { Stack } from '@chakra-ui/react'
|
||||
import random from 'lodash.random'
|
||||
import CategoryListItem from './common/Category/CategoryListItem'
|
||||
|
||||
export default function Search({ categories, brands }: SearchPropsType) {
|
||||
const [activeFilter, setActiveFilter] = useState('')
|
||||
@ -54,6 +52,15 @@ export default function Search({ categories, brands }: SearchPropsType) {
|
||||
locale,
|
||||
})
|
||||
|
||||
const categoriesItems = filtersData.categories[locale as keyof typeof filtersData.categories]
|
||||
|
||||
const SORT = {
|
||||
'trending-desc': locale === "it" ? "Tendenza" :'Trending',
|
||||
'latest-desc': locale === "it" ? "Ultimi Arrivi" : 'Latest arrivals',
|
||||
'price-asc': locale === "it" ? "Prezzo Crescente" : 'Price: Low to high',
|
||||
'price-desc': locale === "it" ? "Prezzo Decrescente" :'Price: High to low',
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <ErrorMessage error={error} />
|
||||
}
|
||||
@ -132,36 +139,12 @@ export default function Search({ categories, brands }: SearchPropsType) {
|
||||
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
|
||||
}
|
||||
>
|
||||
All Categories
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
{categories.map((cat: any) => (
|
||||
<li
|
||||
key={cat.path}
|
||||
className={cn(
|
||||
'block text-sm leading-5 text-accent-4 hover:bg-accent-1 lg:hover:bg-transparent hover:text-accent-8 focus:outline-none focus:bg-accent-1 focus:text-accent-8',
|
||||
{
|
||||
underline: activeCategory?.id === cat.id,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Link
|
||||
href={{
|
||||
pathname: getCategoryPath(cat.path, brand),
|
||||
query,
|
||||
}}
|
||||
>
|
||||
<a
|
||||
onClick={(e) => handleClick(e, 'categories')}
|
||||
className={
|
||||
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
|
||||
}
|
||||
>
|
||||
{cat.name}
|
||||
{locale == "it" ? "Tutte le Categorie" : "All Categories"}
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
{categoriesItems.map((category: any) => (
|
||||
<CategoryListItem key={category.label} {...category} />
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
@ -253,7 +236,7 @@ export default function Search({ categories, brands }: SearchPropsType) {
|
||||
aria-haspopup="true"
|
||||
aria-expanded="true"
|
||||
>
|
||||
{sort ? SORT[sort as keyof typeof SORT] : 'Relevance'}
|
||||
{sort ? SORT[sort as keyof typeof SORT] : locale === "it" ? "Rilevanza" : "Relevance"}
|
||||
<svg
|
||||
className="-mr-1 ml-2 h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -296,7 +279,7 @@ export default function Search({ categories, brands }: SearchPropsType) {
|
||||
'block lg:inline-block px-4 py-2 lg:p-0 lg:my-2 lg:mx-4'
|
||||
}
|
||||
>
|
||||
Relevance
|
||||
{locale === "it" ? "Rilevanza" : "Relevance"}
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
|
@ -28,7 +28,7 @@ export default function WhereWeAre() {
|
||||
</Box>
|
||||
<Box mt={10}>
|
||||
<TableContainer>
|
||||
<Table variant="striped" colorScheme="teal">
|
||||
<Table colorScheme="teal">
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{locale == 'it' ? 'Giorno' : 'Day of Week'}</Th>
|
||||
|
@ -1,17 +1,9 @@
|
||||
{
|
||||
"it": [
|
||||
{
|
||||
"label": "Categorie",
|
||||
"href": "#"
|
||||
},
|
||||
{
|
||||
"label": "Chi Siamo",
|
||||
"href": "/about"
|
||||
},
|
||||
{
|
||||
"label": "News",
|
||||
"href": "/news"
|
||||
},
|
||||
{
|
||||
"label": "Contatti",
|
||||
"href": "/contact"
|
||||
@ -19,25 +11,25 @@
|
||||
{
|
||||
"label": "Dove Siamo",
|
||||
"href": "/where-we-are"
|
||||
},
|
||||
{
|
||||
"label": "News",
|
||||
"href": "/news"
|
||||
}
|
||||
],
|
||||
"en": [
|
||||
{
|
||||
"label": "Categories",
|
||||
"href": "#"
|
||||
},
|
||||
{
|
||||
"label": "About",
|
||||
"href": "/about"
|
||||
},
|
||||
{
|
||||
"label": "News",
|
||||
"href": "/news"
|
||||
},
|
||||
{
|
||||
"label": "Contact",
|
||||
"href": "/contact"
|
||||
},
|
||||
{
|
||||
"label": "News",
|
||||
"href": "/news"
|
||||
},
|
||||
{
|
||||
"label": "Where we are",
|
||||
"href": "/where-we-are"
|
||||
|
Loading…
x
Reference in New Issue
Block a user