Purchase orders

A React block (a whole screen) in Beamline's Shop app.

A salon's purchase orders, received: the orders down the side, the chosen one beside them. Each line still due reads as a strip of received, this delivery and still due, with this delivery's count as text that edits where clicked (inline-edit) and the stock beside it rising by exactly that; one save carries one key, so a retry after a lost answer is counted once and said so; receiving everything still due fills the draft and saves nothing; closing is its own step, asked in place with what will never arrive, and a failed close is said apart from a failed delivery; each line's deliveries unfold as its quantity river. One more part travels with it: OrderPlanner, a supplier's next order planned to par: each product's shelf drawn as what is in stock (solid), what other open orders bring (hatched), this order and what is still short, the suggestion said as its sum (par − stock − on order), a count set by hand kept and marked as your own through a recount, and saving on your records and sending to the supplier as two actions with two receipts.

Use it for

  • Receiving supplier deliveries against an order, often in parts: a salon's back bar, a spa's retail shelf, a café's stock room, a clinic's consumables.
  • Anywhere a retried save must never count stock twice, and closing an order short must be a deliberate step.
  • OrderPlanner: reordering a back bar or retail shelf to par levels from one supplier, with what is already on order counted.

Not for

  • Forecasting what to order over weeks (stock-horizon).
  • One order line's full fulfilment story with shipments and returns (quantity-river).
  • Customer orders and their fulfilment (order screens).

Anatomy

  • header: the product's mark and the title
  • order list (nav): each order's supplier, number and where it stands
  • sheet head: number and supplier, when it was ordered and where, its status in words
  • lines: each product with its size and the stock (a rolling figure; "→ 13" in strong ink while a delivery is counted); a line still due is a strip (received in the success tone, this delivery in ink, still due empty or hatched as won't arrive while closing) and its words: received of ordered · this delivery's count (text that edits where clicked) · still due; a finished line, or any line when looking only or closed, is one quiet line: a slim record bar, "All 12 received" (or received of ordered with what is still due or never arrived) and its deliveries
  • a line's deliveries: a quiet action opening the line's quantity river in place (its own Close folds it back)
  • deliveries record (side): newest first, each delivery's date and who received it, then one row per line with its quantity (+3); the closing on top
  • notice (status or alert): what was saved (green, the outcome), a duplicate counted once, a failed or unanswered save
  • bar (sticky): Receive all still due (secondary button) and Clear (ghost), Close order (confirm-morph, neutral) and Save this delivery (primary, with the item count); on a phone the order's actions (Receive all, Close order) sit under its head and the bar keeps Clear and Save on one row
  • OrderPlanner: the order's number and supplier, the location, Count stock again; a row per product: the name and size, the sum (par − ▪ in stock − ▨ on PO-… = n, or Stock not counted), the shelf against par (in stock solid, on other orders hatched, this order in the accent, short of par empty; the par mark labelled; past it only what the order adds above par), the grip at this order's end and the field as its exact twin, and the words (Suggested n or Your own count · Suggested n, +n to order, n short of par / fills it to par / at par / n above par); the foot: items, lines and cost (rolling), Not saved yet / Changed since saved / Saved, not sent / Sent, Save, Send to <supplier> (asked in place with items and cost), what was said, and the receipts (Saved … by …, Sent to … …)

States

  • awaiting delivery, partly received, all received and still open, closed: said beside the number and in the list
  • counting: the delivery drawn on each line, the stock's new figure, Save counts the items
  • saving: Save pending, the rows held
  • saved: the counted units settle into the record, the stock figure rolls to its new count, the words of what came in; the draft clears; a new key
  • duplicate: the app answers duplicate; the block applies it once and says it was already saved
  • no answer (an Error named TimeoutError): the draft and its key stay; Save becomes Try again
  • failed: the draft stays, nothing added, Try again
  • closing: asked in place (what never arrived, stock unchanged); pending; closed, or refused with its deliveries said saved
  • look only (canReceive false): the rows drawn, no bar, the permission said
  • loading: shaped skeletons; no orders: an empty state
  • phone: the list, then the order full width with Back
  • right to left: rows, arrows and the bar mirror
  • reduced motion: through the tokens
  • OrderPlanner: not counted (no stock drawn, no suggestion)
  • OrderPlanner: none needed (at par already)
  • OrderPlanner: your own count (kept through Count stock again; the others follow their new suggestion, said)
  • OrderPlanner: saved, changed since saved, sent (an open order now; the rows hold)
  • OrderPlanner: a send refused (saved on your records, not sent, said apart; Retry)
  • OrderPlanner: look only, loading, nothing planned

Keyboard

  • Tab through the list, each line's delivery count, the deliveries action and the bar
  • On a line's delivery count: Enter or Space edits it in place, Enter saves, Escape puts it back; more than was ordered is refused with the reason
  • Escape closes the close question
  • OrderPlanner: each row's grip is a slider (←/→ one unit, Shift ten), the field its exact twin; Send asks in place (Enter confirms, Escape backs out)

Motion

A line's strip slides to its new count while the stock figure rolls to its new count (slot-text); the close question morphs in place (confirm-morph); the river unfolds as quantity-river does. Nothing runs at rest. OrderPlanner: units change tone as the grip moves; the totals roll; receipts fade in.

Props

PropTypeDefaultDescription
ordersPurchaseOrder[]—The orders, controlled with onOrdersChange; or defaultOrders.
defaultOrdersPurchaseOrder[]—The starting orders when uncontrolled.
onOrdersChange(orders: PurchaseOrder[]) => void—After a delivery is applied or an order closed.
openstring—The open order's id.
defaultOpenstring—Initial open state when uncontrolled; defaults to false.
onOpenChange(id: string) => void—Reports an open-state change; no callback by default.
onReceive(draft: DeliveryDraft) => Promise<ReceiveResult | void>—Save one delivery. Reject with an Error to keep the draft and its key (said with Try again).
onClose(orderId: string) => Promise<unknown>—Close an order: nothing more is expected. Reject to keep it open (said apart from a failed delivery).
bystring—Who is receiving, written on the receipts the block records itself.
defaultDraftsRecord<string, Record<string, number>>—A delivery counted but not saved, restored from your own storage: per order id, each line's units this delivery.
nownumber—The clock, for the receipts and the closing the block records itself. Default the device's.
canReceiveboolean—false: the person may look but not receive or close (receiving stock needs its own permission).
loadingboolean—Shaped skeletons while the orders load.
productstring—Your product's name, shown as its mark.
classNamestring—Classes on the documented visual root; no override by default.
refRef<HTMLDivElement>—Receives the documented native target or imperative handle; omitted by default.
OrderPlanner: plan / defaultPlan / onPlanChange / onSave / onSend / onRefresh / by / canOrderOrderPlan | null / (id, quantities) => Promise<{ at }> / (id) => Promise<{ at, to }> / (id) => Promise<PlanLine[]> / string / boolean—The plan (lines with unit cost, stock or null, par and what other open orders bring; the quantities set by hand; the last save; sent). Save keeps the quantities on your records; Send sends what is saved (an unsaved change is saved first, its own receipt); a rejected send keeps the save. onRefresh returns the lines counted again; counts set by hand stay. planning.ts has the rule (suggested, quantityOf, totals, unsaved) for your server.

Built from

Dependencies

lucide-react

Import

import { PurchaseOrders, OrderPlanner } from "@beamline/purchase-orders";

Get it

Purchase orders is part of Beamline UI. Install the parts you need in your React app as compiled packages or editable source. Get Beamline · Connect your agent

More in Shop

  • Product editor: A product being made in a shop's back office, every value read as text at rest. The variant grid, grouped by the first option, lists each combination…
  • Category manager: A shop's product categories, nested and ranked. Each category moves up, down or into another from its menu, and every move gets its own receipt (saving…
  • Inventory item: One stock item in a shop's back office, apart from the variants that sell it (how many each uses per unit). Stock per location as stocked, reserved and…
  • Plan comparison: Plans side by side against every feature: prices that roll between monthly and yearly, the current and recommended plan marked, a header that stays in…
  • Step form: The finished frame for any multi-step form you compose — onboarding, intake brief, questionnaire, booking, application: a wide card with progress, the…
  • Orders admin: A shop's order desk: today's orders and revenue, quick filters for what needs doing (to fulfil, unpaid, returns), a virtualised orders grid, and the…
  • Order detail: One shop order with payment and fulfilment as two separate lanes. The header says where each stands (paid, partly paid, awaiting, refunded; not…
  • Order board: A shop's orders as cards in its columns, on the shared kanban with drag and keyboard moves. Each card: number, estimate or work order, customer, vehicle…
  • Order composer: An order made inside a support ticket: products found by name, each variant with its stock drawn and said (in stock, none, oversold, not known) and the…
  • Draft orders: A draft order made for a customer in a shop's back office that reads like the order it will become. The lines lead: each with its variant and SKU or…
  • Order changes: What happens to a shop order after it's placed. Edit: the order as it stands beside the requested version, each line marked new, changed (old → new…
  • Special orders: Customers' special orders as demand to buy for, per outlet: To order apart from Ordered; each product's demand, what is reserved, incoming and on order…
  • Order history and fills: Every order the account placed and every fill it got, for a period: totals for volume, fees, fill rate and maker share; orders with their status and how…
  • Order ledger: Purchase orders as money. Each order's spend is drawn against its approved total (paid, billed, pending, what is left, and any overrun past the end…
  • Ticket orders: A customer's orders inside a support ticket, each action's effect said before it's done: orders and drafts kept apart, a paid draft shown once as its…
  • Record search: One search across connected records (customers, vehicles, orders) by name, phone, plate, VIN or order number. What the words look like is said (info)…
  • Return queue: A queue of return cases. Search by return, order or customer, exactly (the default) or loosely; status tabs with counts, Requires attention first; a date…
  • Return case: One return as one place where every act is its own. The return, its order (linked out) and the customer on three cards; the stage said on its tone. Items…
  • Return request: Staff start a return from an order, and edit the reasons customers pick. New return: the order's lines as a checklist, each with its variant, price and…
  • Print quote: A print shop's quoting in three places. Quote: a group of garments that share one imprint and one quantity break, the group's pieces counted together and…
  • Service estimate: An estimate for one vehicle. Services added from the catalogue (one not listed for this vehicle said on warning, fit unknown said); each with its lines…
  • Job card: A technician's repair order, phone-first. The vehicle, the customer and when it's due in words (due at, due in, overdue by how long); an offline copy…
  • Parts tracker: Parts across a shop's work orders: each with its number, the order and vehicle, supplier, quantity and cost (not known said), and where it is: ordered…
  • Visit board: The staff board for a walk-in queue: visits move from waiting through called and serving to done today. Arrival (here or on the way), the place in the…

Part of Beamline UI: polished, editable React components and complete screens for custom applications. Build your own style from any look; tokens, fonts, radii, motion; not only colours.