feat: frontend
This commit is contained in:
143
ordr-ui/app/components/OrderItemTable.tsx
Normal file
143
ordr-ui/app/components/OrderItemTable.tsx
Normal file
@@ -0,0 +1,143 @@
|
||||
import { useItemStore } from "../providers/ItemsProvider"
|
||||
import { useState } from "react"
|
||||
import useAsyncEffect from "use-async-effect"
|
||||
import styled from "styled-components"
|
||||
import { Mutex } from "async-mutex"
|
||||
|
||||
type OrderItemTableProps = {
|
||||
orderId: number
|
||||
}
|
||||
|
||||
|
||||
const OrderItemTableStyle = styled.table`
|
||||
width: 100%
|
||||
`
|
||||
const OrderItemTableHead = styled.thead`
|
||||
background-color: #34067eff
|
||||
`
|
||||
const OrderItemTableItem = styled.td`
|
||||
align: center
|
||||
`
|
||||
|
||||
const OrderItemTH = styled.th`
|
||||
align: center
|
||||
`
|
||||
|
||||
const OrderItemTableBody = styled.tbody`
|
||||
> :nth-child(even) {
|
||||
background-color: #410041ff;
|
||||
}
|
||||
> :hover {
|
||||
background-color: #707070ff;
|
||||
}
|
||||
`
|
||||
|
||||
const OrderItemTableRow = styled.tr`
|
||||
|
||||
`
|
||||
|
||||
const orderItemMutex = new Mutex()
|
||||
|
||||
export const OrderItemTable = ({orderId}: OrderItemTableProps) => {
|
||||
|
||||
const itemStore = useItemStore((state) => state)
|
||||
|
||||
const [orderItems, setOrderItems] = useState(itemStore.orderItems.filter((oi) => oi.OrderId === orderId))
|
||||
|
||||
const [itemName, setItemName] = useState("")
|
||||
const [itemQuantity, setItemQuantity] = useState(0)
|
||||
const [shouldPostData, setShouldPostData] = useState(false)
|
||||
useAsyncEffect(async () => {
|
||||
if (orderItems.length === 0) {
|
||||
const release = await orderItemMutex.acquire()
|
||||
setOrderItems(await itemStore.getOrderItems(orderId))
|
||||
await release()
|
||||
}
|
||||
if (itemStore.items.length === 0) {
|
||||
const release = await orderItemMutex.acquire()
|
||||
await itemStore.sync()
|
||||
await release()
|
||||
}
|
||||
}, [])
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
if(shouldPostData) {
|
||||
const items = itemStore.items.filter((i) => i.ItemName.toUpperCase().includes(itemName.toUpperCase()))
|
||||
|
||||
if(items.length > 0) {
|
||||
const release = await orderItemMutex.acquire()
|
||||
setOrderItems( [...orderItems, await itemStore.addItemToOrder(items[0].ItemId, orderId, itemQuantity)])
|
||||
await release()
|
||||
}
|
||||
setShouldPostData(false)
|
||||
}
|
||||
}, [shouldPostData])
|
||||
return (
|
||||
<>
|
||||
<OrderItemTableStyle>
|
||||
<OrderItemTableHead>
|
||||
<tr>
|
||||
<OrderItemTH>
|
||||
item
|
||||
</OrderItemTH>
|
||||
<OrderItemTH>
|
||||
needed
|
||||
</OrderItemTH>
|
||||
<OrderItemTH>
|
||||
made
|
||||
</OrderItemTH>
|
||||
<OrderItemTH>
|
||||
total
|
||||
</OrderItemTH>
|
||||
<OrderItemTH>
|
||||
unit
|
||||
</OrderItemTH>
|
||||
</tr>
|
||||
</OrderItemTableHead>
|
||||
<OrderItemTableBody>
|
||||
{orderItems.map((oi) => (
|
||||
<OrderItemTableRow key = {oi.ItemId}>
|
||||
<OrderItemTableItem>
|
||||
{oi.ItemName}
|
||||
</OrderItemTableItem>
|
||||
<OrderItemTableItem>
|
||||
<input className="w-10" defaultValue={oi.Quantity} onChange={async (e) => {
|
||||
if(!Number.isNaN(parseInt(e.currentTarget.value))) {
|
||||
await itemStore.setItemQuantity(oi.OrderId, oi.ItemId, parseInt(e.currentTarget.value))
|
||||
}
|
||||
}} />
|
||||
</OrderItemTableItem>
|
||||
<OrderItemTableItem>
|
||||
<input className="w-10" defaultValue={oi.Made} onChange={async (e) => {
|
||||
if(!Number.isNaN(parseInt(e.currentTarget.value))) {
|
||||
await itemStore.setItemMade(oi.OrderId, oi.ItemId, parseInt(e.currentTarget.value))
|
||||
}
|
||||
|
||||
}} />
|
||||
</OrderItemTableItem>
|
||||
<OrderItemTableItem>
|
||||
${Math.trunc(oi.TotalPrice * 100) / 100}
|
||||
</OrderItemTableItem>
|
||||
<OrderItemTableItem>
|
||||
${Math.trunc(oi.UnitPrice * 100) / 100}
|
||||
</OrderItemTableItem>
|
||||
</OrderItemTableRow>
|
||||
))}
|
||||
</OrderItemTableBody>
|
||||
</OrderItemTableStyle>
|
||||
<h1 className="text-xl font-bold">Add Item To Order</h1>
|
||||
<div className="inline-block">
|
||||
<input className="inline-block w-40" onChange={(e) => {
|
||||
setItemName(e.currentTarget.value)
|
||||
}} placeholder="item name"/>
|
||||
<input className="inline-block w-40" onChange={(e) => {
|
||||
setItemQuantity(parseInt(e.currentTarget.value))
|
||||
}} placeholder="needed" />
|
||||
</div>
|
||||
<br />
|
||||
<button className="border border-white p-1 mt-3" onClick={() => {
|
||||
setShouldPostData(true)
|
||||
}}>Add Item</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user