You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
3.1 KiB
JavaScript

import React, {useReducer} from 'react'
import Router from 'next/router'
import axios from 'axios'
import ActionBar from '~/components/admin/actionBar'
import Table from '~/components/table'
import {Button} from '~/components/form'
ManualOrder.getInitialProps = async ({ctx}) => {
const {data: items} = await ctx.axios.get('/api/items?showUnpublished=true')
return {items}
}
export default function ManualOrder({items}) {
const [itemState, dispatch] = useReducer(itemCountReducer, {})
const totalNumber = Object.values(itemState).reduce((a,b) => (b+a), 0)
const add = (item) => () => dispatch({type: 'add', item: item.uuid})
const subtract = (item) => () => dispatch({type: 'subtract', item: item.uuid})
const remove = (item) => () => dispatch({type: 'remove', item: item.uuid})
const clear = () => dispatch({type: 'clear'})
async function createOrder(){
const items = Object.keys(itemState)
.map(uuid => ({ uuid, count: itemState[uuid] }))
const {data: order} = await axios.put(`/api/orders/manual`, {items})
Router.push(`/admin/orders/new/${order.uuid}/address`)
}
return (
<>
<ActionBar title="New Order" actions={[
{label: 'Cancel', url: `/admin/orders`}
]}/>
<Table
columns={[
{name: 'Name', extractor: item => item.name},
{name: 'Price', extractor: item => `$${(item.price_cents / 100).toFixed(2)}`},
{name: 'Number in stock', extractor: item => item.number_in_stock},
{name: 'Number in order', extractor: item => (
<span style={{display: 'flex', flexDirection: 'row', width: 120, justifyContent: 'space-between', alignItems: 'center'}}>
<Button enabled={itemState[item.uuid] > 0} style={{width: 30}} onClick={subtract(item)}>-</Button>
{itemState[item.uuid] || 0}
<Button enabled={(itemState[item.uuid] || 0) < item.number_in_stock} style={{width: 30}} onClick={add(item)}>+</Button>
</span>
)},
{name: 'Actions', extractor: item => (
<span>
<button className="buttonLink" onClick={remove(item)}>Remove all</button>
</span>
)}
]}
// Map in an id property so the table can use array.map
rows={items.map(item => ({id: item.uuid, ...item}))}
/>
<p style={{textAlign: 'center'}}>
<button className="buttonLink" onClick={clear}>Reset order</button>
</p>
<p style={{maxWidth: 400, margin: '0 auto'}}>
<Button enabled={totalNumber > 0} onClick={createOrder}>Create Order</Button>
</p>
</>
);
}
function itemCountReducer(state, action) {
switch(action.type) {
case 'add':
if (state[action.item])
return {...state, [action.item]: state[action.item] + 1}
else
return {...state, [action.item]: 1}
case 'subtract':
if (state[action.item])
return {...state, [action.item]: state[action.item] - 1}
else
return state
case 'remove':
const newState = {...state}
delete newState[action.item]
return newState;
case 'clear':
return {};
}
}