feat(F-158): completed feature

This commit is contained in:
chattie
2026-08-22 17:50:55 +02:00
parent 7159baf851
commit 3e1a447e43
16 changed files with 348 additions and 77 deletions

View File

@@ -1,4 +1,6 @@
const API = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:3000';
// Browser requests stay on the POS origin. The Next.js route handler proxies
// `/api/*` to the backend, so LAN clients never resolve their own localhost.
const API = '/api';
async function apiFetch<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${API}${path}`, {
@@ -10,8 +12,14 @@ async function apiFetch<T>(path: string, init?: RequestInit): Promise<T> {
},
});
if (!res.ok) {
const err = await res.json().catch(() => ({ message: res.statusText }));
throw Object.assign(new Error((err as { message?: string }).message ?? 'Request failed'), { status: res.status });
const err = await res.json().catch(() => ({ message: res.statusText })) as {
message?: string;
error?: { message?: string; code?: string };
};
throw Object.assign(
new Error(err.error?.message ?? err.message ?? 'Request failed'),
{ status: res.status, code: err.error?.code },
);
}
return res.json() as Promise<T>;
}
@@ -21,9 +29,12 @@ export const posApi = {
me: () => apiFetch('/pos/terminals/me'),
/** Bind terminal with code. */
bind: (bindingCode: string) =>
apiFetch('/pos/terminals/bind', { method: 'POST', body: JSON.stringify({ bindingCode }) }),
apiFetch<{ terminalId: string; storeId: string }>('/pos/terminals/bind', {
method: 'POST',
body: JSON.stringify({ bindingCode }),
}),
/** Get POS config (store + terminal + payment methods + session status). */
config: () => apiFetch('/pos/config'),
config: <T>() => apiFetch<T>('/pos/config'),
/** List products by query. */
searchProducts: (q: string, storeId?: string, limit = 20) =>
apiFetch(`/pos/products/search?q=${encodeURIComponent(q)}&storeId=${storeId ?? ''}&limit=${limit}`),