mirror of
https://github.com/vercel/commerce.git
synced 2025-06-18 21:21:21 +00:00
feat: add useOrders hooks to fetch orders
fix: getProviderName return aquilacms if correct env are sets
This commit is contained in:
parent
0071b6fefc
commit
9df1475c66
@ -1,5 +1,4 @@
|
||||
{
|
||||
"provider": "aquilacms",
|
||||
"features": {
|
||||
"wishlist": false,
|
||||
"customCheckout": false
|
||||
|
35
framework/aquilacms/api/orders/handlers/get-orders.ts
Normal file
35
framework/aquilacms/api/orders/handlers/get-orders.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import type { OrdersHandlers } from '..'
|
||||
import { normalizeOrder } from '../../../lib/normalize'
|
||||
|
||||
const getOrders: OrdersHandlers['getOrders'] = async ({ req, res, config }) => {
|
||||
const token = req.cookies[config.customerCookie]
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const { datas } = await config.storeApiFetch('/v2/orders', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
lang: 'en',
|
||||
PostBody: {
|
||||
sort: { createdAt: -1 },
|
||||
populate: ['items.id'],
|
||||
limit: 6,
|
||||
page: 1,
|
||||
},
|
||||
}),
|
||||
headers: {
|
||||
authorization: token,
|
||||
},
|
||||
})
|
||||
return res
|
||||
.status(200)
|
||||
.json({ data: { orders: datas.map(normalizeOrder) } })
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
res.status(200).json({ data: null })
|
||||
}
|
||||
|
||||
export default getOrders
|
47
framework/aquilacms/api/orders/index.ts
Normal file
47
framework/aquilacms/api/orders/index.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import createApiHandler, {
|
||||
AquilacmsApiHandler,
|
||||
AquilacmsHandler,
|
||||
} from '../utils/create-api-handler'
|
||||
import isAllowedMethod from '../utils/is-allowed-method'
|
||||
import { AquilacmsApiError } from '../utils/errors'
|
||||
import getOrders from './handlers/get-orders'
|
||||
import { Order } from '../../types'
|
||||
|
||||
export type { Order }
|
||||
|
||||
export type OrdersData = {
|
||||
orders: Order[]
|
||||
}
|
||||
|
||||
export type OrdersHandlers = {
|
||||
getOrders: AquilacmsHandler<OrdersData>
|
||||
}
|
||||
|
||||
const METHODS = ['POST']
|
||||
|
||||
const ordersApi: AquilacmsApiHandler<OrdersData, OrdersHandlers> = async (
|
||||
req,
|
||||
res,
|
||||
config,
|
||||
handlers
|
||||
) => {
|
||||
if (!isAllowedMethod(req, res, METHODS)) return
|
||||
|
||||
try {
|
||||
const body = null
|
||||
return await handlers['getOrders']({ req, res, config, body })
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
const message =
|
||||
error instanceof AquilacmsApiError
|
||||
? 'An unexpected error ocurred with the Aquilacms API'
|
||||
: 'An unexpected error ocurred'
|
||||
|
||||
res.status(500).json({ data: null, errors: [{ message }] })
|
||||
}
|
||||
}
|
||||
|
||||
const handlers = { getOrders }
|
||||
|
||||
export default createApiHandler(ordersApi, handlers, {})
|
@ -17,8 +17,7 @@ export const handler: SWRHook<
|
||||
method: 'GET',
|
||||
},
|
||||
async fetcher({ input: { cartId }, options, fetch }) {
|
||||
const data = cartId ? await fetch(options) : null
|
||||
return data // && normalizeCart(data)
|
||||
return cartId ? await fetch(options) : null
|
||||
},
|
||||
useHook: ({ useData }) => (input) => {
|
||||
const response = useData({
|
||||
|
@ -1,5 +1,4 @@
|
||||
import type { Product, ProductOption } from '@commerce/types'
|
||||
import { getConfig } from '../api'
|
||||
import type {
|
||||
Cart,
|
||||
AquilacmsCart,
|
||||
@ -10,6 +9,8 @@ import type {
|
||||
AquilacmsUser,
|
||||
User,
|
||||
AquilacmsProductAttribute,
|
||||
AquilacmsOrder,
|
||||
Order,
|
||||
} from '../types'
|
||||
|
||||
function normalizeProductOption(
|
||||
@ -139,3 +140,17 @@ export function normalizeUser(data: AquilacmsUser): User {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeOrder(data: AquilacmsOrder): Order {
|
||||
return {
|
||||
id: data._id,
|
||||
code: data.number,
|
||||
status: data.status,
|
||||
price: {
|
||||
value: data.priceTotal.ati,
|
||||
currency: 'EUR',
|
||||
},
|
||||
items: [],
|
||||
createdAt: data.created_at,
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
import { AquilacmsConfig } from '..'
|
||||
import { getConfig } from '../api'
|
||||
|
||||
async function getAllOrders({
|
||||
config,
|
||||
}: {
|
||||
config?: AquilacmsConfig
|
||||
}): Promise<{ orders: any[] }> {
|
||||
config = getConfig(config)
|
||||
const data: any = []
|
||||
return { orders: data }
|
||||
}
|
||||
|
||||
export default getAllOrders
|
1
framework/aquilacms/orders/index.ts
Normal file
1
framework/aquilacms/orders/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as useOrders } from './use-orders'
|
39
framework/aquilacms/orders/use-orders.tsx
Normal file
39
framework/aquilacms/orders/use-orders.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import { HookFetcherFn, SWRHook } from '@commerce/utils/types'
|
||||
import type { Order, OrdersData } from '../api/orders'
|
||||
import { useHook, useSWRHook } from '@commerce/utils/use-hook'
|
||||
import SWRFetcher from '@commerce/utils/default-fetcher'
|
||||
import { Provider } from '../../commerce'
|
||||
|
||||
type UseOrders<
|
||||
H extends SWRHook<any, any, any> = SWRHook<Order[] | null>
|
||||
> = ReturnType<H['useHook']>
|
||||
|
||||
const fetcher: HookFetcherFn<Order[] | null, any> = SWRFetcher
|
||||
|
||||
const fn = (provider: Provider) => provider.orders?.useOrders!
|
||||
|
||||
const useOrders: UseOrders = (input) => {
|
||||
const hook = useHook(fn)
|
||||
return useSWRHook({ fetcher, ...hook } as any)(input)
|
||||
}
|
||||
|
||||
export default useOrders as UseOrders<typeof handler>
|
||||
|
||||
export const handler: SWRHook<Order[] | null> = {
|
||||
fetchOptions: {
|
||||
url: '/api/bigcommerce/orders',
|
||||
method: 'POST',
|
||||
},
|
||||
async fetcher({ options, fetch }) {
|
||||
const data = await fetch<OrdersData | null>(options)
|
||||
return data?.orders ?? null
|
||||
},
|
||||
useHook: ({ useData }) => (input) => {
|
||||
return useData({
|
||||
swrOptions: {
|
||||
revalidateOnFocus: false,
|
||||
...input?.swrOptions,
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
@ -10,6 +10,8 @@ import { handler as useLogin } from './auth/use-login'
|
||||
import { handler as useLogout } from './auth/use-logout'
|
||||
import { handler as useSignup } from './auth/use-signup'
|
||||
|
||||
import { handler as useOrders } from './orders/use-orders'
|
||||
|
||||
import fetcher from './fetcher'
|
||||
import { Provider } from '../commerce'
|
||||
|
||||
@ -21,6 +23,7 @@ export const aquilacmsProvider = {
|
||||
customer: { useCustomer },
|
||||
products: { useSearch },
|
||||
auth: { useLogin, useLogout, useSignup },
|
||||
orders: { useOrders },
|
||||
} as Provider
|
||||
|
||||
export type AquilacmsProvider = typeof aquilacmsProvider
|
||||
|
@ -392,6 +392,8 @@ export type RemoveCartItemBody = Core.RemoveCartItemBody
|
||||
|
||||
export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody
|
||||
|
||||
export type Order = Core.Order
|
||||
|
||||
export type User = {
|
||||
entityId: string
|
||||
firstName: string
|
||||
@ -434,3 +436,19 @@ export type AquilacmsStatic = {
|
||||
}
|
||||
name: string
|
||||
}
|
||||
|
||||
export type AquilacmsCartItem = {}
|
||||
|
||||
export type AquilacmsOrder = {
|
||||
_id: string
|
||||
items: AquilacmsCartItem[]
|
||||
number: string
|
||||
priceTotal: {
|
||||
ati: number
|
||||
et: number
|
||||
paidTax: number
|
||||
}
|
||||
status: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
@ -7,17 +7,14 @@ const fs = require('fs')
|
||||
const merge = require('deepmerge')
|
||||
const prettier = require('prettier')
|
||||
|
||||
const PROVIDERS = ['bigcommerce', 'shopify']
|
||||
const PROVIDERS = ['bigcommerce', 'shopify', 'aquilacms']
|
||||
|
||||
function getProviderName() {
|
||||
return (
|
||||
process.env.COMMERCE_PROVIDER ||
|
||||
(process.env.BIGCOMMERCE_STOREFRONT_API_URL
|
||||
? 'bigcommerce'
|
||||
: process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN
|
||||
? 'shopify'
|
||||
: null)
|
||||
)
|
||||
if (process.env.COMMERCE_PROVIDER) return process.env.COMMERCE_PROVIDER
|
||||
else if (process.env.BIGCOMMERCE_STOREFRONT_API_URL) return 'bigcommerce'
|
||||
else if (process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN) return 'shopify'
|
||||
else if (process.env.AQUILACMS_URL) return 'aquilacms'
|
||||
else return null
|
||||
}
|
||||
|
||||
function withCommerceConfig(nextConfig = {}) {
|
||||
|
@ -8,7 +8,13 @@ import {
|
||||
} from 'react'
|
||||
import { Fetcher, SWRHook, MutationHook } from './utils/types'
|
||||
import type { FetchCartInput } from './cart/use-cart'
|
||||
import type { Cart, Wishlist, Customer, SearchProductsData } from './types'
|
||||
import type {
|
||||
Cart,
|
||||
Wishlist,
|
||||
Customer,
|
||||
SearchProductsData,
|
||||
Order,
|
||||
} from './types'
|
||||
|
||||
const Commerce = createContext<CommerceContextValue<any> | {}>({})
|
||||
|
||||
@ -36,6 +42,9 @@ export type Provider = CommerceConfig & {
|
||||
useLogin?: MutationHook<any, any, any>
|
||||
useLogout?: MutationHook<any, any, any>
|
||||
}
|
||||
orders?: {
|
||||
useOrders?: SWRHook<Order[] | null, any, any>
|
||||
}
|
||||
}
|
||||
|
||||
export type CommerceProps<P extends Provider> = {
|
||||
|
@ -151,6 +151,20 @@ export type RemoveCartItemHandlerBody = Partial<RemoveCartItemBody> & {
|
||||
cartId?: string
|
||||
}
|
||||
|
||||
export type OrderItem = {}
|
||||
|
||||
export type Order = {
|
||||
id: string
|
||||
items: OrderItem[]
|
||||
code: string
|
||||
price: {
|
||||
value: number
|
||||
currency: string
|
||||
}
|
||||
status: string
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporal types
|
||||
*/
|
||||
|
3
pages/api/bigcommerce/orders/index.ts
Normal file
3
pages/api/bigcommerce/orders/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import ordersApi from '@framework/api/orders'
|
||||
|
||||
export default ordersApi()
|
@ -1,9 +1,10 @@
|
||||
import type { GetStaticPropsContext } from 'next'
|
||||
import { Bag } from '@components/icons'
|
||||
import { Layout } from '@components/common'
|
||||
import { Container, Text } from '@components/ui'
|
||||
import { Button, Container, Text } from '@components/ui'
|
||||
import { getConfig } from '@framework/api'
|
||||
import getAllPages from '@framework/common/get-all-pages'
|
||||
import { useOrders } from '../framework/aquilacms/orders'
|
||||
|
||||
export async function getStaticProps({
|
||||
preview,
|
||||
@ -17,10 +18,35 @@ export async function getStaticProps({
|
||||
}
|
||||
|
||||
export default function Orders() {
|
||||
const { data: orders } = useOrders()
|
||||
return (
|
||||
<Container>
|
||||
<Text variant="pageHeading">My Orders</Text>
|
||||
<div className="flex-1 p-24 flex flex-col justify-center items-center ">
|
||||
{orders?.length && (
|
||||
<div className="flex flex-col">
|
||||
{orders?.map((o) => (
|
||||
<div className="flex p-5">
|
||||
<div className="flex-1 justify-center items-center">{o.code}</div>
|
||||
<div className="flex-1 justify-center items-center">
|
||||
{o.createdAt}
|
||||
</div>
|
||||
<div className="flex-1 justify-center items-center">
|
||||
{o.price.currency} {o.price.value}
|
||||
</div>
|
||||
<Button
|
||||
Component="a"
|
||||
className="flex-1 justify-center items-center"
|
||||
onClick={() => alert(o.id)}
|
||||
>
|
||||
View Details
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1 p-24 flex flex-col justify-center items-center">
|
||||
{!orders?.length && (
|
||||
<>
|
||||
<span className="border border-dashed border-secondary rounded-full flex items-center justify-center w-16 h-16 p-12 bg-primary text-primary">
|
||||
<Bag className="absolute" />
|
||||
</span>
|
||||
@ -30,6 +56,8 @@ export default function Orders() {
|
||||
<p className="text-accents-6 px-10 text-center pt-2">
|
||||
Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user