puerto 0.17.0

Puerto — Rust full-stack DDD framework CLI. Scaffolds Clean Architecture projects with auto-wired DI, SQLx support, and zero manual wiring. Formerly puerto-framework.
import { Link, useLocation, useSearch } from "wouter";
import { PAGE_SIZE } from "../../../../domain/shared/page";
import { useDependencies } from "../../../core/dependencies";
import { useAsync } from "../../../core/hooks/use-async";
import { EmptyState } from "../../../shared/ui/empty-state";
import { ErrorAlert } from "../../../shared/ui/error-alert";
import { offsetFromSearch, Pagination, pageSearch } from "../../../shared/ui/pagination";
import { {{ pascal }}ListView } from "../views/{{ kebab }}-list-view";

/** The list, one page at a time; the page is in the URL (`?page=2`), so reload and back keep it. */
export function {{ pascal }}ListContainer() {
  const { {{ camel }}Repository } = useDependencies();
  const [location, navigate] = useLocation();
  const offset = offsetFromSearch(useSearch(), PAGE_SIZE);
  const goTo = (next: number) => navigate(location + pageSearch(next, PAGE_SIZE));
  const {{ plural_ident }} = useAsync(
    () => {{ camel }}Repository.list({ limit: PAGE_SIZE, offset }),
    [{{ camel }}Repository, offset],
  );

  return (
    <section className="space-y-4">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold">{{ label_plural }}</h1>
        <Link href="/{{ plural }}/new" className="btn btn-primary">
          New {{ words }}
        </Link>
      </div>
      {{ "{" }}{{ plural_ident }}.status === "loading" && <span className="loading loading-spinner" />}
      {{ "{" }}{{ plural_ident }}.status === "error" && <ErrorAlert error={{ "{" }}{{ plural_ident }}.error} />}
      {{ "{" }}{{ plural_ident }}.status === "ok" &&
        ({{ plural_ident }}.data.total === 0 ? (
          <EmptyState message="No {{ words_plural }} yet." />
        ) : (
          <>
            <{{ pascal }}ListView {{ plural_ident }}={{ "{" }}{{ plural_ident }}.data.items} />
            <Pagination {...{{ plural_ident }}.data} onOffsetChange={goTo} />
          </>
        ))}
    </section>
  );
}