Files
ranaze-pos/client/src/pages/QueuePage.jsx
T

122 lines
4.3 KiB
React

import PageBar from "../components/PageBar.jsx";
import SummaryCard from "../components/SummaryCard.jsx";
import { formatCurrency, formatTime, titleCase } from "../lib/formatters.js";
const queueStatuses = ["new", "making", "ready"];
export default function QueuePage({
adminUnlocked,
logoPressing,
onLogoPointerDown,
onLogoPointerUp,
onLogoPointerLeave,
onLogoPointerCancel,
onHideAdmin,
view,
setView,
orders,
updateOrderStatus,
deleteOrder,
setOrders,
setError
}) {
return (
<section className="queue-screen">
<PageBar
adminUnlocked={adminUnlocked}
logoPressing={logoPressing}
onLogoPointerDown={onLogoPointerDown}
onLogoPointerUp={onLogoPointerUp}
onLogoPointerLeave={onLogoPointerLeave}
onLogoPointerCancel={onLogoPointerCancel}
onHideAdmin={onHideAdmin}
view={view}
setView={setView}
/>
<div className="queue-summary">
<SummaryCard label="Open orders" value={orders.filter((order) => order.status !== "completed").length} />
<SummaryCard label="New" value={orders.filter((order) => order.status === "new").length} />
<SummaryCard label="Making" value={orders.filter((order) => order.status === "making").length} />
<SummaryCard label="Ready" value={orders.filter((order) => order.status === "ready").length} />
</div>
<div className="queue-columns">
{queueStatuses.map((status) => (
<section key={status} className="queue-column">
<div className="column-head">
<p className="eyebrow">{titleCase(status)}</p>
<h3>{orders.filter((order) => order.status === status).length} orders</h3>
</div>
{orders.filter((order) => order.status === status).map((order) => (
<article key={order._id} className="queue-card">
<header>
<div>
<p className="eyebrow">Order #{order.number}</p>
<h3>{order.customerName || "Walk-in"}</h3>
</div>
<strong>{formatCurrency(order.total)}</strong>
</header>
<p className="muted">{formatTime(order.createdAt)} • {titleCase(order.paymentMethod)}</p>
<div>
{order.lines.map((line, index) => (
<p key={`${order._id}-${index}`}>• {line.name} ({line.size})</p>
))}
</div>
<div className="status-actions">
<NextStatusButton
order={order}
onAdvance={async (newStatus) => {
try {
const response = await updateOrderStatus(order._id, newStatus);
setOrders((current) => current.map((item) => {
return item._id === response.order._id ? response.order : item;
}));
} catch (requestError) {
setError(requestError.message);
}
}}
/>
<button
className="status-btn danger"
onClick={async () => {
try {
await deleteOrder(order._id);
setOrders((current) => current.filter((item) => item._id !== order._id));
} catch (requestError) {
setError(requestError.message);
}
}}
>
Delete
</button>
</div>
</article>
))}
{orders.filter((order) => order.status === status).length === 0 && (
<div className="empty-state">No orders in {status}.</div>
)}
</section>
))}
</div>
</section>
);
}
function NextStatusButton({ order, onAdvance }) {
const map = {
new: "making",
making: "ready",
ready: "completed"
};
const next = map[order.status];
if (!next) {
return null;
}
return (
<button className="status-btn" onClick={() => onAdvance(next)}>
{next === "making" ? "Start making" : next === "ready" ? "Mark ready" : "Complete"}
</button>
);
}