Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 42x 1107x 42x 1105x 42x 9x 9x 3x 2x 1x 1x | import { useMutation, useQuery, useQueryClient } from "react-query";
import { customInstance } from "@services/api";
import { buildMerchantEndpoints } from "@services/api/utils.api";
import { showMessage } from "@common/Toast";
import { QKEY_SEATING_ROWS } from "@constants/queryKeys";
import { toSeatingRowsPayload } from "@sections/PayBuilder/seating.helpers";
import type { SeatingRow } from "@sections/PayBuilder/types";
const SAVE_SEATING_ERROR = "Couldn't save the seating layout. Please try again.";
// GET/PUT /merchants/{merchant_id}/products/{product_id}/seating-rows
// merchant_id is injected by buildMerchantEndpoints (getMerchantId()).
// The merchant endpoint returns rows only (assignSeating lives on the product GET).
type SeatingRowsResponse = { rows: SeatingRow[] };
const key = (productId: string | number) => [QKEY_SEATING_ROWS, productId];
export const useGetSeatingRows = (
productId: string | number,
enabled = true,
) =>
useQuery<SeatingRowsResponse>(
key(productId),
() =>
customInstance({
url: buildMerchantEndpoints(`products/${productId}/seating-rows`),
method: "GET",
}),
{ enabled: Boolean(productId) && enabled, refetchOnWindowFocus: false },
);
// PAY Builder 031 (Figma 6722-6428) — persist ONLY the seating layout, decoupled from the full
// form save. "Save Seating" must not run variants/bulk-create: a brand-new, not-yet-assigned
// ticket would be sent seatless, rejected by the BE (ErrTicketNeedsSeatingRow), silently swallowed
// by the full save's Promise.allSettled, and then wiped by the post-save re-hydration — the ticket
// disappears. This PUT replaces the rows in place (ids preserved via toSeatingRowsPayload so the BE
// upserts) and, on success, invalidates the seating-rows query so the editor re-hydrates with the
// freshly-saved rows (now id-bearing, therefore assignable). Local form Items are left untouched.
export const useSaveSeatingRows = () => {
const queryClient = useQueryClient();
return useMutation(
({
productId,
rows,
}: {
productId: string | number;
rows: SeatingRow[];
}) =>
customInstance({
url: buildMerchantEndpoints(`products/${productId}/seating-rows`),
method: "PUT",
data: { rows: toSeatingRowsPayload(rows) },
}),
{
onSuccess: (_data, { productId }) => {
queryClient.invalidateQueries(key(productId));
},
// Surface failures — otherwise a rejected PUT is silent and the layout looks saved when it
// isn't. Prefer the BE message (e.g. a cross-variant row conflict) over the generic fallback.
onError: (error) => {
const message =
(error as { response?: { data?: { message?: string } } })?.response
?.data?.message || SAVE_SEATING_ERROR;
showMessage("Error", message);
},
},
);
};
|