Skip to content
Twilight React Playground
ثيم رائدaren

OrderSingle

route-moduleBeginnerserverbrowser

One order's details for its customer: items, amounts, shipping and status, with reorder, cancel, receipt and rating actions.

import { OrderSingle, OrderSinglePage, orderSingleLoader, OrderSinglePageProps } from '@salla.sa/twilight-theme-engine/routes/account/orders';

In plain words

/account/orders/<id> shows one of the customer's orders in full: what was bought, what it cost, how it ships and where it is. Depending on the order, the customer can reorder it, cancel it, print the receipt or rate it.

Signature

const OrderSingle: {
  readonly id: 'customer.orders.single';
  readonly loader: (
    ctx: { params: { id: string }; locale?: string },
    extend?: (data: OrderSinglePageProps, ctx: { params: { id: string } }) => Record<string, unknown> | Promise<Record<string, unknown>>
  ) => Promise<OrderSinglePageProps>;
  readonly head: (ctx: TwilightContext, data: OrderSinglePageProps) => HeadDescriptor;
  readonly Component: React.LazyExoticComponent<(props: OrderSinglePageProps) => JSX.Element>;
};

const OrderSinglePage: typeof OrderSingle.Component;
function orderSingleLoader({ params }: { params: { id: string } }): Promise<OrderSinglePageProps>;

interface OrderSinglePageProps {
  page: Page;     // { slug: 'customer.orders.single', id, title }
  order: Order;
}

Example

app/routes/account.orders.$id.tsx (generated)
import { createFileRoute } from '@tanstack/react-router';
import { OrderSingle } from '@salla.sa/twilight-theme-engine/routes/account/orders';
import type { OrderSinglePageProps } from '@salla.sa/twilight-theme-engine/routes/account/orders';
import { CustomerPageSkeleton } from '@salla.sa/twilight-theme-engine/skeleton';
import { withHead } from '@salla.sa/twilight-theme-engine/tanstack';

export const Route = createFileRoute('/{-$locale}/account/orders/$id')({
  loader: ({ params }): Promise<OrderSinglePageProps> =>
    OrderSingle.loader({ params: { id: params.id }, locale: params.locale }),
  head: withHead(OrderSingle),
  pendingComponent: () => <CustomerPageSkeleton />,
  component: OrderSingleComponent,
});

function OrderSingleComponent() {
  const data: OrderSinglePageProps = Route.useLoaderData();
  return <OrderSingle.Component {...data} />;
}

How it behaves

  • orderSingleLoader calls order.findOrThrow(id), which is orUnauthorized(order.find(id)). The title is the pages.orders.order_details translation with :id replaced by the id (or Order Details).

  • head sets the title and hreflang alternates only.

  • OrderSinglePage ignores page. In the browser it loads the shipments when the order is shippable and the ratings when it is rateable. Reorder calls Salla.order.createCartFromOrder(id) and then navigates to /cart; cancel calls Salla.order.cancel(id); print opens order.urls.receipt in a window. Slots: customer:orders.single.details.start and customer:orders.single.details.end.

  • Also re-exported from @salla.sa/twilight-theme-engine/routes/account.

Gotchas

  • A wrong order id does not show the 404 page. orUnauthorized turns only a 401 or 403 into the 401 page; any other API error reaches the router's default error component as a 400 page. That includes a guest: Salla answers 400 token_not_provided, not 401.

Related

Source and docs