Files
app/src/admin/lib/queries/offers.ts
BOHA ba95723b61 v1.5.6: boneyard-js skeleton migration, TanStack Query refactor, rate-limit config
- Replace hand-coded skeleton CSS/JSX with boneyard-js auto-generated bones
- Remove skeleton.css and @keyframes shimmer from base.css
- Add <Skeleton> wrappers with fixtures to all 25+ page components
- Generate 20 bone captures via boneyard CLI (CDP auth-gated capture)
- Refactor data fetching from useEffect+useState to TanStack Query
- Extract query hooks into src/admin/lib/queries/ and apiAdapter
- Add usePaginatedQuery hook replacing useApiCall/useListData
- Fix parseFloat || 0 anti-pattern in OfferDetail and OffersTemplates inputs
- Fix customer_id mandatory validation on offer creation
- Fix leave-requests comma-separated status filter (Prisma enum in: [])
- Add cross-entity cache invalidation for orders/offers/invoices/projects
- Make rate limits configurable via env vars (RATE_LIMIT_MAX, RATE_LIMIT_REFRESH, etc.)
- Add boneyard.config.json with routes and breakpoints

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 22:35:43 +02:00

59 lines
1.8 KiB
TypeScript

import { queryOptions } from "@tanstack/react-query";
import { jsonQuery, paginatedJsonQuery } from "../apiAdapter";
export const offerCustomersOptions = () =>
queryOptions({
queryKey: ["offer-customers"],
queryFn: () => jsonQuery<Record<string, unknown>>("/api/admin/customers"),
staleTime: 2 * 60_000,
});
export const offerTemplatesOptions = (action?: string) =>
queryOptions({
queryKey: ["offer-templates", action ?? "all"],
queryFn: () => {
const url = action
? `/api/admin/offers-templates?action=${action}`
: "/api/admin/offers-templates";
return jsonQuery<Record<string, unknown>[]>(url);
},
});
export const offerListOptions = (filters: {
search?: string;
sort?: string;
order?: string;
page?: number;
perPage?: number;
}) =>
queryOptions({
queryKey: ["offers", "list", filters],
queryFn: () => {
const params = new URLSearchParams();
if (filters.search) params.set("search", filters.search);
if (filters.sort) params.set("sort", filters.sort);
if (filters.order) params.set("order", filters.order);
if (filters.page) params.set("page", String(filters.page));
if (filters.perPage) params.set("per_page", String(filters.perPage));
const qs = params.toString();
return paginatedJsonQuery(`/api/admin/offers${qs ? `?${qs}` : ""}`);
},
});
export const offerDetailOptions = (id: string | undefined) =>
queryOptions({
queryKey: ["offers", id],
queryFn: () =>
jsonQuery<Record<string, unknown>>(`/api/admin/offers/${id}`),
enabled: !!id,
});
export const offerNextNumberOptions = () =>
queryOptions({
queryKey: ["offers", "next-number"],
queryFn: () =>
jsonQuery<{ next_number?: string; number?: string }>(
"/api/admin/offers/next-number",
),
});