Latest changes - Normalizing cart

This commit is contained in:
Bel Curcio 2021-06-02 16:12:58 -03:00
parent c1535cb8a6
commit 1b80b53b82
22 changed files with 237 additions and 264 deletions

View File

@ -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;
}

View File

@ -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>
)
}

View File

@ -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;
}

View File

@ -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 couldnt 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>
)
}

View File

@ -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>
)
}

View File

@ -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;
}

View 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

View File

@ -0,0 +1 @@
export { default } from './PaymentWidget'

View File

@ -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>
)
}

View File

@ -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;
}

View 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

View File

@ -0,0 +1 @@
export { default } from './ShippingWidget'

View File

@ -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}

View File

@ -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;
}

View File

@ -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>

View 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;
}

View 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

View File

@ -0,0 +1 @@
export { default } from './SidebarLayout'

View File

@ -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) => (

View File

@ -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>
)
}

View File

@ -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}
>

View File

@ -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"],