Add account hierarchy framework with migrations, RLS policies, and UI components

This commit is contained in:
T. Zehetbauer
2026-03-31 22:18:04 +02:00
parent 7e7da0b465
commit 59546ad6d2
262 changed files with 11671 additions and 3927 deletions

View File

@@ -1,13 +1,17 @@
'use client';
import { useCallback } from 'react';
import { useForm } from 'react-hook-form';
import { useAction } from 'next-safe-action/hooks';
import { useRouter, useSearchParams } from 'next/navigation';
import { toast } from '@kit/ui/sonner';
import { useAction } from 'next-safe-action/hooks';
import { useForm } from 'react-hook-form';
import { formatDate } from '@kit/shared/dates';
import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import { Input } from '@kit/ui/input';
import { toast } from '@kit/ui/sonner';
import { STATUS_LABELS, getMemberStatusColor } from '../lib/member-utils';
@@ -117,7 +121,7 @@ export function MembersDataTable({
<select
value={currentStatus}
onChange={handleStatusChange}
className="flex h-9 rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm"
className="border-input bg-background flex h-9 rounded-md border px-3 py-1 text-sm shadow-sm"
>
{STATUS_OPTIONS.map((opt) => (
<option key={opt.value} value={opt.value}>
@@ -128,9 +132,7 @@ export function MembersDataTable({
<Button
size="sm"
onClick={() =>
router.push(`/home/${account}/members-cms/new`)
}
onClick={() => router.push(`/home/${account}/members-cms/new`)}
>
Neues Mitglied
</Button>
@@ -141,7 +143,7 @@ export function MembersDataTable({
<div className="rounded-md border">
<table className="w-full text-sm">
<thead>
<tr className="border-b bg-muted/50">
<tr className="bg-muted/50 border-b">
<th className="px-4 py-3 text-left font-medium">Nr</th>
<th className="px-4 py-3 text-left font-medium">Name</th>
<th className="px-4 py-3 text-left font-medium">E-Mail</th>
@@ -153,7 +155,10 @@ export function MembersDataTable({
<tbody>
{data.length === 0 ? (
<tr>
<td colSpan={6} className="px-4 py-8 text-center text-muted-foreground">
<td
colSpan={6}
className="text-muted-foreground px-4 py-8 text-center"
>
Keine Mitglieder gefunden.
</td>
</tr>
@@ -165,7 +170,7 @@ export function MembersDataTable({
<tr
key={memberId}
onClick={() => handleRowClick(memberId)}
className="cursor-pointer border-b transition-colors hover:bg-muted/50"
className="hover:bg-muted/50 cursor-pointer border-b transition-colors"
>
<td className="px-4 py-3 font-mono text-xs">
{String(member.member_number ?? '—')}
@@ -174,21 +179,17 @@ export function MembersDataTable({
{String(member.last_name ?? '')},{' '}
{String(member.first_name ?? '')}
</td>
<td className="px-4 py-3 text-muted-foreground">
<td className="text-muted-foreground px-4 py-3">
{String(member.email ?? '—')}
</td>
<td className="px-4 py-3">
{String(member.city ?? '—')}
</td>
<td className="px-4 py-3">{String(member.city ?? '—')}</td>
<td className="px-4 py-3">
<Badge variant={getMemberStatusColor(status)}>
{STATUS_LABELS[status] ?? status}
</Badge>
</td>
<td className="px-4 py-3 text-muted-foreground">
{member.entry_date
? new Date(String(member.entry_date)).toLocaleDateString('de-DE')
: '—'}
<td className="text-muted-foreground px-4 py-3">
{formatDate(member.entry_date as string)}
</td>
</tr>
);
@@ -200,7 +201,7 @@ export function MembersDataTable({
{/* Pagination */}
<div className="flex items-center justify-between">
<p className="text-sm text-muted-foreground">
<p className="text-muted-foreground text-sm">
{total} Mitglied{total !== 1 ? 'er' : ''} insgesamt
</p>
<div className="flex items-center gap-2">