-
-
Save longfellowone/eaed16f3d23e26048530156ab9f0e86e to your computer and use it in GitHub Desktop.
Purchasing tempalte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from "react"; | |
import ReactDOM from "react-dom"; | |
import "./styles.css"; | |
import { orders } from "./models"; | |
const App = () => { | |
const [currentOrder, setCurrentOrder] = useState(null); // orders[0] | |
const [searchFocused, setSearchFocused] = useState(false); | |
const orderDate = order => new Date(order.date * 1000).toDateString(); | |
const groupByDate = groupBy(orderDate); | |
const groupedOrdersByDate = groupByDate(orders); | |
const orderDates = Object.keys(groupedOrdersByDate).map(date => ( | |
<OrderDates | |
date={date} | |
groupedOrdersByDate={groupedOrdersByDate} | |
setCurrentOrder={setCurrentOrder} | |
/> | |
)); | |
const results = ( | |
<div className="relative"> | |
<div className="absolute bg-white w-full border border-grey shadow rounded-b-lg pin-t-1"> | |
<div className="p-2 border-t-2 border-transparent">Text</div> | |
<div className="p-2 border-t-2 border-transparent">Text</div> | |
<div className="p-2 border-t-2 border-transparent">Text</div> | |
<div className="p-2 border-t-2 border-transparent">Text</div> | |
</div> | |
</div> | |
); | |
const searchInputClass = `border border-grey rounded-t-lg ${!searchFocused && | |
"rounded-b-lg"}`; | |
return ( | |
<div className="mt-8 flex items-start container mx-auto font-sans text-sm"> | |
<div> | |
<div className=""> | |
<div className="border border-grey rounded-t-lg px-2 py-2 font-bold bg-blue text-blue-lightest"> | |
Project Search | |
</div> | |
<div className="border-b border-l border-r border-grey p-2 rounded-b-lg"> | |
<div className={searchInputClass}> | |
<input | |
className="w-full my-1 py-1 px-2 outline-none" | |
placeholder="Enter project name" | |
onFocus={() => setSearchFocused(true)} | |
onBlur={() => setSearchFocused(false)} | |
/> | |
</div> | |
{searchFocused && results} | |
</div> | |
</div> | |
<div className="w-96 mt-4 border rounded-lg shadow overflow-hidden border-grey"> | |
<table className="w-full border-collapse"> | |
<thead className="bg-blue text-blue-lightest"> | |
<th className="text-left">Project</th> | |
<th className="text-right">Status</th> | |
</thead> | |
<tbody className="align-middle">{orderDates}</tbody> | |
</table> | |
</div> | |
</div> | |
<div className="flex-1 ml-4"> | |
<Order order={currentOrder} /> | |
</div> | |
</div> | |
); | |
}; | |
const OrderDates = ({ date, groupedOrdersByDate, setCurrentOrder }) => { | |
const orderSummaryItem = groupedOrdersByDate[date].map(order => ( | |
<OrderSummaryItem order={order} setCurrentOrder={setCurrentOrder} /> | |
)); | |
return ( | |
<> | |
<tr> | |
<td | |
className="bg-grey-light text-center border-t border-b border-grey shadow" | |
colspan="2" | |
> | |
{date} | |
</td> | |
</tr> | |
{orderSummaryItem} | |
</> | |
); | |
}; | |
const OrderSummaryItem = ({ order, setCurrentOrder }) => { | |
const status = `text-right ${order.status === "New!" && | |
"text-red font-bold"}`; | |
return ( | |
<tr | |
className="cursor-pointer hover:bg-blue-lightest" | |
onClick={() => setCurrentOrder(order)} | |
> | |
<td className="text-left">{order.project_name}</td> | |
<td className={status}>{order.status}</td> | |
</tr> | |
); | |
}; | |
const Order = ({ order }) => { | |
if (order === null) | |
return ( | |
<div className="border rounded-lg shadow p-2">No order selected</div> | |
); | |
const orderDate = order => new Date(order.date * 1000).toDateString(); | |
const orderItems = order.items.map(item => <Item item={item} />); | |
return ( | |
<> | |
<div className="border rounded-lg shadow pb-2 overflow-hidden border-grey"> | |
<div className="px-2 py-2 font-bold bg-blue text-blue-lightest"> | |
Order Details | |
</div> | |
<div className="mt-2 px-2 leading-normal"> | |
<div> | |
{order.project_name} - {order.status} | |
</div> | |
<div>{orderDate(order)}</div> | |
</div> | |
</div> | |
<div className="border rounded-lg shadow mt-4 pb-2 overflow-hidden border-grey"> | |
<div className="px-2 py-2 font-bold bg-blue text-blue-lightest"> | |
Special Instructions | |
</div> | |
<div className="mt-2 px-2 leading-normal"> | |
<div>{order.comments}</div> | |
</div> | |
</div> | |
<div className="border rounded-lg shadow mt-4 overflow-hidden border-grey"> | |
<table className="w-full border-collapse"> | |
<thead className="bg-blue text-blue-lightest"> | |
<tr> | |
<th className="w-8 text-right">Requested</th> | |
<th className="w-8">U</th> | |
<th className="text-left">Product</th> | |
<th className="text-right">Status</th> | |
</tr> | |
</thead> | |
<tbody>{orderItems}</tbody> | |
</table> | |
</div> | |
</> | |
); | |
}; | |
const Item = ({ item }) => { | |
return ( | |
<tr className=""> | |
<td className="text-right">{item.quantity_requested}</td> | |
<td className="font-bold">{item.product_uom}</td> | |
<td>{item.product_name}</td> | |
<td class="text-right">Waiting</td> | |
</tr> | |
); | |
}; | |
const groupBy = func => array => | |
array.reduce((acc, cur) => { | |
const key = func(cur); | |
acc[key] = (acc[key] || []).concat(cur); | |
return acc; | |
}, {}); | |
const rootElement = document.getElementById("root"); | |
ReactDOM.render(<App />, rootElement); | |
// https://www.quackit.com/css/flexbox/tutorial/align_form_elements_with_flexbox.cfm | |
// var streamRequest = new RepeatHelloRequest(); | |
// streamRequest.setName('World'); | |
// streamRequest.setCount(5); | |
// var stream = client.sayRepeatHello(streamRequest, {}); | |
// stream.on('data', (response) => { | |
// console.log(response.getMessage()); | |
// }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment