mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 07:26:59 +00:00
Latest changes - Normalizing cart
This commit is contained in:
parent
c1535cb8a6
commit
1b80b53b82
@ -1,7 +1,3 @@
|
||||
.root {
|
||||
@apply h-full flex flex-col relative w-full relative;
|
||||
}
|
||||
|
||||
.root.empty {
|
||||
@apply bg-secondary text-secondary;
|
||||
}
|
||||
@ -13,3 +9,7 @@
|
||||
.root.error {
|
||||
@apply bg-red text-white;
|
||||
}
|
||||
|
||||
.lineItemsList {
|
||||
@apply py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2;
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ import Link from 'next/link'
|
||||
import { FC } from 'react'
|
||||
import s from './CartSidebarView.module.css'
|
||||
import CartItem from '../CartItem'
|
||||
import { Button } from '@components/ui'
|
||||
import { UserNav } from '@components/common'
|
||||
import { Button, Text } from '@components/ui'
|
||||
import { useUI } from '@components/ui/context'
|
||||
import { Bag, Cross, Check } from '@components/icons'
|
||||
import useCart from '@framework/cart/use-cart'
|
||||
import usePrice from '@framework/product/use-price'
|
||||
import SidebarLayout from '@components/common/SidebarLayout'
|
||||
|
||||
const CartSidebarView: FC = () => {
|
||||
const { closeSidebar, setSidebarView } = useUI()
|
||||
@ -33,31 +33,12 @@ const CartSidebarView: FC = () => {
|
||||
const success = null
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(s.root, {
|
||||
<SidebarLayout
|
||||
className={cn({
|
||||
[s.empty]: error || success || isLoading || isEmpty,
|
||||
})}
|
||||
handleClose={handleClose}
|
||||
>
|
||||
<header className="pl-4 pr-6 pt-4 pb-4 lg:pt-6">
|
||||
<div className="flex items-start justify-between space-x-3">
|
||||
<div className="h-7 flex items-center">
|
||||
<button
|
||||
onClick={handleClose}
|
||||
aria-label="Close panel"
|
||||
className="hover:text-accent-3 transition ease-in-out duration-150 flex items-center focus:outline-none"
|
||||
>
|
||||
<Cross className="h-6 w-6" />
|
||||
<span className="ml-2 text-accent-7 text-xs hover:text-gray-500">
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<UserNav />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{isLoading || isEmpty ? (
|
||||
<div className="flex-1 px-4 flex flex-col justify-center items-center">
|
||||
<span className="border border-dashed border-primary rounded-full flex items-center justify-center w-16 h-16 p-12 bg-secondary text-secondary">
|
||||
@ -93,14 +74,11 @@ const CartSidebarView: FC = () => {
|
||||
<>
|
||||
<div className="px-4 sm:px-6 flex-1">
|
||||
<Link href="/cart">
|
||||
<h2
|
||||
className="pt-1 pb-8 text-2xl font-semibold tracking-wide cursor-pointer inline-block"
|
||||
onClick={handleClose}
|
||||
>
|
||||
<Text variant="sectionHeading" onClick={handleClose}>
|
||||
My Cart
|
||||
</h2>
|
||||
</Text>
|
||||
</Link>
|
||||
<ul className="py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2">
|
||||
<ul className={s.lineItemsList}>
|
||||
{data!.lineItems.map((item: any) => (
|
||||
<CartItem
|
||||
key={item.id}
|
||||
@ -144,7 +122,7 @@ const CartSidebarView: FC = () => {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</SidebarLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
.root {
|
||||
@apply h-full flex flex-col relative w-full relative;
|
||||
.lineItemsList {
|
||||
@apply py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2;
|
||||
}
|
||||
|
@ -1,26 +1,19 @@
|
||||
import cn from 'classnames'
|
||||
import Link from 'next/link'
|
||||
import { FC } from 'react'
|
||||
import s from './CheckoutSidebarView.module.css'
|
||||
import CartItem from '@components/cart/CartItem'
|
||||
import { Button } from '@components/ui'
|
||||
import { UserNav } from '@components/common'
|
||||
import { Button, Text } from '@components/ui'
|
||||
import { useUI } from '@components/ui/context'
|
||||
import {
|
||||
Bag,
|
||||
Cross,
|
||||
Check,
|
||||
MapPin,
|
||||
CreditCard,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
} from '@components/icons'
|
||||
import useCart from '@framework/cart/use-cart'
|
||||
import usePrice from '@framework/product/use-price'
|
||||
import ShippingWidget from '../ShippingWidget'
|
||||
import PaymentWidget from '../PaymentWidget'
|
||||
import SidebarLayout from '@components/common/SidebarLayout'
|
||||
import s from './CheckoutSidebarView.module.css'
|
||||
|
||||
const CheckoutSidebarView: FC = () => {
|
||||
const { closeSidebar, setSidebarView } = useUI()
|
||||
const { data, isLoading, isEmpty } = useCart()
|
||||
const { setSidebarView } = useUI()
|
||||
const { data } = useCart()
|
||||
|
||||
const { price: subTotal } = usePrice(
|
||||
data && {
|
||||
@ -34,160 +27,59 @@ const CheckoutSidebarView: FC = () => {
|
||||
currencyCode: data.currency.code,
|
||||
}
|
||||
)
|
||||
const handleClose = () => closeSidebar()
|
||||
|
||||
const error = null
|
||||
const success = null
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(s.root, {
|
||||
[s.empty]: error || success || isLoading || isEmpty,
|
||||
})}
|
||||
>
|
||||
<header className="pl-4 pr-6 pt-4 pb-4 lg:pt-6">
|
||||
<div className="flex items-start justify-between space-x-3">
|
||||
<div className="h-7 flex items-center">
|
||||
<button
|
||||
onClick={() => setSidebarView('CART_VIEW')}
|
||||
aria-label="Close panel"
|
||||
className="hover:text-gray-500 transition ease-in-out duration-150 flex items-center focus:outline-none"
|
||||
>
|
||||
<ChevronLeft className="h-6 w-6" />
|
||||
<span className="ml-2 text-accent-7 text-xs hover:text-gray-500">
|
||||
Back
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<UserNav />
|
||||
</div>
|
||||
<SidebarLayout handleBack={() => setSidebarView('CART_VIEW')}>
|
||||
<div className="px-4 sm:px-6 flex-1">
|
||||
<Link href="/cart">
|
||||
<Text variant="sectionHeading">Checkout</Text>
|
||||
</Link>
|
||||
|
||||
<PaymentWidget onClick={() => setSidebarView('PAYMENT_VIEW')} />
|
||||
<ShippingWidget onClick={() => setSidebarView('SHIPPING_VIEW')} />
|
||||
|
||||
<ul className={s.lineItemsList}>
|
||||
{data!.lineItems.map((item: any) => (
|
||||
<CartItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
currencyCode={data!.currency.code}
|
||||
variant="display"
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="flex-shrink-0 px-6 py-6 sm:px-6 sticky z-20 bottom-0 w-full right-0 left-0 bg-accent-0 shadow-outline-normal text-sm">
|
||||
<ul className="pb-2">
|
||||
<li className="flex justify-between py-1">
|
||||
<span>Subtotal</span>
|
||||
<span>{subTotal}</span>
|
||||
</li>
|
||||
<li className="flex justify-between py-1">
|
||||
<span>Taxes</span>
|
||||
<span>Calculated at checkout</span>
|
||||
</li>
|
||||
<li className="flex justify-between py-1">
|
||||
<span>Shipping</span>
|
||||
<span className="font-bold tracking-wide">FREE</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="flex justify-between border-t border-accent-2 py-3 font-bold mb-2">
|
||||
<span>Total</span>
|
||||
<span>{total}</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{isLoading || isEmpty ? (
|
||||
<div className="flex-1 px-4 flex flex-col justify-center items-center">
|
||||
<span className="border border-dashed border-primary rounded-full flex items-center justify-center w-16 h-16 p-12 bg-secondary text-secondary">
|
||||
<Bag className="absolute" />
|
||||
</span>
|
||||
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
|
||||
Your cart is empty
|
||||
</h2>
|
||||
<p className="text-accent-3 px-10 text-center pt-2">
|
||||
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
|
||||
</p>
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="flex-1 px-4 flex flex-col justify-center items-center">
|
||||
<span className="border border-white rounded-full flex items-center justify-center w-16 h-16">
|
||||
<Cross width={24} height={24} />
|
||||
</span>
|
||||
<h2 className="pt-6 text-xl font-light text-center">
|
||||
We couldn’t process the purchase. Please check your card information
|
||||
and try again.
|
||||
</h2>
|
||||
</div>
|
||||
) : success ? (
|
||||
<div className="flex-1 px-4 flex flex-col justify-center items-center">
|
||||
<span className="border border-white rounded-full flex items-center justify-center w-16 h-16">
|
||||
<Check />
|
||||
</span>
|
||||
<h2 className="pt-6 text-xl font-light text-center">
|
||||
Thank you for your order.
|
||||
</h2>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="px-4 sm:px-6 flex-1">
|
||||
<Link href="/cart">
|
||||
<h2 className="pt-1 pb-8 text-2xl font-semibold tracking-wide cursor-pointer inline-block">
|
||||
Checkout
|
||||
</h2>
|
||||
</Link>
|
||||
|
||||
{/* Payment Method */}
|
||||
{/* Only available with checkout set to true - Meaning that the provider does offer checkout functionality. */}
|
||||
<div
|
||||
onClick={() => setSidebarView('PAYMENT_VIEW')}
|
||||
className="border border-accent-2 px-6 py-5 mb-4 text-center flex items-center cursor-pointer hover:border-accent-4"
|
||||
>
|
||||
<div className="flex flex-1 items-center">
|
||||
<CreditCard className="w-5 flex" />
|
||||
<span className="ml-5 text-sm text-center font-medium">
|
||||
Add Payment Method
|
||||
</span>
|
||||
{/* <span>VISA #### #### #### 2345</span> */}
|
||||
</div>
|
||||
<div>
|
||||
<ChevronRight />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Shipping Address */}
|
||||
{/* Only available with checkout set to true - Meaning that the provider does offer checkout functionality. */}
|
||||
<div
|
||||
onClick={() => setSidebarView('SHIPPING_VIEW')}
|
||||
className="border border-accent-2 px-6 py-5 mb-4 text-center flex items-center cursor-pointer hover:border-accent-4"
|
||||
>
|
||||
<div className="flex flex-1 items-center">
|
||||
<MapPin className="w-5 flex" />
|
||||
<span className="ml-5 text-sm text-center font-medium">
|
||||
Add Shipping Address
|
||||
</span>
|
||||
{/* <span>
|
||||
1046 Kearny Street.<br/>
|
||||
San Franssisco, California
|
||||
</span> */}
|
||||
</div>
|
||||
<div>
|
||||
<ChevronRight />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul className="py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2">
|
||||
{data!.lineItems.map((item: any) => (
|
||||
<CartItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
currencyCode={data!.currency.code}
|
||||
variant="display"
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="flex-shrink-0 px-6 py-6 sm:px-6 sticky z-20 bottom-0 w-full right-0 left-0 bg-accent-0 shadow-outline-normal text-sm">
|
||||
<ul className="pb-2">
|
||||
<li className="flex justify-between py-1">
|
||||
<span>Subtotal</span>
|
||||
<span>{subTotal}</span>
|
||||
</li>
|
||||
<li className="flex justify-between py-1">
|
||||
<span>Taxes</span>
|
||||
<span>Calculated at checkout</span>
|
||||
</li>
|
||||
<li className="flex justify-between py-1">
|
||||
<span>Shipping</span>
|
||||
<span className="font-bold tracking-wide">FREE</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="flex justify-between border-t border-accent-2 py-3 font-bold mb-2">
|
||||
<span>Total</span>
|
||||
<span>{total}</span>
|
||||
</div>
|
||||
<div>
|
||||
{/* Once data is correcly filled */}
|
||||
{/* <Button Component="a" width="100%">
|
||||
<div>
|
||||
{/* Once data is correcly filled */}
|
||||
{/* <Button Component="a" width="100%">
|
||||
Confirm Purchase
|
||||
</Button> */}
|
||||
<Button Component="a" width="100%" variant="ghost" disabled>
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<Button Component="a" width="100%" variant="ghost" disabled>
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,39 +1,17 @@
|
||||
import { FC } from 'react'
|
||||
import s from './PaymentMethodView.module.css'
|
||||
import { ChevronLeft } from '@components/icons'
|
||||
import { UserNav } from '@components/common'
|
||||
import { useUI } from '@components/ui/context'
|
||||
import Button from '@components/ui/Button'
|
||||
import cn from 'classnames'
|
||||
import { Button, Text } from '@components/ui'
|
||||
import { useUI } from '@components/ui/context'
|
||||
import s from './PaymentMethodView.module.css'
|
||||
import SidebarLayout from '@components/common/SidebarLayout'
|
||||
|
||||
const PaymentMethodView: FC = () => {
|
||||
const { setSidebarView } = useUI()
|
||||
|
||||
return (
|
||||
<div className={s.root}>
|
||||
<header className="pl-4 pr-6 pt-4 pb-4 lg:pt-6">
|
||||
<div className="flex items-start justify-between space-x-3">
|
||||
<div className="h-7 flex items-center">
|
||||
<button
|
||||
onClick={() => setSidebarView('CHECKOUT_VIEW')}
|
||||
aria-label="Close panel"
|
||||
className="hover:text-gray-500 transition ease-in-out duration-150 flex items-center focus:outline-none"
|
||||
>
|
||||
<ChevronLeft className="h-6 w-6" />
|
||||
<span className="ml-2 text-accent-7 text-xs hover:text-gray-500">
|
||||
Back
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<UserNav />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}>
|
||||
<div className="px-4 sm:px-6 flex-1">
|
||||
<h2 className="pt-1 pb-6 text-2xl font-semibold tracking-wide cursor-pointer inline-block">
|
||||
Payment Method
|
||||
</h2>
|
||||
<Text variant="sectionHeading"> Payment Method</Text>
|
||||
<div>
|
||||
<div className={s.fieldset}>
|
||||
<label className={s.label}>Cardholder Name</label>
|
||||
@ -99,7 +77,7 @@ const PaymentMethodView: FC = () => {
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
.root {
|
||||
@apply border border-accent-2 px-6 py-5 mb-4 text-center
|
||||
flex items-center cursor-pointer hover:border-accent-4;
|
||||
}
|
29
components/checkout/PaymentWidget/PaymentWidget.tsx
Normal file
29
components/checkout/PaymentWidget/PaymentWidget.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import { FC } from 'react'
|
||||
import s from './PaymentWidget.module.css'
|
||||
import { ChevronRight, CreditCard } from '@components/icons'
|
||||
|
||||
interface ComponentProps {
|
||||
onClick?: () => any
|
||||
}
|
||||
|
||||
const PaymentWidget: FC<ComponentProps> = ({ onClick }) => {
|
||||
/* Shipping Address
|
||||
Only available with checkout set to true -
|
||||
This means that the provider does offer checkout functionality. */
|
||||
return (
|
||||
<div onClick={onClick} className={s.root}>
|
||||
<div className="flex flex-1 items-center">
|
||||
<CreditCard className="w-5 flex" />
|
||||
<span className="ml-5 text-sm text-center font-medium">
|
||||
Add Payment Method
|
||||
</span>
|
||||
{/* <span>VISA #### #### #### 2345</span> */}
|
||||
</div>
|
||||
<div>
|
||||
<ChevronRight />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PaymentWidget
|
1
components/checkout/PaymentWidget/index.ts
Normal file
1
components/checkout/PaymentWidget/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './PaymentWidget'
|
@ -1,35 +1,15 @@
|
||||
import { FC } from 'react'
|
||||
import s from './ShippingView.module.css'
|
||||
import { ChevronLeft } from '@components/icons'
|
||||
import { UserNav } from '@components/common'
|
||||
import { useUI } from '@components/ui/context'
|
||||
import Button from '@components/ui/Button'
|
||||
import cn from 'classnames'
|
||||
import s from './ShippingView.module.css'
|
||||
import Button from '@components/ui/Button'
|
||||
import { useUI } from '@components/ui/context'
|
||||
import SidebarLayout from '@components/common/SidebarLayout'
|
||||
|
||||
const PaymentMethodView: FC = () => {
|
||||
const { setSidebarView } = useUI()
|
||||
|
||||
return (
|
||||
<div className={s.root}>
|
||||
<header className="pl-4 pr-6 pt-4 pb-4 lg:pt-6">
|
||||
<div className="flex items-start justify-between space-x-3">
|
||||
<div className="h-7 flex items-center">
|
||||
<button
|
||||
onClick={() => setSidebarView('CHECKOUT_VIEW')}
|
||||
aria-label="Close panel"
|
||||
className="hover:text-gray-500 transition ease-in-out duration-150 flex items-center focus:outline-none"
|
||||
>
|
||||
<ChevronLeft className="h-6 w-6" />
|
||||
<span className="ml-2 text-accent-7 text-xs hover:text-gray-500">
|
||||
Back
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<UserNav />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}>
|
||||
<div className="px-4 sm:px-6 flex-1">
|
||||
<h2 className="pt-1 pb-8 text-2xl font-semibold tracking-wide cursor-pointer inline-block">
|
||||
Shipping
|
||||
@ -91,7 +71,7 @@ const PaymentMethodView: FC = () => {
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
.root {
|
||||
@apply border border-accent-2 px-6 py-5 mb-4 text-center
|
||||
flex items-center cursor-pointer hover:border-accent-4;
|
||||
}
|
33
components/checkout/ShippingWidget/ShippingWidget.tsx
Normal file
33
components/checkout/ShippingWidget/ShippingWidget.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { FC } from 'react'
|
||||
import s from './ShippingWidget.module.css'
|
||||
import { ChevronRight, MapPin } from '@components/icons'
|
||||
import cn from 'classnames'
|
||||
|
||||
interface ComponentProps {
|
||||
onClick?: () => any
|
||||
}
|
||||
|
||||
const ShippingWidget: FC<ComponentProps> = ({ onClick }) => {
|
||||
/* Shipping Address
|
||||
Only available with checkout set to true -
|
||||
This means that the provider does offer checkout functionality. */
|
||||
return (
|
||||
<div onClick={onClick} className={s.root}>
|
||||
<div className="flex flex-1 items-center">
|
||||
<MapPin className="w-5 flex" />
|
||||
<span className="ml-5 text-sm text-center font-medium">
|
||||
Add Shipping Address
|
||||
</span>
|
||||
{/* <span>
|
||||
1046 Kearny Street.<br/>
|
||||
San Franssisco, California
|
||||
</span> */}
|
||||
</div>
|
||||
<div>
|
||||
<ChevronRight />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ShippingWidget
|
1
components/checkout/ShippingWidget/index.ts
Normal file
1
components/checkout/ShippingWidget/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './ShippingWidget'
|
@ -44,7 +44,7 @@ const Footer: FC<Props> = ({ className, pages }) => {
|
||||
<div className="col-span-1 lg:col-span-2">
|
||||
<ul className="flex flex-initial flex-col md:flex-1">
|
||||
{links.map(({ href, name }) => (
|
||||
<li className="py-3 md:py-0 md:pb-4">
|
||||
<li className="py-3 md:py-0 md:pb-4" key={href}>
|
||||
<Link href={href}>
|
||||
<a className="text-primary hover:text-accent-6 transition ease-in-out duration-150">
|
||||
{name}
|
||||
|
@ -3,6 +3,10 @@
|
||||
}
|
||||
|
||||
.nav {
|
||||
@apply relative flex flex-row justify-between py-4 md:py-4;
|
||||
}
|
||||
|
||||
.navMenu {
|
||||
@apply hidden ml-6 space-x-4 lg:block;
|
||||
}
|
||||
|
||||
|
@ -8,14 +8,14 @@ import s from './Navbar.module.css'
|
||||
const Navbar: FC = () => (
|
||||
<NavbarRoot>
|
||||
<Container>
|
||||
<div className="relative flex flex-row justify-between py-4 align-center md:py-6">
|
||||
<div className={s.nav}>
|
||||
<div className="flex items-center flex-1">
|
||||
<Link href="/">
|
||||
<a className={s.logo} aria-label="Logo">
|
||||
<Logo />
|
||||
</a>
|
||||
</Link>
|
||||
<nav className={s.nav}>
|
||||
<nav className={s.navMenu}>
|
||||
<Link href="/search">
|
||||
<a className={s.link}>All</a>
|
||||
</Link>
|
||||
@ -35,7 +35,7 @@ const Navbar: FC = () => (
|
||||
<Searchbar />
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end flex-1 space-x-8">
|
||||
<div className="flex items-center justify-end flex-1 space-x-8">
|
||||
<UserNav />
|
||||
</div>
|
||||
</div>
|
||||
|
8
components/common/SidebarLayout/SidebarLayout.module.css
Normal file
8
components/common/SidebarLayout/SidebarLayout.module.css
Normal file
@ -0,0 +1,8 @@
|
||||
.root {
|
||||
@apply relative h-full flex flex-col w-full;
|
||||
}
|
||||
|
||||
.header {
|
||||
@apply pl-4 pr-6 pt-4 pb-4 lg:pt-5 flex items-center justify-between space-x-3;
|
||||
margin-top: 1px;
|
||||
}
|
56
components/common/SidebarLayout/SidebarLayout.tsx
Normal file
56
components/common/SidebarLayout/SidebarLayout.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import React, { FC } from 'react'
|
||||
import { Cross, ChevronLeft } from '@components/icons'
|
||||
import { UserNav } from '@components/common'
|
||||
import cn from 'classnames'
|
||||
import s from './SidebarLayout.module.css'
|
||||
|
||||
interface BaseProps {
|
||||
className?: string
|
||||
}
|
||||
|
||||
type ComponentProps =
|
||||
| (BaseProps & { handleClose: () => any })
|
||||
| (BaseProps & { handleBack: () => any })
|
||||
|
||||
const SidebarLayout: FC<ComponentProps> = ({
|
||||
children,
|
||||
className,
|
||||
handleClose,
|
||||
handleBack,
|
||||
}) => {
|
||||
return (
|
||||
<div className={cn(s.root, className)}>
|
||||
<header className={s.header}>
|
||||
{handleClose && (
|
||||
<button
|
||||
onClick={handleClose}
|
||||
aria-label="Close"
|
||||
className="hover:text-gray-500 transition ease-in-out duration-150 flex items-center focus:outline-none"
|
||||
>
|
||||
<Cross className="h-6 w-6" />
|
||||
<span className="ml-2 text-accent-7 text-xs hover:text-gray-500">
|
||||
Close
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{handleBack && (
|
||||
<button
|
||||
onClick={handleBack}
|
||||
aria-label="Go back"
|
||||
className="hover:text-gray-500 transition ease-in-out duration-150 flex items-center focus:outline-none"
|
||||
>
|
||||
<ChevronLeft className="h-6 w-6" />
|
||||
<span className="ml-2 text-accent-7 text-xs hover:text-gray-500">
|
||||
Back
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
<UserNav />
|
||||
</header>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SidebarLayout
|
1
components/common/SidebarLayout/index.ts
Normal file
1
components/common/SidebarLayout/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './SidebarLayout'
|
@ -175,7 +175,8 @@ const ProductView: FC<Props> = ({ product, relatedProducts }) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section className="py-12 px-6 mb-10">
|
||||
<hr className="mt-6" />
|
||||
<section className="py-6 px-6 mb-10">
|
||||
<Text variant="sectionHeading">Related Products</Text>
|
||||
<div className="grid grid-cols-4 py-3 gap-10">
|
||||
{relatedProducts.map((p) => (
|
||||
|
@ -34,7 +34,7 @@ const Sidebar: FC<Props> = ({ children, open = false, onClose }) => {
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
{open ? (
|
||||
{open && (
|
||||
<div className={s.root} ref={ref}>
|
||||
<div className="absolute inset-0 overflow-hidden">
|
||||
<div
|
||||
@ -48,7 +48,7 @@ const Sidebar: FC<Props> = ({ children, open = false, onClose }) => {
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
)}
|
||||
</Portal>
|
||||
)
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ interface Props {
|
||||
style?: CSSProperties
|
||||
children?: React.ReactNode | any
|
||||
html?: string
|
||||
onClick?: () => any
|
||||
}
|
||||
|
||||
type Variant = 'heading' | 'body' | 'pageHeading' | 'sectionHeading'
|
||||
@ -22,6 +23,7 @@ const Text: FunctionComponent<Props> = ({
|
||||
variant = 'body',
|
||||
children,
|
||||
html,
|
||||
onClick,
|
||||
}) => {
|
||||
const componentsMap: {
|
||||
[P in Variant]: React.ComponentType<any> | string
|
||||
@ -56,6 +58,7 @@ const Text: FunctionComponent<Props> = ({
|
||||
},
|
||||
className
|
||||
)}
|
||||
onClick={onClick}
|
||||
style={style}
|
||||
{...htmlContentProps}
|
||||
>
|
||||
|
@ -22,8 +22,8 @@
|
||||
"@components/*": ["components/*"],
|
||||
"@commerce": ["framework/commerce"],
|
||||
"@commerce/*": ["framework/commerce/*"],
|
||||
"@framework": ["framework/bigcommerce"],
|
||||
"@framework/*": ["framework/bigcommerce/*"]
|
||||
"@framework": ["framework/shopify"],
|
||||
"@framework/*": ["framework/shopify/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],
|
||||
|
Loading…
x
Reference in New Issue
Block a user