import type { Route } from "./+types/_index"; import { type ActionFunctionArgs, type LoaderFunctionArgs, useFetcher, useLoaderData, } from "react-router"; import { getApi } from "~/bknd"; // biome-ignore lint/correctness/noEmptyPattern: export function meta({}: Route.MetaArgs) { return [ { title: "New bknd React Router App" }, { name: "description", content: "Welcome to bknd & React Router!" }, ]; } export const loader = async (args: LoaderFunctionArgs) => { const api = await getApi(args, { verify: true }); const limit = 5; const { data: todos, body: { meta }, } = await api.data.readMany("todos", { limit, sort: "-id", }); return { todos: todos.reverse(), total: meta.total, limit, user: api.getUser() }; }; export default function Index() { const { todos, total, limit, user } = useLoaderData(); const fetcher = useFetcher(); return (
bknd
React Router React Router
Go to Admin ➝
{user ? (

Authenticated as {user.email}

) : ( Login )}
); } export const action = async (args: ActionFunctionArgs) => { const api = await getApi(); const formData = await args.request.formData(); const action = formData.get("action") as string; switch (action) { case "update": { const id = Number(formData.get("id")); const done = formData.get("done") === "on"; if (id > 0) { await api.data.updateOne("todos", id, { done }); } break; } case "add": { const title = formData.get("title") as string; if (title.length > 0) { await api.data.createOne("todos", { title }); } break; } case "delete": { const id = Number(formData.get("id")); if (id > 0) { await api.data.deleteOne("todos", id); } break; } } return null; };