mirror of
https://github.com/vercel/commerce.git
synced 2025-06-18 21:21:21 +00:00
Merge branch 'agnostic' of github.com:vercel/commerce into shopify
This commit is contained in:
commit
6d5f29d27c
@ -1,14 +1,14 @@
|
|||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import { UserNav } from '@components/common'
|
import Link from 'next/link'
|
||||||
import { Button } from '@components/ui'
|
|
||||||
import { Bag, Cross, Check } from '@components/icons'
|
|
||||||
import { useUI } from '@components/ui/context'
|
|
||||||
import useCart from '@framework/cart/use-cart'
|
|
||||||
import usePrice from '@framework/product/use-price'
|
|
||||||
import CartItem from '../CartItem'
|
import CartItem from '../CartItem'
|
||||||
import s from './CartSidebarView.module.css'
|
import s from './CartSidebarView.module.css'
|
||||||
import { LineItem } from '@commerce/types'
|
import { Button } from '@components/ui'
|
||||||
|
import { UserNav } from '@components/common'
|
||||||
|
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'
|
||||||
|
|
||||||
const CartSidebarView: FC = () => {
|
const CartSidebarView: FC = () => {
|
||||||
const { closeSidebar } = useUI()
|
const { closeSidebar } = useUI()
|
||||||
@ -88,9 +88,14 @@ const CartSidebarView: FC = () => {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="px-4 sm:px-6 flex-1">
|
<div className="px-4 sm:px-6 flex-1">
|
||||||
<h2 className="pt-1 pb-4 text-2xl leading-7 font-bold text-base tracking-wide">
|
<Link href="/cart">
|
||||||
|
<h2
|
||||||
|
className="pt-1 pb-4 text-2xl leading-7 font-bold text-base tracking-wide cursor-pointer inline-block"
|
||||||
|
onClick={handleClose}
|
||||||
|
>
|
||||||
My Cart
|
My Cart
|
||||||
</h2>
|
</h2>
|
||||||
|
</Link>
|
||||||
<ul className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accents-3 border-t border-accents-3">
|
<ul className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accents-3 border-t border-accents-3">
|
||||||
{data!.lineItems.map((item: any) => (
|
{data!.lineItems.map((item: any) => (
|
||||||
<CartItem
|
<CartItem
|
||||||
|
20
components/icons/CreditCard.tsx
Normal file
20
components/icons/CreditCard.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const CreditCard = ({ ...props }) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
fill="none"
|
||||||
|
shapeRendering="geometricPrecision"
|
||||||
|
>
|
||||||
|
<rect x="1" y="4" width="22" height="16" rx="2" ry="2" />
|
||||||
|
<path d="M1 10h22" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CreditCard
|
20
components/icons/MapPin.tsx
Normal file
20
components/icons/MapPin.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const MapPin = ({ ...props }) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
fill="none"
|
||||||
|
shapeRendering="geometricPrecision"
|
||||||
|
>
|
||||||
|
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0118 0z" />
|
||||||
|
<circle cx="12" cy="10" r="3" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MapPin
|
@ -14,3 +14,5 @@ export { default as RightArrow } from './RightArrow'
|
|||||||
export { default as Info } from './Info'
|
export { default as Info } from './Info'
|
||||||
export { default as ChevronUp } from './ChevronUp'
|
export { default as ChevronUp } from './ChevronUp'
|
||||||
export { default as Vercel } from './Vercel'
|
export { default as Vercel } from './Vercel'
|
||||||
|
export { default as MapPin } from './MapPin'
|
||||||
|
export { default as CreditCard } from './CreditCard'
|
||||||
|
@ -59,7 +59,12 @@ type Action =
|
|||||||
value: string
|
value: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type MODAL_VIEWS = 'SIGNUP_VIEW' | 'LOGIN_VIEW' | 'FORGOT_VIEW'
|
type MODAL_VIEWS =
|
||||||
|
| 'SIGNUP_VIEW'
|
||||||
|
| 'LOGIN_VIEW'
|
||||||
|
| 'FORGOT_VIEW'
|
||||||
|
| 'NEW_SHIPPING_ADDRESS'
|
||||||
|
| 'NEW_PAYMENT_METHOD'
|
||||||
type ToastText = string
|
type ToastText = string
|
||||||
|
|
||||||
export const UIContext = React.createContext<State | any>(initialState)
|
export const UIContext = React.createContext<State | any>(initialState)
|
||||||
|
@ -30,7 +30,8 @@ const WishlistButton: FC<Props> = ({
|
|||||||
const itemInWishlist = data?.items?.find(
|
const itemInWishlist = data?.items?.find(
|
||||||
// @ts-ignore Wishlist is not always enabled
|
// @ts-ignore Wishlist is not always enabled
|
||||||
(item) =>
|
(item) =>
|
||||||
item.product_id === productId && (item.variant_id as any) === variant.id
|
item.product_id === Number(productId) &&
|
||||||
|
(item.variant_id as any) === Number(variant.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleWishlistChange = async (e: any) => {
|
const handleWishlistChange = async (e: any) => {
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
import type { ItemBody as WishlistItemBody } from '../wishlist'
|
import type { ItemBody as WishlistItemBody } from '../wishlist'
|
||||||
import type { CartItemBody, OptionSelections } from '../../types'
|
import type { CartItemBody, OptionSelections } from '../../types'
|
||||||
|
|
||||||
|
type BCWishlistItemBody = {
|
||||||
|
product_id: number
|
||||||
|
variant_id: number
|
||||||
|
}
|
||||||
|
|
||||||
type BCCartItemBody = {
|
type BCCartItemBody = {
|
||||||
product_id: number
|
product_id: number
|
||||||
variant_id: number
|
variant_id: number
|
||||||
@ -8,9 +13,11 @@ type BCCartItemBody = {
|
|||||||
option_selections?: OptionSelections
|
option_selections?: OptionSelections
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parseWishlistItem = (item: WishlistItemBody) => ({
|
export const parseWishlistItem = (
|
||||||
product_id: item.productId,
|
item: WishlistItemBody
|
||||||
variant_id: item.variantId,
|
): BCWishlistItemBody => ({
|
||||||
|
product_id: Number(item.productId),
|
||||||
|
variant_id: Number(item.variantId),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const parseCartItem = (item: CartItemBody): BCCartItemBody => ({
|
export const parseCartItem = (item: CartItemBody): BCCartItemBody => ({
|
||||||
|
@ -68,14 +68,15 @@ async function getCustomerWishlist({
|
|||||||
const productsById = graphqlData.products.reduce<{
|
const productsById = graphqlData.products.reduce<{
|
||||||
[k: number]: ProductEdge
|
[k: number]: ProductEdge
|
||||||
}>((prods, p) => {
|
}>((prods, p) => {
|
||||||
prods[Number(p.node.entityId)] = p as any
|
prods[Number(p.id)] = p as any
|
||||||
return prods
|
return prods
|
||||||
}, {})
|
}, {})
|
||||||
// Populate the wishlist items with the graphql products
|
// Populate the wishlist items with the graphql products
|
||||||
wishlist.items.forEach((item) => {
|
wishlist.items.forEach((item) => {
|
||||||
const product = item && productsById[item.product_id!]
|
const product = item && productsById[item.product_id!]
|
||||||
if (item && product) {
|
if (item && product) {
|
||||||
item.product = product.node
|
// @ts-ignore Fix this type when the wishlist type is properly defined
|
||||||
|
item.product = product
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ export const handler: SWRHook<
|
|||||||
url: '/api/bigcommerce/wishlist',
|
url: '/api/bigcommerce/wishlist',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
},
|
},
|
||||||
fetcher({ input: { customerId, includeProducts }, options, fetch }) {
|
async fetcher({ input: { customerId, includeProducts }, options, fetch }) {
|
||||||
if (!customerId) return null
|
if (!customerId) return null
|
||||||
|
|
||||||
// Use a dummy base as we only care about the relative path
|
// Use a dummy base as we only care about the relative path
|
||||||
@ -35,7 +35,7 @@ export const handler: SWRHook<
|
|||||||
const { data: customer } = useCustomer()
|
const { data: customer } = useCustomer()
|
||||||
const response = useData({
|
const response = useData({
|
||||||
input: [
|
input: [
|
||||||
['customerId', (customer as any)?.id],
|
['customerId', customer?.entityId],
|
||||||
['includeProducts', input?.includeProducts],
|
['includeProducts', input?.includeProducts],
|
||||||
],
|
],
|
||||||
swrOptions: {
|
swrOptions: {
|
||||||
|
@ -8,7 +8,6 @@ import {
|
|||||||
} from '../const'
|
} from '../const'
|
||||||
|
|
||||||
if (!API_URL) {
|
if (!API_URL) {
|
||||||
console.log(process.env)
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store`
|
`The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store`
|
||||||
)
|
)
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
"analyze": "BUNDLE_ANALYZE=both yarn build",
|
"analyze": "BUNDLE_ANALYZE=both yarn build",
|
||||||
"prettier-fix": "prettier --write .",
|
"prettier-fix": "prettier --write .",
|
||||||
"find:unused": "next-unused",
|
"find:unused": "next-unused",
|
||||||
"commerce": "node scripts/commerce.js",
|
|
||||||
"generate": "graphql-codegen",
|
"generate": "graphql-codegen",
|
||||||
"generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js"
|
"generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js"
|
||||||
},
|
},
|
||||||
|
@ -5,7 +5,7 @@ import useCart from '@framework/cart/use-cart'
|
|||||||
import usePrice from '@framework/product/use-price'
|
import usePrice from '@framework/product/use-price'
|
||||||
import { Layout } from '@components/common'
|
import { Layout } from '@components/common'
|
||||||
import { Button, Text } from '@components/ui'
|
import { Button, Text } from '@components/ui'
|
||||||
import { Bag, Cross, Check } from '@components/icons'
|
import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons'
|
||||||
import { CartItem } from '@components/cart'
|
import { CartItem } from '@components/cart'
|
||||||
|
|
||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
@ -38,7 +38,7 @@ export default function Cart() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid lg:grid-cols-12">
|
<div className="grid lg:grid-cols-12 w-full max-w-7xl mx-auto">
|
||||||
<div className="lg:col-span-8">
|
<div className="lg:col-span-8">
|
||||||
{isLoading || isEmpty ? (
|
{isLoading || isEmpty ? (
|
||||||
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center ">
|
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center ">
|
||||||
@ -103,6 +103,35 @@ export default function Cart() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="lg:col-span-4">
|
<div className="lg:col-span-4">
|
||||||
<div className="flex-shrink-0 px-4 py-24 sm:px-6">
|
<div className="flex-shrink-0 px-4 py-24 sm:px-6">
|
||||||
|
{process.env.COMMERCE_CUSTOMCHECKOUT_ENABLED && (
|
||||||
|
<>
|
||||||
|
{/* Shipping Address */}
|
||||||
|
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
|
||||||
|
<div className="rounded-md border border-accents-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accents-4">
|
||||||
|
<div className="mr-5">
|
||||||
|
<MapPin />
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-center font-medium">
|
||||||
|
<span className="uppercase">+ Add Shipping Address</span>
|
||||||
|
{/* <span>
|
||||||
|
1046 Kearny Street.<br/>
|
||||||
|
San Franssisco, California
|
||||||
|
</span> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Payment Method */}
|
||||||
|
{/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */}
|
||||||
|
<div className="rounded-md border border-accents-2 px-6 py-6 mb-4 text-center flex items-center justify-center cursor-pointer hover:border-accents-4">
|
||||||
|
<div className="mr-5">
|
||||||
|
<CreditCard />
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-center font-medium">
|
||||||
|
<span className="uppercase">+ Add Payment Method</span>
|
||||||
|
{/* <span>VISA #### #### #### 2345</span> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div className="border-t border-accents-2">
|
<div className="border-t border-accents-2">
|
||||||
<ul className="py-3">
|
<ul className="py-3">
|
||||||
<li className="flex justify-between py-1">
|
<li className="flex justify-between py-1">
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import { useEffect } from 'react'
|
|
||||||
import { useRouter } from 'next/router'
|
|
||||||
import type { GetStaticPropsContext } from 'next'
|
import type { GetStaticPropsContext } from 'next'
|
||||||
|
|
||||||
import { Heart } from '@components/icons'
|
import { Heart } from '@components/icons'
|
||||||
import { Layout } from '@components/common'
|
import { Layout } from '@components/common'
|
||||||
import { Text, Container } from '@components/ui'
|
import { Text, Container } from '@components/ui'
|
||||||
@ -36,8 +33,7 @@ export async function getStaticProps({
|
|||||||
export default function Wishlist() {
|
export default function Wishlist() {
|
||||||
const { data: customer } = useCustomer()
|
const { data: customer } = useCustomer()
|
||||||
// @ts-ignore Shopify - Fix this types
|
// @ts-ignore Shopify - Fix this types
|
||||||
const { data, isLoading, isEmpty } = useWishlist()
|
const { data, isLoading, isEmpty } = useWishlist({ includeProducts: true })
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
@ -60,7 +56,7 @@ export default function Wishlist() {
|
|||||||
data &&
|
data &&
|
||||||
// @ts-ignore Shopify - Fix this types
|
// @ts-ignore Shopify - Fix this types
|
||||||
data.items?.map((item) => (
|
data.items?.map((item) => (
|
||||||
<WishlistCard key={item.id} product={item as any} />
|
<WishlistCard key={item.id} product={item.product! as any} />
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1 +0,0 @@
|
|||||||
console.log('Hello')
|
|
Loading…
x
Reference in New Issue
Block a user