feat: frontend
This commit is contained in:
102
ordr-ui/app/components/ItemTableListRow.tsx
Normal file
102
ordr-ui/app/components/ItemTableListRow.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import { useState } from "react"
|
||||
import styled from "styled-components"
|
||||
import { ItemPriceResponse } from "../client/response"
|
||||
import { ItemHistoryTable } from "./ItemHistoryTable"
|
||||
import useAsyncEffect from "use-async-effect"
|
||||
import { useItemStore } from "../providers/ItemsProvider"
|
||||
import { Mutex } from "async-mutex"
|
||||
|
||||
type ItemTableListRowProps = {
|
||||
item: ItemPriceResponse
|
||||
}
|
||||
|
||||
const ItemRowContainer = styled.div`
|
||||
margin-bottom: 10px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
const ItemFieldContainer = styled.div`
|
||||
display: inline-block;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
`
|
||||
|
||||
const ItemOverviewContainer = styled.div`
|
||||
display: inline-block;
|
||||
background-color: #410041ff;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
background-color: #920592ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
`
|
||||
|
||||
const ItemDetailsContainer = styled.div`
|
||||
display: inline-block;
|
||||
background-color: #6e296eff;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
background-color: #da51daff;
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
const itemTableListRowMutex = new Mutex()
|
||||
export const ItemTableListRow = ({item}: ItemTableListRowProps) => {
|
||||
const [shouldShowDetails, setShouldShowDetails] = useState<boolean>(false)
|
||||
|
||||
const itemStore = useItemStore((state) => state)
|
||||
const [newItemPrice, setNewItemPrice] = useState<number>(item.ItemPrice)
|
||||
|
||||
const [shouldPushNewItemPrice, setShouldPushNewItemPrice] = useState<boolean>(false)
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
if(shouldPushNewItemPrice)
|
||||
{
|
||||
const release = await itemTableListRowMutex.acquire()
|
||||
setShouldPushNewItemPrice(false)
|
||||
await itemStore.setItemPrice(item.ItemId, newItemPrice)
|
||||
await release()
|
||||
}
|
||||
}, [shouldPushNewItemPrice])
|
||||
|
||||
return (
|
||||
<li>
|
||||
<ItemRowContainer>
|
||||
<ItemOverviewContainer onClick={() => {
|
||||
setShouldShowDetails(!shouldShowDetails)
|
||||
}}>
|
||||
<ItemFieldContainer>
|
||||
item: {item.ItemName}
|
||||
</ItemFieldContainer>
|
||||
<ItemFieldContainer>
|
||||
price: {Math.trunc(item.ItemPrice * 100) / 100}
|
||||
</ItemFieldContainer>
|
||||
</ItemOverviewContainer>
|
||||
{shouldShowDetails && (
|
||||
<>
|
||||
<ItemDetailsContainer>
|
||||
<h1 className="text-xl">Set Item Price</h1>
|
||||
<label>Price</label>
|
||||
<br />
|
||||
<input placeholder="price" defaultValue={(Math.trunc(item.ItemPrice * 100) / 100).toString()} onChange={(e) => {
|
||||
const newPrice = parseInt(e.currentTarget.value)
|
||||
if(!Number.isNaN(newPrice))
|
||||
setNewItemPrice(newPrice)
|
||||
}}/>
|
||||
<br />
|
||||
<button className="border p-2 mt-2" onClick={() => {setShouldPushNewItemPrice(true)}}>Set Price</button>
|
||||
</ItemDetailsContainer>
|
||||
<ItemHistoryTable itemId={item.ItemId} />
|
||||
</>
|
||||
)}
|
||||
</ItemRowContainer>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user