diff --git a/components/cart/CartItem/CartItem.module.css b/components/cart/CartItem/CartItem.module.css index feffa0f3a..af094ba99 100644 --- a/components/cart/CartItem/CartItem.module.css +++ b/components/cart/CartItem/CartItem.module.css @@ -6,23 +6,6 @@ padding-top: 0; } -.actions { - @apply flex p-1 border-accent-2 border items-center justify-center w-12 text-accent-7; - transition-property: border-color, background, color, transform, box-shadow; - transition-duration: 0.15s; - transition-timing-function: ease; -} - -.actions:hover { - @apply bg-accent-1 border-accent-3 text-accent-9; - transition: border-color; - z-index: 10; -} - -.actions:focus { - @apply bg-accent-2 outline-none; -} - .quantity { appearance: textfield; @apply w-8 border-accent-2 border mx-3 rounded text-center text-sm text-black; diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index 4f66da868..e51274e0f 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -1,4 +1,4 @@ -import { ChangeEvent, useEffect, useState } from 'react' +import { ChangeEvent, FocusEventHandler, useEffect, useState } from 'react' import cn from 'classnames' import Image from 'next/image' import Link from 'next/link' @@ -9,6 +9,7 @@ import type { LineItem } from '@commerce/types/cart' import usePrice from '@framework/product/use-price' import useUpdateItem from '@framework/cart/use-update-item' import useRemoveItem from '@framework/cart/use-remove-item' +import Quantity from '@components/ui/Quantity' type ItemOption = { name: string @@ -28,6 +29,10 @@ const CartItem = ({ currencyCode: string }) => { const { closeSidebarIfPresent } = useUI() + const [removing, setRemoving] = useState(false) + const [quantity, setQuantity] = useState(item.quantity) + const removeItem = useRemoveItem() + const updateItem = useUpdateItem({ item }) const { price } = usePrice({ amount: item.variant.price * item.quantity, @@ -35,43 +40,22 @@ const CartItem = ({ currencyCode, }) - const updateItem = useUpdateItem({ item }) - const removeItem = useRemoveItem() - const [quantity, setQuantity] = useState(item.quantity) - const [removing, setRemoving] = useState(false) - - const updateQuantity = async (val: number) => { - await updateItem({ quantity: val }) + const handleChange = async ({ + target: { value }, + }: ChangeEvent) => { + setQuantity(Number(value)) + await updateItem({ quantity: Number(value) }) } - const handleQuantity = (e: ChangeEvent) => { - const val = !e.target.value ? '' : Number(e.target.value) - - if (!val || (Number.isInteger(val) && val >= 0)) { - setQuantity(val) - } - } - - const handleBlur = () => { - const val = Number(quantity) - if (val !== item.quantity) { - updateQuantity(val) - } - } - - const increaseQuantity = (n = 1) => { + const increaseQuantity = async (n = 1) => { const val = Number(quantity) + n - if (Number.isInteger(val) && val >= 0) { - setQuantity(val) - updateQuantity(val) - } + setQuantity(val) + await updateItem({ quantity: val }) } const handleRemove = async () => { setRemoving(true) try { - // If this action succeeds then there's no need to do `setRemoving(true)` - // because the component will be removed from the view await removeItem(item) } catch (error) { setRemoving(false) @@ -152,38 +136,13 @@ const CartItem = ({ {variant === 'default' && ( -
- - - - -
+ increaseQuantity(1)} + decrease={() => increaseQuantity(-1)} + /> )} ) diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index 9cf99cf9b..128b928a8 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -89,7 +89,7 @@ const CartSidebarView: FC = () => { -
+
  • Subtotal diff --git a/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx b/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx index d17f46b28..f9dac54f9 100644 --- a/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx +++ b/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx @@ -50,7 +50,7 @@ const CheckoutSidebarView: FC = () => {
-
+
  • Subtotal diff --git a/components/common/I18nWidget/I18nWidget.module.css b/components/common/I18nWidget/I18nWidget.module.css index bd20f14c1..269aa5f61 100644 --- a/components/common/I18nWidget/I18nWidget.module.css +++ b/components/common/I18nWidget/I18nWidget.module.css @@ -3,11 +3,11 @@ } .button { - @apply h-10 px-2 rounded-md border border-accent-2 flex items-center justify-center; + @apply h-10 px-2 rounded-md border border-accent-2 flex items-center justify-center transition-colors ease-linear; } .button:hover { - @apply border-accent-4 shadow-sm; + @apply border-accent-3 shadow-sm; } .button:focus { @@ -38,5 +38,9 @@ } .icon { + transition: transform 0.2s ease; +} + +.icon.active { transform: rotate(180deg); } diff --git a/components/common/I18nWidget/I18nWidget.tsx b/components/common/I18nWidget/I18nWidget.tsx index fbe67a4c1..58135f12a 100644 --- a/components/common/I18nWidget/I18nWidget.tsx +++ b/components/common/I18nWidget/I18nWidget.tsx @@ -59,7 +59,7 @@ const I18nWidget: FC = () => { /> {options && ( - + )} diff --git a/components/common/SidebarLayout/SidebarLayout.tsx b/components/common/SidebarLayout/SidebarLayout.tsx index db2ce13b0..6b95481b7 100644 --- a/components/common/SidebarLayout/SidebarLayout.tsx +++ b/components/common/SidebarLayout/SidebarLayout.tsx @@ -25,7 +25,7 @@ const SidebarLayout: FC = ({ className="hover:text-gray-500 transition ease-in-out duration-150 flex items-center focus:outline-none" > - + Close diff --git a/components/product/ProductSlider/ProductSlider.module.css b/components/product/ProductSlider/ProductSlider.module.css index 8db6561a7..f77a3738d 100644 --- a/components/product/ProductSlider/ProductSlider.module.css +++ b/components/product/ProductSlider/ProductSlider.module.css @@ -1,6 +1,6 @@ .root { - @apply relative w-full h-full; - overflow-y: hidden; + @apply relative w-full h-full select-none; + overflow: hidden; } .slider { @@ -14,7 +14,7 @@ .control { @apply bg-violet absolute bottom-10 right-10 flex flex-row - border-accent-0 border text-accent-0 z-30 shadow-xl; + border-accent-0 border text-accent-0 z-30 shadow-xl select-none; height: 48px; } @@ -59,11 +59,16 @@ } .album { + width: 100%; + height: 100%; @apply bg-violet-dark; + box-sizing: content-box; overflow-y: hidden; overflow-x: auto; white-space: nowrap; height: 125px; + padding-bottom: 10px; + margin-bottom: -10px; } @screen md { diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index b43184e38..b34929aab 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -9,11 +9,11 @@ import { getVariant, SelectedOptions } from '../helpers' import { Swatch, ProductSlider } from '@components/product' import { Button, Container, Text, useUI } from '@components/ui' import { useAddItem } from '@framework/cart' +import Rating from '@components/ui/Rating' import Collapse from '@components/ui/Collapse' import ProductCard from '@components/product/ProductCard' import WishlistButton from '@components/wishlist/WishlistButton' -import rangeMap from '@lib/range-map' -import { Star } from '@components/icons' + interface Props { children?: any product: Product @@ -154,20 +154,10 @@ const ProductView: FC = ({ product, relatedProducts }) => {
- {/** - * TODO make component Rate stars={} - */} -
- {rangeMap(4, (i) => ( - - - - ))} - - - + +
+ 36 reviews
-
36 reviews
+ + + +
+ ) +} + +export default Quantity diff --git a/components/ui/Quantity/index.ts b/components/ui/Quantity/index.ts new file mode 100644 index 000000000..5ee880cc9 --- /dev/null +++ b/components/ui/Quantity/index.ts @@ -0,0 +1,2 @@ +export { default } from './Quantity' +export * from './Quantity' diff --git a/components/ui/Rating/Rating.module.css b/components/ui/Rating/Rating.module.css new file mode 100644 index 000000000..e69de29bb diff --git a/components/ui/Rating/Rating.tsx b/components/ui/Rating/Rating.tsx new file mode 100644 index 000000000..e9ae65833 --- /dev/null +++ b/components/ui/Rating/Rating.tsx @@ -0,0 +1,27 @@ +import React, { FC } from 'react' +import rangeMap from '@lib/range-map' +import { Star } from '@components/icons' +import cn from 'classnames' + +export interface RatingProps { + value: number +} + +const Quantity: FC = ({ value = 5 }) => { + return ( +
+ {rangeMap(5, (i) => ( + = Math.floor(value), + })} + > + + + ))} +
+ ) +} + +export default Quantity diff --git a/components/ui/Rating/index.ts b/components/ui/Rating/index.ts new file mode 100644 index 000000000..1354efb25 --- /dev/null +++ b/components/ui/Rating/index.ts @@ -0,0 +1,2 @@ +export { default } from './Rating' +export * from './Rating' diff --git a/components/ui/Sidebar/Sidebar.tsx b/components/ui/Sidebar/Sidebar.tsx index c894ac035..200d6441e 100644 --- a/components/ui/Sidebar/Sidebar.tsx +++ b/components/ui/Sidebar/Sidebar.tsx @@ -7,13 +7,13 @@ import { clearAllBodyScrollLocks, } from 'body-scroll-lock' -interface Props { +interface SidebarProps { children: any open: boolean onClose: () => void } -const Sidebar: FC = ({ children, open = false, onClose }) => { +const Sidebar: FC = ({ children, open = false, onClose }) => { const ref = useRef() as React.MutableRefObject useEffect(() => { diff --git a/components/ui/Skeleton/Skeleton.tsx b/components/ui/Skeleton/Skeleton.tsx index 153024f18..9d7e668b6 100644 --- a/components/ui/Skeleton/Skeleton.tsx +++ b/components/ui/Skeleton/Skeleton.tsx @@ -3,7 +3,7 @@ import cn from 'classnames' import px from '@lib/to-pixels' import s from './Skeleton.module.css' -interface Props { +interface SkeletonProps { width?: string | number height?: string | number boxHeight?: string | number @@ -13,7 +13,7 @@ interface Props { className?: string } -const Skeleton: React.FC = ({ +const Skeleton: React.FC = ({ style, width, height, diff --git a/components/ui/Text/Text.tsx b/components/ui/Text/Text.tsx index 0ca71da9a..6106c209a 100644 --- a/components/ui/Text/Text.tsx +++ b/components/ui/Text/Text.tsx @@ -6,7 +6,7 @@ import React, { import cn from 'classnames' import s from './Text.module.css' -interface Props { +interface TextProps { variant?: Variant className?: string style?: CSSProperties @@ -17,7 +17,7 @@ interface Props { type Variant = 'heading' | 'body' | 'pageHeading' | 'sectionHeading' -const Text: FunctionComponent = ({ +const Text: FunctionComponent = ({ style, className = '', variant = 'body', diff --git a/components/ui/index.ts b/components/ui/index.ts index 37ddd0dbc..47bdbd9ff 100644 --- a/components/ui/index.ts +++ b/components/ui/index.ts @@ -11,4 +11,6 @@ export { default as Modal } from './Modal' export { default as Text } from './Text' export { default as Input } from './Input' export { default as Collapse } from './Collapse' +export { default as Quantity } from './Quantity' +export { default as Rating } from './Rating' export { useUI } from './context' diff --git a/framework/shopify/product/get-all-product-paths.ts b/framework/shopify/product/get-all-product-paths.ts deleted file mode 100644 index 4431d1e53..000000000 --- a/framework/shopify/product/get-all-product-paths.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Product } from '@commerce/types' -import { getConfig, ShopifyConfig } from '../api' -import fetchAllProducts from '../api/utils/fetch-all-products' -import { ProductEdge } from '../schema' -import getAllProductsPathsQuery from '../utils/queries/get-all-products-paths-query' - -type ProductPath = { - path: string -} - -export type ProductPathNode = { - node: ProductPath -} - -type ReturnType = { - products: ProductPathNode[] -} - -const getAllProductPaths = async (options?: { - variables?: any - config?: ShopifyConfig - preview?: boolean -}): Promise => { - let { config, variables = { first: 250 } } = options ?? {} - config = getConfig(config) - - const products = await fetchAllProducts({ - config, - query: getAllProductsPathsQuery, - variables, - }) - - return { - products: products?.map(({ node: { handle } }: ProductEdge) => ({ - node: { - path: `/${handle}`, - }, - })), - } -} - -export default getAllProductPaths diff --git a/framework/shopify/product/get-all-products.ts b/framework/shopify/product/get-all-products.ts deleted file mode 100644 index 14e486563..000000000 --- a/framework/shopify/product/get-all-products.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { GraphQLFetcherResult } from '@commerce/api' -import { getConfig, ShopifyConfig } from '../api' -import { ProductEdge } from '../schema' -import { getAllProductsQuery } from '../utils/queries' -import { normalizeProduct } from '../utils/normalize' -import { Product } from '@commerce/types' - -type Variables = { - first?: number - field?: string -} - -type ReturnType = { - products: Product[] -} - -const getAllProducts = async (options: { - variables?: Variables - config?: ShopifyConfig - preview?: boolean -}): Promise => { - let { config, variables = { first: 250 } } = options ?? {} - config = getConfig(config) - - const { data }: GraphQLFetcherResult = await config.fetch( - getAllProductsQuery, - { variables } - ) - - const products = - data.products?.edges?.map(({ node: p }: ProductEdge) => - normalizeProduct(p) - ) ?? [] - - return { - products, - } -} - -export default getAllProducts diff --git a/framework/shopify/product/get-product.ts b/framework/shopify/product/get-product.ts deleted file mode 100644 index 047cd92f8..000000000 --- a/framework/shopify/product/get-product.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { GraphQLFetcherResult } from '@commerce/api' -import { getConfig, ShopifyConfig } from '../api' -import { normalizeProduct, getProductQuery } from '../utils' - -type Variables = { - slug: string -} - -type ReturnType = { - product: any -} - -const getProduct = async (options: { - variables: Variables - config: ShopifyConfig - preview?: boolean -}): Promise => { - let { config, variables } = options ?? {} - config = getConfig(config) - - const { data }: GraphQLFetcherResult = await config.fetch(getProductQuery, { - variables, - }) - - const { productByHandle } = data - - return { - product: productByHandle ? normalizeProduct(productByHandle) : null, - } -} - -export default getProduct diff --git a/pages/index.tsx b/pages/index.tsx index 4f741bb90..ebd67436e 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -55,14 +55,8 @@ export default function Home({ ))} {products.slice(0, 3).map((product, i) => (