Add cart loading skeleton and complete the task

This commit is contained in:
Martin Bavio 2020-10-30 16:57:10 -03:00
parent 7ac4625c74
commit 18102bfb72
5 changed files with 127 additions and 22 deletions

View File

@ -0,0 +1,23 @@
import { Bag } from '@components/icons'
import { Button } from '@components/ui'
const CartEmpty: React.FC = () => {
return (
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center ">
<span className="border border-dashed border-secondary rounded-full flex items-center justify-center w-16 h-16 bg-primary p-12 rounded-lg text-primary">
<Bag className="absolute" />
</span>
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
Your cart is empty
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
<Button href="/" Component="a" className="block mt-8">
Continue Shopping
</Button>
</div>
)
}
export default CartEmpty

View File

@ -0,0 +1,76 @@
const CartSkeleton: React.FC = () => {
return (
<div className="grid lg:grid-cols-12">
<div className="lg:col-span-8">
<div className="flex-1">
<div className="border-t border-accents-2 mt-10 pt-16 sm:pt-10">
<div className="animate-cart-pulse flex">
<div className="w-16 h-16 bg-gray-300" />
<div className="ml-8 w-1/6 flex flex-col">
<div className="w-full h-7 bg-gray-300" />
<div className="w-1/2 h-5 bg-gray-300 mt-4" />
</div>
<div className="ml-auto w-24 flex flex-col items-end">
<div className="w-full h-7 bg-gray-300" />
<div className="w-1/2 h-5 bg-gray-300 mt-4" />
</div>
</div>
</div>
<div className="sm:border-t border-accents-2 mt-12 sm:mt-10 pt-12 sm:pt-10 ">
<div
className="animate-cart-pulse flex"
style={{
animationFillMode: 'backwards',
animationDelay: '225ms',
}}
>
<div className="w-16 h-16 bg-gray-300" />
<div className="ml-8 w-1/6 flex flex-col">
<div className="w-full h-7 bg-gray-300" />
<div className="w-1/2 h-5 bg-gray-300 mt-4" />
</div>
<div className="ml-auto w-24 flex flex-col items-end">
<div className="w-full h-7 bg-gray-300" />
<div className="w-1/2 h-5 bg-gray-300 mt-4" />
</div>
</div>
</div>
</div>
</div>
<div className="lg:col-span-4">
<div className="flex-shrink-0 pt-16 sm:pt-10 sm:pl-16">
<div className="border-t border-accents-2">
<ul className="pt-6 pb-7 animate-cart-pulse">
<li className="flex justify-between">
<span className="w-16 h-5 bg-gray-300" />
<span className="w-20 h-5 bg-gray-300" />
</li>
<li className="flex justify-between mt-4">
<span className="w-12 h-5 bg-gray-300" />
<span className="w-24 h-5 bg-gray-300" />
</li>
<li className="flex justify-between mt-4">
<span className="w-36 h-5 bg-gray-300" />
<span className="w-12 h-5 bg-gray-300" />
</li>
</ul>
<div className="border-t border-accents-2 font-bold pt-8 mb-10">
<div
className="flex justify-between animate-cart-pulse"
style={{
animationFillMode: 'backwards',
animationDelay: '225ms',
}}
>
<div className="w-12 h-5 bg-gray-300" />
<div className="w-24 h-5 bg-gray-300" />
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default CartSkeleton

View File

@ -3,7 +3,7 @@ import useBigCommercePrice from '@bigcommerce/storefront-data-hooks/use-price'
export const useCart = () => { export const useCart = () => {
const { data, error, isEmpty } = useBigCommerceCart() const { data, error, isEmpty } = useBigCommerceCart()
const isLoading = data === undefined const items = data?.line_items.physical_items ?? []
const { price: subtotal } = useBigCommercePrice( const { price: subtotal } = useBigCommercePrice(
data && { data && {
@ -18,13 +18,11 @@ export const useCart = () => {
} }
) )
const items = data?.line_items.physical_items ?? []
return { return {
items: data?.line_items.physical_items ?? [], items: data?.line_items.physical_items ?? [],
isLoading: data === undefined, isLoading: data === undefined,
isError: error, isError: error,
isEmpty: isEmpty && data == null, isEmpty: isEmpty && data === null,
subtotal, subtotal,
total, total,
currency: data?.currency, currency: data?.currency,

View File

@ -7,6 +7,8 @@ import { Button } from '@components/ui'
import { Bag, Cross, Check } from '@components/icons' import { Bag, Cross, Check } from '@components/icons'
import { CartItem } from '@components/cart' import { CartItem } from '@components/cart'
import { Text } from '@components/ui' import { Text } from '@components/ui'
import CartSkeleton from '@components/cart/CartSkeleton'
import CartEmpty from '@components/cart/CartEmpty'
export async function getStaticProps({ export async function getStaticProps({
preview, preview,
@ -33,23 +35,12 @@ export default function Cart() {
return ( return (
<div className="px-4 pt-2 sm:px-6 flex-1"> <div className="px-4 pt-2 sm:px-6 flex-1">
<Text variant="pageHeading">My Cart</Text> <Text variant="pageHeading">My Cart</Text>
{isError && <div className="mt-2">Failed to load</div>} {true ? (
{isLoading && <div>Loading...</div>} <CartSkeleton />
{isEmpty ? ( ) : isError ? (
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center "> <div className="mt-2">Failed to load</div>
<span className="border border-dashed border-secondary rounded-full flex items-center justify-center w-16 h-16 bg-primary p-12 rounded-lg text-primary"> ) : isEmpty ? (
<Bag className="absolute" /> <CartEmpty />
</span>
<h2 className="pt-6 text-2xl font-bold tracking-wide text-center">
Your cart is empty
</h2>
<p className="text-accents-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
</p>
<Button href="/" Component="a" className="block mt-8">
Continue Shopping
</Button>
</div>
) : ( ) : (
<div className="grid lg:grid-cols-12"> <div className="grid lg:grid-cols-12">
<div className="lg:col-span-8"> <div className="lg:col-span-8">
@ -72,7 +63,10 @@ export default function Cart() {
</div> </div>
<div className="flex py-6 space-x-6"> <div className="flex py-6 space-x-6">
{[1, 2, 3, 4, 5, 6].map((x) => ( {[1, 2, 3, 4, 5, 6].map((x) => (
<div className="border border-accents-3 w-full h-24 bg-accents-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75" /> <div
key={x}
className="border border-accents-3 w-full h-24 bg-accents-2 bg-opacity-50 transform cursor-pointer hover:scale-110 duration-75"
/>
))} ))}
</div> </div>
</div> </div>

View File

@ -49,6 +49,20 @@ module.exports = {
magical: magical:
'rgba(0, 0, 0, 0.02) 0px 30px 30px, rgba(0, 0, 0, 0.03) 0px 0px 8px, rgba(0, 0, 0, 0.05) 0px 1px 0px', 'rgba(0, 0, 0, 0.02) 0px 30px 30px, rgba(0, 0, 0, 0.03) 0px 0px 8px, rgba(0, 0, 0, 0.05) 0px 1px 0px',
}, },
animation: {
'cart-pulse': 'pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite',
},
keyframes: {
'cart-pulse': {
'0%, 100%': {
opacity: 0.2,
},
'50%': {
opacity: 1,
},
},
},
}, },
}, },
plugins: [require('@tailwindcss/ui')], plugins: [require('@tailwindcss/ui')],