Files
myeasycms-v2/apps/web/app/[locale]/home/[account]/verband/statistics/page.tsx
Zaid Marzguioui 9cbe6652a1
Some checks failed
Workflow / ʦ TypeScript (push) Failing after 4m52s
Workflow / ⚫️ Test (push) Has been skipped
fix: close all remaining known gaps across modules
Every 'read-only placeholder' and 'missing functionality' gap from the
QA audit is now resolved:

COURSES — categories/instructors/locations can now be deleted:
- Added update/delete methods to course-reference-data.service.ts
- Added deleteCategory/deleteInstructor/deleteLocation server actions
- Created DeleteRefDataButton client component with confirmation dialog
- Wired delete buttons into all three table pages

BOOKINGS — calendar month navigation now works:
- Calendar was hardcoded to current month with disabled prev/next
- Added year/month search params for server-side month rendering
- Replaced disabled buttons with Link-based navigation
- Verified: clicking next/prev correctly renders different months

DOCUMENTS — templates page now reads from database:
- Was hardcoded empty array; now queries document_templates table
- Table exists since migration 20260414000006_shared_templates.sql

FISCHEREI — statistics page shows real data:
- Replaced dashed-border placeholder with 6 real stat cards
- Queries waters, species, stocking, catch_books, leases, permits
- Shows counts + stocking costs + pending catch books
- Falls back to helpful message when no data exists

VERBAND — statistics page shows real KPIs:
- Added server-side data fetching (clubs, members, fees)
- Passes activeClubs, totalMembers, openFees as props
- Added 4 KPI cards: Aktive Vereine, Gesamtmitglieder,
  ∅ Mitglieder/Verein, Offene Beiträge
- Kept existing trend charts below KPI cards
2026-04-03 23:52:25 +02:00

65 lines
2.2 KiB
TypeScript

import { getTranslations } from 'next-intl/server';
import { VerbandTabNavigation } from '@kit/verbandsverwaltung/components';
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { AccountNotFound } from '~/components/account-not-found';
import { CmsPageShell } from '~/components/cms-page-shell';
import StatisticsContent from './_components/statistics-content';
interface Props {
params: Promise<{ account: string }>;
}
export default async function StatisticsPage({ params }: Props) {
const { account } = await params;
const t = await getTranslations('verband');
const client = getSupabaseServerClient();
const { data: acct } = await client
.from('accounts')
.select('id')
.eq('slug', account)
.single();
if (!acct) return <AccountNotFound />;
// Fetch real verband stats
const [clubsResult, membersResult, feesResult] = await Promise.allSettled([
client
.from('member_clubs')
.select('id, status, member_count', { count: 'exact' })
.eq('account_id', acct.id),
client
.from('members')
.select('id', { count: 'exact' })
.eq('account_id', acct.id)
.eq('status', 'active'),
(client.from as any)('club_fees')
.select('amount, status')
.eq('account_id', acct.id),
]);
const clubs = clubsResult.status === 'fulfilled' ? (clubsResult.value.data ?? []) : [];
const activeClubs = clubs.filter((c: any) => c.status !== 'archived').length;
const totalMembers = clubsResult.status === 'fulfilled'
? clubs.reduce((sum: number, c: any) => sum + (Number(c.member_count) || 0), 0)
: 0;
const directMembers = membersResult.status === 'fulfilled' ? (membersResult.value.count ?? 0) : 0;
const fees = feesResult.status === 'fulfilled' ? (feesResult.value.data ?? []) : [];
const openFees = fees.filter((f: any) => f.status !== 'paid').reduce((s: number, f: any) => s + (Number(f.amount) || 0), 0);
return (
<CmsPageShell account={account} title={t('pages.statisticsTitle')}>
<VerbandTabNavigation account={account} activeTab="statistics" />
<StatisticsContent
activeClubs={activeClubs}
totalClubs={clubs.length}
totalMembers={totalMembers || directMembers}
openFees={openFees}
/>
</CmsPageShell>
);
}