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.
154 lines
5.5 KiB
JavaScript
154 lines
5.5 KiB
JavaScript
import {useState} from 'react'
|
|
|
|
import Link from 'next/link'
|
|
import AdminToolbar from '~/components/admin/actionBar'
|
|
import {Button as RButton} from '@rmwc/button'
|
|
import {FormController, Input, IntegerInput, Button} from '~/components/form'
|
|
import Table from '~/components/table'
|
|
import axios from 'axios'
|
|
import router from 'next/router'
|
|
|
|
NewShipment.getInitialProps = async ({ctx: {axios}}) => {
|
|
const {data: allItems} = await axios.get('/api/items')
|
|
return {allItems}
|
|
}
|
|
|
|
export default function NewShipment({allItems}){
|
|
const [currentView, setView] = useState('description')
|
|
const [description, setDescription] = useState()
|
|
const [items, setItems] = useState([])
|
|
const [currentItem, setCurrentItem] = useState()
|
|
|
|
const currentUUIDs = items.map(({item}) => item.uuid)
|
|
const addableItems = allItems.filter(({uuid}) => !currentUUIDs.includes(uuid))
|
|
|
|
const handleRemoveItem = item => {
|
|
setItems(items => items.filter(listItem => item.uuid !== listItem.item.uuid))
|
|
}
|
|
|
|
const handleAddItem = ({count}) => {
|
|
const newItem = {
|
|
count,
|
|
item: currentItem
|
|
}
|
|
|
|
setCurrentItem(null)
|
|
|
|
setItems(items => [...items.filter(listItem => currentItem.uuid !== listItem.item.uuid), newItem])
|
|
setView('summary')
|
|
}
|
|
|
|
const saveShipment = async () => {
|
|
const {data: shipment} = await axios.post('/api/shipments', {
|
|
description,
|
|
items: items.map(listItem => ({count: listItem.count, uuid: listItem.item.uuid}))
|
|
})
|
|
|
|
router.push(`/admin/shipments/${shipment.uuid}`)
|
|
}
|
|
|
|
switch(currentView){
|
|
case 'description':
|
|
return (
|
|
<>
|
|
<AdminToolbar title="Add Shipment"/>
|
|
<Link href={`/admin/shipments`}><a><RButton icon="arrow_left">Cancel Shipment</RButton></a></Link>
|
|
<FormController afterSubmit={({description}) => {setDescription(description); setView('summary')}}>
|
|
<h2>Set shipment description</h2>
|
|
<Input label="Description" type="text" name="description" initialValue={description || undefined} validate={value=>value.length > 0} hint="Enter a shipment description" />
|
|
<Button type="submit">Next</Button>
|
|
</FormController>
|
|
</>
|
|
)
|
|
|
|
case 'summary':
|
|
return (
|
|
<>
|
|
<AdminToolbar title={`Add Shipment`}/>
|
|
<div style={{margin: '0 16px', marginBottom: '16px', display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
|
|
<RButton icon="arrow_left" onClick={()=>setView('description')}>Edit Description</RButton>
|
|
<RButton icon="add" onClick={() => setView('selectItem')}>Add Item</RButton>
|
|
</div>
|
|
<Table
|
|
columns={[
|
|
{name: 'Item', extractor: item => item.item.name},
|
|
{name: 'Count', extractor: item => item.count},
|
|
{name: '', extractor: ({item}) => (
|
|
<span>
|
|
<button onClick={()=>{setCurrentItem(item); setView('addItem')}} className="buttonLink">Adjust count</button>
|
|
<button onClick={()=>{handleRemoveItem(item)}} className="buttonLink">Remove</button>
|
|
</span>
|
|
)}
|
|
]}
|
|
// Map in an id property so the table can use array.map
|
|
rows={items.map(listItem => ({...listItem, id: listItem.item.uuid}))}
|
|
/>
|
|
|
|
<FormController afterSubmit={saveShipment}>
|
|
<Button enabled={items.length > 0}>Create Shipment</Button>
|
|
</FormController>
|
|
</>
|
|
)
|
|
|
|
case 'selectItem':
|
|
return (
|
|
<>
|
|
<AdminToolbar title={`Add Shipment`}/>
|
|
|
|
<div style={{margin: '0 16px', display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
|
|
<RButton icon="arrow_left" onClick={()=>setView('summary')}>Cancel Adding Item</RButton>
|
|
</div>
|
|
|
|
<h2 style={{textAlign: 'center'}}>Select Item</h2>
|
|
<Table
|
|
columns={[
|
|
{name: 'Name', extractor: item => item.name},
|
|
{name: '', extractor: item => (
|
|
<span>
|
|
<button onClick={()=>{setCurrentItem(item); setView('addItem')}} className="buttonLink">Use this item</button>
|
|
</span>
|
|
)}
|
|
]}
|
|
|
|
rows={addableItems}
|
|
/>
|
|
</>
|
|
)
|
|
|
|
case 'addItem':
|
|
if(currentItem === null){
|
|
setView('selectItem')
|
|
return null
|
|
}
|
|
|
|
const currentValue = items.find(listItem => currentItem.uuid === listItem.item.uuid)?.count
|
|
|
|
return (
|
|
<>
|
|
<AdminToolbar title={`Add Shipment`}/>
|
|
|
|
<div style={{margin: '0 16px', display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
|
|
<RButton icon="arrow_left" onClick={()=>setView('summary')}>Cancel Adding Item</RButton>
|
|
</div>
|
|
|
|
<FormController afterSubmit={handleAddItem}>
|
|
<h2 style={{textAlign: 'center'}}>{currentValue !== undefined ? 'Adjust Item' : 'Add Item'}</h2>
|
|
<p>How many of “{currentItem.name}” are in this shipment?</p>
|
|
<IntegerInput initialValue={currentValue || 1} label="Count" name="count" minimum={1}/>
|
|
<Button type="submit">Add Item</Button>
|
|
</FormController>
|
|
</>
|
|
)
|
|
|
|
|
|
default:
|
|
return (
|
|
<>
|
|
<AdminToolbar title="Add Shipment"/>
|
|
<Link href={`/admin/shipments`}><a><RButton icon="arrow_left">Cancel Shipment</RButton></a></Link>
|
|
<p>An error occurred trying to create this shipment. Please refresh the page.</p>
|
|
</>
|
|
)
|
|
}
|
|
}
|