import { useMemo, useState } from 'react' import { Link } from 'react-router-dom' import { de } from '../strings/de' import { listLitters } from '../api/litters' import { listGerbils } from '../api/gerbils' import { andFilter, condition, type GridifyQuery } from '../api/gridify' import type { Litter } from '../api/types' import { useApi } from '../hooks/useApi' import { formatDate } from '../format/labels' import { FilterPanel } from '../components/FilterPanel' const PAGE_SIZE = 20 type Tab = 'litters' | 'pairs' type SortKey = 'dateDesc' | 'dateAsc' const SORT_ORDER_BY: Record = { dateDesc: 'date desc', dateAsc: 'date' } function yearOptions(): number[] { const current = new Date().getFullYear() return Array.from({ length: 16 }, (_, i) => current - i) } interface Pair { fatherId: string motherId: string count: number lastDate: string } /** Group litters (with both parents known) by (father, mother). */ function derivePairs(litters: Litter[]): Pair[] { const map = new Map() for (const l of litters) { if (!l.fatherId || !l.motherId) continue const key = `${l.fatherId}|${l.motherId}` const existing = map.get(key) if (existing) { existing.count += 1 if (l.date > existing.lastDate) existing.lastDate = l.date } else { map.set(key, { fatherId: l.fatherId, motherId: l.motherId, count: 1, lastDate: l.date }) } } return Array.from(map.values()).sort((a, b) => b.lastDate.localeCompare(a.lastDate)) } export default function WuerfeListPage() { const t = de.pages.litters const [tab, setTab] = useState('litters') const [year, setYear] = useState('') const [sort, setSort] = useState('dateDesc') const [page, setPage] = useState(1) // Parent names (shared by both tabs). const gerbils = useApi(() => listGerbils({ page: 1, pageSize: 1000, orderBy: 'name' }), []) const nameById = useMemo(() => { const map = new Map() for (const g of gerbils.data?.items ?? []) map.set(g.id, g.name) return map }, [gerbils.data]) const parentName = (id: string | null) => (id ? (nameById.get(id) ?? t.detail.unknownParent) : '—') // Litters tab (paged, filtered). const filter = andFilter( year && condition({ field: 'date', op: '>=', value: `${year}-01-01` }), year && condition({ field: 'date', op: '<=', value: `${year}-12-31` }), ) const orderBy = SORT_ORDER_BY[sort] const query: GridifyQuery = { filter: filter || undefined, orderBy, page, pageSize: PAGE_SIZE } const litters = useApi(() => listLitters(query), [filter, orderBy, page]) // Pairs tab: all litters, grouped client-side. const allLitters = useApi( () => (tab === 'pairs' ? listLitters({ page: 1, pageSize: 1000, orderBy: 'date desc' }) : Promise.resolve(null)), [tab], ) const pairs = useMemo(() => derivePairs(allLitters.data?.items ?? []), [allLitters.data]) const total = litters.data?.totalCount ?? 0 const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE)) const items = litters.data?.items ?? [] return (

{t.title}

+ {t.newButton}
{tab === 'litters' && ( <> { setYear(''); setSort('dateDesc'); setPage(1) }} > {litters.loading &&

{de.common.loading}

} {litters.error && (
{litters.error}
)} {!litters.loading && !litters.error && items.length === 0 && (

{t.empty}

)} {items.length > 0 && (
    {items.map((l) => (
  • {l.name} {formatDate(l.date)} {parentName(l.fatherId)} × {parentName(l.motherId)} {l.totalBorn != null ? `${l.totalBorn} ${t.fields.totalBorn}` : '—'}
  • ))}
)} {totalPages > 1 && ( )} )} {tab === 'pairs' && ( <> {allLitters.loading &&

{de.common.loading}

} {!allLitters.loading && pairs.length === 0 &&

{t.pairs.empty}

} {pairs.length > 0 && (
    {pairs.map((p) => (
  • {parentName(p.fatherId)} × {parentName(p.motherId)} {p.count} {t.pairs.litterCount} {t.pairs.lastLitter}: {formatDate(p.lastDate)} {t.pairs.testMating}
  • ))}
)} )}
) }