feat(companies): show member + yacht counts on list page
All checks were successful
Build & Push Docker Images / lint (pull_request) Successful in 59s
Build & Push Docker Images / build-and-push (pull_request) Has been skipped

listCompanies returns memberCount (active companyMemberships)
and yachtCount (yachts where currentOwnerType=company), each
fetched as a parallel grouped count after the main page query.
Two new badge columns in company-columns render them between
the tax-id and status columns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt Ciaccio
2026-04-27 21:57:13 +02:00
parent e8d61c91c4
commit 999622fd08
2 changed files with 63 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ import Link from 'next/link';
import { MoreHorizontal, Pencil, Archive, Eye } from 'lucide-react';
import type { ColumnDef } from '@tanstack/react-table';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@@ -12,7 +13,6 @@ import {
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
// TODO: add member/yacht counts once the list endpoint returns them via a join.
export interface CompanyRow {
id: string;
name: string;
@@ -27,6 +27,8 @@ export interface CompanyRow {
archivedAt: string | null;
createdAt: string;
updatedAt: string;
memberCount?: number;
yachtCount?: number;
}
const STATUS_COLORS: Record<string, string> = {
@@ -88,6 +90,28 @@ export function getCompanyColumns({
return <span className="text-sm">{value}</span>;
},
},
{
id: 'memberCount',
header: 'Members',
enableSorting: false,
size: 88,
cell: ({ row }) => {
const n = row.original.memberCount ?? 0;
if (n === 0) return <span className="text-muted-foreground"></span>;
return <Badge variant="secondary">{n}</Badge>;
},
},
{
id: 'yachtCount',
header: 'Yachts',
enableSorting: false,
size: 88,
cell: ({ row }) => {
const n = row.original.yachtCount ?? 0;
if (n === 0) return <span className="text-muted-foreground"></span>;
return <Badge variant="secondary">{n}</Badge>;
},
},
{
id: 'status',
accessorKey: 'status',