chore: merge new commerce changes, comment and run project!

This commit is contained in:
Reza Babaei
2021-09-26 18:00:29 +03:00
parent 4fad1ff956
commit 30de7190eb
14 changed files with 450 additions and 47 deletions

View File

@@ -1,7 +1,7 @@
import { FC } from 'react' import { FC } from 'react'
import cn from 'classnames' import cn from 'classnames'
import useAddCard from '@framework/customer/card/use-add-item' // import useAddCard from '@framework/customer/card/use-add-item'
import { Button, Text } from '@components/ui' import { Button, Text } from '@components/ui'
import { useUI } from '@components/ui/context' import { useUI } from '@components/ui/context'
import SidebarLayout from '@components/common/SidebarLayout' import SidebarLayout from '@components/common/SidebarLayout'
@@ -24,24 +24,24 @@ interface Form extends HTMLFormElement {
const PaymentMethodView: FC = () => { const PaymentMethodView: FC = () => {
const { setSidebarView } = useUI() const { setSidebarView } = useUI()
const addCard = useAddCard() // const addCard = useAddCard()
async function handleSubmit(event: React.ChangeEvent<Form>) { async function handleSubmit(event: React.ChangeEvent<Form>) {
event.preventDefault() event.preventDefault()
await addCard({ // await addCard({
cardHolder: event.target.cardHolder.value, // cardHolder: event.target.cardHolder.value,
cardNumber: event.target.cardNumber.value, // cardNumber: event.target.cardNumber.value,
cardExpireDate: event.target.cardExpireDate.value, // cardExpireDate: event.target.cardExpireDate.value,
cardCvc: event.target.cardCvc.value, // cardCvc: event.target.cardCvc.value,
firstName: event.target.firstName.value, // firstName: event.target.firstName.value,
lastName: event.target.lastName.value, // lastName: event.target.lastName.value,
company: event.target.company.value, // company: event.target.company.value,
streetNumber: event.target.streetNumber.value, // streetNumber: event.target.streetNumber.value,
zipCode: event.target.zipCode.value, // zipCode: event.target.zipCode.value,
city: event.target.city.value, // city: event.target.city.value,
country: event.target.country.value, // country: event.target.country.value,
}) // })
setSidebarView('CHECKOUT_VIEW') setSidebarView('CHECKOUT_VIEW')
} }
@@ -49,14 +49,14 @@ const PaymentMethodView: FC = () => {
return ( return (
<form className="h-full" onSubmit={handleSubmit}> <form className="h-full" onSubmit={handleSubmit}>
<SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}> <SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}>
<div className="px-4 sm:px-6 flex-1"> <div className="flex-1 px-4 sm:px-6">
<Text variant="sectionHeading"> Payment Method</Text> <Text variant="sectionHeading"> Payment Method</Text>
<div> <div>
<div className={s.fieldset}> <div className={s.fieldset}>
<label className={s.label}>Cardholder Name</label> <label className={s.label}>Cardholder Name</label>
<input name="cardHolder" className={s.input} /> <input name="cardHolder" className={s.input} />
</div> </div>
<div className="grid gap-3 grid-flow-row grid-cols-12"> <div className="grid grid-flow-row grid-cols-12 gap-3">
<div className={cn(s.fieldset, 'col-span-7')}> <div className={cn(s.fieldset, 'col-span-7')}>
<label className={s.label}>Card Number</label> <label className={s.label}>Card Number</label>
<input name="cardNumber" className={s.input} /> <input name="cardNumber" className={s.input} />
@@ -74,8 +74,8 @@ const PaymentMethodView: FC = () => {
<input name="cardCvc" className={s.input} /> <input name="cardCvc" className={s.input} />
</div> </div>
</div> </div>
<hr className="border-accent-2 my-6" /> <hr className="my-6 border-accent-2" />
<div className="grid gap-3 grid-flow-row grid-cols-12"> <div className="grid grid-flow-row grid-cols-12 gap-3">
<div className={cn(s.fieldset, 'col-span-6')}> <div className={cn(s.fieldset, 'col-span-6')}>
<label className={s.label}>First Name</label> <label className={s.label}>First Name</label>
<input name="firstName" className={s.input} /> <input name="firstName" className={s.input} />
@@ -99,7 +99,7 @@ const PaymentMethodView: FC = () => {
</label> </label>
<input className={s.input} name="apartment" /> <input className={s.input} name="apartment" />
</div> </div>
<div className="grid gap-3 grid-flow-row grid-cols-12"> <div className="grid grid-flow-row grid-cols-12 gap-3">
<div className={cn(s.fieldset, 'col-span-6')}> <div className={cn(s.fieldset, 'col-span-6')}>
<label className={s.label}>Postal Code</label> <label className={s.label}>Postal Code</label>
<input name="zipCode" className={s.input} /> <input name="zipCode" className={s.input} />
@@ -117,7 +117,7 @@ const PaymentMethodView: FC = () => {
</div> </div>
</div> </div>
</div> </div>
<div className="sticky z-20 bottom-0 w-full right-0 left-0 py-12 bg-accent-0 border-t border-accent-2 px-6"> <div className="sticky bottom-0 left-0 right-0 z-20 w-full px-6 py-12 border-t bg-accent-0 border-accent-2">
<Button type="submit" width="100%" variant="ghost"> <Button type="submit" width="100%" variant="ghost">
Continue Continue
</Button> </Button>

View File

@@ -4,7 +4,7 @@ import cn from 'classnames'
import Button from '@components/ui/Button' import Button from '@components/ui/Button'
import { useUI } from '@components/ui/context' import { useUI } from '@components/ui/context'
import SidebarLayout from '@components/common/SidebarLayout' import SidebarLayout from '@components/common/SidebarLayout'
import useAddAddress from '@framework/customer/address/use-add-item' // import useAddAddress from '@framework/customer/address/use-add-item'
import s from './ShippingView.module.css' import s from './ShippingView.module.css'
@@ -24,22 +24,22 @@ interface Form extends HTMLFormElement {
const PaymentMethodView: FC = () => { const PaymentMethodView: FC = () => {
const { setSidebarView } = useUI() const { setSidebarView } = useUI()
const addAddress = useAddAddress() // const addAddress = useAddAddress()
async function handleSubmit(event: React.ChangeEvent<Form>) { async function handleSubmit(event: React.ChangeEvent<Form>) {
event.preventDefault() event.preventDefault()
await addAddress({ // await addAddress({
type: event.target.type.value, // type: event.target.type.value,
firstName: event.target.firstName.value, // firstName: event.target.firstName.value,
lastName: event.target.lastName.value, // lastName: event.target.lastName.value,
company: event.target.company.value, // company: event.target.company.value,
streetNumber: event.target.streetNumber.value, // streetNumber: event.target.streetNumber.value,
apartments: event.target.streetNumber.value, // apartments: event.target.streetNumber.value,
zipCode: event.target.zipCode.value, // zipCode: event.target.zipCode.value,
city: event.target.city.value, // city: event.target.city.value,
country: event.target.country.value, // country: event.target.country.value,
}) // })
setSidebarView('CHECKOUT_VIEW') setSidebarView('CHECKOUT_VIEW')
} }
@@ -47,23 +47,23 @@ const PaymentMethodView: FC = () => {
return ( return (
<form className="h-full" onSubmit={handleSubmit}> <form className="h-full" onSubmit={handleSubmit}>
<SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}> <SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}>
<div className="px-4 sm:px-6 flex-1"> <div className="flex-1 px-4 sm:px-6">
<h2 className="pt-1 pb-8 text-2xl font-semibold tracking-wide cursor-pointer inline-block"> <h2 className="inline-block pt-1 pb-8 text-2xl font-semibold tracking-wide cursor-pointer">
Shipping Shipping
</h2> </h2>
<div> <div>
<div className="flex flex-row my-3 items-center"> <div className="flex flex-row items-center my-3">
<input name="type" className={s.radio} type="radio" /> <input name="type" className={s.radio} type="radio" />
<span className="ml-3 text-sm">Same as billing address</span> <span className="ml-3 text-sm">Same as billing address</span>
</div> </div>
<div className="flex flex-row my-3 items-center"> <div className="flex flex-row items-center my-3">
<input name="type" className={s.radio} type="radio" /> <input name="type" className={s.radio} type="radio" />
<span className="ml-3 text-sm"> <span className="ml-3 text-sm">
Use a different shipping address Use a different shipping address
</span> </span>
</div> </div>
<hr className="border-accent-2 my-6" /> <hr className="my-6 border-accent-2" />
<div className="grid gap-3 grid-flow-row grid-cols-12"> <div className="grid grid-flow-row grid-cols-12 gap-3">
<div className={cn(s.fieldset, 'col-span-6')}> <div className={cn(s.fieldset, 'col-span-6')}>
<label className={s.label}>First Name</label> <label className={s.label}>First Name</label>
<input name="firstName" className={s.input} /> <input name="firstName" className={s.input} />
@@ -87,7 +87,7 @@ const PaymentMethodView: FC = () => {
</label> </label>
<input name="apartments" className={s.input} /> <input name="apartments" className={s.input} />
</div> </div>
<div className="grid gap-3 grid-flow-row grid-cols-12"> <div className="grid grid-flow-row grid-cols-12 gap-3">
<div className={cn(s.fieldset, 'col-span-6')}> <div className={cn(s.fieldset, 'col-span-6')}>
<label className={s.label}>Postal Code</label> <label className={s.label}>Postal Code</label>
<input name="zipCode" className={s.input} /> <input name="zipCode" className={s.input} />
@@ -105,7 +105,7 @@ const PaymentMethodView: FC = () => {
</div> </div>
</div> </div>
</div> </div>
<div className="sticky z-20 bottom-0 w-full right-0 left-0 py-12 bg-accent-0 border-t border-accent-2 px-6"> <div className="sticky bottom-0 left-0 right-0 z-20 w-full px-6 py-12 border-t bg-accent-0 border-accent-2">
<Button type="submit" width="100%" variant="ghost"> <Button type="submit" width="100%" variant="ghost">
Continue Continue
</Button> </Button>

View File

@@ -0,0 +1,21 @@
// import type { HookFetcherFn, MutationHook } from '../../utils/types'
// import type { AddItemHook } from '../../types/customer/address'
// import type { WooCommerceProvider } from '../..'
// import { useHook, useMutationHook } from '../../utils/use-hook'
// import { mutationFetcher } from '../../utils/default-fetcher'
// export type UseAddItem<
// H extends MutationHook<AddItemHook<any>> = MutationHook<AddItemHook>
// > = ReturnType<H['useHook']>
// export const fetcher: HookFetcherFn<AddItemHook> = mutationFetcher
// const fn = (provider: WooCommerceProvider) => provider.customer?.address?.useAddItem!
// const useAddItem: UseAddItem = (...args) => {
// const hook = useHook(fn)
// return useMutationHook({ fetcher, ...hook })(...args)
// }
// export default useAddItem

View File

@@ -0,0 +1,34 @@
import type { SWRHook, HookFetcherFn } from '../../utils/types'
import type { GetAddressesHook } from '../../types/customer/address'
import Cookies from 'js-cookie'
import { useHook, useSWRHook } from '../../utils/use-hook'
import { Provider, useCommerce } from '../..'
export type UseAddresses<
H extends SWRHook<GetAddressesHook<any>> = SWRHook<GetAddressesHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<GetAddressesHook> = async ({
options,
input: { cartId },
fetch,
}) => {
return cartId ? await fetch(options) : null
}
const fn = (provider: Provider) => provider.customer?.address?.useAddresses!
const useAddresses: UseAddresses = (input) => {
const hook = useHook(fn)
const { cartCookie } = useCommerce()
const fetcherFn = hook.fetcher ?? fetcher
const wrapper: typeof fetcher = (context) => {
context.input.cartId = Cookies.get(cartCookie)
return fetcherFn(context)
}
return useSWRHook({ ...hook, fetcher: wrapper })(input)
}
export default useAddresses

View File

@@ -0,0 +1,21 @@
import type { HookFetcherFn, MutationHook } from '../../utils/types'
import type { RemoveItemHook } from '../../types/customer/address'
import type { Provider } from '../..'
import { useHook, useMutationHook } from '../../utils/use-hook'
import { mutationFetcher } from '../../utils/default-fetcher'
export type UseRemoveItem<
H extends MutationHook<RemoveItemHook<any>> = MutationHook<RemoveItemHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
const fn = (provider: Provider) => provider.customer?.address?.useRemoveItem!
const useRemoveItem: UseRemoveItem = (input) => {
const hook = useHook(fn)
return useMutationHook({ fetcher, ...hook })(input)
}
export default useRemoveItem

View File

@@ -0,0 +1,21 @@
import type { HookFetcherFn, MutationHook } from '../../utils/types'
import type { UpdateItemHook } from '../../types/customer/address'
import type { Provider } from '../..'
import { useHook, useMutationHook } from '../../utils/use-hook'
import { mutationFetcher } from '../../utils/default-fetcher'
export type UseUpdateItem<
H extends MutationHook<UpdateItemHook<any>> = MutationHook<UpdateItemHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<UpdateItemHook> = mutationFetcher
const fn = (provider: Provider) => provider.customer?.address?.useUpdateItem!
const useUpdateItem: UseUpdateItem = (input) => {
const hook = useHook(fn)
return useMutationHook({ fetcher, ...hook })(input)
}
export default useUpdateItem

View File

@@ -0,0 +1,21 @@
import type { HookFetcherFn, MutationHook } from '../../utils/types'
import type { AddItemHook } from '../../types/customer/card'
import type { Provider } from '../..'
import { useHook, useMutationHook } from '../../utils/use-hook'
import { mutationFetcher } from '../../utils/default-fetcher'
export type UseAddItem<
H extends MutationHook<AddItemHook<any>> = MutationHook<AddItemHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<AddItemHook> = mutationFetcher
const fn = (provider: Provider) => provider.customer?.card?.useAddItem!
const useAddItem: UseAddItem = (...args) => {
const hook = useHook(fn)
return useMutationHook({ fetcher, ...hook })(...args)
}
export default useAddItem

View File

@@ -0,0 +1,34 @@
import type { SWRHook, HookFetcherFn } from '../../utils/types'
import type { GetCardsHook } from '../../types/customer/card'
import Cookies from 'js-cookie'
import { useHook, useSWRHook } from '../../utils/use-hook'
import { Provider, useCommerce } from '../..'
export type UseCards<
H extends SWRHook<GetCardsHook<any>> = SWRHook<GetCardsHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<GetCardsHook> = async ({
options,
input: { cartId },
fetch,
}) => {
return cartId ? await fetch(options) : null
}
const fn = (provider: Provider) => provider.customer?.card?.useCards!
const useCards: UseCards = (input) => {
const hook = useHook(fn)
const { cartCookie } = useCommerce()
const fetcherFn = hook.fetcher ?? fetcher
const wrapper: typeof fetcher = (context) => {
context.input.cartId = Cookies.get(cartCookie)
return fetcherFn(context)
}
return useSWRHook({ ...hook, fetcher: wrapper })(input)
}
export default useCards

View File

@@ -0,0 +1,21 @@
import type { HookFetcherFn, MutationHook } from '../../utils/types'
import type { RemoveItemHook } from '../../types/customer/card'
import type { Provider } from '../..'
import { useHook, useMutationHook } from '../../utils/use-hook'
import { mutationFetcher } from '../../utils/default-fetcher'
export type UseRemoveItem<
H extends MutationHook<RemoveItemHook<any>> = MutationHook<RemoveItemHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
const fn = (provider: Provider) => provider.customer?.card?.useRemoveItem!
const useRemoveItem: UseRemoveItem = (input) => {
const hook = useHook(fn)
return useMutationHook({ fetcher, ...hook })(input)
}
export default useRemoveItem

View File

@@ -0,0 +1,21 @@
import type { HookFetcherFn, MutationHook } from '../../utils/types'
import type { UpdateItemHook } from '../../types/customer/card'
import type { Provider } from '../..'
import { useHook, useMutationHook } from '../../utils/use-hook'
import { mutationFetcher } from '../../utils/default-fetcher'
export type UseUpdateItem<
H extends MutationHook<UpdateItemHook<any>> = MutationHook<UpdateItemHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<UpdateItemHook> = mutationFetcher
const fn = (provider: Provider) => provider?.customer?.card?.useUpdateItem!
const useUpdateItem: UseUpdateItem = (input) => {
const hook = useHook(fn)
return useMutationHook({ fetcher, ...hook })(input)
}
export default useUpdateItem

View File

@@ -1,5 +0,0 @@
import * as Core from '@commerce/types/customer'
export * from '@commerce/types/customer'
export type CustomerSchema = Core.CustomerSchema

View File

@@ -0,0 +1,93 @@
export interface Address {
id: string;
mask: string;
}
export interface AddressFields {
type: string;
firstName: string;
lastName: string;
company: string;
streetNumber: string;
apartments: string;
zipCode: string;
city: string;
country: string;
}
export type CustomerAddressTypes = {
address?: Address;
fields: AddressFields;
}
export type GetAddressesHook<T extends CustomerAddressTypes = CustomerAddressTypes> = {
data: T['address'] | null
input: {}
fetcherInput: { cartId?: string }
swrState: { isEmpty: boolean }
}
export type AddItemHook<T extends CustomerAddressTypes = CustomerAddressTypes> = {
data: T['address']
input?: T['fields']
fetcherInput: T['fields']
body: { item: T['fields'] }
actionInput: T['fields']
}
export type UpdateItemHook<T extends CustomerAddressTypes = CustomerAddressTypes> = {
data: T['address'] | null
input: { item?: T['fields']; wait?: number }
fetcherInput: { itemId: string; item: T['fields'] }
body: { itemId: string; item: T['fields'] }
actionInput: T['fields'] & { id: string }
}
export type RemoveItemHook<T extends CustomerAddressTypes = CustomerAddressTypes> = {
data: T['address'] | null
input: { item?: T['fields'] }
fetcherInput: { itemId: string }
body: { itemId: string }
actionInput: { id: string }
}
export type CustomerAddressHooks<T extends CustomerAddressTypes = CustomerAddressTypes> = {
getAddresses: GetAddressesHook<T>
addItem: AddItemHook<T>
updateItem: UpdateItemHook<T>
removeItem: RemoveItemHook<T>
}
export type AddresssHandler<T extends CustomerAddressTypes = CustomerAddressTypes> = GetAddressesHook<T> & {
body: { cartId?: string }
}
export type AddItemHandler<T extends CustomerAddressTypes = CustomerAddressTypes> = AddItemHook<T> & {
body: { cartId: string }
}
export type UpdateItemHandler<T extends CustomerAddressTypes = CustomerAddressTypes> =
UpdateItemHook<T> & {
data: T['address']
body: { cartId: string }
}
export type RemoveItemHandler<T extends CustomerAddressTypes = CustomerAddressTypes> =
RemoveItemHook<T> & {
body: { cartId: string }
}
export type CustomerAddressHandlers<T extends CustomerAddressTypes = CustomerAddressTypes> = {
getAddresses: GetAddressesHook<T>
addItem: AddItemHandler<T>
updateItem: UpdateItemHandler<T>
removeItem: RemoveItemHandler<T>
}
export type CustomerAddressSchema<T extends CustomerAddressTypes = CustomerAddressTypes> = {
endpoint: {
options: {}
handlers: CustomerAddressHandlers<T>
}
}

View File

@@ -0,0 +1,96 @@
export interface Card {
id: string;
mask: string;
provider: string;
}
export interface CardFields {
cardHolder: string;
cardNumber: string;
cardExpireDate: string;
cardCvc: string;
firstName: string;
lastName: string;
company: string;
streetNumber: string;
zipCode: string;
city: string;
country: string;
}
export type CustomerCardTypes = {
card?: Card;
fields: CardFields;
}
export type GetCardsHook<T extends CustomerCardTypes = CustomerCardTypes> = {
data: T['card'] | null
input: {}
fetcherInput: { cartId?: string }
swrState: { isEmpty: boolean }
}
export type AddItemHook<T extends CustomerCardTypes = CustomerCardTypes> = {
data: T['card']
input?: T['fields']
fetcherInput: T['fields']
body: { item: T['fields'] }
actionInput: T['fields']
}
export type UpdateItemHook<T extends CustomerCardTypes = CustomerCardTypes> = {
data: T['card'] | null
input: { item?: T['fields']; wait?: number }
fetcherInput: { itemId: string; item: T['fields'] }
body: { itemId: string; item: T['fields'] }
actionInput: T['fields'] & { id: string }
}
export type RemoveItemHook<T extends CustomerCardTypes = CustomerCardTypes> = {
data: T['card'] | null
input: { item?: T['fields'] }
fetcherInput: { itemId: string }
body: { itemId: string }
actionInput: { id: string }
}
export type CustomerCardHooks<T extends CustomerCardTypes = CustomerCardTypes> = {
getCards: GetCardsHook<T>
addItem: AddItemHook<T>
updateItem: UpdateItemHook<T>
removeItem: RemoveItemHook<T>
}
export type CardsHandler<T extends CustomerCardTypes = CustomerCardTypes> = GetCardsHook<T> & {
body: { cartId?: string }
}
export type AddItemHandler<T extends CustomerCardTypes = CustomerCardTypes> = AddItemHook<T> & {
body: { cartId: string }
}
export type UpdateItemHandler<T extends CustomerCardTypes = CustomerCardTypes> =
UpdateItemHook<T> & {
data: T['card']
body: { cartId: string }
}
export type RemoveItemHandler<T extends CustomerCardTypes = CustomerCardTypes> =
RemoveItemHook<T> & {
body: { cartId: string }
}
export type CustomerCardHandlers<T extends CustomerCardTypes = CustomerCardTypes> = {
getCards: GetCardsHook<T>
addItem: AddItemHandler<T>
updateItem: UpdateItemHandler<T>
removeItem: RemoveItemHandler<T>
}
export type CustomerCardSchema<T extends CustomerCardTypes = CustomerCardTypes> = {
endpoint: {
options: {}
handlers: CustomerCardHandlers<T>
}
}

View File

@@ -0,0 +1,25 @@
export * as Card from "./card"
export * as Address from "./address"
// TODO: define this type
export type Customer = any
export type CustomerTypes = {
customer: Customer
}
export type CustomerHook<T extends CustomerTypes = CustomerTypes> = {
data: T['customer'] | null
fetchData: { customer: T['customer'] } | null
}
export type CustomerSchema<T extends CustomerTypes = CustomerTypes> = {
endpoint: {
options: {}
handlers: {
getLoggedInCustomer: {
data: { customer: T['customer'] } | null
}
}
}
}