Add complete production-ready Ysterbaard PocketBase registry browser frontend: - Next.js 14 App Router with TypeScript, Tailwind CSS, and TanStack React Query - Secure server-side PocketBase API proxy to avoid exposing superuser tokens - Read-only directors and companies registry browse pages with search, filtering, and pagination - Client onboarding workflow for creating and managing client submissions - Docker container configuration for easy deployment - All supporting UI components, utility functions, and configuration files
52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
// lib/api.ts
|
|
// Browser-safe thin client that calls our own /api/pb proxy.
|
|
// This module is "use client" friendly — it never imports PocketBase
|
|
// directly and never touches process.env.PB_TOKEN.
|
|
|
|
import type { PBList, ListParams } from "./types";
|
|
|
|
export interface ClientListParams extends ListParams {
|
|
collection: string;
|
|
}
|
|
|
|
export interface ClientGetParams {
|
|
collection: string;
|
|
id: string;
|
|
expand?: string;
|
|
}
|
|
|
|
/** Type-safe client fetcher for paginated lists. */
|
|
export async function pbList<T>(params: ClientListParams): Promise<PBList<T>> {
|
|
const qs = new URLSearchParams();
|
|
qs.set("collection", params.collection);
|
|
if (params.page) qs.set("page", String(params.page));
|
|
if (params.perPage) qs.set("perPage", String(params.perPage));
|
|
if (params.sort) qs.set("sort", params.sort);
|
|
if (params.filter) qs.set("filter", params.filter);
|
|
if (params.expand) qs.set("expand", params.expand);
|
|
if (params.fields) qs.set("fields", params.fields);
|
|
|
|
const res = await fetch(`/api/pb/records/list?${qs.toString()}`, {
|
|
cache: "no-store"
|
|
});
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`PB list failed (${res.status}): ${text || res.statusText}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function pbGet<T>(params: ClientGetParams): Promise<T> {
|
|
const qs = new URLSearchParams();
|
|
qs.set("collection", params.collection);
|
|
if (params.expand) qs.set("expand", params.expand);
|
|
|
|
const res = await fetch(`/api/pb/records/${params.id}?${qs.toString()}`, {
|
|
cache: "no-store"
|
|
});
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`PB get failed (${res.status}): ${text || res.statusText}`);
|
|
}
|
|
return res.json();
|
|
}
|