From c7c3cbb173a29dfde5810fa8b90630d1d92378d0 Mon Sep 17 00:00:00 2001 From: FadyGergesRezk <84906847+FadyGergesRezk@users.noreply.github.com> Date: Sat, 27 Jun 2026 17:48:20 +0200 Subject: [PATCH 01/15] feat: role-aware auth foundation and mock switch --- web-client/src/features/auth/currentUser.ts | 63 ++++++++++++++++ web-client/src/features/auth/useAuth.ts | 16 +--- web-client/src/mocks/mockSwitch.ts | 7 ++ web-client/src/mocks/personas.ts | 33 ++++++++ web-client/src/types.ts | 83 +++++++++++++++++++-- web-client/src/vite-env.d.ts | 14 ++++ 6 files changed, 194 insertions(+), 22 deletions(-) create mode 100644 web-client/src/features/auth/currentUser.ts create mode 100644 web-client/src/mocks/mockSwitch.ts create mode 100644 web-client/src/mocks/personas.ts create mode 100644 web-client/src/vite-env.d.ts diff --git a/web-client/src/features/auth/currentUser.ts b/web-client/src/features/auth/currentUser.ts new file mode 100644 index 0000000..39a989d --- /dev/null +++ b/web-client/src/features/auth/currentUser.ts @@ -0,0 +1,63 @@ +import type { KeycloakTokenParsed } from 'keycloak-js' + +import keycloak from '@/lib/keycloak' +import { USE_MOCKS } from '@/mocks/mockSwitch' +import { MOCK_PERSONAS, type MockPersonaKey } from '@/mocks/personas' +import type { AuthUser, Role } from '@/types' + +type AuthTokenSnapshot = KeycloakTokenParsed & { + email?: string + name?: string + preferred_username?: string + realm_access?: { roles?: string[] } +} + +const ROLE_POWER: Record = { + member: 0, + trainer: 1, + director: 2, + admin: 3, +} + +function isRole(role: string): role is Role { + return role === 'member' || role === 'trainer' || role === 'director' || role === 'admin' +} + +function tokenRole(roles: string[] | undefined): Role { + if (!roles?.length) return 'member' + + return roles.reduce((resolved, role) => { + if (!isRole(role)) return resolved + + return ROLE_POWER[role] > ROLE_POWER[resolved] ? role : resolved + }, 'member') +} + +// Identity is coupled to the mock switch: mocks on => persona identity (matches +// fixtures), mocks off => real token. Defaults to 'member' so fixtures always resolve. +function mockPersona(): AuthUser | null { + if (!USE_MOCKS) return null + + const persona = import.meta.env.VITE_MOCK_PERSONA + const key: MockPersonaKey = + typeof persona === 'string' && persona in MOCK_PERSONAS + ? (persona as MockPersonaKey) + : 'member' + + return MOCK_PERSONAS[key] +} + +function tokenUser(): AuthUser { + const parsed = keycloak.tokenParsed as AuthTokenSnapshot | undefined + + return { + id: parsed?.sub ?? '', + name: parsed?.name ?? parsed?.preferred_username ?? parsed?.email ?? 'Unknown', + email: parsed?.email ?? '', + role: tokenRole(parsed?.realm_access?.roles), + } +} + +export function getCurrentUser(): AuthUser { + return mockPersona() ?? tokenUser() +} diff --git a/web-client/src/features/auth/useAuth.ts b/web-client/src/features/auth/useAuth.ts index aa115c5..ce38dfe 100644 --- a/web-client/src/features/auth/useAuth.ts +++ b/web-client/src/features/auth/useAuth.ts @@ -1,20 +1,8 @@ -import type { KeycloakTokenParsed } from 'keycloak-js' import keycloak from '@/lib/keycloak' import type { AuthUser } from '@/types' - -type AuthTokenSnapshot = KeycloakTokenParsed & { - email?: string - name?: string - preferred_username?: string -} +import { getCurrentUser } from './currentUser' export function useAuth(): { user: AuthUser; logout: () => void } { - // This is a render-time snapshot of the current token, not reactive auth state. - const parsed = keycloak.tokenParsed as AuthTokenSnapshot | undefined - const user: AuthUser = { - name: parsed?.name ?? parsed?.preferred_username ?? parsed?.email ?? 'Unknown', - email: parsed?.email ?? '', - } const logout = () => keycloak.logout({ redirectUri: window.location.origin }) - return { user, logout } + return { user: getCurrentUser(), logout } } diff --git a/web-client/src/mocks/mockSwitch.ts b/web-client/src/mocks/mockSwitch.ts new file mode 100644 index 0000000..8792165 --- /dev/null +++ b/web-client/src/mocks/mockSwitch.ts @@ -0,0 +1,7 @@ +// VITE_USE_MOCKS=true => queries serve fixtures; otherwise they hit the backend. +export const USE_MOCKS = import.meta.env.VITE_USE_MOCKS === 'true' + +// Thunks so the unused branch is never evaluated. +export function mockOr(mock: () => T, live: () => T): T { + return USE_MOCKS ? mock() : live() +} diff --git a/web-client/src/mocks/personas.ts b/web-client/src/mocks/personas.ts new file mode 100644 index 0000000..71c5645 --- /dev/null +++ b/web-client/src/mocks/personas.ts @@ -0,0 +1,33 @@ +import type { Role } from '@/types' + +// Persona ids are real members in the fixtures; `coach` maps to server role `trainer`. +export interface MockPersona { id: string; role: Role; name: string; email: string } + +export const MOCK_PERSONAS = { + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "role": "member", + "name": "Lena Roth", + "email": "lena.roth@club.de" + }, + "coach": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "role": "trainer", + "name": "Coach Devoops", + "email": "coach.devoops@club.de" + }, + "director": { + "id": "99999999-0003-0000-daa6-00000001daa5", + "role": "director", + "name": "Director Devoops", + "email": "director.devoops@club.de" + }, + "admin": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "role": "admin", + "name": "Admin Devoops", + "email": "admin.devoops@club.de" + } +} as const satisfies Record + +export type MockPersonaKey = keyof typeof MOCK_PERSONAS diff --git a/web-client/src/types.ts b/web-client/src/types.ts index 1232ce0..1c03b51 100644 --- a/web-client/src/types.ts +++ b/web-client/src/types.ts @@ -2,35 +2,102 @@ import type { components } from './api' type S = components['schemas'] +// Read models resolve member/team FKs to objects; write DTOs keep bare ids. +export interface MemberRef { + id: string + first_name: string + last_name: string +} + +export interface TeamRef { + id: string + name: string +} + export type Member = S['Member'] export type MemberSummary = S['MemberSummary'] export type MemberCreate = S['MemberCreate'] export type MemberPartialUpdate = S['MemberPartialUpdate'] -export type SportEvent = S['Event'] -export type EventSummary = S['EventSummary'] +export type SportEvent = Omit & { + attendees?: MemberRef[] + creator: MemberRef + teams_linked?: TeamRef[] +} +export type EventSummary = S['EventSummary'] & { + attendees?: MemberRef[] + teams_linked?: TeamRef[] +} export type EventCreate = S['EventCreate'] export type EventPartialUpdate = S['EventPartialUpdate'] -export type Sport = S['Sport'] +export type Sport = Omit & { + directors: MemberRef[] +} export type SportCreate = S['SportCreate'] export type SportPartialUpdate = S['SportPartialUpdate'] -export type Team = S['Team'] +export type Team = Omit & { + trainers: MemberRef[] + trainees: MemberRef[] +} export type TeamCreate = S['TeamCreate'] export type TeamPartialUpdate = S['TeamPartialUpdate'] -export type Feedback = S['Feedback'] -export type FeedbackSummary = S['FeedbackSummary'] +// rating: 0-10, optional until the live schema adds it. +export type Feedback = Omit & { + member: MemberRef + creator: MemberRef + rating?: number +} +export type FeedbackSummary = Omit & { + member: MemberRef + creator: MemberRef + rating?: number +} export type FeedbackCreate = S['FeedbackCreate'] export type FeedbackPartialUpdate = S['FeedbackPartialUpdate'] -export type Transaction = S['Transaction'] +export type Transaction = Omit & { + member: MemberRef + creator: MemberRef +} export type TransactionCreate = S['TransactionCreate'] export type TransactionPartialUpdate = S['TransactionPartialUpdate'] -export type Balance = S['Balance'] +export type Balance = Omit & { + member: MemberRef +} + +export interface DashboardAggregate { + member: MemberSummary + events: EventSummary[] + feedback: FeedbackSummary[] + balance: Balance + transactions: Transaction[] + report: string +} + +export type Role = 'member' | 'trainer' | 'director' | 'admin' + +const ROLE_LABELS = { + member: 'Member', + trainer: 'Coach', + director: 'Director', + admin: 'Admin', +} as const satisfies Record + +export function roleLabel(role: Role): string { + return ROLE_LABELS[role] +} export interface AuthUser { + id: string name: string email: string + role: Role +} + +/** Render a resolved member reference as a display name. */ +export function memberRefName(ref: MemberRef): string { + return `${ref.first_name} ${ref.last_name}` } diff --git a/web-client/src/vite-env.d.ts b/web-client/src/vite-env.d.ts new file mode 100644 index 0000000..e890a41 --- /dev/null +++ b/web-client/src/vite-env.d.ts @@ -0,0 +1,14 @@ +/// + +interface ImportMetaEnv { + /** Keycloak base URL (e.g. http://localhost:8081/auth). */ + readonly VITE_KEYCLOAK_URL?: string + /** 'true' => feature queries serve fixtures instead of the backend. */ + readonly VITE_USE_MOCKS?: string + /** Identity override: 'member' | 'coach' | 'director' | 'admin'. */ + readonly VITE_MOCK_PERSONA?: string +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} From 4411f589ee0c459d496353bb1926f3153304fe8e Mon Sep 17 00:00:00 2001 From: FadyGergesRezk <84906847+FadyGergesRezk@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:05:15 +0200 Subject: [PATCH 02/15] feat: typed fixtures and role-aware mock scoping --- web-client/src/mocks/fixtures/dashboard.ts | 64 + web-client/src/mocks/fixtures/events.ts | 5829 +++++++++++++++++ web-client/src/mocks/fixtures/feedback.ts | 3958 +++++++++++ web-client/src/mocks/fixtures/finance.ts | 2659 ++++++++ web-client/src/mocks/fixtures/index.ts | 7 + web-client/src/mocks/fixtures/members.ts | 3745 +++++++++++ web-client/src/mocks/fixtures/organization.ts | 2142 ++++++ web-client/src/mocks/fixtures/report.ts | 7 + web-client/src/mocks/scope.test.ts | 205 + web-client/src/mocks/scope.ts | 175 + web-client/src/types.ts | 4 +- 11 files changed, 18794 insertions(+), 1 deletion(-) create mode 100644 web-client/src/mocks/fixtures/dashboard.ts create mode 100644 web-client/src/mocks/fixtures/events.ts create mode 100644 web-client/src/mocks/fixtures/feedback.ts create mode 100644 web-client/src/mocks/fixtures/finance.ts create mode 100644 web-client/src/mocks/fixtures/index.ts create mode 100644 web-client/src/mocks/fixtures/members.ts create mode 100644 web-client/src/mocks/fixtures/organization.ts create mode 100644 web-client/src/mocks/fixtures/report.ts create mode 100644 web-client/src/mocks/scope.test.ts create mode 100644 web-client/src/mocks/scope.ts diff --git a/web-client/src/mocks/fixtures/dashboard.ts b/web-client/src/mocks/fixtures/dashboard.ts new file mode 100644 index 0000000..43f5050 --- /dev/null +++ b/web-client/src/mocks/fixtures/dashboard.ts @@ -0,0 +1,64 @@ +import type { AuthUser, Balance, DashboardAggregate, MemberSummary } from '@/types' +import type { MockPersonaKey } from '../personas' +import { MOCK_PERSONAS } from '../personas' +import { scopeEvents, scopeFeedback } from '../scope' +import { eventSummaryFixtures } from './events' +import { feedbackSummaryFixtures } from './feedback' +import { balanceFixtures } from './finance' +import { memberSummaryFixtures } from './members' +import { sportFixtures, teamFixtures } from './organization' +import { reportTextById } from './report' + +// Pre-built dashboard responses, one per persona — the object GET /members/dashboard +// would return. Assembled once at module load from the typed fixtures; the page reads +// these verbatim and derives nothing. + +const EMPTY_MEMBER: MemberSummary = { id: '', first_name: '', last_name: '', email: '' } + +function personaMember(id: string): MemberSummary { + return memberSummaryFixtures.find((member) => member.id === id) ?? EMPTY_MEMBER +} + +function personaBalance(id: string): Balance { + return ( + balanceFixtures.find((entry) => entry.member.id === id) ?? { + member: { id, first_name: '', last_name: '' }, + balance_cents: 0, + } + ) +} + +function dashboardFor(key: MockPersonaKey): DashboardAggregate { + const user = MOCK_PERSONAS[key] + const isAdmin = user.role === 'admin' + + return { + member: personaMember(user.id), + events: scopeEvents(eventSummaryFixtures, user), + feedback: scopeFeedback(feedbackSummaryFixtures, user), + balance: personaBalance(user.id), + report: reportTextById[user.id] ?? '', + sports: isAdmin ? sportFixtures : [], + teams: isAdmin ? teamFixtures : [], + } +} + +export const dashboardFixtures: Record = { + member: dashboardFor('member'), + coach: dashboardFor('coach'), + director: dashboardFor('director'), + admin: dashboardFor('admin'), +} + +// Pick the pre-built dashboard for the current persona (matched by id, role as fallback). +export function dashboardForUser(user: AuthUser): DashboardAggregate { + const byId = (Object.keys(dashboardFixtures) as MockPersonaKey[]).find( + (key) => MOCK_PERSONAS[key].id === user.id, + ) + if (byId) return dashboardFixtures[byId] + + const byRole = (Object.keys(dashboardFixtures) as MockPersonaKey[]).find( + (key) => MOCK_PERSONAS[key].role === user.role, + ) + return dashboardFixtures[byRole ?? 'member'] +} diff --git a/web-client/src/mocks/fixtures/events.ts b/web-client/src/mocks/fixtures/events.ts new file mode 100644 index 0000000..4ecab81 --- /dev/null +++ b/web-client/src/mocks/fixtures/events.ts @@ -0,0 +1,5829 @@ +import type { EventSummary, SportEvent } from '@/types' + +// Summary rows for list views; full detail lives on eventDetailsById. +export const eventSummaryFixtures: EventSummary[] = [ + { + "id": "aaaaaaaa-0001-0000-9e37-000000009e37", + "name": "Football Juniors Open Session", + "start_time": "2026-05-17T17:30:00.000Z", + "end_time": "2026-05-17T19:00:00.000Z", + "attendees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-001c-0001-4e11-000000114e04", + "first_name": "Erik", + "last_name": "Lange" + }, + { + "id": "99999999-001d-0001-ec48-00000011ec3b", + "first_name": "Janne", + "last_name": "Roth" + }, + { + "id": "99999999-001e-0001-8a80-000000128a72", + "first_name": "Theo", + "last_name": "Diaz" + }, + { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + { + "id": "99999999-0020-0002-c6ef-00000013c6e0", + "first_name": "Levi", + "last_name": "Voigt" + }, + { + "id": "99999999-0022-0002-035e-00000015034e", + "first_name": "Ida", + "last_name": "Krüger" + }, + { + "id": "99999999-0023-0002-a195-00000015a185", + "first_name": "Oskar", + "last_name": "Schulz" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0026-0002-7c3c-000000177c2a", + "first_name": "Moritz", + "last_name": "Seidel" + }, + { + "id": "99999999-0027-0002-1a73-000000181a61", + "first_name": "Nora", + "last_name": "Krause" + }, + { + "id": "99999999-0028-0002-b8ab-00000018b898", + "first_name": "Mats", + "last_name": "Huber" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors" + } + ] + }, + { + "id": "aaaaaaaa-0002-0000-3c6e-000000013c6e", + "name": "Football Juniors Tournament", + "start_time": "2026-07-18T10:30:00.000Z", + "end_time": "2026-07-18T12:00:00.000Z", + "attendees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-0020-0002-c6ef-00000013c6e0", + "first_name": "Levi", + "last_name": "Voigt" + }, + { + "id": "99999999-0021-0002-6526-000000146517", + "first_name": "Mia", + "last_name": "Albrecht" + }, + { + "id": "99999999-0022-0002-035e-00000015034e", + "first_name": "Ida", + "last_name": "Krüger" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0028-0002-b8ab-00000018b898", + "first_name": "Mats", + "last_name": "Huber" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors" + } + ] + }, + { + "id": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "name": "Football Group A Open Session", + "start_time": "2026-05-21T10:00:00.000Z", + "end_time": "2026-05-21T11:30:00.000Z", + "attendees": [ + { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + { + "id": "99999999-002d-0002-cfc0-0000001bcfab", + "first_name": "Romi", + "last_name": "Werner" + }, + { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + { + "id": "99999999-002f-0002-0c2f-0000001d0c19", + "first_name": "Romi", + "last_name": "Fuchs" + }, + { + "id": "99999999-0030-0003-aa66-0000001daa50", + "first_name": "Ben", + "last_name": "Vogel" + }, + { + "id": "99999999-0032-0003-e6d5-0000001ee6be", + "first_name": "Toni", + "last_name": "Brandt" + }, + { + "id": "99999999-0033-0003-850d-0000001f84f5", + "first_name": "Ida", + "last_name": "Arnold" + }, + { + "id": "99999999-0034-0003-2344-00000020232c", + "first_name": "Stella", + "last_name": "Zimmermann" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0002-0000-3c6e-000000013c6e", + "name": "Football Group A" + } + ] + }, + { + "id": "aaaaaaaa-0004-0000-78dd-0000000278dc", + "name": "Football Group A Friendly", + "start_time": "2026-06-29T17:00:00.000Z", + "end_time": "2026-06-29T18:30:00.000Z", + "attendees": [ + { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + { + "id": "99999999-0031-0003-489e-0000001e4887", + "first_name": "Edda", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0033-0003-850d-0000001f84f5", + "first_name": "Ida", + "last_name": "Arnold" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0002-0000-3c6e-000000013c6e", + "name": "Football Group A" + } + ] + }, + { + "id": "aaaaaaaa-0005-0000-1715-000000031713", + "name": "Football Squad 2 Open Session", + "start_time": "2026-05-13T11:30:00.000Z", + "end_time": "2026-05-13T13:00:00.000Z", + "attendees": [ + { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + { + "id": "99999999-0039-0003-3a5a-000000233a3f", + "first_name": "Clara", + "last_name": "Stein" + }, + { + "id": "99999999-003a-0003-d891-00000023d876", + "first_name": "Joris", + "last_name": "Stein" + }, + { + "id": "99999999-003d-0003-b337-00000025b31b", + "first_name": "Fynn", + "last_name": "Koch" + }, + { + "id": "99999999-003e-0003-516f-000000265152", + "first_name": "Marie", + "last_name": "Fuchs" + }, + { + "id": "99999999-0041-0004-2c15-000000282bf7", + "first_name": "Smilla", + "last_name": "Krause" + }, + { + "id": "99999999-0042-0004-ca4d-00000028ca2e", + "first_name": "Konrad", + "last_name": "Schwarz" + }, + { + "id": "99999999-0044-0004-06bc-0000002a069c", + "first_name": "Arne", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0045-0004-a4f3-0000002aa4d3", + "first_name": "Mats", + "last_name": "Graf" + }, + { + "id": "99999999-0046-0004-432b-0000002b430a", + "first_name": "Martha", + "last_name": "Voigt" + }, + { + "id": "99999999-0047-0004-e162-0000002be141", + "first_name": "Stella", + "last_name": "Horn" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0003-0000-daa6-00000001daa5", + "name": "Football Squad 2" + } + ] + }, + { + "id": "aaaaaaaa-0006-0000-b54c-00000003b54a", + "name": "Football Squad 2 Open Session", + "start_time": "2026-06-24T14:30:00.000Z", + "end_time": "2026-06-24T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + { + "id": "99999999-0039-0003-3a5a-000000233a3f", + "first_name": "Clara", + "last_name": "Stein" + }, + { + "id": "99999999-003a-0003-d891-00000023d876", + "first_name": "Joris", + "last_name": "Stein" + }, + { + "id": "99999999-003d-0003-b337-00000025b31b", + "first_name": "Fynn", + "last_name": "Koch" + }, + { + "id": "99999999-0044-0004-06bc-0000002a069c", + "first_name": "Arne", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0045-0004-a4f3-0000002aa4d3", + "first_name": "Mats", + "last_name": "Graf" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0003-0000-daa6-00000001daa5", + "name": "Football Squad 2" + } + ] + }, + { + "id": "aaaaaaaa-0007-0000-5384-000000045381", + "name": "Football Seniors Training", + "start_time": "2026-05-22T18:00:00.000Z", + "end_time": "2026-05-22T19:30:00.000Z", + "attendees": [ + { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0004-0000-78dd-0000000278dc", + "name": "Football Seniors" + } + ] + }, + { + "id": "aaaaaaaa-0008-0000-f1bb-00000004f1b8", + "name": "Football Seniors Match", + "start_time": "2026-07-17T14:30:00.000Z", + "end_time": "2026-07-17T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0004-0000-78dd-0000000278dc", + "name": "Football Seniors" + } + ] + }, + { + "id": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "name": "Basketball Masters Tournament", + "start_time": "2026-05-29T15:30:00.000Z", + "end_time": "2026-05-29T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + { + "id": "99999999-0052-0005-adc4-00000032ad9e", + "first_name": "Martha", + "last_name": "Braun" + }, + { + "id": "99999999-0053-0005-4bfc-000000334bd5", + "first_name": "Johanna", + "last_name": "Hartmann" + }, + { + "id": "99999999-0054-0005-ea33-00000033ea0c", + "first_name": "Marie", + "last_name": "Pohl" + }, + { + "id": "99999999-0055-0005-886b-000000348843", + "first_name": "Tomas", + "last_name": "Brandt" + }, + { + "id": "99999999-0057-0005-c4da-00000035c4b1", + "first_name": "Helena", + "last_name": "Neumann" + }, + { + "id": "99999999-0058-0005-6311-0000003662e8", + "first_name": "Leon", + "last_name": "Hartmann" + }, + { + "id": "99999999-0059-0005-0149-00000037011f", + "first_name": "Paul", + "last_name": "Werner" + }, + { + "id": "99999999-005b-0005-3db8-000000383d8d", + "first_name": "Romy", + "last_name": "Voigt" + }, + { + "id": "99999999-005c-0005-dbef-00000038dbc4", + "first_name": "Felix", + "last_name": "Frank" + }, + { + "id": "99999999-005d-0005-7a27-0000003979fb", + "first_name": "Jakob", + "last_name": "Klein" + }, + { + "id": "99999999-005e-0005-185e-0000003a1832", + "first_name": "Ben", + "last_name": "Horn" + }, + { + "id": "99999999-005f-0005-b696-0000003ab669", + "first_name": "Jonah", + "last_name": "Krüger" + }, + { + "id": "99999999-0060-0006-54cd-0000003b54a0", + "first_name": "Lina", + "last_name": "Graf" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0005-0000-1715-000000031713", + "name": "Basketball Masters" + } + ] + }, + { + "id": "aaaaaaaa-000a-0000-2e2a-000000062e26", + "name": "Basketball Masters Match", + "start_time": "2026-07-08T12:30:00.000Z", + "end_time": "2026-07-08T14:00:00.000Z", + "attendees": [ + { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + { + "id": "99999999-0054-0005-ea33-00000033ea0c", + "first_name": "Marie", + "last_name": "Pohl" + }, + { + "id": "99999999-0055-0005-886b-000000348843", + "first_name": "Tomas", + "last_name": "Brandt" + }, + { + "id": "99999999-0057-0005-c4da-00000035c4b1", + "first_name": "Helena", + "last_name": "Neumann" + }, + { + "id": "99999999-005e-0005-185e-0000003a1832", + "first_name": "Ben", + "last_name": "Horn" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0005-0000-1715-000000031713", + "name": "Basketball Masters" + } + ] + }, + { + "id": "aaaaaaaa-000b-0000-cc62-00000006cc5d", + "name": "Basketball Juniors Open Session", + "start_time": "2026-05-10T10:30:00.000Z", + "end_time": "2026-05-10T12:00:00.000Z", + "attendees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0061-0006-f305-0000003bf2d7", + "first_name": "Leon", + "last_name": "Braun" + }, + { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + { + "id": "99999999-0064-0006-cdab-0000003dcd7c", + "first_name": "Greta", + "last_name": "Roth" + }, + { + "id": "99999999-0065-0006-6be3-0000003e6bb3", + "first_name": "Frida", + "last_name": "Werner" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0006-0000-b54c-00000003b54a", + "name": "Basketball Juniors" + } + ] + }, + { + "id": "aaaaaaaa-000c-0000-6a99-000000076a94", + "name": "Basketball Juniors Friendly", + "start_time": "2026-06-28T15:30:00.000Z", + "end_time": "2026-06-28T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-0061-0006-f305-0000003bf2d7", + "first_name": "Leon", + "last_name": "Braun" + }, + { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0006-0000-b54c-00000003b54a", + "name": "Basketball Juniors" + } + ] + }, + { + "id": "aaaaaaaa-000d-0000-08d1-0000000808cb", + "name": "Basketball U14 Tournament", + "start_time": "2026-06-04T13:30:00.000Z", + "end_time": "2026-06-04T15:00:00.000Z", + "attendees": [ + { + "id": "99999999-0066-0006-0a1a-0000003f09ea", + "first_name": "Jonah", + "last_name": "Nowak" + }, + { + "id": "99999999-0067-0006-a851-0000003fa821", + "first_name": "Luca", + "last_name": "Peters" + }, + { + "id": "99999999-0068-0006-4689-000000404658", + "first_name": "Clara", + "last_name": "Seidel" + }, + { + "id": "99999999-0069-0006-e4c0-00000040e48f", + "first_name": "Edda", + "last_name": "Pohl" + }, + { + "id": "99999999-006a-0006-82f8-0000004182c6", + "first_name": "Ben", + "last_name": "Park" + }, + { + "id": "99999999-006d-0006-5d9e-000000435d6b", + "first_name": "Tilda", + "last_name": "Albrecht" + }, + { + "id": "99999999-006e-0006-fbd6-00000043fba2", + "first_name": "Ben", + "last_name": "Lehmann" + }, + { + "id": "99999999-006f-0006-9a0d-0000004499d9", + "first_name": "Liv", + "last_name": "Brandt" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0007-0000-5384-000000045381", + "name": "Basketball U14" + } + ] + }, + { + "id": "aaaaaaaa-000e-0000-a708-00000008a702", + "name": "Basketball U14 Tournament", + "start_time": "2026-07-07T10:00:00.000Z", + "end_time": "2026-07-07T11:30:00.000Z", + "attendees": [ + { + "id": "99999999-0068-0006-4689-000000404658", + "first_name": "Clara", + "last_name": "Seidel" + }, + { + "id": "99999999-006b-0006-212f-0000004220fd", + "first_name": "Felix", + "last_name": "Koch" + }, + { + "id": "99999999-006d-0006-5d9e-000000435d6b", + "first_name": "Tilda", + "last_name": "Albrecht" + }, + { + "id": "99999999-006f-0006-9a0d-0000004499d9", + "first_name": "Liv", + "last_name": "Brandt" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0007-0000-5384-000000045381", + "name": "Basketball U14" + } + ] + }, + { + "id": "aaaaaaaa-000f-0000-4540-000000094539", + "name": "Basketball Squad 1 Time Trial", + "start_time": "2026-06-03T14:00:00.000Z", + "end_time": "2026-06-03T15:30:00.000Z", + "attendees": [ + { + "id": "99999999-0071-0007-d67c-00000045d647", + "first_name": "Nele", + "last_name": "Schwarz" + }, + { + "id": "99999999-0072-0007-74b4-00000046747e", + "first_name": "Lena", + "last_name": "Pohl" + }, + { + "id": "99999999-0073-0007-12eb-0000004712b5", + "first_name": "Helena", + "last_name": "Vogel" + }, + { + "id": "99999999-0074-0007-b123-00000047b0ec", + "first_name": "Helena", + "last_name": "Wagner" + }, + { + "id": "99999999-0075-0007-4f5a-000000484f23", + "first_name": "Emil", + "last_name": "Kaiser" + }, + { + "id": "99999999-0077-0007-8bc9-000000498b91", + "first_name": "Ada", + "last_name": "Hoffmann" + }, + { + "id": "99999999-0078-0007-2a01-0000004a29c8", + "first_name": "Oskar", + "last_name": "Nowak" + }, + { + "id": "99999999-0079-0007-c838-0000004ac7ff", + "first_name": "Charlotte", + "last_name": "Berger" + }, + { + "id": "99999999-007a-0007-666f-0000004b6636", + "first_name": "Leon", + "last_name": "Neumann" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0008-0000-f1bb-00000004f1b8", + "name": "Basketball Squad 1" + } + ] + }, + { + "id": "aaaaaaaa-0010-0001-e377-00000009e370", + "name": "Basketball Squad 1 Time Trial", + "start_time": "2026-07-16T18:30:00.000Z", + "end_time": "2026-07-16T20:00:00.000Z", + "attendees": [ + { + "id": "99999999-0072-0007-74b4-00000046747e", + "first_name": "Lena", + "last_name": "Pohl" + }, + { + "id": "99999999-0074-0007-b123-00000047b0ec", + "first_name": "Helena", + "last_name": "Wagner" + }, + { + "id": "99999999-0079-0007-c838-0000004ac7ff", + "first_name": "Charlotte", + "last_name": "Berger" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0008-0000-f1bb-00000004f1b8", + "name": "Basketball Squad 1" + } + ] + }, + { + "id": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "name": "Basketball Group B Friendly", + "start_time": "2026-05-26T11:30:00.000Z", + "end_time": "2026-05-26T13:00:00.000Z", + "attendees": [ + { + "id": "99999999-007c-0007-a2de-0000004ca2a4", + "first_name": "Erik", + "last_name": "Scholz" + }, + { + "id": "99999999-007d-0007-4116-0000004d40db", + "first_name": "Mia", + "last_name": "Neumann" + }, + { + "id": "99999999-007e-0007-df4d-0000004ddf12", + "first_name": "Elias", + "last_name": "Diaz" + }, + { + "id": "99999999-007f-0007-7d85-0000004e7d49", + "first_name": "Tilda", + "last_name": "Neumann" + }, + { + "id": "99999999-0080-0008-1bbc-0000004f1b80", + "first_name": "Noah", + "last_name": "Richter" + }, + { + "id": "99999999-0081-0008-b9f4-0000004fb9b7", + "first_name": "Leon", + "last_name": "Busch" + }, + { + "id": "99999999-0084-0008-949a-00000051945c", + "first_name": "Juna", + "last_name": "Reil" + }, + { + "id": "99999999-0086-0008-d109-00000052d0ca", + "first_name": "Johanna", + "last_name": "Kaiser" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0009-0000-8ff3-000000058fef", + "name": "Basketball Group B" + } + ] + }, + { + "id": "aaaaaaaa-0012-0001-1fe6-0000000b1fde", + "name": "Basketball Group B Match", + "start_time": "2026-07-13T16:00:00.000Z", + "end_time": "2026-07-13T17:30:00.000Z", + "attendees": [ + { + "id": "99999999-007d-0007-4116-0000004d40db", + "first_name": "Mia", + "last_name": "Neumann" + }, + { + "id": "99999999-0087-0008-6f41-000000536f01", + "first_name": "Sofia", + "last_name": "Brandt" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0009-0000-8ff3-000000058fef", + "name": "Basketball Group B" + } + ] + }, + { + "id": "aaaaaaaa-0013-0001-be1e-0000000bbe15", + "name": "Swimming Juniors Open Session", + "start_time": "2026-06-05T12:00:00.000Z", + "end_time": "2026-06-05T13:30:00.000Z", + "attendees": [ + { + "id": "99999999-0089-0008-abb0-00000054ab6f", + "first_name": "Hannah", + "last_name": "Pohl" + }, + { + "id": "99999999-008a-0008-49e7-0000005549a6", + "first_name": "Fynn", + "last_name": "Reil" + }, + { + "id": "99999999-008b-0008-e81f-00000055e7dd", + "first_name": "Toni", + "last_name": "Neumann" + }, + { + "id": "99999999-008c-0008-8656-000000568614", + "first_name": "Moritz", + "last_name": "Wolf" + }, + { + "id": "99999999-008d-0008-248e-00000057244b", + "first_name": "Frieda", + "last_name": "Winter" + }, + { + "id": "99999999-008e-0008-c2c5-00000057c282", + "first_name": "Charlotte", + "last_name": "Schwarz" + }, + { + "id": "99999999-008f-0008-60fc-0000005860b9", + "first_name": "Moritz", + "last_name": "Krause" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000a-0000-2e2a-000000062e26", + "name": "Swimming Juniors" + } + ] + }, + { + "id": "aaaaaaaa-0014-0001-5c55-0000000c5c4c", + "name": "Swimming Juniors Friendly", + "start_time": "2026-06-28T16:00:00.000Z", + "end_time": "2026-06-28T17:30:00.000Z", + "attendees": [ + { + "id": "99999999-008a-0008-49e7-0000005549a6", + "first_name": "Fynn", + "last_name": "Reil" + }, + { + "id": "99999999-008d-0008-248e-00000057244b", + "first_name": "Frieda", + "last_name": "Winter" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000a-0000-2e2a-000000062e26", + "name": "Swimming Juniors" + } + ] + }, + { + "id": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "name": "Swimming Group A Tournament", + "start_time": "2026-06-04T13:00:00.000Z", + "end_time": "2026-06-04T14:30:00.000Z", + "attendees": [ + { + "id": "99999999-0090-0009-ff34-00000058fef0", + "first_name": "Hannah", + "last_name": "Lange" + }, + { + "id": "99999999-0091-0009-9d6b-000000599d27", + "first_name": "Smilla", + "last_name": "Busch" + }, + { + "id": "99999999-0092-0009-3ba3-0000005a3b5e", + "first_name": "Ida", + "last_name": "Neumann" + }, + { + "id": "99999999-0093-0009-d9da-0000005ad995", + "first_name": "Finn", + "last_name": "Vogel" + }, + { + "id": "99999999-0094-0009-7812-0000005b77cc", + "first_name": "Greta", + "last_name": "Pohl" + }, + { + "id": "99999999-0095-0009-1649-0000005c1603", + "first_name": "Lea", + "last_name": "Park" + }, + { + "id": "99999999-0097-0009-52b8-0000005d5271", + "first_name": "Stella", + "last_name": "Krüger" + }, + { + "id": "99999999-0098-0009-f0f0-0000005df0a8", + "first_name": "Aaron", + "last_name": "Sommer" + }, + { + "id": "99999999-0099-0009-8f27-0000005e8edf", + "first_name": "Bela", + "last_name": "Arnold" + }, + { + "id": "99999999-009a-0009-2d5f-0000005f2d16", + "first_name": "Mathilda", + "last_name": "Kaiser" + }, + { + "id": "99999999-009b-0009-cb96-0000005fcb4d", + "first_name": "Jonas", + "last_name": "Krause" + }, + { + "id": "99999999-009c-0009-69ce-000000606984", + "first_name": "Carla", + "last_name": "Albrecht" + }, + { + "id": "99999999-009d-0009-0805-0000006107bb", + "first_name": "Lena", + "last_name": "Kaiser" + }, + { + "id": "99999999-009e-0009-a63d-00000061a5f2", + "first_name": "Joris", + "last_name": "Schulz" + }, + { + "id": "99999999-00a0-000a-e2ac-00000062e260", + "first_name": "Jonah", + "last_name": "Peters" + }, + { + "id": "99999999-00a1-000a-80e3-000000638097", + "first_name": "Amelie", + "last_name": "Lange" + }, + { + "id": "99999999-00a2-000a-1f1b-000000641ece", + "first_name": "Jonas", + "last_name": "Nowak" + }, + { + "id": "99999999-00a4-000a-5b89-000000655b3c", + "first_name": "Smilla", + "last_name": "Hoffmann" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000b-0000-cc62-00000006cc5d", + "name": "Swimming Group A" + } + ] + }, + { + "id": "aaaaaaaa-0016-0001-98c4-0000000d98ba", + "name": "Swimming Group A Friendly", + "start_time": "2026-07-05T11:30:00.000Z", + "end_time": "2026-07-05T13:00:00.000Z", + "attendees": [ + { + "id": "99999999-0092-0009-3ba3-0000005a3b5e", + "first_name": "Ida", + "last_name": "Neumann" + }, + { + "id": "99999999-0095-0009-1649-0000005c1603", + "first_name": "Lea", + "last_name": "Park" + }, + { + "id": "99999999-0098-0009-f0f0-0000005df0a8", + "first_name": "Aaron", + "last_name": "Sommer" + }, + { + "id": "99999999-009d-0009-0805-0000006107bb", + "first_name": "Lena", + "last_name": "Kaiser" + }, + { + "id": "99999999-009f-0009-4474-000000624429", + "first_name": "Wilma", + "last_name": "Otto" + }, + { + "id": "99999999-00a1-000a-80e3-000000638097", + "first_name": "Amelie", + "last_name": "Lange" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000b-0000-cc62-00000006cc5d", + "name": "Swimming Group A" + } + ] + }, + { + "id": "aaaaaaaa-0017-0001-36fb-0000000e36f1", + "name": "Swimming Group B Time Trial", + "start_time": "2026-05-29T10:00:00.000Z", + "end_time": "2026-05-29T11:30:00.000Z", + "attendees": [ + { + "id": "99999999-00a5-000a-f9c1-00000065f973", + "first_name": "Toni", + "last_name": "Huber" + }, + { + "id": "99999999-00a6-000a-97f8-0000006697aa", + "first_name": "Jan", + "last_name": "Lange" + }, + { + "id": "99999999-00a7-000a-3630-0000006735e1", + "first_name": "Carla", + "last_name": "Arnold" + }, + { + "id": "99999999-00a8-000a-d467-00000067d418", + "first_name": "Noah", + "last_name": "Braun" + }, + { + "id": "99999999-00a9-000a-729f-00000068724f", + "first_name": "Alma", + "last_name": "Busch" + }, + { + "id": "99999999-00ab-000a-af0e-00000069aebd", + "first_name": "Bruno", + "last_name": "Berger" + }, + { + "id": "99999999-00ac-000a-4d45-0000006a4cf4", + "first_name": "Romy", + "last_name": "Beck" + }, + { + "id": "99999999-00ad-000a-eb7d-0000006aeb2b", + "first_name": "Joris", + "last_name": "Hoffmann" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000c-0000-6a99-000000076a94", + "name": "Swimming Group B" + } + ] + }, + { + "id": "aaaaaaaa-0018-0001-d533-0000000ed528", + "name": "Swimming Group B Friendly", + "start_time": "2026-07-10T17:00:00.000Z", + "end_time": "2026-07-10T18:30:00.000Z", + "attendees": [], + "teams_linked": [ + { + "id": "bbbbbbbb-000c-0000-6a99-000000076a94", + "name": "Swimming Group B" + } + ] + }, + { + "id": "aaaaaaaa-0019-0001-736a-0000000f735f", + "name": "Swimming Seniors Open Session", + "start_time": "2026-05-14T14:30:00.000Z", + "end_time": "2026-05-14T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-00ae-000a-89b4-0000006b8962", + "first_name": "Jonah", + "last_name": "König" + }, + { + "id": "99999999-00af-000a-27ec-0000006c2799", + "first_name": "Emil", + "last_name": "Stein" + }, + { + "id": "99999999-00b2-000b-0292-0000006e023e", + "first_name": "Noah", + "last_name": "Beck" + }, + { + "id": "99999999-00b3-000b-a0ca-0000006ea075", + "first_name": "David", + "last_name": "Klein" + }, + { + "id": "99999999-00b4-000b-3f01-0000006f3eac", + "first_name": "Leon", + "last_name": "Berger" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000d-0000-08d1-0000000808cb", + "name": "Swimming Seniors" + } + ] + }, + { + "id": "aaaaaaaa-001a-0001-11a2-000000101196", + "name": "Swimming Seniors Match", + "start_time": "2026-07-04T14:00:00.000Z", + "end_time": "2026-07-04T15:30:00.000Z", + "attendees": [ + { + "id": "99999999-00af-000a-27ec-0000006c2799", + "first_name": "Emil", + "last_name": "Stein" + }, + { + "id": "99999999-00b1-000b-645b-0000006d6407", + "first_name": "Elias", + "last_name": "Braun" + }, + { + "id": "99999999-00b4-000b-3f01-0000006f3eac", + "first_name": "Leon", + "last_name": "Berger" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000d-0000-08d1-0000000808cb", + "name": "Swimming Seniors" + } + ] + }, + { + "id": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "name": "Swimming Squad 1 Tournament", + "start_time": "2026-05-16T14:30:00.000Z", + "end_time": "2026-05-16T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-00b6-000b-7b70-000000707b1a", + "first_name": "Finn", + "last_name": "Neumann" + }, + { + "id": "99999999-00b7-000b-19a7-000000711951", + "first_name": "Konrad", + "last_name": "Klein" + }, + { + "id": "99999999-00b8-000b-b7df-00000071b788", + "first_name": "Ben", + "last_name": "Frank" + }, + { + "id": "99999999-00b9-000b-5616-0000007255bf", + "first_name": "Frida", + "last_name": "Brandt" + }, + { + "id": "99999999-00ba-000b-f44e-00000072f3f6", + "first_name": "Lea", + "last_name": "Brandt" + }, + { + "id": "99999999-00bb-000b-9285-00000073922d", + "first_name": "Sofia", + "last_name": "Pohl" + }, + { + "id": "99999999-00bd-000b-cef4-00000074ce9b", + "first_name": "Mara", + "last_name": "Engel" + }, + { + "id": "99999999-00be-000b-6d2c-000000756cd2", + "first_name": "Emil", + "last_name": "Diaz" + }, + { + "id": "99999999-00bf-000b-0b63-000000760b09", + "first_name": "David", + "last_name": "Braun" + }, + { + "id": "99999999-00c0-000c-a99b-00000076a940", + "first_name": "Aaron", + "last_name": "Hoffmann" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000e-0000-a708-00000008a702", + "name": "Swimming Squad 1" + } + ] + }, + { + "id": "aaaaaaaa-001c-0001-4e11-000000114e04", + "name": "Swimming Squad 1 Tournament", + "start_time": "2026-06-29T18:00:00.000Z", + "end_time": "2026-06-29T19:30:00.000Z", + "attendees": [ + { + "id": "99999999-00b6-000b-7b70-000000707b1a", + "first_name": "Finn", + "last_name": "Neumann" + }, + { + "id": "99999999-00bb-000b-9285-00000073922d", + "first_name": "Sofia", + "last_name": "Pohl" + }, + { + "id": "99999999-00bf-000b-0b63-000000760b09", + "first_name": "David", + "last_name": "Braun" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000e-0000-a708-00000008a702", + "name": "Swimming Squad 1" + } + ] + }, + { + "id": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "name": "Athletics Group A Time Trial", + "start_time": "2026-05-27T15:30:00.000Z", + "end_time": "2026-05-27T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-00c1-000c-47d2-000000774777", + "first_name": "Emil", + "last_name": "Schwarz" + }, + { + "id": "99999999-00c3-000c-8441-0000007883e5", + "first_name": "Rosa", + "last_name": "Frank" + }, + { + "id": "99999999-00c4-000c-2279-00000079221c", + "first_name": "Frida", + "last_name": "Neumann" + }, + { + "id": "99999999-00c5-000c-c0b0-00000079c053", + "first_name": "Clara", + "last_name": "Hartmann" + }, + { + "id": "99999999-00c6-000c-5ee8-0000007a5e8a", + "first_name": "Edda", + "last_name": "Vogt" + }, + { + "id": "99999999-00c7-000c-fd1f-0000007afcc1", + "first_name": "Leon", + "last_name": "Beck" + }, + { + "id": "99999999-00c8-000c-9b57-0000007b9af8", + "first_name": "Emil", + "last_name": "Klein" + }, + { + "id": "99999999-00c9-000c-398e-0000007c392f", + "first_name": "Jonas", + "last_name": "Stein" + }, + { + "id": "99999999-00ca-000c-d7c6-0000007cd766", + "first_name": "Nele", + "last_name": "Seidel" + }, + { + "id": "99999999-00cb-000c-75fd-0000007d759d", + "first_name": "Moritz", + "last_name": "Busch" + }, + { + "id": "99999999-00cc-000c-1434-0000007e13d4", + "first_name": "Rosa", + "last_name": "Klein" + }, + { + "id": "99999999-00cd-000c-b26c-0000007eb20b", + "first_name": "Samuel", + "last_name": "Winter" + }, + { + "id": "99999999-00ce-000c-50a3-0000007f5042", + "first_name": "Bruno", + "last_name": "Hartmann" + }, + { + "id": "99999999-00cf-000c-eedb-0000007fee79", + "first_name": "Toni", + "last_name": "Krause" + }, + { + "id": "99999999-00d0-000d-8d12-000000808cb0", + "first_name": "Lotte", + "last_name": "Richter" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000f-0000-4540-000000094539", + "name": "Athletics Group A" + } + ] + }, + { + "id": "aaaaaaaa-001e-0001-8a80-000000128a72", + "name": "Athletics Group A Match", + "start_time": "2026-07-19T18:30:00.000Z", + "end_time": "2026-07-19T20:00:00.000Z", + "attendees": [ + { + "id": "99999999-00c1-000c-47d2-000000774777", + "first_name": "Emil", + "last_name": "Schwarz" + }, + { + "id": "99999999-00c5-000c-c0b0-00000079c053", + "first_name": "Clara", + "last_name": "Hartmann" + }, + { + "id": "99999999-00ca-000c-d7c6-0000007cd766", + "first_name": "Nele", + "last_name": "Seidel" + }, + { + "id": "99999999-00cc-000c-1434-0000007e13d4", + "first_name": "Rosa", + "last_name": "Klein" + }, + { + "id": "99999999-00ce-000c-50a3-0000007f5042", + "first_name": "Bruno", + "last_name": "Hartmann" + }, + { + "id": "99999999-00d0-000d-8d12-000000808cb0", + "first_name": "Lotte", + "last_name": "Richter" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000f-0000-4540-000000094539", + "name": "Athletics Group A" + } + ] + }, + { + "id": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "name": "Athletics Development Open Session", + "start_time": "2026-05-17T17:00:00.000Z", + "end_time": "2026-05-17T18:30:00.000Z", + "attendees": [ + { + "id": "99999999-00d1-000d-2b4a-000000812ae7", + "first_name": "Lotte", + "last_name": "Frank" + }, + { + "id": "99999999-00d2-000d-c981-00000081c91e", + "first_name": "Mara", + "last_name": "Seidel" + }, + { + "id": "99999999-00d3-000d-67b9-000000826755", + "first_name": "Ella", + "last_name": "Pohl" + }, + { + "id": "99999999-00d4-000d-05f0-00000083058c", + "first_name": "Martha", + "last_name": "Engel" + }, + { + "id": "99999999-00d5-000d-a428-00000083a3c3", + "first_name": "Alma", + "last_name": "Vogel" + }, + { + "id": "99999999-00d6-000d-425f-0000008441fa", + "first_name": "Nele", + "last_name": "Scholz" + }, + { + "id": "99999999-00d7-000d-e097-00000084e031", + "first_name": "Oskar", + "last_name": "Stein" + }, + { + "id": "99999999-00d8-000d-7ece-000000857e68", + "first_name": "Juna", + "last_name": "Diaz" + }, + { + "id": "99999999-00d9-000d-1d06-000000861c9f", + "first_name": "Wilma", + "last_name": "Stein" + }, + { + "id": "99999999-00da-000d-bb3d-00000086bad6", + "first_name": "Fynn", + "last_name": "Hoffmann" + }, + { + "id": "99999999-00db-000d-5975-00000087590d", + "first_name": "Ida", + "last_name": "Vogel" + }, + { + "id": "99999999-00dd-000d-95e4-00000088957b", + "first_name": "Felix", + "last_name": "Krause" + }, + { + "id": "99999999-00de-000d-341b-0000008933b2", + "first_name": "Helena", + "last_name": "Koch" + }, + { + "id": "99999999-00df-000d-d253-00000089d1e9", + "first_name": "Toni", + "last_name": "Seidel" + }, + { + "id": "99999999-00e0-000e-708a-0000008a7020", + "first_name": "Nele", + "last_name": "Braun" + }, + { + "id": "99999999-00e1-000e-0ec1-0000008b0e57", + "first_name": "Ella", + "last_name": "Nowak" + }, + { + "id": "99999999-00e2-000e-acf9-0000008bac8e", + "first_name": "Ben", + "last_name": "Busch" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0010-0001-e377-00000009e370", + "name": "Athletics Development" + } + ] + }, + { + "id": "aaaaaaaa-0020-0002-c6ef-00000013c6e0", + "name": "Athletics Development Friendly", + "start_time": "2026-07-05T15:30:00.000Z", + "end_time": "2026-07-05T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-00d3-000d-67b9-000000826755", + "first_name": "Ella", + "last_name": "Pohl" + }, + { + "id": "99999999-00d5-000d-a428-00000083a3c3", + "first_name": "Alma", + "last_name": "Vogel" + }, + { + "id": "99999999-00d8-000d-7ece-000000857e68", + "first_name": "Juna", + "last_name": "Diaz" + }, + { + "id": "99999999-00da-000d-bb3d-00000086bad6", + "first_name": "Fynn", + "last_name": "Hoffmann" + }, + { + "id": "99999999-00db-000d-5975-00000087590d", + "first_name": "Ida", + "last_name": "Vogel" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0010-0001-e377-00000009e370", + "name": "Athletics Development" + } + ] + }, + { + "id": "aaaaaaaa-0021-0002-6526-000000146517", + "name": "Athletics Varsity Friendly", + "start_time": "2026-05-15T18:30:00.000Z", + "end_time": "2026-05-15T20:00:00.000Z", + "attendees": [ + { + "id": "99999999-00e3-000e-4b30-0000008c4ac5", + "first_name": "Nele", + "last_name": "Brandt" + }, + { + "id": "99999999-00e4-000e-e968-0000008ce8fc", + "first_name": "Jonah", + "last_name": "Frank" + }, + { + "id": "99999999-00e5-000e-879f-0000008d8733", + "first_name": "Aaron", + "last_name": "Arnold" + }, + { + "id": "99999999-00e7-000e-c40e-0000008ec3a1", + "first_name": "Amelie", + "last_name": "Seidel" + }, + { + "id": "99999999-00e8-000e-6246-0000008f61d8", + "first_name": "Lea", + "last_name": "Stein" + }, + { + "id": "99999999-00e9-000e-007d-00000090000f", + "first_name": "Arne", + "last_name": "Horn" + }, + { + "id": "99999999-00eb-000e-3cec-000000913c7d", + "first_name": "Emil", + "last_name": "Sauer" + }, + { + "id": "99999999-00ec-000e-db24-00000091dab4", + "first_name": "Romi", + "last_name": "Park" + }, + { + "id": "99999999-00ed-000e-795b-0000009278eb", + "first_name": "Mats", + "last_name": "Horn" + }, + { + "id": "99999999-00ee-000e-1793-000000931722", + "first_name": "Lina", + "last_name": "Krüger" + }, + { + "id": "99999999-00f1-000f-f239-00000094f1c7", + "first_name": "Charlotte", + "last_name": "Ziegler" + }, + { + "id": "99999999-00f2-000f-9071-000000958ffe", + "first_name": "Rosa", + "last_name": "Brandt" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0011-0001-81af-0000000a81a7", + "name": "Athletics Varsity" + } + ] + }, + { + "id": "aaaaaaaa-0022-0002-035e-00000015034e", + "name": "Athletics Varsity Friendly", + "start_time": "2026-07-16T12:00:00.000Z", + "end_time": "2026-07-16T13:30:00.000Z", + "attendees": [ + { + "id": "99999999-00e4-000e-e968-0000008ce8fc", + "first_name": "Jonah", + "last_name": "Frank" + }, + { + "id": "99999999-00ed-000e-795b-0000009278eb", + "first_name": "Mats", + "last_name": "Horn" + }, + { + "id": "99999999-00ee-000e-1793-000000931722", + "first_name": "Lina", + "last_name": "Krüger" + }, + { + "id": "99999999-00ef-000e-b5ca-00000093b559", + "first_name": "Henry", + "last_name": "Hartmann" + }, + { + "id": "99999999-00f2-000f-9071-000000958ffe", + "first_name": "Rosa", + "last_name": "Brandt" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0011-0001-81af-0000000a81a7", + "name": "Athletics Varsity" + } + ] + }, + { + "id": "aaaaaaaa-0023-0002-a195-00000015a185", + "name": "Athletics Masters Training", + "start_time": "2026-06-11T12:00:00.000Z", + "end_time": "2026-06-11T13:30:00.000Z", + "attendees": [ + { + "id": "99999999-00f5-000f-6b17-000000976aa3", + "first_name": "Til", + "last_name": "Lehmann" + }, + { + "id": "99999999-00f6-000f-094e-0000009808da", + "first_name": "Anton", + "last_name": "Vogt" + }, + { + "id": "99999999-00f8-000f-45bd-000000994548", + "first_name": "Til", + "last_name": "Bauer" + }, + { + "id": "99999999-00f9-000f-e3f5-00000099e37f", + "first_name": "Joris", + "last_name": "Huber" + }, + { + "id": "99999999-00fa-000f-822c-0000009a81b6", + "first_name": "Mara", + "last_name": "Vogel" + }, + { + "id": "99999999-00fb-000f-2064-0000009b1fed", + "first_name": "Martha", + "last_name": "Vogel" + }, + { + "id": "99999999-00fc-000f-be9b-0000009bbe24", + "first_name": "Mats", + "last_name": "Kaiser" + }, + { + "id": "99999999-00fd-000f-5cd3-0000009c5c5b", + "first_name": "Linus", + "last_name": "Hartmann" + }, + { + "id": "99999999-00fe-000f-fb0a-0000009cfa92", + "first_name": "Erik", + "last_name": "Schulz" + }, + { + "id": "99999999-00ff-000f-9942-0000009d98c9", + "first_name": "Ida", + "last_name": "Kaiser" + }, + { + "id": "99999999-0100-0010-3779-0000009e3700", + "first_name": "Felix", + "last_name": "Brandt" + }, + { + "id": "99999999-0101-0010-d5b1-0000009ed537", + "first_name": "Clara", + "last_name": "Pohl" + }, + { + "id": "99999999-0102-0010-73e8-0000009f736e", + "first_name": "Niklas", + "last_name": "Fuchs" + }, + { + "id": "99999999-0103-0010-1220-000000a011a5", + "first_name": "Leon", + "last_name": "Roth" + }, + { + "id": "99999999-0104-0010-b057-000000a0afdc", + "first_name": "Alma", + "last_name": "Roth" + }, + { + "id": "99999999-0105-0010-4e8f-000000a14e13", + "first_name": "Levi", + "last_name": "Kaiser" + }, + { + "id": "99999999-0107-0010-8afe-000000a28a81", + "first_name": "Greta", + "last_name": "Sommer" + }, + { + "id": "99999999-0108-0010-2935-000000a328b8", + "first_name": "Helena", + "last_name": "Park" + }, + { + "id": "99999999-0109-0010-c76c-000000a3c6ef", + "first_name": "Alma", + "last_name": "Frank" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0012-0001-1fe6-0000000b1fde", + "name": "Athletics Masters" + } + ] + }, + { + "id": "aaaaaaaa-0024-0002-3fcd-000000163fbc", + "name": "Athletics Masters Match", + "start_time": "2026-07-05T13:30:00.000Z", + "end_time": "2026-07-05T15:00:00.000Z", + "attendees": [ + { + "id": "99999999-00f6-000f-094e-0000009808da", + "first_name": "Anton", + "last_name": "Vogt" + }, + { + "id": "99999999-00f8-000f-45bd-000000994548", + "first_name": "Til", + "last_name": "Bauer" + }, + { + "id": "99999999-00fc-000f-be9b-0000009bbe24", + "first_name": "Mats", + "last_name": "Kaiser" + }, + { + "id": "99999999-00fd-000f-5cd3-0000009c5c5b", + "first_name": "Linus", + "last_name": "Hartmann" + }, + { + "id": "99999999-0105-0010-4e8f-000000a14e13", + "first_name": "Levi", + "last_name": "Kaiser" + }, + { + "id": "99999999-0108-0010-2935-000000a328b8", + "first_name": "Helena", + "last_name": "Park" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0012-0001-1fe6-0000000b1fde", + "name": "Athletics Masters" + } + ] + }, + { + "id": "aaaaaaaa-0025-0002-de04-00000016ddf3", + "name": "Volleyball Juniors Time Trial", + "start_time": "2026-05-19T14:00:00.000Z", + "end_time": "2026-05-19T15:30:00.000Z", + "attendees": [ + { + "id": "99999999-010c-0010-a213-000000a5a194", + "first_name": "Joris", + "last_name": "Krause" + }, + { + "id": "99999999-010d-0010-404a-000000a63fcb", + "first_name": "Mia", + "last_name": "Braun" + }, + { + "id": "99999999-010f-0010-7cb9-000000a77c39", + "first_name": "Martha", + "last_name": "Diaz" + }, + { + "id": "99999999-0111-0011-b928-000000a8b8a7", + "first_name": "Romy", + "last_name": "Park" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0013-0001-be1e-0000000bbe15", + "name": "Volleyball Juniors" + } + ] + }, + { + "id": "aaaaaaaa-0026-0002-7c3c-000000177c2a", + "name": "Volleyball Juniors Friendly", + "start_time": "2026-07-17T18:30:00.000Z", + "end_time": "2026-07-17T20:00:00.000Z", + "attendees": [ + { + "id": "99999999-010d-0010-404a-000000a63fcb", + "first_name": "Mia", + "last_name": "Braun" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0013-0001-be1e-0000000bbe15", + "name": "Volleyball Juniors" + } + ] + }, + { + "id": "aaaaaaaa-0027-0002-1a73-000000181a61", + "name": "Volleyball Squad 1 Training", + "start_time": "2026-05-10T15:00:00.000Z", + "end_time": "2026-05-10T16:30:00.000Z", + "attendees": [ + { + "id": "99999999-0112-0011-5760-000000a956de", + "first_name": "Paul", + "last_name": "Reil" + }, + { + "id": "99999999-0113-0011-f597-000000a9f515", + "first_name": "Nora", + "last_name": "Diaz" + }, + { + "id": "99999999-0114-0011-93cf-000000aa934c", + "first_name": "Samuel", + "last_name": "Koch" + }, + { + "id": "99999999-0115-0011-3206-000000ab3183", + "first_name": "Wilma", + "last_name": "Braun" + }, + { + "id": "99999999-0116-0011-d03e-000000abcfba", + "first_name": "Pia", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0117-0011-6e75-000000ac6df1", + "first_name": "Sofia", + "last_name": "Wolf" + }, + { + "id": "99999999-0118-0011-0cad-000000ad0c28", + "first_name": "Joris", + "last_name": "Arnold" + }, + { + "id": "99999999-0119-0011-aae4-000000adaa5f", + "first_name": "Elias", + "last_name": "Busch" + }, + { + "id": "99999999-011a-0011-491c-000000ae4896", + "first_name": "Jonah", + "last_name": "Diaz" + }, + { + "id": "99999999-011c-0011-858b-000000af8504", + "first_name": "Greta", + "last_name": "Koch" + }, + { + "id": "99999999-011e-0011-c1f9-000000b0c172", + "first_name": "Amelie", + "last_name": "Wolf" + }, + { + "id": "99999999-011f-0011-6031-000000b15fa9", + "first_name": "Leon", + "last_name": "Sommer" + }, + { + "id": "99999999-0120-0012-fe68-000000b1fde0", + "first_name": "Lea", + "last_name": "Engel" + }, + { + "id": "99999999-0121-0012-9ca0-000000b29c17", + "first_name": "Stella", + "last_name": "Braun" + }, + { + "id": "99999999-0122-0012-3ad7-000000b33a4e", + "first_name": "Helena", + "last_name": "König" + }, + { + "id": "99999999-0124-0012-7746-000000b476bc", + "first_name": "Nora", + "last_name": "Hoffmann" + }, + { + "id": "99999999-0125-0012-157e-000000b514f3", + "first_name": "Nele", + "last_name": "Krause" + }, + { + "id": "99999999-0126-0012-b3b5-000000b5b32a", + "first_name": "Johanna", + "last_name": "Frank" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0014-0001-5c55-0000000c5c4c", + "name": "Volleyball Squad 1" + } + ] + }, + { + "id": "aaaaaaaa-0028-0002-b8ab-00000018b898", + "name": "Volleyball Squad 1 Time Trial", + "start_time": "2026-06-21T16:00:00.000Z", + "end_time": "2026-06-21T17:30:00.000Z", + "attendees": [ + { + "id": "99999999-0112-0011-5760-000000a956de", + "first_name": "Paul", + "last_name": "Reil" + }, + { + "id": "99999999-0113-0011-f597-000000a9f515", + "first_name": "Nora", + "last_name": "Diaz" + }, + { + "id": "99999999-0117-0011-6e75-000000ac6df1", + "first_name": "Sofia", + "last_name": "Wolf" + }, + { + "id": "99999999-011e-0011-c1f9-000000b0c172", + "first_name": "Amelie", + "last_name": "Wolf" + }, + { + "id": "99999999-011f-0011-6031-000000b15fa9", + "first_name": "Leon", + "last_name": "Sommer" + }, + { + "id": "99999999-0125-0012-157e-000000b514f3", + "first_name": "Nele", + "last_name": "Krause" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0014-0001-5c55-0000000c5c4c", + "name": "Volleyball Squad 1" + } + ] + }, + { + "id": "aaaaaaaa-0029-0002-56e2-0000001956cf", + "name": "Volleyball Squad 2 Match", + "start_time": "2026-05-10T14:30:00.000Z", + "end_time": "2026-05-10T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-0128-0012-f024-000000b6ef98", + "first_name": "Linus", + "last_name": "Scholz" + }, + { + "id": "99999999-0129-0012-8e5c-000000b78dcf", + "first_name": "Luca", + "last_name": "Schulz" + }, + { + "id": "99999999-012a-0012-2c93-000000b82c06", + "first_name": "Clara", + "last_name": "Voigt" + }, + { + "id": "99999999-012b-0012-cacb-000000b8ca3d", + "first_name": "Noah", + "last_name": "Schulz" + }, + { + "id": "99999999-012c-0012-6902-000000b96874", + "first_name": "Linus", + "last_name": "Graf" + }, + { + "id": "99999999-012d-0012-073a-000000ba06ab", + "first_name": "Mats", + "last_name": "Voigt" + }, + { + "id": "99999999-012e-0012-a571-000000baa4e2", + "first_name": "Janne", + "last_name": "Albrecht" + }, + { + "id": "99999999-012f-0012-43a9-000000bb4319", + "first_name": "Nora", + "last_name": "Bauer" + }, + { + "id": "99999999-0130-0013-e1e0-000000bbe150", + "first_name": "Luca", + "last_name": "Wolf" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0015-0001-fa8c-0000000cfa83", + "name": "Volleyball Squad 2" + } + ] + }, + { + "id": "aaaaaaaa-002a-0002-f519-00000019f506", + "name": "Volleyball Squad 2 Time Trial", + "start_time": "2026-07-17T11:30:00.000Z", + "end_time": "2026-07-17T13:00:00.000Z", + "attendees": [ + { + "id": "99999999-0128-0012-f024-000000b6ef98", + "first_name": "Linus", + "last_name": "Scholz" + }, + { + "id": "99999999-012a-0012-2c93-000000b82c06", + "first_name": "Clara", + "last_name": "Voigt" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0015-0001-fa8c-0000000cfa83", + "name": "Volleyball Squad 2" + } + ] + }, + { + "id": "aaaaaaaa-002b-0002-9351-0000001a933d", + "name": "Volleyball U16 Tournament", + "start_time": "2026-05-25T13:00:00.000Z", + "end_time": "2026-05-25T14:30:00.000Z", + "attendees": [ + { + "id": "99999999-0131-0013-8017-000000bc7f87", + "first_name": "Ada", + "last_name": "Kaiser" + }, + { + "id": "99999999-0132-0013-1e4f-000000bd1dbe", + "first_name": "Emil", + "last_name": "Engel" + }, + { + "id": "99999999-0133-0013-bc86-000000bdbbf5", + "first_name": "Max", + "last_name": "Ziegler" + }, + { + "id": "99999999-0134-0013-5abe-000000be5a2c", + "first_name": "Linus", + "last_name": "Vogt" + }, + { + "id": "99999999-0135-0013-f8f5-000000bef863", + "first_name": "Romi", + "last_name": "Vogt" + }, + { + "id": "99999999-0136-0013-972d-000000bf969a", + "first_name": "Moritz", + "last_name": "Albrecht" + }, + { + "id": "99999999-0137-0013-3564-000000c034d1", + "first_name": "Juna", + "last_name": "Schulz" + }, + { + "id": "99999999-0138-0013-d39c-000000c0d308", + "first_name": "Rosa", + "last_name": "Koch" + }, + { + "id": "99999999-0139-0013-71d3-000000c1713f", + "first_name": "Janne", + "last_name": "Park" + }, + { + "id": "99999999-013a-0013-100b-000000c20f76", + "first_name": "Romy", + "last_name": "Sauer" + }, + { + "id": "99999999-013c-0013-4c7a-000000c34be4", + "first_name": "Theo", + "last_name": "Hoffmann" + }, + { + "id": "99999999-013e-0013-88e9-000000c48852", + "first_name": "Martha", + "last_name": "Lange" + }, + { + "id": "99999999-013f-0013-2720-000000c52689", + "first_name": "Levi", + "last_name": "Brandt" + }, + { + "id": "99999999-0140-0014-c558-000000c5c4c0", + "first_name": "Mats", + "last_name": "Hartmann" + }, + { + "id": "99999999-0141-0014-638f-000000c662f7", + "first_name": "Amelie", + "last_name": "Diaz" + }, + { + "id": "99999999-0143-0014-9ffe-000000c79f65", + "first_name": "Emil", + "last_name": "Busch" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0016-0001-98c4-0000000d98ba", + "name": "Volleyball U16" + } + ] + }, + { + "id": "aaaaaaaa-002c-0002-3188-0000001b3174", + "name": "Volleyball U16 Friendly", + "start_time": "2026-07-04T13:00:00.000Z", + "end_time": "2026-07-04T14:30:00.000Z", + "attendees": [ + { + "id": "99999999-0131-0013-8017-000000bc7f87", + "first_name": "Ada", + "last_name": "Kaiser" + }, + { + "id": "99999999-0134-0013-5abe-000000be5a2c", + "first_name": "Linus", + "last_name": "Vogt" + }, + { + "id": "99999999-0138-0013-d39c-000000c0d308", + "first_name": "Rosa", + "last_name": "Koch" + }, + { + "id": "99999999-013d-0013-eab1-000000c3ea1b", + "first_name": "Alma", + "last_name": "Klein" + }, + { + "id": "99999999-013e-0013-88e9-000000c48852", + "first_name": "Martha", + "last_name": "Lange" + }, + { + "id": "99999999-013f-0013-2720-000000c52689", + "first_name": "Levi", + "last_name": "Brandt" + }, + { + "id": "99999999-0142-0014-01c7-000000c7012e", + "first_name": "Anton", + "last_name": "Braun" + }, + { + "id": "99999999-0143-0014-9ffe-000000c79f65", + "first_name": "Emil", + "last_name": "Busch" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0016-0001-98c4-0000000d98ba", + "name": "Volleyball U16" + } + ] + }, + { + "id": "aaaaaaaa-002d-0002-cfc0-0000001bcfab", + "name": "Volleyball Varsity Open Session", + "start_time": "2026-06-13T09:00:00.000Z", + "end_time": "2026-06-13T10:30:00.000Z", + "attendees": [ + { + "id": "99999999-0144-0014-3e36-000000c83d9c", + "first_name": "Fynn", + "last_name": "Bauer" + }, + { + "id": "99999999-0145-0014-dc6d-000000c8dbd3", + "first_name": "David", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0147-0014-18dc-000000ca1841", + "first_name": "Henry", + "last_name": "Huber" + }, + { + "id": "99999999-0149-0014-554b-000000cb54af", + "first_name": "Lotte", + "last_name": "Engel" + }, + { + "id": "99999999-014a-0014-f382-000000cbf2e6", + "first_name": "Samuel", + "last_name": "Wolf" + }, + { + "id": "99999999-014b-0014-91ba-000000cc911d", + "first_name": "Konrad", + "last_name": "Sommer" + }, + { + "id": "99999999-014c-0014-2ff1-000000cd2f54", + "first_name": "Elias", + "last_name": "Wolf" + }, + { + "id": "99999999-014d-0014-ce29-000000cdcd8b", + "first_name": "Konrad", + "last_name": "Beck" + }, + { + "id": "99999999-014e-0014-6c60-000000ce6bc2", + "first_name": "Hannah", + "last_name": "Arnold" + }, + { + "id": "99999999-014f-0014-0a98-000000cf09f9", + "first_name": "Bruno", + "last_name": "Krüger" + }, + { + "id": "99999999-0150-0015-a8cf-000000cfa830", + "first_name": "Luca", + "last_name": "Pohl" + }, + { + "id": "99999999-0152-0015-e53e-000000d0e49e", + "first_name": "Paul", + "last_name": "Engel" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0017-0001-36fb-0000000e36f1", + "name": "Volleyball Varsity" + } + ] + }, + { + "id": "aaaaaaaa-002e-0002-6df7-0000001c6de2", + "name": "Volleyball Varsity Training", + "start_time": "2026-06-29T15:30:00.000Z", + "end_time": "2026-06-29T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-0144-0014-3e36-000000c83d9c", + "first_name": "Fynn", + "last_name": "Bauer" + }, + { + "id": "99999999-0145-0014-dc6d-000000c8dbd3", + "first_name": "David", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0146-0014-7aa4-000000c97a0a", + "first_name": "Noah", + "last_name": "Klein" + }, + { + "id": "99999999-0147-0014-18dc-000000ca1841", + "first_name": "Henry", + "last_name": "Huber" + }, + { + "id": "99999999-0148-0014-b713-000000cab678", + "first_name": "Rosa", + "last_name": "Schulz" + }, + { + "id": "99999999-014a-0014-f382-000000cbf2e6", + "first_name": "Samuel", + "last_name": "Wolf" + }, + { + "id": "99999999-014c-0014-2ff1-000000cd2f54", + "first_name": "Elias", + "last_name": "Wolf" + }, + { + "id": "99999999-014e-0014-6c60-000000ce6bc2", + "first_name": "Hannah", + "last_name": "Arnold" + }, + { + "id": "99999999-0150-0015-a8cf-000000cfa830", + "first_name": "Luca", + "last_name": "Pohl" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0017-0001-36fb-0000000e36f1", + "name": "Volleyball Varsity" + } + ] + }, + { + "id": "aaaaaaaa-002f-0002-0c2f-0000001d0c19", + "name": "Football Juniors Match", + "start_time": "2026-06-16T10:00:00.000Z", + "end_time": "2026-06-16T11:30:00.000Z", + "attendees": [ + { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-001c-0001-4e11-000000114e04", + "first_name": "Erik", + "last_name": "Lange" + }, + { + "id": "99999999-001e-0001-8a80-000000128a72", + "first_name": "Theo", + "last_name": "Diaz" + }, + { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + { + "id": "99999999-0021-0002-6526-000000146517", + "first_name": "Mia", + "last_name": "Albrecht" + }, + { + "id": "99999999-0022-0002-035e-00000015034e", + "first_name": "Ida", + "last_name": "Krüger" + }, + { + "id": "99999999-0023-0002-a195-00000015a185", + "first_name": "Oskar", + "last_name": "Schulz" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0026-0002-7c3c-000000177c2a", + "first_name": "Moritz", + "last_name": "Seidel" + }, + { + "id": "99999999-0029-0002-56e2-0000001956cf", + "first_name": "Oskar", + "last_name": "Werner" + }, + { + "id": "99999999-002a-0002-f519-00000019f506", + "first_name": "Erik", + "last_name": "Richter" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors" + } + ] + }, + { + "id": "aaaaaaaa-0030-0003-aa66-0000001daa50", + "name": "Basketball Juniors Open Session", + "start_time": "2026-06-14T14:00:00.000Z", + "end_time": "2026-06-14T15:30:00.000Z", + "attendees": [ + { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + { + "id": "99999999-0064-0006-cdab-0000003dcd7c", + "first_name": "Greta", + "last_name": "Roth" + }, + { + "id": "99999999-0065-0006-6be3-0000003e6bb3", + "first_name": "Frida", + "last_name": "Werner" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0006-0000-b54c-00000003b54a", + "name": "Basketball Juniors" + } + ] + }, + { + "id": "aaaaaaaa-0031-0003-489e-0000001e4887", + "name": "Football Juniors Open Session", + "start_time": "2026-06-03T18:00:00.000Z", + "end_time": "2026-06-03T19:30:00.000Z", + "attendees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-001c-0001-4e11-000000114e04", + "first_name": "Erik", + "last_name": "Lange" + }, + { + "id": "99999999-001d-0001-ec48-00000011ec3b", + "first_name": "Janne", + "last_name": "Roth" + }, + { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + { + "id": "99999999-0021-0002-6526-000000146517", + "first_name": "Mia", + "last_name": "Albrecht" + }, + { + "id": "99999999-0023-0002-a195-00000015a185", + "first_name": "Oskar", + "last_name": "Schulz" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0027-0002-1a73-000000181a61", + "first_name": "Nora", + "last_name": "Krause" + }, + { + "id": "99999999-0028-0002-b8ab-00000018b898", + "first_name": "Mats", + "last_name": "Huber" + }, + { + "id": "99999999-0029-0002-56e2-0000001956cf", + "first_name": "Oskar", + "last_name": "Werner" + }, + { + "id": "99999999-002a-0002-f519-00000019f506", + "first_name": "Erik", + "last_name": "Richter" + } + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors" + } + ] + } +] + +export const eventDetailsById: Record = { + "aaaaaaaa-0001-0000-9e37-000000009e37": { + "id": "aaaaaaaa-0001-0000-9e37-000000009e37", + "name": "Football Juniors Open Session", + "description": "Match session for Football Juniors.", + "start_time": "2026-05-17T17:30:00.000Z", + "end_time": "2026-05-17T19:00:00.000Z", + "attendees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-001c-0001-4e11-000000114e04", + "first_name": "Erik", + "last_name": "Lange" + }, + { + "id": "99999999-001d-0001-ec48-00000011ec3b", + "first_name": "Janne", + "last_name": "Roth" + }, + { + "id": "99999999-001e-0001-8a80-000000128a72", + "first_name": "Theo", + "last_name": "Diaz" + }, + { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + { + "id": "99999999-0020-0002-c6ef-00000013c6e0", + "first_name": "Levi", + "last_name": "Voigt" + }, + { + "id": "99999999-0022-0002-035e-00000015034e", + "first_name": "Ida", + "last_name": "Krüger" + }, + { + "id": "99999999-0023-0002-a195-00000015a185", + "first_name": "Oskar", + "last_name": "Schulz" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0026-0002-7c3c-000000177c2a", + "first_name": "Moritz", + "last_name": "Seidel" + }, + { + "id": "99999999-0027-0002-1a73-000000181a61", + "first_name": "Nora", + "last_name": "Krause" + }, + { + "id": "99999999-0028-0002-b8ab-00000018b898", + "first_name": "Mats", + "last_name": "Huber" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors" + } + ], + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + }, + "aaaaaaaa-0002-0000-3c6e-000000013c6e": { + "id": "aaaaaaaa-0002-0000-3c6e-000000013c6e", + "name": "Football Juniors Tournament", + "description": "Training session for Football Juniors.", + "start_time": "2026-07-18T10:30:00.000Z", + "end_time": "2026-07-18T12:00:00.000Z", + "attendees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-0020-0002-c6ef-00000013c6e0", + "first_name": "Levi", + "last_name": "Voigt" + }, + { + "id": "99999999-0021-0002-6526-000000146517", + "first_name": "Mia", + "last_name": "Albrecht" + }, + { + "id": "99999999-0022-0002-035e-00000015034e", + "first_name": "Ida", + "last_name": "Krüger" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0028-0002-b8ab-00000018b898", + "first_name": "Mats", + "last_name": "Huber" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors" + } + ], + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + }, + "aaaaaaaa-0003-0000-daa6-00000001daa5": { + "id": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "name": "Football Group A Open Session", + "description": "Time Trial session for Football Group A.", + "start_time": "2026-05-21T10:00:00.000Z", + "end_time": "2026-05-21T11:30:00.000Z", + "attendees": [ + { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + { + "id": "99999999-002d-0002-cfc0-0000001bcfab", + "first_name": "Romi", + "last_name": "Werner" + }, + { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + { + "id": "99999999-002f-0002-0c2f-0000001d0c19", + "first_name": "Romi", + "last_name": "Fuchs" + }, + { + "id": "99999999-0030-0003-aa66-0000001daa50", + "first_name": "Ben", + "last_name": "Vogel" + }, + { + "id": "99999999-0032-0003-e6d5-0000001ee6be", + "first_name": "Toni", + "last_name": "Brandt" + }, + { + "id": "99999999-0033-0003-850d-0000001f84f5", + "first_name": "Ida", + "last_name": "Arnold" + }, + { + "id": "99999999-0034-0003-2344-00000020232c", + "first_name": "Stella", + "last_name": "Zimmermann" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0002-0000-3c6e-000000013c6e", + "name": "Football Group A" + } + ], + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + } + }, + "aaaaaaaa-0004-0000-78dd-0000000278dc": { + "id": "aaaaaaaa-0004-0000-78dd-0000000278dc", + "name": "Football Group A Friendly", + "description": "Tournament session for Football Group A.", + "start_time": "2026-06-29T17:00:00.000Z", + "end_time": "2026-06-29T18:30:00.000Z", + "attendees": [ + { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + { + "id": "99999999-0031-0003-489e-0000001e4887", + "first_name": "Edda", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0033-0003-850d-0000001f84f5", + "first_name": "Ida", + "last_name": "Arnold" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0002-0000-3c6e-000000013c6e", + "name": "Football Group A" + } + ], + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + } + }, + "aaaaaaaa-0005-0000-1715-000000031713": { + "id": "aaaaaaaa-0005-0000-1715-000000031713", + "name": "Football Squad 2 Open Session", + "description": "Time Trial session for Football Squad 2.", + "start_time": "2026-05-13T11:30:00.000Z", + "end_time": "2026-05-13T13:00:00.000Z", + "attendees": [ + { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + { + "id": "99999999-0039-0003-3a5a-000000233a3f", + "first_name": "Clara", + "last_name": "Stein" + }, + { + "id": "99999999-003a-0003-d891-00000023d876", + "first_name": "Joris", + "last_name": "Stein" + }, + { + "id": "99999999-003d-0003-b337-00000025b31b", + "first_name": "Fynn", + "last_name": "Koch" + }, + { + "id": "99999999-003e-0003-516f-000000265152", + "first_name": "Marie", + "last_name": "Fuchs" + }, + { + "id": "99999999-0041-0004-2c15-000000282bf7", + "first_name": "Smilla", + "last_name": "Krause" + }, + { + "id": "99999999-0042-0004-ca4d-00000028ca2e", + "first_name": "Konrad", + "last_name": "Schwarz" + }, + { + "id": "99999999-0044-0004-06bc-0000002a069c", + "first_name": "Arne", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0045-0004-a4f3-0000002aa4d3", + "first_name": "Mats", + "last_name": "Graf" + }, + { + "id": "99999999-0046-0004-432b-0000002b430a", + "first_name": "Martha", + "last_name": "Voigt" + }, + { + "id": "99999999-0047-0004-e162-0000002be141", + "first_name": "Stella", + "last_name": "Horn" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0003-0000-daa6-00000001daa5", + "name": "Football Squad 2" + } + ], + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + } + }, + "aaaaaaaa-0006-0000-b54c-00000003b54a": { + "id": "aaaaaaaa-0006-0000-b54c-00000003b54a", + "name": "Football Squad 2 Open Session", + "description": "Match session for Football Squad 2.", + "start_time": "2026-06-24T14:30:00.000Z", + "end_time": "2026-06-24T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + { + "id": "99999999-0039-0003-3a5a-000000233a3f", + "first_name": "Clara", + "last_name": "Stein" + }, + { + "id": "99999999-003a-0003-d891-00000023d876", + "first_name": "Joris", + "last_name": "Stein" + }, + { + "id": "99999999-003d-0003-b337-00000025b31b", + "first_name": "Fynn", + "last_name": "Koch" + }, + { + "id": "99999999-0044-0004-06bc-0000002a069c", + "first_name": "Arne", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0045-0004-a4f3-0000002aa4d3", + "first_name": "Mats", + "last_name": "Graf" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0003-0000-daa6-00000001daa5", + "name": "Football Squad 2" + } + ], + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + } + }, + "aaaaaaaa-0007-0000-5384-000000045381": { + "id": "aaaaaaaa-0007-0000-5384-000000045381", + "name": "Football Seniors Training", + "description": "Friendly session for Football Seniors.", + "start_time": "2026-05-22T18:00:00.000Z", + "end_time": "2026-05-22T19:30:00.000Z", + "attendees": [ + { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0004-0000-78dd-0000000278dc", + "name": "Football Seniors" + } + ], + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + }, + "aaaaaaaa-0008-0000-f1bb-00000004f1b8": { + "id": "aaaaaaaa-0008-0000-f1bb-00000004f1b8", + "name": "Football Seniors Match", + "description": "Training session for Football Seniors.", + "start_time": "2026-07-17T14:30:00.000Z", + "end_time": "2026-07-17T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0004-0000-78dd-0000000278dc", + "name": "Football Seniors" + } + ], + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + }, + "aaaaaaaa-0009-0000-8ff3-000000058fef": { + "id": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "name": "Basketball Masters Tournament", + "description": "Training session for Basketball Masters.", + "start_time": "2026-05-29T15:30:00.000Z", + "end_time": "2026-05-29T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + { + "id": "99999999-0052-0005-adc4-00000032ad9e", + "first_name": "Martha", + "last_name": "Braun" + }, + { + "id": "99999999-0053-0005-4bfc-000000334bd5", + "first_name": "Johanna", + "last_name": "Hartmann" + }, + { + "id": "99999999-0054-0005-ea33-00000033ea0c", + "first_name": "Marie", + "last_name": "Pohl" + }, + { + "id": "99999999-0055-0005-886b-000000348843", + "first_name": "Tomas", + "last_name": "Brandt" + }, + { + "id": "99999999-0057-0005-c4da-00000035c4b1", + "first_name": "Helena", + "last_name": "Neumann" + }, + { + "id": "99999999-0058-0005-6311-0000003662e8", + "first_name": "Leon", + "last_name": "Hartmann" + }, + { + "id": "99999999-0059-0005-0149-00000037011f", + "first_name": "Paul", + "last_name": "Werner" + }, + { + "id": "99999999-005b-0005-3db8-000000383d8d", + "first_name": "Romy", + "last_name": "Voigt" + }, + { + "id": "99999999-005c-0005-dbef-00000038dbc4", + "first_name": "Felix", + "last_name": "Frank" + }, + { + "id": "99999999-005d-0005-7a27-0000003979fb", + "first_name": "Jakob", + "last_name": "Klein" + }, + { + "id": "99999999-005e-0005-185e-0000003a1832", + "first_name": "Ben", + "last_name": "Horn" + }, + { + "id": "99999999-005f-0005-b696-0000003ab669", + "first_name": "Jonah", + "last_name": "Krüger" + }, + { + "id": "99999999-0060-0006-54cd-0000003b54a0", + "first_name": "Lina", + "last_name": "Graf" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0005-0000-1715-000000031713", + "name": "Basketball Masters" + } + ], + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + } + }, + "aaaaaaaa-000a-0000-2e2a-000000062e26": { + "id": "aaaaaaaa-000a-0000-2e2a-000000062e26", + "name": "Basketball Masters Match", + "description": "Tournament session for Basketball Masters.", + "start_time": "2026-07-08T12:30:00.000Z", + "end_time": "2026-07-08T14:00:00.000Z", + "attendees": [ + { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + { + "id": "99999999-0054-0005-ea33-00000033ea0c", + "first_name": "Marie", + "last_name": "Pohl" + }, + { + "id": "99999999-0055-0005-886b-000000348843", + "first_name": "Tomas", + "last_name": "Brandt" + }, + { + "id": "99999999-0057-0005-c4da-00000035c4b1", + "first_name": "Helena", + "last_name": "Neumann" + }, + { + "id": "99999999-005e-0005-185e-0000003a1832", + "first_name": "Ben", + "last_name": "Horn" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0005-0000-1715-000000031713", + "name": "Basketball Masters" + } + ], + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + } + }, + "aaaaaaaa-000b-0000-cc62-00000006cc5d": { + "id": "aaaaaaaa-000b-0000-cc62-00000006cc5d", + "name": "Basketball Juniors Open Session", + "description": "Friendly session for Basketball Juniors.", + "start_time": "2026-05-10T10:30:00.000Z", + "end_time": "2026-05-10T12:00:00.000Z", + "attendees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0061-0006-f305-0000003bf2d7", + "first_name": "Leon", + "last_name": "Braun" + }, + { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + { + "id": "99999999-0064-0006-cdab-0000003dcd7c", + "first_name": "Greta", + "last_name": "Roth" + }, + { + "id": "99999999-0065-0006-6be3-0000003e6bb3", + "first_name": "Frida", + "last_name": "Werner" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0006-0000-b54c-00000003b54a", + "name": "Basketball Juniors" + } + ], + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + }, + "aaaaaaaa-000c-0000-6a99-000000076a94": { + "id": "aaaaaaaa-000c-0000-6a99-000000076a94", + "name": "Basketball Juniors Friendly", + "description": "Friendly session for Basketball Juniors.", + "start_time": "2026-06-28T15:30:00.000Z", + "end_time": "2026-06-28T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-0061-0006-f305-0000003bf2d7", + "first_name": "Leon", + "last_name": "Braun" + }, + { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0006-0000-b54c-00000003b54a", + "name": "Basketball Juniors" + } + ], + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + }, + "aaaaaaaa-000d-0000-08d1-0000000808cb": { + "id": "aaaaaaaa-000d-0000-08d1-0000000808cb", + "name": "Basketball U14 Tournament", + "description": "Tournament session for Basketball U14.", + "start_time": "2026-06-04T13:30:00.000Z", + "end_time": "2026-06-04T15:00:00.000Z", + "attendees": [ + { + "id": "99999999-0066-0006-0a1a-0000003f09ea", + "first_name": "Jonah", + "last_name": "Nowak" + }, + { + "id": "99999999-0067-0006-a851-0000003fa821", + "first_name": "Luca", + "last_name": "Peters" + }, + { + "id": "99999999-0068-0006-4689-000000404658", + "first_name": "Clara", + "last_name": "Seidel" + }, + { + "id": "99999999-0069-0006-e4c0-00000040e48f", + "first_name": "Edda", + "last_name": "Pohl" + }, + { + "id": "99999999-006a-0006-82f8-0000004182c6", + "first_name": "Ben", + "last_name": "Park" + }, + { + "id": "99999999-006d-0006-5d9e-000000435d6b", + "first_name": "Tilda", + "last_name": "Albrecht" + }, + { + "id": "99999999-006e-0006-fbd6-00000043fba2", + "first_name": "Ben", + "last_name": "Lehmann" + }, + { + "id": "99999999-006f-0006-9a0d-0000004499d9", + "first_name": "Liv", + "last_name": "Brandt" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0007-0000-5384-000000045381", + "name": "Basketball U14" + } + ], + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + } + }, + "aaaaaaaa-000e-0000-a708-00000008a702": { + "id": "aaaaaaaa-000e-0000-a708-00000008a702", + "name": "Basketball U14 Tournament", + "description": "Match session for Basketball U14.", + "start_time": "2026-07-07T10:00:00.000Z", + "end_time": "2026-07-07T11:30:00.000Z", + "attendees": [ + { + "id": "99999999-0068-0006-4689-000000404658", + "first_name": "Clara", + "last_name": "Seidel" + }, + { + "id": "99999999-006b-0006-212f-0000004220fd", + "first_name": "Felix", + "last_name": "Koch" + }, + { + "id": "99999999-006d-0006-5d9e-000000435d6b", + "first_name": "Tilda", + "last_name": "Albrecht" + }, + { + "id": "99999999-006f-0006-9a0d-0000004499d9", + "first_name": "Liv", + "last_name": "Brandt" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0007-0000-5384-000000045381", + "name": "Basketball U14" + } + ], + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + } + }, + "aaaaaaaa-000f-0000-4540-000000094539": { + "id": "aaaaaaaa-000f-0000-4540-000000094539", + "name": "Basketball Squad 1 Time Trial", + "description": "Tournament session for Basketball Squad 1.", + "start_time": "2026-06-03T14:00:00.000Z", + "end_time": "2026-06-03T15:30:00.000Z", + "attendees": [ + { + "id": "99999999-0071-0007-d67c-00000045d647", + "first_name": "Nele", + "last_name": "Schwarz" + }, + { + "id": "99999999-0072-0007-74b4-00000046747e", + "first_name": "Lena", + "last_name": "Pohl" + }, + { + "id": "99999999-0073-0007-12eb-0000004712b5", + "first_name": "Helena", + "last_name": "Vogel" + }, + { + "id": "99999999-0074-0007-b123-00000047b0ec", + "first_name": "Helena", + "last_name": "Wagner" + }, + { + "id": "99999999-0075-0007-4f5a-000000484f23", + "first_name": "Emil", + "last_name": "Kaiser" + }, + { + "id": "99999999-0077-0007-8bc9-000000498b91", + "first_name": "Ada", + "last_name": "Hoffmann" + }, + { + "id": "99999999-0078-0007-2a01-0000004a29c8", + "first_name": "Oskar", + "last_name": "Nowak" + }, + { + "id": "99999999-0079-0007-c838-0000004ac7ff", + "first_name": "Charlotte", + "last_name": "Berger" + }, + { + "id": "99999999-007a-0007-666f-0000004b6636", + "first_name": "Leon", + "last_name": "Neumann" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0008-0000-f1bb-00000004f1b8", + "name": "Basketball Squad 1" + } + ], + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + } + }, + "aaaaaaaa-0010-0001-e377-00000009e370": { + "id": "aaaaaaaa-0010-0001-e377-00000009e370", + "name": "Basketball Squad 1 Time Trial", + "description": "Friendly session for Basketball Squad 1.", + "start_time": "2026-07-16T18:30:00.000Z", + "end_time": "2026-07-16T20:00:00.000Z", + "attendees": [ + { + "id": "99999999-0072-0007-74b4-00000046747e", + "first_name": "Lena", + "last_name": "Pohl" + }, + { + "id": "99999999-0074-0007-b123-00000047b0ec", + "first_name": "Helena", + "last_name": "Wagner" + }, + { + "id": "99999999-0079-0007-c838-0000004ac7ff", + "first_name": "Charlotte", + "last_name": "Berger" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0008-0000-f1bb-00000004f1b8", + "name": "Basketball Squad 1" + } + ], + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + } + }, + "aaaaaaaa-0011-0001-81af-0000000a81a7": { + "id": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "name": "Basketball Group B Friendly", + "description": "Match session for Basketball Group B.", + "start_time": "2026-05-26T11:30:00.000Z", + "end_time": "2026-05-26T13:00:00.000Z", + "attendees": [ + { + "id": "99999999-007c-0007-a2de-0000004ca2a4", + "first_name": "Erik", + "last_name": "Scholz" + }, + { + "id": "99999999-007d-0007-4116-0000004d40db", + "first_name": "Mia", + "last_name": "Neumann" + }, + { + "id": "99999999-007e-0007-df4d-0000004ddf12", + "first_name": "Elias", + "last_name": "Diaz" + }, + { + "id": "99999999-007f-0007-7d85-0000004e7d49", + "first_name": "Tilda", + "last_name": "Neumann" + }, + { + "id": "99999999-0080-0008-1bbc-0000004f1b80", + "first_name": "Noah", + "last_name": "Richter" + }, + { + "id": "99999999-0081-0008-b9f4-0000004fb9b7", + "first_name": "Leon", + "last_name": "Busch" + }, + { + "id": "99999999-0084-0008-949a-00000051945c", + "first_name": "Juna", + "last_name": "Reil" + }, + { + "id": "99999999-0086-0008-d109-00000052d0ca", + "first_name": "Johanna", + "last_name": "Kaiser" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0009-0000-8ff3-000000058fef", + "name": "Basketball Group B" + } + ], + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + } + }, + "aaaaaaaa-0012-0001-1fe6-0000000b1fde": { + "id": "aaaaaaaa-0012-0001-1fe6-0000000b1fde", + "name": "Basketball Group B Match", + "description": "Time Trial session for Basketball Group B.", + "start_time": "2026-07-13T16:00:00.000Z", + "end_time": "2026-07-13T17:30:00.000Z", + "attendees": [ + { + "id": "99999999-007d-0007-4116-0000004d40db", + "first_name": "Mia", + "last_name": "Neumann" + }, + { + "id": "99999999-0087-0008-6f41-000000536f01", + "first_name": "Sofia", + "last_name": "Brandt" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0009-0000-8ff3-000000058fef", + "name": "Basketball Group B" + } + ], + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + } + }, + "aaaaaaaa-0013-0001-be1e-0000000bbe15": { + "id": "aaaaaaaa-0013-0001-be1e-0000000bbe15", + "name": "Swimming Juniors Open Session", + "description": "Open Session session for Swimming Juniors.", + "start_time": "2026-06-05T12:00:00.000Z", + "end_time": "2026-06-05T13:30:00.000Z", + "attendees": [ + { + "id": "99999999-0089-0008-abb0-00000054ab6f", + "first_name": "Hannah", + "last_name": "Pohl" + }, + { + "id": "99999999-008a-0008-49e7-0000005549a6", + "first_name": "Fynn", + "last_name": "Reil" + }, + { + "id": "99999999-008b-0008-e81f-00000055e7dd", + "first_name": "Toni", + "last_name": "Neumann" + }, + { + "id": "99999999-008c-0008-8656-000000568614", + "first_name": "Moritz", + "last_name": "Wolf" + }, + { + "id": "99999999-008d-0008-248e-00000057244b", + "first_name": "Frieda", + "last_name": "Winter" + }, + { + "id": "99999999-008e-0008-c2c5-00000057c282", + "first_name": "Charlotte", + "last_name": "Schwarz" + }, + { + "id": "99999999-008f-0008-60fc-0000005860b9", + "first_name": "Moritz", + "last_name": "Krause" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000a-0000-2e2a-000000062e26", + "name": "Swimming Juniors" + } + ], + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + }, + "aaaaaaaa-0014-0001-5c55-0000000c5c4c": { + "id": "aaaaaaaa-0014-0001-5c55-0000000c5c4c", + "name": "Swimming Juniors Friendly", + "description": "Tournament session for Swimming Juniors.", + "start_time": "2026-06-28T16:00:00.000Z", + "end_time": "2026-06-28T17:30:00.000Z", + "attendees": [ + { + "id": "99999999-008a-0008-49e7-0000005549a6", + "first_name": "Fynn", + "last_name": "Reil" + }, + { + "id": "99999999-008d-0008-248e-00000057244b", + "first_name": "Frieda", + "last_name": "Winter" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000a-0000-2e2a-000000062e26", + "name": "Swimming Juniors" + } + ], + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + }, + "aaaaaaaa-0015-0001-fa8c-0000000cfa83": { + "id": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "name": "Swimming Group A Tournament", + "description": "Time Trial session for Swimming Group A.", + "start_time": "2026-06-04T13:00:00.000Z", + "end_time": "2026-06-04T14:30:00.000Z", + "attendees": [ + { + "id": "99999999-0090-0009-ff34-00000058fef0", + "first_name": "Hannah", + "last_name": "Lange" + }, + { + "id": "99999999-0091-0009-9d6b-000000599d27", + "first_name": "Smilla", + "last_name": "Busch" + }, + { + "id": "99999999-0092-0009-3ba3-0000005a3b5e", + "first_name": "Ida", + "last_name": "Neumann" + }, + { + "id": "99999999-0093-0009-d9da-0000005ad995", + "first_name": "Finn", + "last_name": "Vogel" + }, + { + "id": "99999999-0094-0009-7812-0000005b77cc", + "first_name": "Greta", + "last_name": "Pohl" + }, + { + "id": "99999999-0095-0009-1649-0000005c1603", + "first_name": "Lea", + "last_name": "Park" + }, + { + "id": "99999999-0097-0009-52b8-0000005d5271", + "first_name": "Stella", + "last_name": "Krüger" + }, + { + "id": "99999999-0098-0009-f0f0-0000005df0a8", + "first_name": "Aaron", + "last_name": "Sommer" + }, + { + "id": "99999999-0099-0009-8f27-0000005e8edf", + "first_name": "Bela", + "last_name": "Arnold" + }, + { + "id": "99999999-009a-0009-2d5f-0000005f2d16", + "first_name": "Mathilda", + "last_name": "Kaiser" + }, + { + "id": "99999999-009b-0009-cb96-0000005fcb4d", + "first_name": "Jonas", + "last_name": "Krause" + }, + { + "id": "99999999-009c-0009-69ce-000000606984", + "first_name": "Carla", + "last_name": "Albrecht" + }, + { + "id": "99999999-009d-0009-0805-0000006107bb", + "first_name": "Lena", + "last_name": "Kaiser" + }, + { + "id": "99999999-009e-0009-a63d-00000061a5f2", + "first_name": "Joris", + "last_name": "Schulz" + }, + { + "id": "99999999-00a0-000a-e2ac-00000062e260", + "first_name": "Jonah", + "last_name": "Peters" + }, + { + "id": "99999999-00a1-000a-80e3-000000638097", + "first_name": "Amelie", + "last_name": "Lange" + }, + { + "id": "99999999-00a2-000a-1f1b-000000641ece", + "first_name": "Jonas", + "last_name": "Nowak" + }, + { + "id": "99999999-00a4-000a-5b89-000000655b3c", + "first_name": "Smilla", + "last_name": "Hoffmann" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000b-0000-cc62-00000006cc5d", + "name": "Swimming Group A" + } + ], + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + }, + "aaaaaaaa-0016-0001-98c4-0000000d98ba": { + "id": "aaaaaaaa-0016-0001-98c4-0000000d98ba", + "name": "Swimming Group A Friendly", + "description": "Training session for Swimming Group A.", + "start_time": "2026-07-05T11:30:00.000Z", + "end_time": "2026-07-05T13:00:00.000Z", + "attendees": [ + { + "id": "99999999-0092-0009-3ba3-0000005a3b5e", + "first_name": "Ida", + "last_name": "Neumann" + }, + { + "id": "99999999-0095-0009-1649-0000005c1603", + "first_name": "Lea", + "last_name": "Park" + }, + { + "id": "99999999-0098-0009-f0f0-0000005df0a8", + "first_name": "Aaron", + "last_name": "Sommer" + }, + { + "id": "99999999-009d-0009-0805-0000006107bb", + "first_name": "Lena", + "last_name": "Kaiser" + }, + { + "id": "99999999-009f-0009-4474-000000624429", + "first_name": "Wilma", + "last_name": "Otto" + }, + { + "id": "99999999-00a1-000a-80e3-000000638097", + "first_name": "Amelie", + "last_name": "Lange" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000b-0000-cc62-00000006cc5d", + "name": "Swimming Group A" + } + ], + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + }, + "aaaaaaaa-0017-0001-36fb-0000000e36f1": { + "id": "aaaaaaaa-0017-0001-36fb-0000000e36f1", + "name": "Swimming Group B Time Trial", + "description": "Training session for Swimming Group B.", + "start_time": "2026-05-29T10:00:00.000Z", + "end_time": "2026-05-29T11:30:00.000Z", + "attendees": [ + { + "id": "99999999-00a5-000a-f9c1-00000065f973", + "first_name": "Toni", + "last_name": "Huber" + }, + { + "id": "99999999-00a6-000a-97f8-0000006697aa", + "first_name": "Jan", + "last_name": "Lange" + }, + { + "id": "99999999-00a7-000a-3630-0000006735e1", + "first_name": "Carla", + "last_name": "Arnold" + }, + { + "id": "99999999-00a8-000a-d467-00000067d418", + "first_name": "Noah", + "last_name": "Braun" + }, + { + "id": "99999999-00a9-000a-729f-00000068724f", + "first_name": "Alma", + "last_name": "Busch" + }, + { + "id": "99999999-00ab-000a-af0e-00000069aebd", + "first_name": "Bruno", + "last_name": "Berger" + }, + { + "id": "99999999-00ac-000a-4d45-0000006a4cf4", + "first_name": "Romy", + "last_name": "Beck" + }, + { + "id": "99999999-00ad-000a-eb7d-0000006aeb2b", + "first_name": "Joris", + "last_name": "Hoffmann" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000c-0000-6a99-000000076a94", + "name": "Swimming Group B" + } + ], + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + } + }, + "aaaaaaaa-0018-0001-d533-0000000ed528": { + "id": "aaaaaaaa-0018-0001-d533-0000000ed528", + "name": "Swimming Group B Friendly", + "description": "Time Trial session for Swimming Group B.", + "start_time": "2026-07-10T17:00:00.000Z", + "end_time": "2026-07-10T18:30:00.000Z", + "attendees": [], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000c-0000-6a99-000000076a94", + "name": "Swimming Group B" + } + ], + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + } + }, + "aaaaaaaa-0019-0001-736a-0000000f735f": { + "id": "aaaaaaaa-0019-0001-736a-0000000f735f", + "name": "Swimming Seniors Open Session", + "description": "Open Session session for Swimming Seniors.", + "start_time": "2026-05-14T14:30:00.000Z", + "end_time": "2026-05-14T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-00ae-000a-89b4-0000006b8962", + "first_name": "Jonah", + "last_name": "König" + }, + { + "id": "99999999-00af-000a-27ec-0000006c2799", + "first_name": "Emil", + "last_name": "Stein" + }, + { + "id": "99999999-00b2-000b-0292-0000006e023e", + "first_name": "Noah", + "last_name": "Beck" + }, + { + "id": "99999999-00b3-000b-a0ca-0000006ea075", + "first_name": "David", + "last_name": "Klein" + }, + { + "id": "99999999-00b4-000b-3f01-0000006f3eac", + "first_name": "Leon", + "last_name": "Berger" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000d-0000-08d1-0000000808cb", + "name": "Swimming Seniors" + } + ], + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + }, + "aaaaaaaa-001a-0001-11a2-000000101196": { + "id": "aaaaaaaa-001a-0001-11a2-000000101196", + "name": "Swimming Seniors Match", + "description": "Time Trial session for Swimming Seniors.", + "start_time": "2026-07-04T14:00:00.000Z", + "end_time": "2026-07-04T15:30:00.000Z", + "attendees": [ + { + "id": "99999999-00af-000a-27ec-0000006c2799", + "first_name": "Emil", + "last_name": "Stein" + }, + { + "id": "99999999-00b1-000b-645b-0000006d6407", + "first_name": "Elias", + "last_name": "Braun" + }, + { + "id": "99999999-00b4-000b-3f01-0000006f3eac", + "first_name": "Leon", + "last_name": "Berger" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000d-0000-08d1-0000000808cb", + "name": "Swimming Seniors" + } + ], + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + }, + "aaaaaaaa-001b-0001-afd9-00000010afcd": { + "id": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "name": "Swimming Squad 1 Tournament", + "description": "Tournament session for Swimming Squad 1.", + "start_time": "2026-05-16T14:30:00.000Z", + "end_time": "2026-05-16T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-00b6-000b-7b70-000000707b1a", + "first_name": "Finn", + "last_name": "Neumann" + }, + { + "id": "99999999-00b7-000b-19a7-000000711951", + "first_name": "Konrad", + "last_name": "Klein" + }, + { + "id": "99999999-00b8-000b-b7df-00000071b788", + "first_name": "Ben", + "last_name": "Frank" + }, + { + "id": "99999999-00b9-000b-5616-0000007255bf", + "first_name": "Frida", + "last_name": "Brandt" + }, + { + "id": "99999999-00ba-000b-f44e-00000072f3f6", + "first_name": "Lea", + "last_name": "Brandt" + }, + { + "id": "99999999-00bb-000b-9285-00000073922d", + "first_name": "Sofia", + "last_name": "Pohl" + }, + { + "id": "99999999-00bd-000b-cef4-00000074ce9b", + "first_name": "Mara", + "last_name": "Engel" + }, + { + "id": "99999999-00be-000b-6d2c-000000756cd2", + "first_name": "Emil", + "last_name": "Diaz" + }, + { + "id": "99999999-00bf-000b-0b63-000000760b09", + "first_name": "David", + "last_name": "Braun" + }, + { + "id": "99999999-00c0-000c-a99b-00000076a940", + "first_name": "Aaron", + "last_name": "Hoffmann" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000e-0000-a708-00000008a702", + "name": "Swimming Squad 1" + } + ], + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + } + }, + "aaaaaaaa-001c-0001-4e11-000000114e04": { + "id": "aaaaaaaa-001c-0001-4e11-000000114e04", + "name": "Swimming Squad 1 Tournament", + "description": "Match session for Swimming Squad 1.", + "start_time": "2026-06-29T18:00:00.000Z", + "end_time": "2026-06-29T19:30:00.000Z", + "attendees": [ + { + "id": "99999999-00b6-000b-7b70-000000707b1a", + "first_name": "Finn", + "last_name": "Neumann" + }, + { + "id": "99999999-00bb-000b-9285-00000073922d", + "first_name": "Sofia", + "last_name": "Pohl" + }, + { + "id": "99999999-00bf-000b-0b63-000000760b09", + "first_name": "David", + "last_name": "Braun" + } + ], + "sports_linked": [ + "Swimming" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000e-0000-a708-00000008a702", + "name": "Swimming Squad 1" + } + ], + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + } + }, + "aaaaaaaa-001d-0001-ec48-00000011ec3b": { + "id": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "name": "Athletics Group A Time Trial", + "description": "Time Trial session for Athletics Group A.", + "start_time": "2026-05-27T15:30:00.000Z", + "end_time": "2026-05-27T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-00c1-000c-47d2-000000774777", + "first_name": "Emil", + "last_name": "Schwarz" + }, + { + "id": "99999999-00c3-000c-8441-0000007883e5", + "first_name": "Rosa", + "last_name": "Frank" + }, + { + "id": "99999999-00c4-000c-2279-00000079221c", + "first_name": "Frida", + "last_name": "Neumann" + }, + { + "id": "99999999-00c5-000c-c0b0-00000079c053", + "first_name": "Clara", + "last_name": "Hartmann" + }, + { + "id": "99999999-00c6-000c-5ee8-0000007a5e8a", + "first_name": "Edda", + "last_name": "Vogt" + }, + { + "id": "99999999-00c7-000c-fd1f-0000007afcc1", + "first_name": "Leon", + "last_name": "Beck" + }, + { + "id": "99999999-00c8-000c-9b57-0000007b9af8", + "first_name": "Emil", + "last_name": "Klein" + }, + { + "id": "99999999-00c9-000c-398e-0000007c392f", + "first_name": "Jonas", + "last_name": "Stein" + }, + { + "id": "99999999-00ca-000c-d7c6-0000007cd766", + "first_name": "Nele", + "last_name": "Seidel" + }, + { + "id": "99999999-00cb-000c-75fd-0000007d759d", + "first_name": "Moritz", + "last_name": "Busch" + }, + { + "id": "99999999-00cc-000c-1434-0000007e13d4", + "first_name": "Rosa", + "last_name": "Klein" + }, + { + "id": "99999999-00cd-000c-b26c-0000007eb20b", + "first_name": "Samuel", + "last_name": "Winter" + }, + { + "id": "99999999-00ce-000c-50a3-0000007f5042", + "first_name": "Bruno", + "last_name": "Hartmann" + }, + { + "id": "99999999-00cf-000c-eedb-0000007fee79", + "first_name": "Toni", + "last_name": "Krause" + }, + { + "id": "99999999-00d0-000d-8d12-000000808cb0", + "first_name": "Lotte", + "last_name": "Richter" + } + ], + "sports_linked": [ + "Athletics" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000f-0000-4540-000000094539", + "name": "Athletics Group A" + } + ], + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + } + }, + "aaaaaaaa-001e-0001-8a80-000000128a72": { + "id": "aaaaaaaa-001e-0001-8a80-000000128a72", + "name": "Athletics Group A Match", + "description": "Friendly session for Athletics Group A.", + "start_time": "2026-07-19T18:30:00.000Z", + "end_time": "2026-07-19T20:00:00.000Z", + "attendees": [ + { + "id": "99999999-00c1-000c-47d2-000000774777", + "first_name": "Emil", + "last_name": "Schwarz" + }, + { + "id": "99999999-00c5-000c-c0b0-00000079c053", + "first_name": "Clara", + "last_name": "Hartmann" + }, + { + "id": "99999999-00ca-000c-d7c6-0000007cd766", + "first_name": "Nele", + "last_name": "Seidel" + }, + { + "id": "99999999-00cc-000c-1434-0000007e13d4", + "first_name": "Rosa", + "last_name": "Klein" + }, + { + "id": "99999999-00ce-000c-50a3-0000007f5042", + "first_name": "Bruno", + "last_name": "Hartmann" + }, + { + "id": "99999999-00d0-000d-8d12-000000808cb0", + "first_name": "Lotte", + "last_name": "Richter" + } + ], + "sports_linked": [ + "Athletics" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-000f-0000-4540-000000094539", + "name": "Athletics Group A" + } + ], + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + } + }, + "aaaaaaaa-001f-0001-28b7-0000001328a9": { + "id": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "name": "Athletics Development Open Session", + "description": "Training session for Athletics Development.", + "start_time": "2026-05-17T17:00:00.000Z", + "end_time": "2026-05-17T18:30:00.000Z", + "attendees": [ + { + "id": "99999999-00d1-000d-2b4a-000000812ae7", + "first_name": "Lotte", + "last_name": "Frank" + }, + { + "id": "99999999-00d2-000d-c981-00000081c91e", + "first_name": "Mara", + "last_name": "Seidel" + }, + { + "id": "99999999-00d3-000d-67b9-000000826755", + "first_name": "Ella", + "last_name": "Pohl" + }, + { + "id": "99999999-00d4-000d-05f0-00000083058c", + "first_name": "Martha", + "last_name": "Engel" + }, + { + "id": "99999999-00d5-000d-a428-00000083a3c3", + "first_name": "Alma", + "last_name": "Vogel" + }, + { + "id": "99999999-00d6-000d-425f-0000008441fa", + "first_name": "Nele", + "last_name": "Scholz" + }, + { + "id": "99999999-00d7-000d-e097-00000084e031", + "first_name": "Oskar", + "last_name": "Stein" + }, + { + "id": "99999999-00d8-000d-7ece-000000857e68", + "first_name": "Juna", + "last_name": "Diaz" + }, + { + "id": "99999999-00d9-000d-1d06-000000861c9f", + "first_name": "Wilma", + "last_name": "Stein" + }, + { + "id": "99999999-00da-000d-bb3d-00000086bad6", + "first_name": "Fynn", + "last_name": "Hoffmann" + }, + { + "id": "99999999-00db-000d-5975-00000087590d", + "first_name": "Ida", + "last_name": "Vogel" + }, + { + "id": "99999999-00dd-000d-95e4-00000088957b", + "first_name": "Felix", + "last_name": "Krause" + }, + { + "id": "99999999-00de-000d-341b-0000008933b2", + "first_name": "Helena", + "last_name": "Koch" + }, + { + "id": "99999999-00df-000d-d253-00000089d1e9", + "first_name": "Toni", + "last_name": "Seidel" + }, + { + "id": "99999999-00e0-000e-708a-0000008a7020", + "first_name": "Nele", + "last_name": "Braun" + }, + { + "id": "99999999-00e1-000e-0ec1-0000008b0e57", + "first_name": "Ella", + "last_name": "Nowak" + }, + { + "id": "99999999-00e2-000e-acf9-0000008bac8e", + "first_name": "Ben", + "last_name": "Busch" + } + ], + "sports_linked": [ + "Athletics" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0010-0001-e377-00000009e370", + "name": "Athletics Development" + } + ], + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + } + }, + "aaaaaaaa-0020-0002-c6ef-00000013c6e0": { + "id": "aaaaaaaa-0020-0002-c6ef-00000013c6e0", + "name": "Athletics Development Friendly", + "description": "Tournament session for Athletics Development.", + "start_time": "2026-07-05T15:30:00.000Z", + "end_time": "2026-07-05T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-00d3-000d-67b9-000000826755", + "first_name": "Ella", + "last_name": "Pohl" + }, + { + "id": "99999999-00d5-000d-a428-00000083a3c3", + "first_name": "Alma", + "last_name": "Vogel" + }, + { + "id": "99999999-00d8-000d-7ece-000000857e68", + "first_name": "Juna", + "last_name": "Diaz" + }, + { + "id": "99999999-00da-000d-bb3d-00000086bad6", + "first_name": "Fynn", + "last_name": "Hoffmann" + }, + { + "id": "99999999-00db-000d-5975-00000087590d", + "first_name": "Ida", + "last_name": "Vogel" + } + ], + "sports_linked": [ + "Athletics" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0010-0001-e377-00000009e370", + "name": "Athletics Development" + } + ], + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + } + }, + "aaaaaaaa-0021-0002-6526-000000146517": { + "id": "aaaaaaaa-0021-0002-6526-000000146517", + "name": "Athletics Varsity Friendly", + "description": "Time Trial session for Athletics Varsity.", + "start_time": "2026-05-15T18:30:00.000Z", + "end_time": "2026-05-15T20:00:00.000Z", + "attendees": [ + { + "id": "99999999-00e3-000e-4b30-0000008c4ac5", + "first_name": "Nele", + "last_name": "Brandt" + }, + { + "id": "99999999-00e4-000e-e968-0000008ce8fc", + "first_name": "Jonah", + "last_name": "Frank" + }, + { + "id": "99999999-00e5-000e-879f-0000008d8733", + "first_name": "Aaron", + "last_name": "Arnold" + }, + { + "id": "99999999-00e7-000e-c40e-0000008ec3a1", + "first_name": "Amelie", + "last_name": "Seidel" + }, + { + "id": "99999999-00e8-000e-6246-0000008f61d8", + "first_name": "Lea", + "last_name": "Stein" + }, + { + "id": "99999999-00e9-000e-007d-00000090000f", + "first_name": "Arne", + "last_name": "Horn" + }, + { + "id": "99999999-00eb-000e-3cec-000000913c7d", + "first_name": "Emil", + "last_name": "Sauer" + }, + { + "id": "99999999-00ec-000e-db24-00000091dab4", + "first_name": "Romi", + "last_name": "Park" + }, + { + "id": "99999999-00ed-000e-795b-0000009278eb", + "first_name": "Mats", + "last_name": "Horn" + }, + { + "id": "99999999-00ee-000e-1793-000000931722", + "first_name": "Lina", + "last_name": "Krüger" + }, + { + "id": "99999999-00f1-000f-f239-00000094f1c7", + "first_name": "Charlotte", + "last_name": "Ziegler" + }, + { + "id": "99999999-00f2-000f-9071-000000958ffe", + "first_name": "Rosa", + "last_name": "Brandt" + } + ], + "sports_linked": [ + "Athletics" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0011-0001-81af-0000000a81a7", + "name": "Athletics Varsity" + } + ], + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + } + }, + "aaaaaaaa-0022-0002-035e-00000015034e": { + "id": "aaaaaaaa-0022-0002-035e-00000015034e", + "name": "Athletics Varsity Friendly", + "description": "Match session for Athletics Varsity.", + "start_time": "2026-07-16T12:00:00.000Z", + "end_time": "2026-07-16T13:30:00.000Z", + "attendees": [ + { + "id": "99999999-00e4-000e-e968-0000008ce8fc", + "first_name": "Jonah", + "last_name": "Frank" + }, + { + "id": "99999999-00ed-000e-795b-0000009278eb", + "first_name": "Mats", + "last_name": "Horn" + }, + { + "id": "99999999-00ee-000e-1793-000000931722", + "first_name": "Lina", + "last_name": "Krüger" + }, + { + "id": "99999999-00ef-000e-b5ca-00000093b559", + "first_name": "Henry", + "last_name": "Hartmann" + }, + { + "id": "99999999-00f2-000f-9071-000000958ffe", + "first_name": "Rosa", + "last_name": "Brandt" + } + ], + "sports_linked": [ + "Athletics" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0011-0001-81af-0000000a81a7", + "name": "Athletics Varsity" + } + ], + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + } + }, + "aaaaaaaa-0023-0002-a195-00000015a185": { + "id": "aaaaaaaa-0023-0002-a195-00000015a185", + "name": "Athletics Masters Training", + "description": "Match session for Athletics Masters.", + "start_time": "2026-06-11T12:00:00.000Z", + "end_time": "2026-06-11T13:30:00.000Z", + "attendees": [ + { + "id": "99999999-00f5-000f-6b17-000000976aa3", + "first_name": "Til", + "last_name": "Lehmann" + }, + { + "id": "99999999-00f6-000f-094e-0000009808da", + "first_name": "Anton", + "last_name": "Vogt" + }, + { + "id": "99999999-00f8-000f-45bd-000000994548", + "first_name": "Til", + "last_name": "Bauer" + }, + { + "id": "99999999-00f9-000f-e3f5-00000099e37f", + "first_name": "Joris", + "last_name": "Huber" + }, + { + "id": "99999999-00fa-000f-822c-0000009a81b6", + "first_name": "Mara", + "last_name": "Vogel" + }, + { + "id": "99999999-00fb-000f-2064-0000009b1fed", + "first_name": "Martha", + "last_name": "Vogel" + }, + { + "id": "99999999-00fc-000f-be9b-0000009bbe24", + "first_name": "Mats", + "last_name": "Kaiser" + }, + { + "id": "99999999-00fd-000f-5cd3-0000009c5c5b", + "first_name": "Linus", + "last_name": "Hartmann" + }, + { + "id": "99999999-00fe-000f-fb0a-0000009cfa92", + "first_name": "Erik", + "last_name": "Schulz" + }, + { + "id": "99999999-00ff-000f-9942-0000009d98c9", + "first_name": "Ida", + "last_name": "Kaiser" + }, + { + "id": "99999999-0100-0010-3779-0000009e3700", + "first_name": "Felix", + "last_name": "Brandt" + }, + { + "id": "99999999-0101-0010-d5b1-0000009ed537", + "first_name": "Clara", + "last_name": "Pohl" + }, + { + "id": "99999999-0102-0010-73e8-0000009f736e", + "first_name": "Niklas", + "last_name": "Fuchs" + }, + { + "id": "99999999-0103-0010-1220-000000a011a5", + "first_name": "Leon", + "last_name": "Roth" + }, + { + "id": "99999999-0104-0010-b057-000000a0afdc", + "first_name": "Alma", + "last_name": "Roth" + }, + { + "id": "99999999-0105-0010-4e8f-000000a14e13", + "first_name": "Levi", + "last_name": "Kaiser" + }, + { + "id": "99999999-0107-0010-8afe-000000a28a81", + "first_name": "Greta", + "last_name": "Sommer" + }, + { + "id": "99999999-0108-0010-2935-000000a328b8", + "first_name": "Helena", + "last_name": "Park" + }, + { + "id": "99999999-0109-0010-c76c-000000a3c6ef", + "first_name": "Alma", + "last_name": "Frank" + } + ], + "sports_linked": [ + "Athletics" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0012-0001-1fe6-0000000b1fde", + "name": "Athletics Masters" + } + ], + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + }, + "aaaaaaaa-0024-0002-3fcd-000000163fbc": { + "id": "aaaaaaaa-0024-0002-3fcd-000000163fbc", + "name": "Athletics Masters Match", + "description": "Friendly session for Athletics Masters.", + "start_time": "2026-07-05T13:30:00.000Z", + "end_time": "2026-07-05T15:00:00.000Z", + "attendees": [ + { + "id": "99999999-00f6-000f-094e-0000009808da", + "first_name": "Anton", + "last_name": "Vogt" + }, + { + "id": "99999999-00f8-000f-45bd-000000994548", + "first_name": "Til", + "last_name": "Bauer" + }, + { + "id": "99999999-00fc-000f-be9b-0000009bbe24", + "first_name": "Mats", + "last_name": "Kaiser" + }, + { + "id": "99999999-00fd-000f-5cd3-0000009c5c5b", + "first_name": "Linus", + "last_name": "Hartmann" + }, + { + "id": "99999999-0105-0010-4e8f-000000a14e13", + "first_name": "Levi", + "last_name": "Kaiser" + }, + { + "id": "99999999-0108-0010-2935-000000a328b8", + "first_name": "Helena", + "last_name": "Park" + } + ], + "sports_linked": [ + "Athletics" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0012-0001-1fe6-0000000b1fde", + "name": "Athletics Masters" + } + ], + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + }, + "aaaaaaaa-0025-0002-de04-00000016ddf3": { + "id": "aaaaaaaa-0025-0002-de04-00000016ddf3", + "name": "Volleyball Juniors Time Trial", + "description": "Match session for Volleyball Juniors.", + "start_time": "2026-05-19T14:00:00.000Z", + "end_time": "2026-05-19T15:30:00.000Z", + "attendees": [ + { + "id": "99999999-010c-0010-a213-000000a5a194", + "first_name": "Joris", + "last_name": "Krause" + }, + { + "id": "99999999-010d-0010-404a-000000a63fcb", + "first_name": "Mia", + "last_name": "Braun" + }, + { + "id": "99999999-010f-0010-7cb9-000000a77c39", + "first_name": "Martha", + "last_name": "Diaz" + }, + { + "id": "99999999-0111-0011-b928-000000a8b8a7", + "first_name": "Romy", + "last_name": "Park" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0013-0001-be1e-0000000bbe15", + "name": "Volleyball Juniors" + } + ], + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + } + }, + "aaaaaaaa-0026-0002-7c3c-000000177c2a": { + "id": "aaaaaaaa-0026-0002-7c3c-000000177c2a", + "name": "Volleyball Juniors Friendly", + "description": "Time Trial session for Volleyball Juniors.", + "start_time": "2026-07-17T18:30:00.000Z", + "end_time": "2026-07-17T20:00:00.000Z", + "attendees": [ + { + "id": "99999999-010d-0010-404a-000000a63fcb", + "first_name": "Mia", + "last_name": "Braun" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0013-0001-be1e-0000000bbe15", + "name": "Volleyball Juniors" + } + ], + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + } + }, + "aaaaaaaa-0027-0002-1a73-000000181a61": { + "id": "aaaaaaaa-0027-0002-1a73-000000181a61", + "name": "Volleyball Squad 1 Training", + "description": "Friendly session for Volleyball Squad 1.", + "start_time": "2026-05-10T15:00:00.000Z", + "end_time": "2026-05-10T16:30:00.000Z", + "attendees": [ + { + "id": "99999999-0112-0011-5760-000000a956de", + "first_name": "Paul", + "last_name": "Reil" + }, + { + "id": "99999999-0113-0011-f597-000000a9f515", + "first_name": "Nora", + "last_name": "Diaz" + }, + { + "id": "99999999-0114-0011-93cf-000000aa934c", + "first_name": "Samuel", + "last_name": "Koch" + }, + { + "id": "99999999-0115-0011-3206-000000ab3183", + "first_name": "Wilma", + "last_name": "Braun" + }, + { + "id": "99999999-0116-0011-d03e-000000abcfba", + "first_name": "Pia", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0117-0011-6e75-000000ac6df1", + "first_name": "Sofia", + "last_name": "Wolf" + }, + { + "id": "99999999-0118-0011-0cad-000000ad0c28", + "first_name": "Joris", + "last_name": "Arnold" + }, + { + "id": "99999999-0119-0011-aae4-000000adaa5f", + "first_name": "Elias", + "last_name": "Busch" + }, + { + "id": "99999999-011a-0011-491c-000000ae4896", + "first_name": "Jonah", + "last_name": "Diaz" + }, + { + "id": "99999999-011c-0011-858b-000000af8504", + "first_name": "Greta", + "last_name": "Koch" + }, + { + "id": "99999999-011e-0011-c1f9-000000b0c172", + "first_name": "Amelie", + "last_name": "Wolf" + }, + { + "id": "99999999-011f-0011-6031-000000b15fa9", + "first_name": "Leon", + "last_name": "Sommer" + }, + { + "id": "99999999-0120-0012-fe68-000000b1fde0", + "first_name": "Lea", + "last_name": "Engel" + }, + { + "id": "99999999-0121-0012-9ca0-000000b29c17", + "first_name": "Stella", + "last_name": "Braun" + }, + { + "id": "99999999-0122-0012-3ad7-000000b33a4e", + "first_name": "Helena", + "last_name": "König" + }, + { + "id": "99999999-0124-0012-7746-000000b476bc", + "first_name": "Nora", + "last_name": "Hoffmann" + }, + { + "id": "99999999-0125-0012-157e-000000b514f3", + "first_name": "Nele", + "last_name": "Krause" + }, + { + "id": "99999999-0126-0012-b3b5-000000b5b32a", + "first_name": "Johanna", + "last_name": "Frank" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0014-0001-5c55-0000000c5c4c", + "name": "Volleyball Squad 1" + } + ], + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + }, + "aaaaaaaa-0028-0002-b8ab-00000018b898": { + "id": "aaaaaaaa-0028-0002-b8ab-00000018b898", + "name": "Volleyball Squad 1 Time Trial", + "description": "Tournament session for Volleyball Squad 1.", + "start_time": "2026-06-21T16:00:00.000Z", + "end_time": "2026-06-21T17:30:00.000Z", + "attendees": [ + { + "id": "99999999-0112-0011-5760-000000a956de", + "first_name": "Paul", + "last_name": "Reil" + }, + { + "id": "99999999-0113-0011-f597-000000a9f515", + "first_name": "Nora", + "last_name": "Diaz" + }, + { + "id": "99999999-0117-0011-6e75-000000ac6df1", + "first_name": "Sofia", + "last_name": "Wolf" + }, + { + "id": "99999999-011e-0011-c1f9-000000b0c172", + "first_name": "Amelie", + "last_name": "Wolf" + }, + { + "id": "99999999-011f-0011-6031-000000b15fa9", + "first_name": "Leon", + "last_name": "Sommer" + }, + { + "id": "99999999-0125-0012-157e-000000b514f3", + "first_name": "Nele", + "last_name": "Krause" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0014-0001-5c55-0000000c5c4c", + "name": "Volleyball Squad 1" + } + ], + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + }, + "aaaaaaaa-0029-0002-56e2-0000001956cf": { + "id": "aaaaaaaa-0029-0002-56e2-0000001956cf", + "name": "Volleyball Squad 2 Match", + "description": "Tournament session for Volleyball Squad 2.", + "start_time": "2026-05-10T14:30:00.000Z", + "end_time": "2026-05-10T16:00:00.000Z", + "attendees": [ + { + "id": "99999999-0128-0012-f024-000000b6ef98", + "first_name": "Linus", + "last_name": "Scholz" + }, + { + "id": "99999999-0129-0012-8e5c-000000b78dcf", + "first_name": "Luca", + "last_name": "Schulz" + }, + { + "id": "99999999-012a-0012-2c93-000000b82c06", + "first_name": "Clara", + "last_name": "Voigt" + }, + { + "id": "99999999-012b-0012-cacb-000000b8ca3d", + "first_name": "Noah", + "last_name": "Schulz" + }, + { + "id": "99999999-012c-0012-6902-000000b96874", + "first_name": "Linus", + "last_name": "Graf" + }, + { + "id": "99999999-012d-0012-073a-000000ba06ab", + "first_name": "Mats", + "last_name": "Voigt" + }, + { + "id": "99999999-012e-0012-a571-000000baa4e2", + "first_name": "Janne", + "last_name": "Albrecht" + }, + { + "id": "99999999-012f-0012-43a9-000000bb4319", + "first_name": "Nora", + "last_name": "Bauer" + }, + { + "id": "99999999-0130-0013-e1e0-000000bbe150", + "first_name": "Luca", + "last_name": "Wolf" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0015-0001-fa8c-0000000cfa83", + "name": "Volleyball Squad 2" + } + ], + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + } + }, + "aaaaaaaa-002a-0002-f519-00000019f506": { + "id": "aaaaaaaa-002a-0002-f519-00000019f506", + "name": "Volleyball Squad 2 Time Trial", + "description": "Friendly session for Volleyball Squad 2.", + "start_time": "2026-07-17T11:30:00.000Z", + "end_time": "2026-07-17T13:00:00.000Z", + "attendees": [ + { + "id": "99999999-0128-0012-f024-000000b6ef98", + "first_name": "Linus", + "last_name": "Scholz" + }, + { + "id": "99999999-012a-0012-2c93-000000b82c06", + "first_name": "Clara", + "last_name": "Voigt" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0015-0001-fa8c-0000000cfa83", + "name": "Volleyball Squad 2" + } + ], + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + } + }, + "aaaaaaaa-002b-0002-9351-0000001a933d": { + "id": "aaaaaaaa-002b-0002-9351-0000001a933d", + "name": "Volleyball U16 Tournament", + "description": "Friendly session for Volleyball U16.", + "start_time": "2026-05-25T13:00:00.000Z", + "end_time": "2026-05-25T14:30:00.000Z", + "attendees": [ + { + "id": "99999999-0131-0013-8017-000000bc7f87", + "first_name": "Ada", + "last_name": "Kaiser" + }, + { + "id": "99999999-0132-0013-1e4f-000000bd1dbe", + "first_name": "Emil", + "last_name": "Engel" + }, + { + "id": "99999999-0133-0013-bc86-000000bdbbf5", + "first_name": "Max", + "last_name": "Ziegler" + }, + { + "id": "99999999-0134-0013-5abe-000000be5a2c", + "first_name": "Linus", + "last_name": "Vogt" + }, + { + "id": "99999999-0135-0013-f8f5-000000bef863", + "first_name": "Romi", + "last_name": "Vogt" + }, + { + "id": "99999999-0136-0013-972d-000000bf969a", + "first_name": "Moritz", + "last_name": "Albrecht" + }, + { + "id": "99999999-0137-0013-3564-000000c034d1", + "first_name": "Juna", + "last_name": "Schulz" + }, + { + "id": "99999999-0138-0013-d39c-000000c0d308", + "first_name": "Rosa", + "last_name": "Koch" + }, + { + "id": "99999999-0139-0013-71d3-000000c1713f", + "first_name": "Janne", + "last_name": "Park" + }, + { + "id": "99999999-013a-0013-100b-000000c20f76", + "first_name": "Romy", + "last_name": "Sauer" + }, + { + "id": "99999999-013c-0013-4c7a-000000c34be4", + "first_name": "Theo", + "last_name": "Hoffmann" + }, + { + "id": "99999999-013e-0013-88e9-000000c48852", + "first_name": "Martha", + "last_name": "Lange" + }, + { + "id": "99999999-013f-0013-2720-000000c52689", + "first_name": "Levi", + "last_name": "Brandt" + }, + { + "id": "99999999-0140-0014-c558-000000c5c4c0", + "first_name": "Mats", + "last_name": "Hartmann" + }, + { + "id": "99999999-0141-0014-638f-000000c662f7", + "first_name": "Amelie", + "last_name": "Diaz" + }, + { + "id": "99999999-0143-0014-9ffe-000000c79f65", + "first_name": "Emil", + "last_name": "Busch" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0016-0001-98c4-0000000d98ba", + "name": "Volleyball U16" + } + ], + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + } + }, + "aaaaaaaa-002c-0002-3188-0000001b3174": { + "id": "aaaaaaaa-002c-0002-3188-0000001b3174", + "name": "Volleyball U16 Friendly", + "description": "Time Trial session for Volleyball U16.", + "start_time": "2026-07-04T13:00:00.000Z", + "end_time": "2026-07-04T14:30:00.000Z", + "attendees": [ + { + "id": "99999999-0131-0013-8017-000000bc7f87", + "first_name": "Ada", + "last_name": "Kaiser" + }, + { + "id": "99999999-0134-0013-5abe-000000be5a2c", + "first_name": "Linus", + "last_name": "Vogt" + }, + { + "id": "99999999-0138-0013-d39c-000000c0d308", + "first_name": "Rosa", + "last_name": "Koch" + }, + { + "id": "99999999-013d-0013-eab1-000000c3ea1b", + "first_name": "Alma", + "last_name": "Klein" + }, + { + "id": "99999999-013e-0013-88e9-000000c48852", + "first_name": "Martha", + "last_name": "Lange" + }, + { + "id": "99999999-013f-0013-2720-000000c52689", + "first_name": "Levi", + "last_name": "Brandt" + }, + { + "id": "99999999-0142-0014-01c7-000000c7012e", + "first_name": "Anton", + "last_name": "Braun" + }, + { + "id": "99999999-0143-0014-9ffe-000000c79f65", + "first_name": "Emil", + "last_name": "Busch" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0016-0001-98c4-0000000d98ba", + "name": "Volleyball U16" + } + ], + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + } + }, + "aaaaaaaa-002d-0002-cfc0-0000001bcfab": { + "id": "aaaaaaaa-002d-0002-cfc0-0000001bcfab", + "name": "Volleyball Varsity Open Session", + "description": "Open Session session for Volleyball Varsity.", + "start_time": "2026-06-13T09:00:00.000Z", + "end_time": "2026-06-13T10:30:00.000Z", + "attendees": [ + { + "id": "99999999-0144-0014-3e36-000000c83d9c", + "first_name": "Fynn", + "last_name": "Bauer" + }, + { + "id": "99999999-0145-0014-dc6d-000000c8dbd3", + "first_name": "David", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0147-0014-18dc-000000ca1841", + "first_name": "Henry", + "last_name": "Huber" + }, + { + "id": "99999999-0149-0014-554b-000000cb54af", + "first_name": "Lotte", + "last_name": "Engel" + }, + { + "id": "99999999-014a-0014-f382-000000cbf2e6", + "first_name": "Samuel", + "last_name": "Wolf" + }, + { + "id": "99999999-014b-0014-91ba-000000cc911d", + "first_name": "Konrad", + "last_name": "Sommer" + }, + { + "id": "99999999-014c-0014-2ff1-000000cd2f54", + "first_name": "Elias", + "last_name": "Wolf" + }, + { + "id": "99999999-014d-0014-ce29-000000cdcd8b", + "first_name": "Konrad", + "last_name": "Beck" + }, + { + "id": "99999999-014e-0014-6c60-000000ce6bc2", + "first_name": "Hannah", + "last_name": "Arnold" + }, + { + "id": "99999999-014f-0014-0a98-000000cf09f9", + "first_name": "Bruno", + "last_name": "Krüger" + }, + { + "id": "99999999-0150-0015-a8cf-000000cfa830", + "first_name": "Luca", + "last_name": "Pohl" + }, + { + "id": "99999999-0152-0015-e53e-000000d0e49e", + "first_name": "Paul", + "last_name": "Engel" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0017-0001-36fb-0000000e36f1", + "name": "Volleyball Varsity" + } + ], + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + } + }, + "aaaaaaaa-002e-0002-6df7-0000001c6de2": { + "id": "aaaaaaaa-002e-0002-6df7-0000001c6de2", + "name": "Volleyball Varsity Training", + "description": "Tournament session for Volleyball Varsity.", + "start_time": "2026-06-29T15:30:00.000Z", + "end_time": "2026-06-29T17:00:00.000Z", + "attendees": [ + { + "id": "99999999-0144-0014-3e36-000000c83d9c", + "first_name": "Fynn", + "last_name": "Bauer" + }, + { + "id": "99999999-0145-0014-dc6d-000000c8dbd3", + "first_name": "David", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0146-0014-7aa4-000000c97a0a", + "first_name": "Noah", + "last_name": "Klein" + }, + { + "id": "99999999-0147-0014-18dc-000000ca1841", + "first_name": "Henry", + "last_name": "Huber" + }, + { + "id": "99999999-0148-0014-b713-000000cab678", + "first_name": "Rosa", + "last_name": "Schulz" + }, + { + "id": "99999999-014a-0014-f382-000000cbf2e6", + "first_name": "Samuel", + "last_name": "Wolf" + }, + { + "id": "99999999-014c-0014-2ff1-000000cd2f54", + "first_name": "Elias", + "last_name": "Wolf" + }, + { + "id": "99999999-014e-0014-6c60-000000ce6bc2", + "first_name": "Hannah", + "last_name": "Arnold" + }, + { + "id": "99999999-0150-0015-a8cf-000000cfa830", + "first_name": "Luca", + "last_name": "Pohl" + } + ], + "sports_linked": [ + "Volleyball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0017-0001-36fb-0000000e36f1", + "name": "Volleyball Varsity" + } + ], + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + } + }, + "aaaaaaaa-002f-0002-0c2f-0000001d0c19": { + "id": "aaaaaaaa-002f-0002-0c2f-0000001d0c19", + "name": "Football Juniors Match", + "description": "Match session for Football Juniors.", + "start_time": "2026-06-16T10:00:00.000Z", + "end_time": "2026-06-16T11:30:00.000Z", + "attendees": [ + { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-001c-0001-4e11-000000114e04", + "first_name": "Erik", + "last_name": "Lange" + }, + { + "id": "99999999-001e-0001-8a80-000000128a72", + "first_name": "Theo", + "last_name": "Diaz" + }, + { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + { + "id": "99999999-0021-0002-6526-000000146517", + "first_name": "Mia", + "last_name": "Albrecht" + }, + { + "id": "99999999-0022-0002-035e-00000015034e", + "first_name": "Ida", + "last_name": "Krüger" + }, + { + "id": "99999999-0023-0002-a195-00000015a185", + "first_name": "Oskar", + "last_name": "Schulz" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0026-0002-7c3c-000000177c2a", + "first_name": "Moritz", + "last_name": "Seidel" + }, + { + "id": "99999999-0029-0002-56e2-0000001956cf", + "first_name": "Oskar", + "last_name": "Werner" + }, + { + "id": "99999999-002a-0002-f519-00000019f506", + "first_name": "Erik", + "last_name": "Richter" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors" + } + ], + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + }, + "aaaaaaaa-0030-0003-aa66-0000001daa50": { + "id": "aaaaaaaa-0030-0003-aa66-0000001daa50", + "name": "Basketball Juniors Open Session", + "description": "Time Trial session for Basketball Juniors.", + "start_time": "2026-06-14T14:00:00.000Z", + "end_time": "2026-06-14T15:30:00.000Z", + "attendees": [ + { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + { + "id": "99999999-0064-0006-cdab-0000003dcd7c", + "first_name": "Greta", + "last_name": "Roth" + }, + { + "id": "99999999-0065-0006-6be3-0000003e6bb3", + "first_name": "Frida", + "last_name": "Werner" + } + ], + "sports_linked": [ + "Basketball" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0006-0000-b54c-00000003b54a", + "name": "Basketball Juniors" + } + ], + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + }, + "aaaaaaaa-0031-0003-489e-0000001e4887": { + "id": "aaaaaaaa-0031-0003-489e-0000001e4887", + "name": "Football Juniors Open Session", + "description": "Training session for Football Juniors.", + "start_time": "2026-06-03T18:00:00.000Z", + "end_time": "2026-06-03T19:30:00.000Z", + "attendees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-001c-0001-4e11-000000114e04", + "first_name": "Erik", + "last_name": "Lange" + }, + { + "id": "99999999-001d-0001-ec48-00000011ec3b", + "first_name": "Janne", + "last_name": "Roth" + }, + { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + { + "id": "99999999-0021-0002-6526-000000146517", + "first_name": "Mia", + "last_name": "Albrecht" + }, + { + "id": "99999999-0023-0002-a195-00000015a185", + "first_name": "Oskar", + "last_name": "Schulz" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0027-0002-1a73-000000181a61", + "first_name": "Nora", + "last_name": "Krause" + }, + { + "id": "99999999-0028-0002-b8ab-00000018b898", + "first_name": "Mats", + "last_name": "Huber" + }, + { + "id": "99999999-0029-0002-56e2-0000001956cf", + "first_name": "Oskar", + "last_name": "Werner" + }, + { + "id": "99999999-002a-0002-f519-00000019f506", + "first_name": "Erik", + "last_name": "Richter" + } + ], + "sports_linked": [ + "Football" + ], + "teams_linked": [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors" + } + ], + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + } +} diff --git a/web-client/src/mocks/fixtures/feedback.ts b/web-client/src/mocks/fixtures/feedback.ts new file mode 100644 index 0000000..4186528 --- /dev/null +++ b/web-client/src/mocks/fixtures/feedback.ts @@ -0,0 +1,3958 @@ +import type { Feedback, FeedbackSummary } from '@/types' + +// Summary rows (no body text); full text lives on feedbackDetailsById. +export const feedbackSummaryFixtures: FeedbackSummary[] = [ + { + "id": "ffffffff-0001-0000-9e37-000000009e37", + "event": "aaaaaaaa-0031-0003-489e-0000001e4887", + "member": { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-23T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0002-0000-3c6e-000000013c6e", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0003-0000-daa6-00000001daa5", + "event": "aaaaaaaa-002f-0002-0c2f-0000001d0c19", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0004-0000-78dd-0000000278dc", + "event": "aaaaaaaa-002f-0002-0c2f-0000001d0c19", + "member": { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0005-0000-1715-000000031713", + "event": "aaaaaaaa-0031-0003-489e-0000001e4887", + "member": { + "id": "99999999-001d-0001-ec48-00000011ec3b", + "first_name": "Janne", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0006-0000-b54c-00000003b54a", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "99999999-001e-0001-8a80-000000128a72", + "first_name": "Theo", + "last_name": "Diaz" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-03T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-0007-0000-5384-000000045381", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-23T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0008-0000-f1bb-00000004f1b8", + "event": "aaaaaaaa-0031-0003-489e-0000001e4887", + "member": { + "id": "99999999-0020-0002-c6ef-00000013c6e0", + "first_name": "Levi", + "last_name": "Voigt" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0009-0000-8ff3-000000058fef", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "99999999-0025-0002-de04-00000016ddf3", + "first_name": "Fynn", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-000a-0000-2e2a-000000062e26", + "event": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "member": { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-06-02T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-000b-0000-cc62-00000006cc5d", + "event": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "member": { + "id": "99999999-002d-0002-cfc0-0000001bcfab", + "first_name": "Romi", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "rating": 10 + }, + { + "id": "ffffffff-000c-0000-6a99-000000076a94", + "event": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "member": { + "id": "99999999-0031-0003-489e-0000001e4887", + "first_name": "Edda", + "last_name": "Zimmermann" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-06-02T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-000d-0000-08d1-0000000808cb", + "event": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "member": { + "id": "99999999-0032-0003-e6d5-0000001ee6be", + "first_name": "Toni", + "last_name": "Brandt" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-06-01T00:00:00.000Z" + }, + { + "id": "ffffffff-000e-0000-a708-00000008a702", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-000f-0000-4540-000000094539", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-26T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0010-0001-e377-00000009e370", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003a-0003-d891-00000023d876", + "first_name": "Joris", + "last_name": "Stein" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0011-0001-81af-0000000a81a7", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003b-0003-76c9-0000002476ad", + "first_name": "Frieda", + "last_name": "Bauer" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0012-0001-1fe6-0000000b1fde", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003d-0003-b337-00000025b31b", + "first_name": "Fynn", + "last_name": "Koch" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-20T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0013-0001-be1e-0000000bbe15", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003e-0003-516f-000000265152", + "first_name": "Marie", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-21T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-0014-0001-5c55-0000000c5c4c", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003f-0003-efa6-00000026ef89", + "first_name": "Joris", + "last_name": "Lehmann" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0015-0001-fa8c-0000000cfa83", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-0041-0004-2c15-000000282bf7", + "first_name": "Smilla", + "last_name": "Krause" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "rating": 4 + }, + { + "id": "ffffffff-0016-0001-98c4-0000000d98ba", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-0045-0004-a4f3-0000002aa4d3", + "first_name": "Mats", + "last_name": "Graf" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0017-0001-36fb-0000000e36f1", + "event": "aaaaaaaa-0007-0000-5384-000000045381", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0018-0001-d533-0000000ed528", + "event": "aaaaaaaa-0007-0000-5384-000000045381", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0019-0001-736a-0000000f735f", + "event": "aaaaaaaa-0007-0000-5384-000000045381", + "member": { + "id": "99999999-004c-0004-f878-0000002ef854", + "first_name": "Tomas", + "last_name": "Hartmann" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-001a-0001-11a2-000000101196", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-001b-0001-afd9-00000010afcd", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-001c-0001-4e11-000000114e04", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-0051-0005-0f8d-000000320f67", + "first_name": "Paul", + "last_name": "Busch" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-03T00:00:00.000Z", + "rating": 10 + }, + { + "id": "ffffffff-001d-0001-ec48-00000011ec3b", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-0054-0005-ea33-00000033ea0c", + "first_name": "Marie", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-001e-0001-8a80-000000128a72", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-0057-0005-c4da-00000035c4b1", + "first_name": "Helena", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-05-31T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-001f-0001-28b7-0000001328a9", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-0058-0005-6311-0000003662e8", + "first_name": "Leon", + "last_name": "Hartmann" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "rating": 3 + }, + { + "id": "ffffffff-0020-0002-c6ef-00000013c6e0", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-005d-0005-7a27-0000003979fb", + "first_name": "Jakob", + "last_name": "Klein" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0021-0002-6526-000000146517", + "event": "aaaaaaaa-000b-0000-cc62-00000006cc5d", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0022-0002-035e-00000015034e", + "event": "aaaaaaaa-000b-0000-cc62-00000006cc5d", + "member": { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-0023-0002-a195-00000015a185", + "event": "aaaaaaaa-000b-0000-cc62-00000006cc5d", + "member": { + "id": "99999999-0065-0006-6be3-0000003e6bb3", + "first_name": "Frida", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0024-0002-3fcd-000000163fbc", + "event": "aaaaaaaa-000d-0000-08d1-0000000808cb", + "member": { + "id": "99999999-0067-0006-a851-0000003fa821", + "first_name": "Luca", + "last_name": "Peters" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-05T00:00:00.000Z" + }, + { + "id": "ffffffff-0025-0002-de04-00000016ddf3", + "event": "aaaaaaaa-000d-0000-08d1-0000000808cb", + "member": { + "id": "99999999-006f-0006-9a0d-0000004499d9", + "first_name": "Liv", + "last_name": "Brandt" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-05-21T00:00:00.000Z", + "rating": 0 + }, + { + "id": "ffffffff-0026-0002-7c3c-000000177c2a", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0072-0007-74b4-00000046747e", + "first_name": "Lena", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0027-0002-1a73-000000181a61", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0075-0007-4f5a-000000484f23", + "first_name": "Emil", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0028-0002-b8ab-00000018b898", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0076-0007-ed92-00000048ed5a", + "first_name": "Leon", + "last_name": "Diaz" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0029-0002-56e2-0000001956cf", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0078-0007-2a01-0000004a29c8", + "first_name": "Oskar", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-002a-0002-f519-00000019f506", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-007a-0007-666f-0000004b6636", + "first_name": "Leon", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-05-20T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-002b-0002-9351-0000001a933d", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-007f-0007-7d85-0000004e7d49", + "first_name": "Tilda", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-002c-0002-3188-0000001b3174", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0081-0008-b9f4-0000004fb9b7", + "first_name": "Leon", + "last_name": "Busch" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-002d-0002-cfc0-0000001bcfab", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0084-0008-949a-00000051945c", + "first_name": "Juna", + "last_name": "Reil" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-002e-0002-6df7-0000001c6de2", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0085-0008-32d2-000000523293", + "first_name": "Juna", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-002f-0002-0c2f-0000001d0c19", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0087-0008-6f41-000000536f01", + "first_name": "Sofia", + "last_name": "Brandt" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-17T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0030-0003-aa66-0000001daa50", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0088-0008-0d78-000000540d38", + "first_name": "Samuel", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0031-0003-489e-0000001e4887", + "event": "aaaaaaaa-0013-0001-be1e-0000000bbe15", + "member": { + "id": "99999999-008c-0008-8656-000000568614", + "first_name": "Moritz", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0032-0003-e6d5-0000001ee6be", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-0093-0009-d9da-0000005ad995", + "first_name": "Finn", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-07T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0033-0003-850d-0000001f84f5", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-0095-0009-1649-0000005c1603", + "first_name": "Lea", + "last_name": "Park" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-04T00:00:00.000Z", + "rating": 10 + }, + { + "id": "ffffffff-0034-0003-2344-00000020232c", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-0098-0009-f0f0-0000005df0a8", + "first_name": "Aaron", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-26T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0035-0003-c17c-00000020c163", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-009d-0009-0805-0000006107bb", + "first_name": "Lena", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-21T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-0036-0003-5fb3-000000215f9a", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-009e-0009-a63d-00000061a5f2", + "first_name": "Joris", + "last_name": "Schulz" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0037-0003-fdeb-00000021fdd1", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-00a1-000a-80e3-000000638097", + "first_name": "Amelie", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0038-0003-9c22-000000229c08", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-00a2-000a-1f1b-000000641ece", + "first_name": "Jonas", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0039-0003-3a5a-000000233a3f", + "event": "aaaaaaaa-0017-0001-36fb-0000000e36f1", + "member": { + "id": "99999999-00a7-000a-3630-0000006735e1", + "first_name": "Carla", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-003a-0003-d891-00000023d876", + "event": "aaaaaaaa-0017-0001-36fb-0000000e36f1", + "member": { + "id": "99999999-00aa-000a-10d6-000000691086", + "first_name": "Bela", + "last_name": "Klein" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-003b-0003-76c9-0000002476ad", + "event": "aaaaaaaa-0019-0001-736a-0000000f735f", + "member": { + "id": "99999999-00ae-000a-89b4-0000006b8962", + "first_name": "Jonah", + "last_name": "König" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-08T00:00:00.000Z" + }, + { + "id": "ffffffff-003c-0003-1500-0000002514e4", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00b6-000b-7b70-000000707b1a", + "first_name": "Finn", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-003d-0003-b337-00000025b31b", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00b9-000b-5616-0000007255bf", + "first_name": "Frida", + "last_name": "Brandt" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "rating": 4 + }, + { + "id": "ffffffff-003e-0003-516f-000000265152", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00bb-000b-9285-00000073922d", + "first_name": "Sofia", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-06-02T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-003f-0003-efa6-00000026ef89", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00bc-000b-30bd-000000743064", + "first_name": "Jonah", + "last_name": "Park" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-05-31T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0040-0004-8dde-000000278dc0", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00be-000b-6d2c-000000756cd2", + "first_name": "Emil", + "last_name": "Diaz" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0041-0004-2c15-000000282bf7", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00bf-000b-0b63-000000760b09", + "first_name": "David", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-06-14T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0042-0004-ca4d-00000028ca2e", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c1-000c-47d2-000000774777", + "first_name": "Emil", + "last_name": "Schwarz" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-0043-0004-6884-000000296865", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c3-000c-8441-0000007883e5", + "first_name": "Rosa", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0044-0004-06bc-0000002a069c", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c4-000c-2279-00000079221c", + "first_name": "Frida", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-07T00:00:00.000Z", + "rating": 10 + }, + { + "id": "ffffffff-0045-0004-a4f3-0000002aa4d3", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c6-000c-5ee8-0000007a5e8a", + "first_name": "Edda", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0046-0004-432b-0000002b430a", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c8-000c-9b57-0000007b9af8", + "first_name": "Emil", + "last_name": "Klein" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0047-0004-e162-0000002be141", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00cf-000c-eedb-0000007fee79", + "first_name": "Toni", + "last_name": "Krause" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-02T00:00:00.000Z", + "rating": 3 + }, + { + "id": "ffffffff-0048-0004-7f9a-0000002c7f78", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00d0-000d-8d12-000000808cb0", + "first_name": "Lotte", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-05-23T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0049-0004-1dd1-0000002d1daf", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d1-000d-2b4a-000000812ae7", + "first_name": "Lotte", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-004a-0004-bc09-0000002dbbe6", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d2-000d-c981-00000081c91e", + "first_name": "Mara", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-004b-0004-5a40-0000002e5a1d", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d3-000d-67b9-000000826755", + "first_name": "Ella", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-26T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-004c-0004-f878-0000002ef854", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d6-000d-425f-0000008441fa", + "first_name": "Nele", + "last_name": "Scholz" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-14T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-004d-0004-96af-0000002f968b", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d7-000d-e097-00000084e031", + "first_name": "Oskar", + "last_name": "Stein" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "rating": 0 + }, + { + "id": "ffffffff-004e-0004-34e7-0000003034c2", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00db-000d-5975-00000087590d", + "first_name": "Ida", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-23T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-004f-0004-d31e-00000030d2f9", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00dc-000d-f7ac-00000087f744", + "first_name": "Levi", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-04T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0050-0005-7156-000000317130", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00df-000d-d253-00000089d1e9", + "first_name": "Toni", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0051-0005-0f8d-000000320f67", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00e0-000e-708a-0000008a7020", + "first_name": "Nele", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0052-0005-adc4-00000032ad9e", + "event": "aaaaaaaa-0021-0002-6526-000000146517", + "member": { + "id": "99999999-00e8-000e-6246-0000008f61d8", + "first_name": "Lea", + "last_name": "Stein" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-10T00:00:00.000Z" + }, + { + "id": "ffffffff-0053-0005-4bfc-000000334bd5", + "event": "aaaaaaaa-0021-0002-6526-000000146517", + "member": { + "id": "99999999-00ed-000e-795b-0000009278eb", + "first_name": "Mats", + "last_name": "Horn" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-24T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0054-0005-ea33-00000033ea0c", + "event": "aaaaaaaa-0021-0002-6526-000000146517", + "member": { + "id": "99999999-00ee-000e-1793-000000931722", + "first_name": "Lina", + "last_name": "Krüger" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0055-0005-886b-000000348843", + "event": "aaaaaaaa-0021-0002-6526-000000146517", + "member": { + "id": "99999999-00f4-000f-ccdf-00000096cc6c", + "first_name": "Stella", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-20T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0056-0005-26a2-00000035267a", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00f9-000f-e3f5-00000099e37f", + "first_name": "Joris", + "last_name": "Huber" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-29T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-0057-0005-c4da-00000035c4b1", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00fa-000f-822c-0000009a81b6", + "first_name": "Mara", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-21T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0058-0005-6311-0000003662e8", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00fb-000f-2064-0000009b1fed", + "first_name": "Martha", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0059-0005-0149-00000037011f", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00fc-000f-be9b-0000009bbe24", + "first_name": "Mats", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-14T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-005a-0005-9f80-000000379f56", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00fe-000f-fb0a-0000009cfa92", + "first_name": "Erik", + "last_name": "Schulz" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-005b-0005-3db8-000000383d8d", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-0101-0010-d5b1-0000009ed537", + "first_name": "Clara", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 10 + }, + { + "id": "ffffffff-005c-0005-dbef-00000038dbc4", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-0102-0010-73e8-0000009f736e", + "first_name": "Niklas", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-005d-0005-7a27-0000003979fb", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-0106-0010-ecc6-000000a1ec4a", + "first_name": "Nele", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-005e-0005-185e-0000003a1832", + "event": "aaaaaaaa-0025-0002-de04-00000016ddf3", + "member": { + "id": "99999999-010e-0010-de82-000000a6de02", + "first_name": "Magda", + "last_name": "Bauer" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-05-26T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-005f-0005-b696-0000003ab669", + "event": "aaaaaaaa-0025-0002-de04-00000016ddf3", + "member": { + "id": "99999999-0110-0011-1af1-000000a81a70", + "first_name": "Mira", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0060-0006-54cd-0000003b54a0", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0112-0011-5760-000000a956de", + "first_name": "Paul", + "last_name": "Reil" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-31T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0061-0006-f305-0000003bf2d7", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0116-0011-d03e-000000abcfba", + "first_name": "Pia", + "last_name": "Zimmermann" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0062-0006-913c-0000003c910e", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0118-0011-0cad-000000ad0c28", + "first_name": "Joris", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-07T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0063-0006-2f74-0000003d2f45", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-011a-0011-491c-000000ae4896", + "first_name": "Jonah", + "last_name": "Diaz" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-31T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-0064-0006-cdab-0000003dcd7c", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-011b-0011-e753-000000aee6cd", + "first_name": "Mats", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0065-0006-6be3-0000003e6bb3", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-011d-0011-23c2-000000b0233b", + "first_name": "Janne", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "rating": 4 + }, + { + "id": "ffffffff-0066-0006-0a1a-0000003f09ea", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-011e-0011-c1f9-000000b0c172", + "first_name": "Amelie", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0067-0006-a851-0000003fa821", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0120-0012-fe68-000000b1fde0", + "first_name": "Lea", + "last_name": "Engel" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0068-0006-4689-000000404658", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0121-0012-9ca0-000000b29c17", + "first_name": "Stella", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-24T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0069-0006-e4c0-00000040e48f", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0122-0012-3ad7-000000b33a4e", + "first_name": "Helena", + "last_name": "König" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-16T00:00:00.000Z" + }, + { + "id": "ffffffff-006a-0006-82f8-0000004182c6", + "event": "aaaaaaaa-0029-0002-56e2-0000001956cf", + "member": { + "id": "99999999-012b-0012-cacb-000000b8ca3d", + "first_name": "Noah", + "last_name": "Schulz" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-006b-0006-212f-0000004220fd", + "event": "aaaaaaaa-0029-0002-56e2-0000001956cf", + "member": { + "id": "99999999-012f-0012-43a9-000000bb4319", + "first_name": "Nora", + "last_name": "Bauer" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-006c-0006-bf67-00000042bf34", + "event": "aaaaaaaa-0029-0002-56e2-0000001956cf", + "member": { + "id": "99999999-0130-0013-e1e0-000000bbe150", + "first_name": "Luca", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "rating": 10 + }, + { + "id": "ffffffff-006d-0006-5d9e-000000435d6b", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0131-0013-8017-000000bc7f87", + "first_name": "Ada", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-006e-0006-fbd6-00000043fba2", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0133-0013-bc86-000000bdbbf5", + "first_name": "Max", + "last_name": "Ziegler" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-09T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-006f-0006-9a0d-0000004499d9", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0135-0013-f8f5-000000bef863", + "first_name": "Romi", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "rating": 3 + }, + { + "id": "ffffffff-0070-0007-3845-000000453810", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0136-0013-972d-000000bf969a", + "first_name": "Moritz", + "last_name": "Albrecht" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0071-0007-d67c-00000045d647", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-013d-0013-eab1-000000c3ea1b", + "first_name": "Alma", + "last_name": "Klein" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-04T00:00:00.000Z", + "rating": 9 + }, + { + "id": "ffffffff-0072-0007-74b4-00000046747e", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0140-0014-c558-000000c5c4c0", + "first_name": "Mats", + "last_name": "Hartmann" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-04T00:00:00.000Z", + "rating": 5 + }, + { + "id": "ffffffff-0073-0007-12eb-0000004712b5", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0142-0014-01c7-000000c7012e", + "first_name": "Anton", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0074-0007-b123-00000047b0ec", + "event": "aaaaaaaa-002d-0002-cfc0-0000001bcfab", + "member": { + "id": "99999999-014b-0014-91ba-000000cc911d", + "first_name": "Konrad", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "rating": 6 + }, + { + "id": "ffffffff-0075-0007-4f5a-000000484f23", + "event": "aaaaaaaa-002d-0002-cfc0-0000001bcfab", + "member": { + "id": "99999999-014c-0014-2ff1-000000cd2f54", + "first_name": "Elias", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "rating": 0 + }, + { + "id": "ffffffff-0076-0007-ed92-00000048ed5a", + "event": "aaaaaaaa-0031-0003-489e-0000001e4887", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "rating": 7 + }, + { + "id": "ffffffff-0077-0007-8bc9-000000498b91", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "rating": 8 + }, + { + "id": "ffffffff-0078-0007-2a01-0000004a29c8", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "rating": 9 + } +] + +export const feedbackDetailsById: Record = { + "ffffffff-0001-0000-9e37-000000009e37": { + "id": "ffffffff-0001-0000-9e37-000000009e37", + "event": "aaaaaaaa-0031-0003-489e-0000001e4887", + "member": { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-23T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 8 + }, + "ffffffff-0002-0000-3c6e-000000013c6e": { + "id": "ffffffff-0002-0000-3c6e-000000013c6e", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 7 + }, + "ffffffff-0003-0000-daa6-00000001daa5": { + "id": "ffffffff-0003-0000-daa6-00000001daa5", + "event": "aaaaaaaa-002f-0002-0c2f-0000001d0c19", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 9 + }, + "ffffffff-0004-0000-78dd-0000000278dc": { + "id": "ffffffff-0004-0000-78dd-0000000278dc", + "event": "aaaaaaaa-002f-0002-0c2f-0000001d0c19", + "member": { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 6 + }, + "ffffffff-0005-0000-1715-000000031713": { + "id": "ffffffff-0005-0000-1715-000000031713", + "event": "aaaaaaaa-0031-0003-489e-0000001e4887", + "member": { + "id": "99999999-001d-0001-ec48-00000011ec3b", + "first_name": "Janne", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "feedback": "Technique is coming along well. Focus next on consistency across both sides.", + "rating": 8 + }, + "ffffffff-0006-0000-b54c-00000003b54a": { + "id": "ffffffff-0006-0000-b54c-00000003b54a", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "99999999-001e-0001-8a80-000000128a72", + "first_name": "Theo", + "last_name": "Diaz" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-03T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 5 + }, + "ffffffff-0007-0000-5384-000000045381": { + "id": "ffffffff-0007-0000-5384-000000045381", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-23T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 7 + }, + "ffffffff-0008-0000-f1bb-00000004f1b8": { + "id": "ffffffff-0008-0000-f1bb-00000004f1b8", + "event": "aaaaaaaa-0031-0003-489e-0000001e4887", + "member": { + "id": "99999999-0020-0002-c6ef-00000013c6e0", + "first_name": "Levi", + "last_name": "Voigt" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 9 + }, + "ffffffff-0009-0000-8ff3-000000058fef": { + "id": "ffffffff-0009-0000-8ff3-000000058fef", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "99999999-0025-0002-de04-00000016ddf3", + "first_name": "Fynn", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 6 + }, + "ffffffff-000a-0000-2e2a-000000062e26": { + "id": "ffffffff-000a-0000-2e2a-000000062e26", + "event": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "member": { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-06-02T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 8 + }, + "ffffffff-000b-0000-cc62-00000006cc5d": { + "id": "ffffffff-000b-0000-cc62-00000006cc5d", + "event": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "member": { + "id": "99999999-002d-0002-cfc0-0000001bcfab", + "first_name": "Romi", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 10 + }, + "ffffffff-000c-0000-6a99-000000076a94": { + "id": "ffffffff-000c-0000-6a99-000000076a94", + "event": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "member": { + "id": "99999999-0031-0003-489e-0000001e4887", + "first_name": "Edda", + "last_name": "Zimmermann" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-06-02T00:00:00.000Z", + "feedback": "Technique is coming along well. Focus next on consistency across both sides.", + "rating": 7 + }, + "ffffffff-000d-0000-08d1-0000000808cb": { + "id": "ffffffff-000d-0000-08d1-0000000808cb", + "event": "aaaaaaaa-0003-0000-daa6-00000001daa5", + "member": { + "id": "99999999-0032-0003-e6d5-0000001ee6be", + "first_name": "Toni", + "last_name": "Brandt" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure." + }, + "ffffffff-000e-0000-a708-00000008a702": { + "id": "ffffffff-000e-0000-a708-00000008a702", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 9 + }, + "ffffffff-000f-0000-4540-000000094539": { + "id": "ffffffff-000f-0000-4540-000000094539", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-26T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 8 + }, + "ffffffff-0010-0001-e377-00000009e370": { + "id": "ffffffff-0010-0001-e377-00000009e370", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003a-0003-d891-00000023d876", + "first_name": "Joris", + "last_name": "Stein" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 6 + }, + "ffffffff-0011-0001-81af-0000000a81a7": { + "id": "ffffffff-0011-0001-81af-0000000a81a7", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003b-0003-76c9-0000002476ad", + "first_name": "Frieda", + "last_name": "Bauer" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 7 + }, + "ffffffff-0012-0001-1fe6-0000000b1fde": { + "id": "ffffffff-0012-0001-1fe6-0000000b1fde", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003d-0003-b337-00000025b31b", + "first_name": "Fynn", + "last_name": "Koch" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-20T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 9 + }, + "ffffffff-0013-0001-be1e-0000000bbe15": { + "id": "ffffffff-0013-0001-be1e-0000000bbe15", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003e-0003-516f-000000265152", + "first_name": "Marie", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-05-21T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 5 + }, + "ffffffff-0014-0001-5c55-0000000c5c4c": { + "id": "ffffffff-0014-0001-5c55-0000000c5c4c", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-003f-0003-efa6-00000026ef89", + "first_name": "Joris", + "last_name": "Lehmann" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 8 + }, + "ffffffff-0015-0001-fa8c-0000000cfa83": { + "id": "ffffffff-0015-0001-fa8c-0000000cfa83", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-0041-0004-2c15-000000282bf7", + "first_name": "Smilla", + "last_name": "Krause" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 4 + }, + "ffffffff-0016-0001-98c4-0000000d98ba": { + "id": "ffffffff-0016-0001-98c4-0000000d98ba", + "event": "aaaaaaaa-0005-0000-1715-000000031713", + "member": { + "id": "99999999-0045-0004-a4f3-0000002aa4d3", + "first_name": "Mats", + "last_name": "Graf" + }, + "creator": { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 7 + }, + "ffffffff-0017-0001-36fb-0000000e36f1": { + "id": "ffffffff-0017-0001-36fb-0000000e36f1", + "event": "aaaaaaaa-0007-0000-5384-000000045381", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 6 + }, + "ffffffff-0018-0001-d533-0000000ed528": { + "id": "ffffffff-0018-0001-d533-0000000ed528", + "event": "aaaaaaaa-0007-0000-5384-000000045381", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 9 + }, + "ffffffff-0019-0001-736a-0000000f735f": { + "id": "ffffffff-0019-0001-736a-0000000f735f", + "event": "aaaaaaaa-0007-0000-5384-000000045381", + "member": { + "id": "99999999-004c-0004-f878-0000002ef854", + "first_name": "Tomas", + "last_name": "Hartmann" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "feedback": "Technique is coming along well. Focus next on consistency across both sides.", + "rating": 8 + }, + "ffffffff-001a-0001-11a2-000000101196": { + "id": "ffffffff-001a-0001-11a2-000000101196", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 5 + }, + "ffffffff-001b-0001-afd9-00000010afcd": { + "id": "ffffffff-001b-0001-afd9-00000010afcd", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 7 + }, + "ffffffff-001c-0001-4e11-000000114e04": { + "id": "ffffffff-001c-0001-4e11-000000114e04", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-0051-0005-0f8d-000000320f67", + "first_name": "Paul", + "last_name": "Busch" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-03T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 10 + }, + "ffffffff-001d-0001-ec48-00000011ec3b": { + "id": "ffffffff-001d-0001-ec48-00000011ec3b", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-0054-0005-ea33-00000033ea0c", + "first_name": "Marie", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "feedback": "Technique is coming along well. Focus next on consistency across both sides.", + "rating": 6 + }, + "ffffffff-001e-0001-8a80-000000128a72": { + "id": "ffffffff-001e-0001-8a80-000000128a72", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-0057-0005-c4da-00000035c4b1", + "first_name": "Helena", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-05-31T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 8 + }, + "ffffffff-001f-0001-28b7-0000001328a9": { + "id": "ffffffff-001f-0001-28b7-0000001328a9", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-0058-0005-6311-0000003662e8", + "first_name": "Leon", + "last_name": "Hartmann" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 3 + }, + "ffffffff-0020-0002-c6ef-00000013c6e0": { + "id": "ffffffff-0020-0002-c6ef-00000013c6e0", + "event": "aaaaaaaa-0009-0000-8ff3-000000058fef", + "member": { + "id": "99999999-005d-0005-7a27-0000003979fb", + "first_name": "Jakob", + "last_name": "Klein" + }, + "creator": { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 7 + }, + "ffffffff-0021-0002-6526-000000146517": { + "id": "ffffffff-0021-0002-6526-000000146517", + "event": "aaaaaaaa-000b-0000-cc62-00000006cc5d", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 9 + }, + "ffffffff-0022-0002-035e-00000015034e": { + "id": "ffffffff-0022-0002-035e-00000015034e", + "event": "aaaaaaaa-000b-0000-cc62-00000006cc5d", + "member": { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 5 + }, + "ffffffff-0023-0002-a195-00000015a185": { + "id": "ffffffff-0023-0002-a195-00000015a185", + "event": "aaaaaaaa-000b-0000-cc62-00000006cc5d", + "member": { + "id": "99999999-0065-0006-6be3-0000003e6bb3", + "first_name": "Frida", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 8 + }, + "ffffffff-0024-0002-3fcd-000000163fbc": { + "id": "ffffffff-0024-0002-3fcd-000000163fbc", + "event": "aaaaaaaa-000d-0000-08d1-0000000808cb", + "member": { + "id": "99999999-0067-0006-a851-0000003fa821", + "first_name": "Luca", + "last_name": "Peters" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine." + }, + "ffffffff-0025-0002-de04-00000016ddf3": { + "id": "ffffffff-0025-0002-de04-00000016ddf3", + "event": "aaaaaaaa-000d-0000-08d1-0000000808cb", + "member": { + "id": "99999999-006f-0006-9a0d-0000004499d9", + "first_name": "Liv", + "last_name": "Brandt" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-05-21T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 0 + }, + "ffffffff-0026-0002-7c3c-000000177c2a": { + "id": "ffffffff-0026-0002-7c3c-000000177c2a", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0072-0007-74b4-00000046747e", + "first_name": "Lena", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 7 + }, + "ffffffff-0027-0002-1a73-000000181a61": { + "id": "ffffffff-0027-0002-1a73-000000181a61", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0075-0007-4f5a-000000484f23", + "first_name": "Emil", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 8 + }, + "ffffffff-0028-0002-b8ab-00000018b898": { + "id": "ffffffff-0028-0002-b8ab-00000018b898", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0076-0007-ed92-00000048ed5a", + "first_name": "Leon", + "last_name": "Diaz" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 9 + }, + "ffffffff-0029-0002-56e2-0000001956cf": { + "id": "ffffffff-0029-0002-56e2-0000001956cf", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0078-0007-2a01-0000004a29c8", + "first_name": "Oskar", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 8 + }, + "ffffffff-002a-0002-f519-00000019f506": { + "id": "ffffffff-002a-0002-f519-00000019f506", + "event": "aaaaaaaa-000f-0000-4540-000000094539", + "member": { + "id": "99999999-007a-0007-666f-0000004b6636", + "first_name": "Leon", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + "created_at": "2026-05-20T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 7 + }, + "ffffffff-002b-0002-9351-0000001a933d": { + "id": "ffffffff-002b-0002-9351-0000001a933d", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-007f-0007-7d85-0000004e7d49", + "first_name": "Tilda", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 9 + }, + "ffffffff-002c-0002-3188-0000001b3174": { + "id": "ffffffff-002c-0002-3188-0000001b3174", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0081-0008-b9f4-0000004fb9b7", + "first_name": "Leon", + "last_name": "Busch" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 6 + }, + "ffffffff-002d-0002-cfc0-0000001bcfab": { + "id": "ffffffff-002d-0002-cfc0-0000001bcfab", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0084-0008-949a-00000051945c", + "first_name": "Juna", + "last_name": "Reil" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 8 + }, + "ffffffff-002e-0002-6df7-0000001c6de2": { + "id": "ffffffff-002e-0002-6df7-0000001c6de2", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0085-0008-32d2-000000523293", + "first_name": "Juna", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 5 + }, + "ffffffff-002f-0002-0c2f-0000001d0c19": { + "id": "ffffffff-002f-0002-0c2f-0000001d0c19", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0087-0008-6f41-000000536f01", + "first_name": "Sofia", + "last_name": "Brandt" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-17T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 7 + }, + "ffffffff-0030-0003-aa66-0000001daa50": { + "id": "ffffffff-0030-0003-aa66-0000001daa50", + "event": "aaaaaaaa-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0088-0008-0d78-000000540d38", + "first_name": "Samuel", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 9 + }, + "ffffffff-0031-0003-489e-0000001e4887": { + "id": "ffffffff-0031-0003-489e-0000001e4887", + "event": "aaaaaaaa-0013-0001-be1e-0000000bbe15", + "member": { + "id": "99999999-008c-0008-8656-000000568614", + "first_name": "Moritz", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 6 + }, + "ffffffff-0032-0003-e6d5-0000001ee6be": { + "id": "ffffffff-0032-0003-e6d5-0000001ee6be", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-0093-0009-d9da-0000005ad995", + "first_name": "Finn", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-07T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 8 + }, + "ffffffff-0033-0003-850d-0000001f84f5": { + "id": "ffffffff-0033-0003-850d-0000001f84f5", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-0095-0009-1649-0000005c1603", + "first_name": "Lea", + "last_name": "Park" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-04T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 10 + }, + "ffffffff-0034-0003-2344-00000020232c": { + "id": "ffffffff-0034-0003-2344-00000020232c", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-0098-0009-f0f0-0000005df0a8", + "first_name": "Aaron", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-26T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 7 + }, + "ffffffff-0035-0003-c17c-00000020c163": { + "id": "ffffffff-0035-0003-c17c-00000020c163", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-009d-0009-0805-0000006107bb", + "first_name": "Lena", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-21T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 5 + }, + "ffffffff-0036-0003-5fb3-000000215f9a": { + "id": "ffffffff-0036-0003-5fb3-000000215f9a", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-009e-0009-a63d-00000061a5f2", + "first_name": "Joris", + "last_name": "Schulz" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 9 + }, + "ffffffff-0037-0003-fdeb-00000021fdd1": { + "id": "ffffffff-0037-0003-fdeb-00000021fdd1", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-00a1-000a-80e3-000000638097", + "first_name": "Amelie", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 8 + }, + "ffffffff-0038-0003-9c22-000000229c08": { + "id": "ffffffff-0038-0003-9c22-000000229c08", + "event": "aaaaaaaa-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-00a2-000a-1f1b-000000641ece", + "first_name": "Jonas", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 6 + }, + "ffffffff-0039-0003-3a5a-000000233a3f": { + "id": "ffffffff-0039-0003-3a5a-000000233a3f", + "event": "aaaaaaaa-0017-0001-36fb-0000000e36f1", + "member": { + "id": "99999999-00a7-000a-3630-0000006735e1", + "first_name": "Carla", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 7 + }, + "ffffffff-003a-0003-d891-00000023d876": { + "id": "ffffffff-003a-0003-d891-00000023d876", + "event": "aaaaaaaa-0017-0001-36fb-0000000e36f1", + "member": { + "id": "99999999-00aa-000a-10d6-000000691086", + "first_name": "Bela", + "last_name": "Klein" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "feedback": "Technique is coming along well. Focus next on consistency across both sides.", + "rating": 9 + }, + "ffffffff-003b-0003-76c9-0000002476ad": { + "id": "ffffffff-003b-0003-76c9-0000002476ad", + "event": "aaaaaaaa-0019-0001-736a-0000000f735f", + "member": { + "id": "99999999-00ae-000a-89b4-0000006b8962", + "first_name": "Jonah", + "last_name": "König" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today." + }, + "ffffffff-003c-0003-1500-0000002514e4": { + "id": "ffffffff-003c-0003-1500-0000002514e4", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00b6-000b-7b70-000000707b1a", + "first_name": "Finn", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 8 + }, + "ffffffff-003d-0003-b337-00000025b31b": { + "id": "ffffffff-003d-0003-b337-00000025b31b", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00b9-000b-5616-0000007255bf", + "first_name": "Frida", + "last_name": "Brandt" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 4 + }, + "ffffffff-003e-0003-516f-000000265152": { + "id": "ffffffff-003e-0003-516f-000000265152", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00bb-000b-9285-00000073922d", + "first_name": "Sofia", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-06-02T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 7 + }, + "ffffffff-003f-0003-efa6-00000026ef89": { + "id": "ffffffff-003f-0003-efa6-00000026ef89", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00bc-000b-30bd-000000743064", + "first_name": "Jonah", + "last_name": "Park" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-05-31T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 6 + }, + "ffffffff-0040-0004-8dde-000000278dc0": { + "id": "ffffffff-0040-0004-8dde-000000278dc0", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00be-000b-6d2c-000000756cd2", + "first_name": "Emil", + "last_name": "Diaz" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 9 + }, + "ffffffff-0041-0004-2c15-000000282bf7": { + "id": "ffffffff-0041-0004-2c15-000000282bf7", + "event": "aaaaaaaa-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-00bf-000b-0b63-000000760b09", + "first_name": "David", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-06-14T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 8 + }, + "ffffffff-0042-0004-ca4d-00000028ca2e": { + "id": "ffffffff-0042-0004-ca4d-00000028ca2e", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c1-000c-47d2-000000774777", + "first_name": "Emil", + "last_name": "Schwarz" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 5 + }, + "ffffffff-0043-0004-6884-000000296865": { + "id": "ffffffff-0043-0004-6884-000000296865", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c3-000c-8441-0000007883e5", + "first_name": "Rosa", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 7 + }, + "ffffffff-0044-0004-06bc-0000002a069c": { + "id": "ffffffff-0044-0004-06bc-0000002a069c", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c4-000c-2279-00000079221c", + "first_name": "Frida", + "last_name": "Neumann" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-07T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 10 + }, + "ffffffff-0045-0004-a4f3-0000002aa4d3": { + "id": "ffffffff-0045-0004-a4f3-0000002aa4d3", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c6-000c-5ee8-0000007a5e8a", + "first_name": "Edda", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 6 + }, + "ffffffff-0046-0004-432b-0000002b430a": { + "id": "ffffffff-0046-0004-432b-0000002b430a", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00c8-000c-9b57-0000007b9af8", + "first_name": "Emil", + "last_name": "Klein" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-13T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 8 + }, + "ffffffff-0047-0004-e162-0000002be141": { + "id": "ffffffff-0047-0004-e162-0000002be141", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00cf-000c-eedb-0000007fee79", + "first_name": "Toni", + "last_name": "Krause" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-02T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 3 + }, + "ffffffff-0048-0004-7f9a-0000002c7f78": { + "id": "ffffffff-0048-0004-7f9a-0000002c7f78", + "event": "aaaaaaaa-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-00d0-000d-8d12-000000808cb0", + "first_name": "Lotte", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-05-23T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 7 + }, + "ffffffff-0049-0004-1dd1-0000002d1daf": { + "id": "ffffffff-0049-0004-1dd1-0000002d1daf", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d1-000d-2b4a-000000812ae7", + "first_name": "Lotte", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-06T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 9 + }, + "ffffffff-004a-0004-bc09-0000002dbbe6": { + "id": "ffffffff-004a-0004-bc09-0000002dbbe6", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d2-000d-c981-00000081c91e", + "first_name": "Mara", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 5 + }, + "ffffffff-004b-0004-5a40-0000002e5a1d": { + "id": "ffffffff-004b-0004-5a40-0000002e5a1d", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d3-000d-67b9-000000826755", + "first_name": "Ella", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-26T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 8 + }, + "ffffffff-004c-0004-f878-0000002ef854": { + "id": "ffffffff-004c-0004-f878-0000002ef854", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d6-000d-425f-0000008441fa", + "first_name": "Nele", + "last_name": "Scholz" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-14T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 6 + }, + "ffffffff-004d-0004-96af-0000002f968b": { + "id": "ffffffff-004d-0004-96af-0000002f968b", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00d7-000d-e097-00000084e031", + "first_name": "Oskar", + "last_name": "Stein" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 0 + }, + "ffffffff-004e-0004-34e7-0000003034c2": { + "id": "ffffffff-004e-0004-34e7-0000003034c2", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00db-000d-5975-00000087590d", + "first_name": "Ida", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-23T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 7 + }, + "ffffffff-004f-0004-d31e-00000030d2f9": { + "id": "ffffffff-004f-0004-d31e-00000030d2f9", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00dc-000d-f7ac-00000087f744", + "first_name": "Levi", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-04T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 8 + }, + "ffffffff-0050-0005-7156-000000317130": { + "id": "ffffffff-0050-0005-7156-000000317130", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00df-000d-d253-00000089d1e9", + "first_name": "Toni", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 9 + }, + "ffffffff-0051-0005-0f8d-000000320f67": { + "id": "ffffffff-0051-0005-0f8d-000000320f67", + "event": "aaaaaaaa-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-00e0-000e-708a-0000008a7020", + "first_name": "Nele", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 8 + }, + "ffffffff-0052-0005-adc4-00000032ad9e": { + "id": "ffffffff-0052-0005-adc4-00000032ad9e", + "event": "aaaaaaaa-0021-0002-6526-000000146517", + "member": { + "id": "99999999-00e8-000e-6246-0000008f61d8", + "first_name": "Lea", + "last_name": "Stein" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure." + }, + "ffffffff-0053-0005-4bfc-000000334bd5": { + "id": "ffffffff-0053-0005-4bfc-000000334bd5", + "event": "aaaaaaaa-0021-0002-6526-000000146517", + "member": { + "id": "99999999-00ed-000e-795b-0000009278eb", + "first_name": "Mats", + "last_name": "Horn" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-24T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 9 + }, + "ffffffff-0054-0005-ea33-00000033ea0c": { + "id": "ffffffff-0054-0005-ea33-00000033ea0c", + "event": "aaaaaaaa-0021-0002-6526-000000146517", + "member": { + "id": "99999999-00ee-000e-1793-000000931722", + "first_name": "Lina", + "last_name": "Krüger" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 6 + }, + "ffffffff-0055-0005-886b-000000348843": { + "id": "ffffffff-0055-0005-886b-000000348843", + "event": "aaaaaaaa-0021-0002-6526-000000146517", + "member": { + "id": "99999999-00f4-000f-ccdf-00000096cc6c", + "first_name": "Stella", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + "created_at": "2026-05-20T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 8 + }, + "ffffffff-0056-0005-26a2-00000035267a": { + "id": "ffffffff-0056-0005-26a2-00000035267a", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00f9-000f-e3f5-00000099e37f", + "first_name": "Joris", + "last_name": "Huber" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-29T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 5 + }, + "ffffffff-0057-0005-c4da-00000035c4b1": { + "id": "ffffffff-0057-0005-c4da-00000035c4b1", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00fa-000f-822c-0000009a81b6", + "first_name": "Mara", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-21T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 7 + }, + "ffffffff-0058-0005-6311-0000003662e8": { + "id": "ffffffff-0058-0005-6311-0000003662e8", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00fb-000f-2064-0000009b1fed", + "first_name": "Martha", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 9 + }, + "ffffffff-0059-0005-0149-00000037011f": { + "id": "ffffffff-0059-0005-0149-00000037011f", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00fc-000f-be9b-0000009bbe24", + "first_name": "Mats", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-14T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 6 + }, + "ffffffff-005a-0005-9f80-000000379f56": { + "id": "ffffffff-005a-0005-9f80-000000379f56", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-00fe-000f-fb0a-0000009cfa92", + "first_name": "Erik", + "last_name": "Schulz" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 8 + }, + "ffffffff-005b-0005-3db8-000000383d8d": { + "id": "ffffffff-005b-0005-3db8-000000383d8d", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-0101-0010-d5b1-0000009ed537", + "first_name": "Clara", + "last_name": "Pohl" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 10 + }, + "ffffffff-005c-0005-dbef-00000038dbc4": { + "id": "ffffffff-005c-0005-dbef-00000038dbc4", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-0102-0010-73e8-0000009f736e", + "first_name": "Niklas", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-08T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 7 + }, + "ffffffff-005d-0005-7a27-0000003979fb": { + "id": "ffffffff-005d-0005-7a27-0000003979fb", + "event": "aaaaaaaa-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-0106-0010-ecc6-000000a1ec4a", + "first_name": "Nele", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 5 + }, + "ffffffff-005e-0005-185e-0000003a1832": { + "id": "ffffffff-005e-0005-185e-0000003a1832", + "event": "aaaaaaaa-0025-0002-de04-00000016ddf3", + "member": { + "id": "99999999-010e-0010-de82-000000a6de02", + "first_name": "Magda", + "last_name": "Bauer" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-05-26T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 9 + }, + "ffffffff-005f-0005-b696-0000003ab669": { + "id": "ffffffff-005f-0005-b696-0000003ab669", + "event": "aaaaaaaa-0025-0002-de04-00000016ddf3", + "member": { + "id": "99999999-0110-0011-1af1-000000a81a70", + "first_name": "Mira", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 8 + }, + "ffffffff-0060-0006-54cd-0000003b54a0": { + "id": "ffffffff-0060-0006-54cd-0000003b54a0", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0112-0011-5760-000000a956de", + "first_name": "Paul", + "last_name": "Reil" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-31T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 6 + }, + "ffffffff-0061-0006-f305-0000003bf2d7": { + "id": "ffffffff-0061-0006-f305-0000003bf2d7", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0116-0011-d03e-000000abcfba", + "first_name": "Pia", + "last_name": "Zimmermann" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-22T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 7 + }, + "ffffffff-0062-0006-913c-0000003c910e": { + "id": "ffffffff-0062-0006-913c-0000003c910e", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0118-0011-0cad-000000ad0c28", + "first_name": "Joris", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-07T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 9 + }, + "ffffffff-0063-0006-2f74-0000003d2f45": { + "id": "ffffffff-0063-0006-2f74-0000003d2f45", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-011a-0011-491c-000000ae4896", + "first_name": "Jonah", + "last_name": "Diaz" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-31T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 5 + }, + "ffffffff-0064-0006-cdab-0000003dcd7c": { + "id": "ffffffff-0064-0006-cdab-0000003dcd7c", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-011b-0011-e753-000000aee6cd", + "first_name": "Mats", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 8 + }, + "ffffffff-0065-0006-6be3-0000003e6bb3": { + "id": "ffffffff-0065-0006-6be3-0000003e6bb3", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-011d-0011-23c2-000000b0233b", + "first_name": "Janne", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 4 + }, + "ffffffff-0066-0006-0a1a-0000003f09ea": { + "id": "ffffffff-0066-0006-0a1a-0000003f09ea", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-011e-0011-c1f9-000000b0c172", + "first_name": "Amelie", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 7 + }, + "ffffffff-0067-0006-a851-0000003fa821": { + "id": "ffffffff-0067-0006-a851-0000003fa821", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0120-0012-fe68-000000b1fde0", + "first_name": "Lea", + "last_name": "Engel" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-11T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 6 + }, + "ffffffff-0068-0006-4689-000000404658": { + "id": "ffffffff-0068-0006-4689-000000404658", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0121-0012-9ca0-000000b29c17", + "first_name": "Stella", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-05-24T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 9 + }, + "ffffffff-0069-0006-e4c0-00000040e48f": { + "id": "ffffffff-0069-0006-e4c0-00000040e48f", + "event": "aaaaaaaa-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0122-0012-3ad7-000000b33a4e", + "first_name": "Helena", + "last_name": "König" + }, + "creator": { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine." + }, + "ffffffff-006a-0006-82f8-0000004182c6": { + "id": "ffffffff-006a-0006-82f8-0000004182c6", + "event": "aaaaaaaa-0029-0002-56e2-0000001956cf", + "member": { + "id": "99999999-012b-0012-cacb-000000b8ca3d", + "first_name": "Noah", + "last_name": "Schulz" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 5 + }, + "ffffffff-006b-0006-212f-0000004220fd": { + "id": "ffffffff-006b-0006-212f-0000004220fd", + "event": "aaaaaaaa-0029-0002-56e2-0000001956cf", + "member": { + "id": "99999999-012f-0012-43a9-000000bb4319", + "first_name": "Nora", + "last_name": "Bauer" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 7 + }, + "ffffffff-006c-0006-bf67-00000042bf34": { + "id": "ffffffff-006c-0006-bf67-00000042bf34", + "event": "aaaaaaaa-0029-0002-56e2-0000001956cf", + "member": { + "id": "99999999-0130-0013-e1e0-000000bbe150", + "first_name": "Luca", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + "created_at": "2026-06-16T00:00:00.000Z", + "feedback": "Great session — first touch under pressure has noticeably improved. Keep your head up earlier when scanning.", + "rating": 10 + }, + "ffffffff-006d-0006-5d9e-000000435d6b": { + "id": "ffffffff-006d-0006-5d9e-000000435d6b", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0131-0013-8017-000000bc7f87", + "first_name": "Ada", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-05-28T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 6 + }, + "ffffffff-006e-0006-fbd6-00000043fba2": { + "id": "ffffffff-006e-0006-fbd6-00000043fba2", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0133-0013-bc86-000000bdbbf5", + "first_name": "Max", + "last_name": "Ziegler" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-09T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 8 + }, + "ffffffff-006f-0006-9a0d-0000004499d9": { + "id": "ffffffff-006f-0006-9a0d-0000004499d9", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0135-0013-f8f5-000000bef863", + "first_name": "Romi", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 3 + }, + "ffffffff-0070-0007-3845-000000453810": { + "id": "ffffffff-0070-0007-3845-000000453810", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0136-0013-972d-000000bf969a", + "first_name": "Moritz", + "last_name": "Albrecht" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-01T00:00:00.000Z", + "feedback": "Nice progress since last month. The extra reps are showing in your sharpness.", + "rating": 7 + }, + "ffffffff-0071-0007-d67c-00000045d647": { + "id": "ffffffff-0071-0007-d67c-00000045d647", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-013d-0013-eab1-000000c3ea1b", + "first_name": "Alma", + "last_name": "Klein" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-04T00:00:00.000Z", + "feedback": "Worked hard in the drills. Weight of pass is improving but still occasionally heavy under pressure.", + "rating": 9 + }, + "ffffffff-0072-0007-74b4-00000046747e": { + "id": "ffffffff-0072-0007-74b4-00000046747e", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0140-0014-c558-000000c5c4c0", + "first_name": "Mats", + "last_name": "Hartmann" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-04T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 5 + }, + "ffffffff-0073-0007-12eb-0000004712b5": { + "id": "ffffffff-0073-0007-12eb-0000004712b5", + "event": "aaaaaaaa-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-0142-0014-01c7-000000c7012e", + "first_name": "Anton", + "last_name": "Braun" + }, + "creator": { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 8 + }, + "ffffffff-0074-0007-b123-00000047b0ec": { + "id": "ffffffff-0074-0007-b123-00000047b0ec", + "event": "aaaaaaaa-002d-0002-cfc0-0000001bcfab", + "member": { + "id": "99999999-014b-0014-91ba-000000cc911d", + "first_name": "Konrad", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-05-27T00:00:00.000Z", + "feedback": "Excellent attitude and leadership on the pitch. Communication with teammates stood out today.", + "rating": 6 + }, + "ffffffff-0075-0007-4f5a-000000484f23": { + "id": "ffffffff-0075-0007-4f5a-000000484f23", + "event": "aaaaaaaa-002d-0002-cfc0-0000001bcfab", + "member": { + "id": "99999999-014c-0014-2ff1-000000cd2f54", + "first_name": "Elias", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + "created_at": "2026-05-25T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 0 + }, + "ffffffff-0076-0007-ed92-00000048ed5a": { + "id": "ffffffff-0076-0007-ed92-00000048ed5a", + "event": "aaaaaaaa-0031-0003-489e-0000001e4887", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-05T00:00:00.000Z", + "feedback": "Strong recovery runs and good awareness defensively. Keep building match fitness.", + "rating": 7 + }, + "ffffffff-0077-0007-8bc9-000000498b91": { + "id": "ffffffff-0077-0007-8bc9-000000498b91", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-15T00:00:00.000Z", + "feedback": "Solid work today. Positional discipline was strong; decision-making in the final third can be quicker.", + "rating": 8 + }, + "ffffffff-0078-0007-2a01-0000004a29c8": { + "id": "ffffffff-0078-0007-2a01-0000004a29c8", + "event": "aaaaaaaa-0001-0000-9e37-000000009e37", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + "created_at": "2026-06-10T00:00:00.000Z", + "feedback": "Good intensity throughout the conditioning block. Keep up the post-session stretching routine.", + "rating": 9 + } +} diff --git a/web-client/src/mocks/fixtures/finance.ts b/web-client/src/mocks/fixtures/finance.ts new file mode 100644 index 0000000..ba48f78 --- /dev/null +++ b/web-client/src/mocks/fixtures/finance.ts @@ -0,0 +1,2659 @@ +import type { Balance, Transaction } from '@/types' +import { CURRENT_MEMBER_ID } from './members' + +// Convention: negative amount_cents = charge, positive = payment received. +export const transactionFixtures: Transaction[] = [ + { + "id": "cccccccc-000a-0000-2e2a-000000062e26", + "member": { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-03-13T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-000b-0000-cc62-00000006cc5d", + "member": { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-05T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-000c-0000-6a99-000000076a94", + "member": { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-04-08T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-000d-0000-08d1-0000000808cb", + "member": { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-04-04T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-000e-0000-a708-00000008a702", + "member": { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-05-22T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-000f-0000-4540-000000094539", + "member": { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-24T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0010-0001-e377-00000009e370", + "member": { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-04-07T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0011-0001-81af-0000000a81a7", + "member": { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-04-22T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0012-0001-1fe6-0000000b1fde", + "member": { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-06-14T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-0013-0001-be1e-0000000bbe15", + "member": { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-06-13T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-0014-0001-5c55-0000000c5c4c", + "member": { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-03-22T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-0015-0001-fa8c-0000000cfa83", + "member": { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-06-11T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0016-0001-98c4-0000000d98ba", + "member": { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-04-04T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0017-0001-36fb-0000000e36f1", + "member": { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-03-31T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0018-0001-d533-0000000ed528", + "member": { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-06-13T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-0019-0001-736a-0000000f735f", + "member": { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-06-07T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-001a-0001-11a2-000000101196", + "member": { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-05-14T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-001b-0001-afd9-00000010afcd", + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-04-03T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-001c-0001-4e11-000000114e04", + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-04-16T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-001d-0001-ec48-00000011ec3b", + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-04-25T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-001e-0001-8a80-000000128a72", + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-25T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-001f-0001-28b7-0000001328a9", + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-05-27T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0020-0002-c6ef-00000013c6e0", + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-02-22T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-0021-0002-6526-000000146517", + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-04-02T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0022-0002-035e-00000015034e", + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-06-03T00:00:00.000Z", + "title": "Payment received", + "description": "Balancing payment" + }, + { + "id": "cccccccc-0023-0002-a195-00000015a185", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-07T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0024-0002-3fcd-000000163fbc", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-06-04T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0025-0002-de04-00000016ddf3", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-05-20T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-0026-0002-7c3c-000000177c2a", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-05-14T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-0027-0002-1a73-000000181a61", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-03-11T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0028-0002-b8ab-00000018b898", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-06-01T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0029-0002-56e2-0000001956cf", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-05-27T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-002a-0002-f519-00000019f506", + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-03-10T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-002b-0002-9351-0000001a933d", + "member": { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-03-21T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-002c-0002-3188-0000001b3174", + "member": { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-05-14T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-002d-0002-cfc0-0000001bcfab", + "member": { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-03-10T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-002e-0002-6df7-0000001c6de2", + "member": { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-04-02T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-002f-0002-0c2f-0000001d0c19", + "member": { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-04-22T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0030-0003-aa66-0000001daa50", + "member": { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-05-25T00:00:00.000Z", + "title": "Payment received", + "description": "Balancing payment" + }, + { + "id": "cccccccc-0031-0003-489e-0000001e4887", + "member": { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-05-16T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0032-0003-e6d5-0000001ee6be", + "member": { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-06-12T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0033-0003-850d-0000001f84f5", + "member": { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-03-04T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0034-0003-2344-00000020232c", + "member": { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-03-02T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0035-0003-c17c-00000020c163", + "member": { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-06-03T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0036-0003-5fb3-000000215f9a", + "member": { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-02-21T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0037-0003-fdeb-00000021fdd1", + "member": { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-06-02T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0038-0003-9c22-000000229c08", + "member": { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-05-01T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0039-0003-3a5a-000000233a3f", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-04-20T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-003a-0003-d891-00000023d876", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-04-10T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-003b-0003-76c9-0000002476ad", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-04-07T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-003c-0003-1500-0000002514e4", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-03-21T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-003d-0003-b337-00000025b31b", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-05-09T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-003e-0003-516f-000000265152", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-05-21T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-003f-0003-efa6-00000026ef89", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-02-19T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0040-0004-8dde-000000278dc0", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-06-14T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0041-0004-2c15-000000282bf7", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-04-24T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0042-0004-ca4d-00000028ca2e", + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 9500, + "created_at": "2026-06-11T00:00:00.000Z", + "title": "Payment received", + "description": "Balancing payment" + }, + { + "id": "cccccccc-0043-0004-6884-000000296865", + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-06-08T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-0044-0004-06bc-0000002a069c", + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-05-07T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-0045-0004-a4f3-0000002aa4d3", + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-06-13T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-0046-0004-432b-0000002b430a", + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-06-12T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-0047-0004-e162-0000002be141", + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-05-20T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-0048-0004-7f9a-0000002c7f78", + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-06-11T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0049-0004-1dd1-0000002d1daf", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-03-07T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-004a-0004-bc09-0000002dbbe6", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-22T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-004b-0004-5a40-0000002e5a1d", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-05-26T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-004c-0004-f878-0000002ef854", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-02-25T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-004d-0004-96af-0000002f968b", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-05-05T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-004e-0004-34e7-0000003034c2", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-06-08T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-004f-0004-d31e-00000030d2f9", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-04-15T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0050-0005-7156-000000317130", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-04-04T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0051-0005-0f8d-000000320f67", + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-06-16T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-0052-0005-adc4-00000032ad9e", + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-03-31T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0053-0005-4bfc-000000334bd5", + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-23T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0054-0005-ea33-00000033ea0c", + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-05-06T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0055-0005-886b-000000348843", + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-02-28T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0056-0005-26a2-00000035267a", + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-03-14T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0057-0005-c4da-00000035c4b1", + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-06-08T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0058-0005-6311-0000003662e8", + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-06-18T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0059-0005-0149-00000037011f", + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-05-08T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-005a-0005-9f80-000000379f56", + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-03-07T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-005b-0005-3db8-000000383d8d", + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-05-28T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-005c-0005-dbef-00000038dbc4", + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-04-22T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-005d-0005-7a27-0000003979fb", + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-05-03T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-005e-0005-185e-0000003a1832", + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-04-01T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-005f-0005-b696-0000003ab669", + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-04-25T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-0060-0006-54cd-0000003b54a0", + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-03-02T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0061-0006-f305-0000003bf2d7", + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-05-01T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0062-0006-913c-0000003c910e", + "member": { + "id": "99999999-0049-0004-1dd1-0000002d1daf", + "first_name": "Henry", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-05-13T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0063-0006-2f74-0000003d2f45", + "member": { + "id": "99999999-0049-0004-1dd1-0000002d1daf", + "first_name": "Henry", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-03-11T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0064-0006-cdab-0000003dcd7c", + "member": { + "id": "99999999-0049-0004-1dd1-0000002d1daf", + "first_name": "Henry", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-06-04T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0065-0006-6be3-0000003e6bb3", + "member": { + "id": "99999999-0049-0004-1dd1-0000002d1daf", + "first_name": "Henry", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-04-29T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-0066-0006-0a1a-0000003f09ea", + "member": { + "id": "99999999-0049-0004-1dd1-0000002d1daf", + "first_name": "Henry", + "last_name": "Richter" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-02-20T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0067-0006-a851-0000003fa821", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-28T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0068-0006-4689-000000404658", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-06-03T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0069-0006-e4c0-00000040e48f", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-06-03T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-006a-0006-82f8-0000004182c6", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-06-11T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-006b-0006-212f-0000004220fd", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-02-23T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-006c-0006-bf67-00000042bf34", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-05-23T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-006d-0006-5d9e-000000435d6b", + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 2000, + "created_at": "2026-04-25T00:00:00.000Z", + "title": "Payment received", + "description": "Standing order" + }, + { + "id": "cccccccc-006e-0006-fbd6-00000043fba2", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-05-17T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-006f-0006-9a0d-0000004499d9", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-05-30T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0070-0007-3845-000000453810", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-20T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0071-0007-d67c-00000045d647", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-04-14T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-0072-0007-74b4-00000046747e", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-04-30T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0073-0007-12eb-0000004712b5", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-03-09T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0074-0007-b123-00000047b0ec", + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-04-22T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0075-0007-4f5a-000000484f23", + "member": { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-06-13T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0076-0007-ed92-00000048ed5a", + "member": { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-05-28T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0077-0007-8bc9-000000498b91", + "member": { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-05-26T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-0078-0007-2a01-0000004a29c8", + "member": { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-06-10T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0079-0007-c838-0000004ac7ff", + "member": { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-06-04T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-007a-0007-666f-0000004b6636", + "member": { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-06-15T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-007b-0007-04a7-0000004c046d", + "member": { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -3000, + "created_at": "2026-04-11T00:00:00.000Z", + "title": "Equipment", + "description": "Training gear" + }, + { + "id": "cccccccc-007c-0007-a2de-0000004ca2a4", + "member": { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-06-04T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-007d-0007-4116-0000004d40db", + "member": { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-04-30T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-007e-0007-df4d-0000004ddf12", + "member": { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-05-04T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-007f-0007-7d85-0000004e7d49", + "member": { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-03-23T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0080-0008-1bbc-0000004f1b80", + "member": { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-05-27T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0081-0008-b9f4-0000004fb9b7", + "member": { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-03-11T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-0082-0008-582b-0000005057ee", + "member": { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-06-13T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0083-0008-f663-00000050f625", + "member": { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-05-27T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0084-0008-949a-00000051945c", + "member": { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-02-19T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-0085-0008-32d2-000000523293", + "member": { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-31T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0086-0008-d109-00000052d0ca", + "member": { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-02-28T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-0087-0008-6f41-000000536f01", + "member": { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-05-14T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0088-0008-0d78-000000540d38", + "member": { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-02-24T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + }, + { + "id": "cccccccc-0089-0008-abb0-00000054ab6f", + "member": { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-06-12T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-008a-0008-49e7-0000005549a6", + "member": { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-06-13T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-008b-0008-e81f-00000055e7dd", + "member": { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-03-20T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-008c-0008-8656-000000568614", + "member": { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-06-15T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-008d-0008-248e-00000057244b", + "member": { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -1500, + "created_at": "2026-05-23T00:00:00.000Z", + "title": "Tournament entry", + "description": "Regional cup" + }, + { + "id": "cccccccc-008e-0008-c2c5-00000057c282", + "member": { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-04-01T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-008f-0008-60fc-0000005860b9", + "member": { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -4500, + "created_at": "2026-03-09T00:00:00.000Z", + "title": "Kit purchase", + "description": "Club jersey + shorts" + }, + { + "id": "cccccccc-0090-0009-ff34-00000058fef0", + "member": { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-03-27T00:00:00.000Z", + "title": "Monthly dues", + "description": "Membership fee" + }, + { + "id": "cccccccc-0091-0009-9d6b-000000599d27", + "member": { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-05-25T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-0092-0009-3ba3-0000005a3b5e", + "member": { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-05-08T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-0093-0009-d9da-0000005ad995", + "member": { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 8000, + "created_at": "2026-06-15T00:00:00.000Z", + "title": "Payment received", + "description": "Card payment" + }, + { + "id": "cccccccc-0094-0009-7812-0000005b77cc", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-06-01T00:00:00.000Z", + "title": "Monthly dues", + "description": "June membership fee" + }, + { + "id": "cccccccc-0095-0009-1649-0000005c1603", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 6000, + "created_at": "2026-05-26T00:00:00.000Z", + "title": "Payment received", + "description": "Bank transfer" + }, + { + "id": "cccccccc-0096-0009-b481-0000005cb43a", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2500, + "created_at": "2026-05-20T00:00:00.000Z", + "title": "Court fee", + "description": "League match — away" + }, + { + "id": "cccccccc-0097-0009-52b8-0000005d5271", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": -2000, + "created_at": "2026-05-01T00:00:00.000Z", + "title": "Monthly dues", + "description": "May membership fee" + }, + { + "id": "cccccccc-0098-0009-f0f0-0000005df0a8", + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "creator": { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops" + }, + "amount_cents": 4000, + "created_at": "2026-04-20T00:00:00.000Z", + "title": "Payment received", + "description": "Cash — front desk" + } +] + +export const balanceFixtures: Balance[] = [ + { + "member": { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + "balance_cents": -1000 + }, + { + "member": { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + "balance_cents": 9500 + }, + { + "member": { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + "balance_cents": 0 + }, + { + "member": { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + "balance_cents": 1500 + }, + { + "member": { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + "balance_cents": -500 + }, + { + "member": { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + "balance_cents": 0 + }, + { + "member": { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + "balance_cents": 8500 + }, + { + "member": { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + "balance_cents": 3000 + }, + { + "member": { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + "balance_cents": -3000 + }, + { + "member": { + "id": "99999999-002d-0002-cfc0-0000001bcfab", + "first_name": "Romi", + "last_name": "Werner" + }, + "balance_cents": 0 + }, + { + "member": { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + "balance_cents": 1000 + }, + { + "member": { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + "balance_cents": 3000 + }, + { + "member": { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + "balance_cents": -7500 + }, + { + "member": { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + "balance_cents": 4500 + }, + { + "member": { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + "balance_cents": 9000 + }, + { + "member": { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + "balance_cents": 5500 + }, + { + "member": { + "id": "99999999-0049-0004-1dd1-0000002d1daf", + "first_name": "Henry", + "last_name": "Richter" + }, + "balance_cents": -6500 + }, + { + "member": { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + "balance_cents": 2000 + }, + { + "member": { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + "balance_cents": 11000 + }, + { + "member": { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + "balance_cents": 1500 + }, + { + "member": { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler" + }, + "balance_cents": -5500 + }, + { + "member": { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + "balance_cents": 5000 + }, + { + "member": { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + "balance_cents": 500 + }, + { + "member": { + "id": "99999999-0061-0006-f305-0000003bf2d7", + "first_name": "Leon", + "last_name": "Braun" + }, + "balance_cents": 0 + }, + { + "member": { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + "balance_cents": -9000 + }, + { + "member": { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + "balance_cents": 11500 + }, + { + "member": { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + "balance_cents": 3500 + } +] + +export const currentMemberBalance: Balance = + balanceFixtures.find((b) => b.member.id === CURRENT_MEMBER_ID) ?? balanceFixtures[0] diff --git a/web-client/src/mocks/fixtures/index.ts b/web-client/src/mocks/fixtures/index.ts new file mode 100644 index 0000000..46198bb --- /dev/null +++ b/web-client/src/mocks/fixtures/index.ts @@ -0,0 +1,7 @@ +// Shared fixtures, typed against the generated API schema so they can't drift. +export * from './members' +export * from './events' +export * from './feedback' +export * from './finance' +export * from './organization' +export * from './report' diff --git a/web-client/src/mocks/fixtures/members.ts b/web-client/src/mocks/fixtures/members.ts new file mode 100644 index 0000000..c45dc7f --- /dev/null +++ b/web-client/src/mocks/fixtures/members.ts @@ -0,0 +1,3745 @@ +import type { Member, MemberSummary } from '@/types' + +// Signed-in member (`sub`) for the default mock persona. +export const CURRENT_MEMBER_ID = '11111111-1111-1111-1111-111111111111' + +export const memberFixtures: Member[] = [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth", + "email": "lena.roth@club.de", + "birthday": "2008-02-19", + "phone_number": "+49 177 1914194", + "address": "Rosenstraße 4, 80469 München", + "joining_date": "2021-07-15", + "information": "U16 squad. Left midfield." + }, + { + "id": "99999999-0001-0000-9e37-000000009e37", + "first_name": "Johanna", + "last_name": "Horn", + "email": "johanna.horn@club.de", + "birthday": "1983-02-07", + "phone_number": "+49 157 8648693", + "address": "Birkenallee 93, 81667 München", + "joining_date": "2024-10-26", + "information": "Club director." + }, + { + "id": "99999999-0002-0000-3c6e-000000013c6e", + "first_name": "Tilda", + "last_name": "Huber", + "email": "tilda.huber@club.de", + "birthday": "1981-04-28", + "phone_number": "+49 169 8646592", + "address": "Kirchplatz 69, 80333 München", + "joining_date": "2023-01-10", + "information": "Club director." + }, + { + "id": "99999999-0003-0000-daa6-00000001daa5", + "first_name": "Director", + "last_name": "Devoops", + "email": "director.devoops@club.de", + "birthday": "1994-01-11", + "phone_number": "+49 157 6684918", + "address": "Lindenstraße 133, 80337 München", + "joining_date": "2019-08-19", + "information": "Club director." + }, + { + "id": "99999999-0004-0000-78dd-0000000278dc", + "first_name": "Admin", + "last_name": "Devoops", + "email": "admin.devoops@club.de", + "birthday": "1994-07-05", + "phone_number": "+49 164 9960184", + "address": "Ahornweg 20, 81667 München", + "joining_date": "2024-12-06", + "information": "Club administrator." + }, + { + "id": "99999999-0005-0000-1715-000000031713", + "first_name": "Ella", + "last_name": "Reil", + "email": "ella.reil@club.de", + "birthday": "1989-12-05", + "phone_number": "+49 156 2883472", + "address": "Wiesenweg 69, 81243 München", + "joining_date": "2018-03-07", + "information": "Coach / trainer." + }, + { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger", + "email": "erik.berger@club.de", + "birthday": "1983-05-14", + "phone_number": "+49 160 6529327", + "address": "Lindenstraße 14, 80636 München", + "joining_date": "2024-11-14", + "information": "Coach / trainer." + }, + { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann", + "email": "lina.zimmermann@club.de", + "birthday": "1991-08-26", + "phone_number": "+49 171 8122796", + "address": "Ahornweg 56, 80335 München", + "joining_date": "2024-10-10", + "information": "Coach / trainer." + }, + { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht", + "email": "theo.albrecht@club.de", + "birthday": "1987-10-14", + "phone_number": "+49 164 1909138", + "address": "Mühlgasse 9, 80337 München", + "joining_date": "2018-01-14", + "information": "Coach / trainer." + }, + { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber", + "email": "magda.huber@club.de", + "birthday": "1996-03-16", + "phone_number": "+49 170 3476169", + "address": "Mühlgasse 18, 80636 München", + "joining_date": "2020-02-12", + "information": "Coach / trainer." + }, + { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank", + "email": "ella.frank@club.de", + "birthday": "1976-05-22", + "phone_number": "+49 150 6547182", + "address": "Talstraße 18, 80801 München", + "joining_date": "2019-10-23", + "information": "Coach / trainer." + }, + { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt", + "email": "felix.voigt@club.de", + "birthday": "1982-05-21", + "phone_number": "+49 155 9402739", + "address": "Parkstraße 30, 80331 München", + "joining_date": "2019-07-11", + "information": "Coach / trainer." + }, + { + "id": "99999999-000c-0000-6a99-000000076a94", + "first_name": "Liv", + "last_name": "Scholz", + "email": "liv.scholz@club.de", + "birthday": "1996-10-10", + "phone_number": "+49 160 8142947", + "address": "Mühlgasse 74, 80801 München", + "joining_date": "2024-11-07", + "information": "Coach / trainer." + }, + { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops", + "email": "coach.devoops@club.de", + "birthday": "1983-07-17", + "phone_number": "+49 163 1250170", + "address": "Ahornweg 119, 80801 München", + "joining_date": "2018-03-25", + "information": "Coach / trainer." + }, + { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank", + "email": "smilla.frank@club.de", + "birthday": "1989-03-14", + "phone_number": "+49 151 7592426", + "address": "Parkstraße 14, 80333 München", + "joining_date": "2025-09-02", + "information": "Coach / trainer." + }, + { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch", + "email": "mara.koch@club.de", + "birthday": "1994-12-08", + "phone_number": "+49 167 5733796", + "address": "Sonnenweg 65, 80337 München", + "joining_date": "2019-07-06", + "information": "Coach / trainer." + }, + { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt", + "email": "wilma.vogt@club.de", + "birthday": "1988-02-12", + "phone_number": "+49 156 3465920", + "address": "Sonnenweg 67, 80469 München", + "joining_date": "2025-01-10", + "information": "Coach / trainer." + }, + { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel", + "email": "niklas.engel@club.de", + "birthday": "1982-07-03", + "phone_number": "+49 163 6952840", + "address": "Mühlgasse 94, 80538 München", + "joining_date": "2023-12-10", + "information": "Coach / trainer." + }, + { + "id": "99999999-0012-0001-1fe6-0000000b1fde", + "first_name": "Mats", + "last_name": "Klein", + "email": "mats.klein@club.de", + "birthday": "1978-07-16", + "phone_number": "+49 178 5131402", + "address": "Schulstraße 126, 80636 München", + "joining_date": "2023-12-04", + "information": "Coach / trainer." + }, + { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf", + "email": "marie.wolf@club.de", + "birthday": "2010-03-08", + "phone_number": "+49 160 4836968", + "address": "Uferweg 125, 80469 München", + "joining_date": "2022-09-28", + "information": "Football — Juniors." + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch", + "email": "linus.koch@club.de", + "birthday": "2007-12-15", + "phone_number": "+49 157 1881442", + "address": "Lindenstraße 44, 80801 München", + "joining_date": "2019-10-26", + "information": "Football — Juniors." + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck", + "email": "linus.beck@club.de", + "birthday": "2007-09-09", + "phone_number": "+49 151 3524808", + "address": "Birkenallee 108, 81667 München", + "joining_date": "2021-11-10", + "information": "Football — Juniors." + }, + { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank", + "email": "clara.frank@club.de", + "birthday": "2011-03-28", + "phone_number": "+49 155 5640888", + "address": "Schulstraße 66, 80333 München", + "joining_date": "2024-03-19", + "information": "Football — Juniors." + }, + { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank", + "email": "edda.frank@club.de", + "birthday": "2007-11-22", + "phone_number": "+49 153 2831581", + "address": "Schulstraße 61, 80335 München", + "joining_date": "2023-04-04", + "information": "Football — Juniors." + }, + { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner", + "email": "mia.werner@club.de", + "birthday": "2011-03-11", + "phone_number": "+49 165 2756125", + "address": "Rosenstraße 130, 81667 München", + "joining_date": "2019-03-22", + "information": "Football — Juniors." + }, + { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner", + "email": "charlotte.wagner@club.de", + "birthday": "2011-08-24", + "phone_number": "+49 170 4177031", + "address": "Sonnenweg 83, 80331 München", + "joining_date": "2018-11-20", + "information": "Football — Juniors." + }, + { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel", + "email": "jakob.seidel@club.de", + "birthday": "2011-04-24", + "phone_number": "+49 155 9313377", + "address": "Ahornweg 19, 80337 München", + "joining_date": "2023-03-06", + "information": "Football — Juniors." + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger", + "email": "ella.krüger@club.de", + "birthday": "2010-03-24", + "phone_number": "+49 176 9681608", + "address": "Birkenallee 77, 80469 München", + "joining_date": "2022-05-03", + "information": "Football — Juniors." + }, + { + "id": "99999999-001c-0001-4e11-000000114e04", + "first_name": "Erik", + "last_name": "Lange", + "email": "erik.lange@club.de", + "birthday": "2010-08-17", + "phone_number": "+49 174 1117619", + "address": "Schulstraße 62, 80636 München", + "joining_date": "2022-01-13", + "information": "Football — Juniors." + }, + { + "id": "99999999-001d-0001-ec48-00000011ec3b", + "first_name": "Janne", + "last_name": "Roth", + "email": "janne.roth@club.de", + "birthday": "2010-04-12", + "phone_number": "+49 152 1635032", + "address": "Schulstraße 125, 80801 München", + "joining_date": "2025-01-10", + "information": "Football — Juniors." + }, + { + "id": "99999999-001e-0001-8a80-000000128a72", + "first_name": "Theo", + "last_name": "Diaz", + "email": "theo.diaz@club.de", + "birthday": "2011-03-02", + "phone_number": "+49 158 8407799", + "address": "Kirchplatz 13, 81667 München", + "joining_date": "2019-12-06", + "information": "Football — Juniors." + }, + { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann", + "email": "samuel.neumann@club.de", + "birthday": "2009-07-20", + "phone_number": "+49 168 3629386", + "address": "Sonnenweg 2, 80333 München", + "joining_date": "2023-10-16", + "information": "Football — Juniors." + }, + { + "id": "99999999-0020-0002-c6ef-00000013c6e0", + "first_name": "Levi", + "last_name": "Voigt", + "email": "levi.voigt@club.de", + "birthday": "2010-05-22", + "phone_number": "+49 173 8543792", + "address": "Wiesenweg 128, 81667 München", + "joining_date": "2018-01-20", + "information": "Football — Juniors." + }, + { + "id": "99999999-0021-0002-6526-000000146517", + "first_name": "Mia", + "last_name": "Albrecht", + "email": "mia.albrecht@club.de", + "birthday": "2010-06-11", + "phone_number": "+49 179 5348520", + "address": "Gartenweg 55, 80335 München", + "joining_date": "2020-10-07", + "information": "Football — Juniors." + }, + { + "id": "99999999-0022-0002-035e-00000015034e", + "first_name": "Ida", + "last_name": "Krüger", + "email": "ida.krüger@club.de", + "birthday": "2011-07-08", + "phone_number": "+49 163 1549161", + "address": "Lindenstraße 124, 81667 München", + "joining_date": "2022-12-07", + "information": "Football — Juniors." + }, + { + "id": "99999999-0023-0002-a195-00000015a185", + "first_name": "Oskar", + "last_name": "Schulz", + "email": "oskar.schulz@club.de", + "birthday": "2007-08-14", + "phone_number": "+49 158 8658816", + "address": "Gartenweg 77, 81667 München", + "joining_date": "2024-01-26", + "information": "Football — Juniors." + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch", + "email": "clara.koch@club.de", + "birthday": "2010-03-05", + "phone_number": "+49 151 6249865", + "address": "Kirchplatz 108, 80337 München", + "joining_date": "2020-04-17", + "information": "Football — Juniors." + }, + { + "id": "99999999-0025-0002-de04-00000016ddf3", + "first_name": "Fynn", + "last_name": "Vogt", + "email": "fynn.vogt@club.de", + "birthday": "2008-08-27", + "phone_number": "+49 152 7715199", + "address": "Schulstraße 104, 80801 München", + "joining_date": "2022-04-26", + "information": "Football — Juniors." + }, + { + "id": "99999999-0026-0002-7c3c-000000177c2a", + "first_name": "Moritz", + "last_name": "Seidel", + "email": "moritz.seidel@club.de", + "birthday": "2011-01-10", + "phone_number": "+49 157 8217042", + "address": "Mühlgasse 19, 80801 München", + "joining_date": "2024-09-07", + "information": "Football — Juniors." + }, + { + "id": "99999999-0027-0002-1a73-000000181a61", + "first_name": "Nora", + "last_name": "Krause", + "email": "nora.krause@club.de", + "birthday": "2010-10-27", + "phone_number": "+49 176 4571076", + "address": "Schulstraße 79, 81667 München", + "joining_date": "2024-10-27", + "information": "Football — Juniors." + }, + { + "id": "99999999-0028-0002-b8ab-00000018b898", + "first_name": "Mats", + "last_name": "Huber", + "email": "mats.huber@club.de", + "birthday": "2009-01-22", + "phone_number": "+49 171 6065278", + "address": "Rosenstraße 101, 80469 München", + "joining_date": "2018-09-14", + "information": "Football — Juniors." + }, + { + "id": "99999999-0029-0002-56e2-0000001956cf", + "first_name": "Oskar", + "last_name": "Werner", + "email": "oskar.werner@club.de", + "birthday": "2007-08-13", + "phone_number": "+49 160 3102994", + "address": "Wiesenweg 61, 80538 München", + "joining_date": "2021-05-12", + "information": "Football — Juniors." + }, + { + "id": "99999999-002a-0002-f519-00000019f506", + "first_name": "Erik", + "last_name": "Richter", + "email": "erik.richter@club.de", + "birthday": "2008-04-08", + "phone_number": "+49 164 7099460", + "address": "Rosenstraße 96, 80538 München", + "joining_date": "2025-04-21", + "information": "Football — Juniors." + }, + { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold", + "email": "david.arnold@club.de", + "birthday": "2009-03-06", + "phone_number": "+49 152 3513994", + "address": "Schulstraße 114, 80801 München", + "joining_date": "2018-11-13", + "information": "Football — Group A." + }, + { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel", + "email": "marie.vogel@club.de", + "birthday": "2007-07-17", + "phone_number": "+49 152 3562802", + "address": "Kirchplatz 20, 80801 München", + "joining_date": "2021-06-25", + "information": "Football — Group A." + }, + { + "id": "99999999-002d-0002-cfc0-0000001bcfab", + "first_name": "Romi", + "last_name": "Werner", + "email": "romi.werner@club.de", + "birthday": "2010-09-04", + "phone_number": "+49 165 2325757", + "address": "Mühlgasse 41, 80801 München", + "joining_date": "2020-04-04", + "information": "Football — Group A." + }, + { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser", + "email": "wilma.kaiser@club.de", + "birthday": "2007-03-07", + "phone_number": "+49 150 4751883", + "address": "Bergstraße 138, 81243 München", + "joining_date": "2021-07-27", + "information": "Football — Group A." + }, + { + "id": "99999999-002f-0002-0c2f-0000001d0c19", + "first_name": "Romi", + "last_name": "Fuchs", + "email": "romi.fuchs@club.de", + "birthday": "2007-01-27", + "phone_number": "+49 150 6051586", + "address": "Rosenstraße 135, 80469 München", + "joining_date": "2020-10-09", + "information": "Football — Group A." + }, + { + "id": "99999999-0030-0003-aa66-0000001daa50", + "first_name": "Ben", + "last_name": "Vogel", + "email": "ben.vogel@club.de", + "birthday": "2008-02-17", + "phone_number": "+49 151 4754971", + "address": "Kirchplatz 131, 80636 München", + "joining_date": "2025-09-24", + "information": "Football — Group A." + }, + { + "id": "99999999-0031-0003-489e-0000001e4887", + "first_name": "Edda", + "last_name": "Zimmermann", + "email": "edda.zimmermann@club.de", + "birthday": "2010-04-05", + "phone_number": "+49 151 8551324", + "address": "Bergstraße 140, 80636 München", + "joining_date": "2021-02-13", + "information": "Football — Group A." + }, + { + "id": "99999999-0032-0003-e6d5-0000001ee6be", + "first_name": "Toni", + "last_name": "Brandt", + "email": "toni.brandt@club.de", + "birthday": "2011-12-02", + "phone_number": "+49 172 7815118", + "address": "Wiesenweg 74, 80801 München", + "joining_date": "2021-02-07", + "information": "Football — Group A." + }, + { + "id": "99999999-0033-0003-850d-0000001f84f5", + "first_name": "Ida", + "last_name": "Arnold", + "email": "ida.arnold@club.de", + "birthday": "2008-03-14", + "phone_number": "+49 164 5964871", + "address": "Uferweg 89, 80333 München", + "joining_date": "2025-06-16", + "information": "Football — Group A." + }, + { + "id": "99999999-0034-0003-2344-00000020232c", + "first_name": "Stella", + "last_name": "Zimmermann", + "email": "stella.zimmermann@club.de", + "birthday": "2007-12-26", + "phone_number": "+49 152 2368512", + "address": "Rosenstraße 87, 81243 München", + "joining_date": "2023-11-03", + "information": "Football — Group A." + }, + { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger", + "email": "helena.berger@club.de", + "birthday": "2009-05-25", + "phone_number": "+49 179 6612123", + "address": "Sonnenweg 21, 80469 München", + "joining_date": "2019-10-05", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter", + "email": "vincent.richter@club.de", + "birthday": "2008-05-04", + "phone_number": "+49 161 5594918", + "address": "Sonnenweg 22, 80331 München", + "joining_date": "2023-10-06", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank", + "email": "anton.frank@club.de", + "birthday": "2011-03-28", + "phone_number": "+49 162 6263090", + "address": "Lindenstraße 96, 81243 München", + "joining_date": "2018-02-03", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak", + "email": "greta.nowak@club.de", + "birthday": "2009-11-23", + "phone_number": "+49 152 4221496", + "address": "Talstraße 19, 80331 München", + "joining_date": "2019-07-13", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0039-0003-3a5a-000000233a3f", + "first_name": "Clara", + "last_name": "Stein", + "email": "clara.stein@club.de", + "birthday": "2009-12-17", + "phone_number": "+49 156 1591527", + "address": "Ahornweg 68, 80337 München", + "joining_date": "2023-06-26", + "information": "Football — Squad 2." + }, + { + "id": "99999999-003a-0003-d891-00000023d876", + "first_name": "Joris", + "last_name": "Stein", + "email": "joris.stein@club.de", + "birthday": "2008-08-02", + "phone_number": "+49 166 9626971", + "address": "Lindenstraße 1, 80636 München", + "joining_date": "2018-03-04", + "information": "Football — Squad 2." + }, + { + "id": "99999999-003b-0003-76c9-0000002476ad", + "first_name": "Frieda", + "last_name": "Bauer", + "email": "frieda.bauer@club.de", + "birthday": "2010-06-24", + "phone_number": "+49 169 8162763", + "address": "Bergstraße 79, 80337 München", + "joining_date": "2023-03-24", + "information": "Football — Squad 2." + }, + { + "id": "99999999-003c-0003-1500-0000002514e4", + "first_name": "Martha", + "last_name": "Schwarz", + "email": "martha.schwarz@club.de", + "birthday": "2010-05-28", + "phone_number": "+49 166 2984924", + "address": "Gartenweg 91, 81243 München", + "joining_date": "2022-12-19", + "information": "Football — Squad 2." + }, + { + "id": "99999999-003d-0003-b337-00000025b31b", + "first_name": "Fynn", + "last_name": "Koch", + "email": "fynn.koch@club.de", + "birthday": "2007-08-26", + "phone_number": "+49 160 8863565", + "address": "Birkenallee 65, 80337 München", + "joining_date": "2018-01-16", + "information": "Football — Squad 2." + }, + { + "id": "99999999-003e-0003-516f-000000265152", + "first_name": "Marie", + "last_name": "Fuchs", + "email": "marie.fuchs@club.de", + "birthday": "2009-02-07", + "phone_number": "+49 153 8105309", + "address": "Schulstraße 68, 80469 München", + "joining_date": "2020-10-22", + "information": "Football — Squad 2." + }, + { + "id": "99999999-003f-0003-efa6-00000026ef89", + "first_name": "Joris", + "last_name": "Lehmann", + "email": "joris.lehmann@club.de", + "birthday": "2008-09-22", + "phone_number": "+49 178 8432963", + "address": "Feldweg 18, 80337 München", + "joining_date": "2022-03-22", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0040-0004-8dde-000000278dc0", + "first_name": "Helena", + "last_name": "Graf", + "email": "helena.graf@club.de", + "birthday": "2007-12-19", + "phone_number": "+49 167 1116612", + "address": "Uferweg 116, 80331 München", + "joining_date": "2020-04-17", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0041-0004-2c15-000000282bf7", + "first_name": "Smilla", + "last_name": "Krause", + "email": "smilla.krause@club.de", + "birthday": "2010-11-23", + "phone_number": "+49 156 3649606", + "address": "Ahornweg 10, 80538 München", + "joining_date": "2025-01-05", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0042-0004-ca4d-00000028ca2e", + "first_name": "Konrad", + "last_name": "Schwarz", + "email": "konrad.schwarz@club.de", + "birthday": "2008-04-01", + "phone_number": "+49 158 3359439", + "address": "Wiesenweg 63, 80801 München", + "joining_date": "2021-01-11", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0043-0004-6884-000000296865", + "first_name": "Rosa", + "last_name": "Zimmermann", + "email": "rosa.zimmermann@club.de", + "birthday": "2008-11-02", + "phone_number": "+49 173 9991027", + "address": "Gartenweg 113, 80337 München", + "joining_date": "2019-07-07", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0044-0004-06bc-0000002a069c", + "first_name": "Arne", + "last_name": "Zimmermann", + "email": "arne.zimmermann@club.de", + "birthday": "2010-10-28", + "phone_number": "+49 175 4692781", + "address": "Lindenstraße 56, 80801 München", + "joining_date": "2025-04-20", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0045-0004-a4f3-0000002aa4d3", + "first_name": "Mats", + "last_name": "Graf", + "email": "mats.graf@club.de", + "birthday": "2008-08-23", + "phone_number": "+49 178 1701714", + "address": "Gartenweg 134, 80333 München", + "joining_date": "2022-09-09", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0046-0004-432b-0000002b430a", + "first_name": "Martha", + "last_name": "Voigt", + "email": "martha.voigt@club.de", + "birthday": "2007-05-14", + "phone_number": "+49 169 4066232", + "address": "Rosenstraße 11, 81243 München", + "joining_date": "2022-11-23", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0047-0004-e162-0000002be141", + "first_name": "Stella", + "last_name": "Horn", + "email": "stella.horn@club.de", + "birthday": "2010-07-23", + "phone_number": "+49 177 2910321", + "address": "Kirchplatz 136, 80333 München", + "joining_date": "2020-04-26", + "information": "Football — Squad 2." + }, + { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange", + "email": "levi.lange@club.de", + "birthday": "1980-09-11", + "phone_number": "+49 175 3970690", + "address": "Wiesenweg 138, 80331 München", + "joining_date": "2022-07-19", + "information": "Football — Seniors." + }, + { + "id": "99999999-0049-0004-1dd1-0000002d1daf", + "first_name": "Henry", + "last_name": "Richter", + "email": "henry.richter@club.de", + "birthday": "1993-10-13", + "phone_number": "+49 155 9122074", + "address": "Sonnenweg 133, 80801 München", + "joining_date": "2018-03-15", + "information": "Football — Seniors." + }, + { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer", + "email": "liv.sommer@club.de", + "birthday": "1994-09-20", + "phone_number": "+49 177 8366462", + "address": "Uferweg 37, 80538 München", + "joining_date": "2024-09-04", + "information": "Football — Seniors." + }, + { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt", + "email": "vincent.vogt@club.de", + "birthday": "1975-03-25", + "phone_number": "+49 165 7713066", + "address": "Gartenweg 51, 80335 München", + "joining_date": "2023-03-06", + "information": "Football — Seniors." + }, + { + "id": "99999999-004c-0004-f878-0000002ef854", + "first_name": "Tomas", + "last_name": "Hartmann", + "email": "tomas.hartmann@club.de", + "birthday": "1998-10-27", + "phone_number": "+49 151 3020443", + "address": "Schulstraße 25, 80337 München", + "joining_date": "2025-12-09", + "information": "Football — Seniors." + }, + { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs", + "email": "frida.fuchs@club.de", + "birthday": "1985-07-10", + "phone_number": "+49 154 4582467", + "address": "Talstraße 121, 80333 München", + "joining_date": "2022-04-11", + "information": "Basketball — Masters." + }, + { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler", + "email": "luca.ziegler@club.de", + "birthday": "1989-07-03", + "phone_number": "+49 168 9734985", + "address": "Sonnenweg 70, 81667 München", + "joining_date": "2018-05-10", + "information": "Basketball — Masters." + }, + { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer", + "email": "til.sommer@club.de", + "birthday": "1981-08-28", + "phone_number": "+49 178 2005503", + "address": "Feldweg 89, 80538 München", + "joining_date": "2025-07-11", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel", + "email": "finn.seidel@club.de", + "birthday": "1988-04-07", + "phone_number": "+49 167 9725942", + "address": "Parkstraße 76, 80636 München", + "joining_date": "2018-09-19", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0051-0005-0f8d-000000320f67", + "first_name": "Paul", + "last_name": "Busch", + "email": "paul.busch@club.de", + "birthday": "1979-09-19", + "phone_number": "+49 159 1493067", + "address": "Birkenallee 42, 80335 München", + "joining_date": "2022-06-23", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0052-0005-adc4-00000032ad9e", + "first_name": "Martha", + "last_name": "Braun", + "email": "martha.braun@club.de", + "birthday": "1992-09-18", + "phone_number": "+49 172 3172169", + "address": "Wiesenweg 51, 80331 München", + "joining_date": "2022-02-14", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0053-0005-4bfc-000000334bd5", + "first_name": "Johanna", + "last_name": "Hartmann", + "email": "johanna.hartmann@club.de", + "birthday": "1995-03-02", + "phone_number": "+49 175 4332431", + "address": "Schulstraße 130, 80335 München", + "joining_date": "2020-10-13", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0054-0005-ea33-00000033ea0c", + "first_name": "Marie", + "last_name": "Pohl", + "email": "marie.pohl@club.de", + "birthday": "1984-02-28", + "phone_number": "+49 176 8410784", + "address": "Wiesenweg 123, 81243 München", + "joining_date": "2019-12-08", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0055-0005-886b-000000348843", + "first_name": "Tomas", + "last_name": "Brandt", + "email": "tomas.brandt@club.de", + "birthday": "1994-03-17", + "phone_number": "+49 173 4987863", + "address": "Feldweg 93, 80469 München", + "joining_date": "2023-11-07", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0056-0005-26a2-00000035267a", + "first_name": "Lina", + "last_name": "Nowak", + "email": "lina.nowak@club.de", + "birthday": "1989-02-02", + "phone_number": "+49 152 4652669", + "address": "Wiesenweg 17, 80335 München", + "joining_date": "2022-05-08", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0057-0005-c4da-00000035c4b1", + "first_name": "Helena", + "last_name": "Neumann", + "email": "helena.neumann@club.de", + "birthday": "1990-06-20", + "phone_number": "+49 168 2830874", + "address": "Ahornweg 127, 80801 München", + "joining_date": "2020-11-04", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0058-0005-6311-0000003662e8", + "first_name": "Leon", + "last_name": "Hartmann", + "email": "leon.hartmann@club.de", + "birthday": "1996-08-01", + "phone_number": "+49 150 5316401", + "address": "Mühlgasse 4, 80331 München", + "joining_date": "2023-10-22", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0059-0005-0149-00000037011f", + "first_name": "Paul", + "last_name": "Werner", + "email": "paul.werner@club.de", + "birthday": "1980-04-26", + "phone_number": "+49 166 4056436", + "address": "Talstraße 6, 80636 München", + "joining_date": "2024-11-17", + "information": "Basketball — Masters." + }, + { + "id": "99999999-005a-0005-9f80-000000379f56", + "first_name": "Alma", + "last_name": "Beck", + "email": "alma.beck@club.de", + "birthday": "1986-12-18", + "phone_number": "+49 151 9495401", + "address": "Sonnenweg 56, 80331 München", + "joining_date": "2018-11-17", + "information": "Basketball — Masters." + }, + { + "id": "99999999-005b-0005-3db8-000000383d8d", + "first_name": "Romy", + "last_name": "Voigt", + "email": "romy.voigt@club.de", + "birthday": "1982-07-26", + "phone_number": "+49 164 4402714", + "address": "Uferweg 88, 81667 München", + "joining_date": "2022-04-07", + "information": "Basketball — Masters." + }, + { + "id": "99999999-005c-0005-dbef-00000038dbc4", + "first_name": "Felix", + "last_name": "Frank", + "email": "felix.frank@club.de", + "birthday": "1975-11-06", + "phone_number": "+49 156 2371371", + "address": "Bergstraße 124, 80331 München", + "joining_date": "2018-05-16", + "information": "Basketball — Masters." + }, + { + "id": "99999999-005d-0005-7a27-0000003979fb", + "first_name": "Jakob", + "last_name": "Klein", + "email": "jakob.klein@club.de", + "birthday": "1988-12-04", + "phone_number": "+49 165 6061651", + "address": "Sonnenweg 121, 80331 München", + "joining_date": "2020-08-16", + "information": "Basketball — Masters." + }, + { + "id": "99999999-005e-0005-185e-0000003a1832", + "first_name": "Ben", + "last_name": "Horn", + "email": "ben.horn@club.de", + "birthday": "1978-12-23", + "phone_number": "+49 158 2313586", + "address": "Bergstraße 124, 80331 München", + "joining_date": "2023-06-21", + "information": "Basketball — Masters." + }, + { + "id": "99999999-005f-0005-b696-0000003ab669", + "first_name": "Jonah", + "last_name": "Krüger", + "email": "jonah.krüger@club.de", + "birthday": "1982-11-04", + "phone_number": "+49 172 5713530", + "address": "Wiesenweg 39, 80331 München", + "joining_date": "2018-08-13", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0060-0006-54cd-0000003b54a0", + "first_name": "Lina", + "last_name": "Graf", + "email": "lina.graf@club.de", + "birthday": "1987-09-25", + "phone_number": "+49 168 9104360", + "address": "Bergstraße 7, 80331 München", + "joining_date": "2024-08-14", + "information": "Basketball — Masters." + }, + { + "id": "99999999-0061-0006-f305-0000003bf2d7", + "first_name": "Leon", + "last_name": "Braun", + "email": "leon.braun@club.de", + "birthday": "2008-11-06", + "phone_number": "+49 173 6287812", + "address": "Wiesenweg 120, 80636 München", + "joining_date": "2025-08-18", + "information": "Basketball — Juniors." + }, + { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht", + "email": "lotte.albrecht@club.de", + "birthday": "2011-03-18", + "phone_number": "+49 155 9197063", + "address": "Schulstraße 129, 80801 München", + "joining_date": "2024-08-25", + "information": "Basketball — Juniors." + }, + { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck", + "email": "lena.beck@club.de", + "birthday": "2010-01-03", + "phone_number": "+49 162 7028270", + "address": "Birkenallee 58, 80469 München", + "joining_date": "2018-08-10", + "information": "Basketball — Juniors." + }, + { + "id": "99999999-0064-0006-cdab-0000003dcd7c", + "first_name": "Greta", + "last_name": "Roth", + "email": "greta.roth@club.de", + "birthday": "2007-04-06", + "phone_number": "+49 174 8638517", + "address": "Feldweg 119, 80335 München", + "joining_date": "2018-02-25", + "information": "Basketball — Juniors." + }, + { + "id": "99999999-0065-0006-6be3-0000003e6bb3", + "first_name": "Frida", + "last_name": "Werner", + "email": "frida.werner@club.de", + "birthday": "2010-08-27", + "phone_number": "+49 155 2580116", + "address": "Wiesenweg 49, 80636 München", + "joining_date": "2018-08-16", + "information": "Basketball — Juniors." + }, + { + "id": "99999999-0066-0006-0a1a-0000003f09ea", + "first_name": "Jonah", + "last_name": "Nowak", + "email": "jonah.nowak@club.de", + "birthday": "2011-03-15", + "phone_number": "+49 151 7071078", + "address": "Gartenweg 98, 80335 München", + "joining_date": "2021-03-19", + "information": "Basketball — U14." + }, + { + "id": "99999999-0067-0006-a851-0000003fa821", + "first_name": "Luca", + "last_name": "Peters", + "email": "luca.peters@club.de", + "birthday": "2008-11-24", + "phone_number": "+49 179 7287041", + "address": "Ahornweg 58, 80538 München", + "joining_date": "2018-07-19", + "information": "Basketball — U14." + }, + { + "id": "99999999-0068-0006-4689-000000404658", + "first_name": "Clara", + "last_name": "Seidel", + "email": "clara.seidel@club.de", + "birthday": "2007-02-28", + "phone_number": "+49 164 3106817", + "address": "Birkenallee 73, 80331 München", + "joining_date": "2021-05-22", + "information": "Basketball — U14." + }, + { + "id": "99999999-0069-0006-e4c0-00000040e48f", + "first_name": "Edda", + "last_name": "Pohl", + "email": "edda.pohl@club.de", + "birthday": "2010-02-25", + "phone_number": "+49 165 6590166", + "address": "Bergstraße 22, 80335 München", + "joining_date": "2021-02-11", + "information": "Basketball — U14." + }, + { + "id": "99999999-006a-0006-82f8-0000004182c6", + "first_name": "Ben", + "last_name": "Park", + "email": "ben.park@club.de", + "birthday": "2007-11-19", + "phone_number": "+49 165 2956611", + "address": "Kirchplatz 121, 81243 München", + "joining_date": "2022-11-10", + "information": "Basketball — U14." + }, + { + "id": "99999999-006b-0006-212f-0000004220fd", + "first_name": "Felix", + "last_name": "Koch", + "email": "felix.koch@club.de", + "birthday": "2010-12-01", + "phone_number": "+49 159 1941640", + "address": "Lindenstraße 85, 80333 München", + "joining_date": "2019-04-25", + "information": "Basketball — U14." + }, + { + "id": "99999999-006c-0006-bf67-00000042bf34", + "first_name": "Toni", + "last_name": "Sauer", + "email": "toni.sauer@club.de", + "birthday": "2007-09-06", + "phone_number": "+49 153 3682769", + "address": "Ahornweg 100, 80538 München", + "joining_date": "2020-10-25", + "information": "Basketball — U14." + }, + { + "id": "99999999-006d-0006-5d9e-000000435d6b", + "first_name": "Tilda", + "last_name": "Albrecht", + "email": "tilda.albrecht@club.de", + "birthday": "2007-04-09", + "phone_number": "+49 173 1671014", + "address": "Rosenstraße 138, 81667 München", + "joining_date": "2024-12-19", + "information": "Basketball — U14." + }, + { + "id": "99999999-006e-0006-fbd6-00000043fba2", + "first_name": "Ben", + "last_name": "Lehmann", + "email": "ben.lehmann@club.de", + "birthday": "2009-06-18", + "phone_number": "+49 165 2468446", + "address": "Ahornweg 114, 80636 München", + "joining_date": "2018-06-07", + "information": "Basketball — U14." + }, + { + "id": "99999999-006f-0006-9a0d-0000004499d9", + "first_name": "Liv", + "last_name": "Brandt", + "email": "liv.brandt@club.de", + "birthday": "2011-06-23", + "phone_number": "+49 176 8901158", + "address": "Feldweg 53, 80801 München", + "joining_date": "2021-07-11", + "information": "Basketball — U14." + }, + { + "id": "99999999-0070-0007-3845-000000453810", + "first_name": "Paul", + "last_name": "Albrecht", + "email": "paul.albrecht@club.de", + "birthday": "2008-05-22", + "phone_number": "+49 167 3562542", + "address": "Feldweg 40, 80335 München", + "joining_date": "2025-01-12", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0071-0007-d67c-00000045d647", + "first_name": "Nele", + "last_name": "Schwarz", + "email": "nele.schwarz@club.de", + "birthday": "2007-03-22", + "phone_number": "+49 178 3348177", + "address": "Feldweg 83, 80469 München", + "joining_date": "2018-12-09", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0072-0007-74b4-00000046747e", + "first_name": "Lena", + "last_name": "Pohl", + "email": "lena.pohl@club.de", + "birthday": "2010-04-04", + "phone_number": "+49 172 8954547", + "address": "Kirchplatz 119, 80636 München", + "joining_date": "2020-01-26", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0073-0007-12eb-0000004712b5", + "first_name": "Helena", + "last_name": "Vogel", + "email": "helena.vogel@club.de", + "birthday": "2010-05-01", + "phone_number": "+49 157 5055707", + "address": "Gartenweg 121, 80538 München", + "joining_date": "2025-06-16", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0074-0007-b123-00000047b0ec", + "first_name": "Helena", + "last_name": "Wagner", + "email": "helena.wagner@club.de", + "birthday": "2010-10-28", + "phone_number": "+49 167 9925718", + "address": "Mühlgasse 81, 80333 München", + "joining_date": "2021-10-16", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0075-0007-4f5a-000000484f23", + "first_name": "Emil", + "last_name": "Kaiser", + "email": "emil.kaiser@club.de", + "birthday": "2010-02-12", + "phone_number": "+49 150 7491756", + "address": "Talstraße 107, 80538 München", + "joining_date": "2024-08-07", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0076-0007-ed92-00000048ed5a", + "first_name": "Leon", + "last_name": "Diaz", + "email": "leon.diaz@club.de", + "birthday": "2010-01-26", + "phone_number": "+49 175 4520302", + "address": "Mühlgasse 56, 80337 München", + "joining_date": "2019-07-17", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0077-0007-8bc9-000000498b91", + "first_name": "Ada", + "last_name": "Hoffmann", + "email": "ada.hoffmann@club.de", + "birthday": "2008-09-17", + "phone_number": "+49 165 2052373", + "address": "Birkenallee 71, 80335 München", + "joining_date": "2018-05-19", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0078-0007-2a01-0000004a29c8", + "first_name": "Oskar", + "last_name": "Nowak", + "email": "oskar.nowak@club.de", + "birthday": "2007-06-16", + "phone_number": "+49 169 9234659", + "address": "Lindenstraße 30, 80335 München", + "joining_date": "2021-01-13", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-0079-0007-c838-0000004ac7ff", + "first_name": "Charlotte", + "last_name": "Berger", + "email": "charlotte.berger@club.de", + "birthday": "2008-12-08", + "phone_number": "+49 171 9307192", + "address": "Uferweg 9, 80335 München", + "joining_date": "2024-08-01", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-007a-0007-666f-0000004b6636", + "first_name": "Leon", + "last_name": "Neumann", + "email": "leon.neumann@club.de", + "birthday": "2010-03-22", + "phone_number": "+49 151 6959147", + "address": "Birkenallee 83, 81667 München", + "joining_date": "2019-08-27", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-007b-0007-04a7-0000004c046d", + "first_name": "Jonah", + "last_name": "Wagner", + "email": "jonah.wagner@club.de", + "birthday": "2009-09-25", + "phone_number": "+49 164 4050926", + "address": "Talstraße 35, 80469 München", + "joining_date": "2020-07-14", + "information": "Basketball — Squad 1." + }, + { + "id": "99999999-007c-0007-a2de-0000004ca2a4", + "first_name": "Erik", + "last_name": "Scholz", + "email": "erik.scholz@club.de", + "birthday": "2007-08-20", + "phone_number": "+49 155 9255210", + "address": "Sonnenweg 2, 80538 München", + "joining_date": "2025-04-27", + "information": "Basketball — Group B." + }, + { + "id": "99999999-007d-0007-4116-0000004d40db", + "first_name": "Mia", + "last_name": "Neumann", + "email": "mia.neumann@club.de", + "birthday": "2009-04-19", + "phone_number": "+49 162 7983400", + "address": "Gartenweg 22, 80636 München", + "joining_date": "2024-10-27", + "information": "Basketball — Group B." + }, + { + "id": "99999999-007e-0007-df4d-0000004ddf12", + "first_name": "Elias", + "last_name": "Diaz", + "email": "elias.diaz@club.de", + "birthday": "2009-08-11", + "phone_number": "+49 167 3288738", + "address": "Feldweg 123, 81243 München", + "joining_date": "2019-01-23", + "information": "Basketball — Group B." + }, + { + "id": "99999999-007f-0007-7d85-0000004e7d49", + "first_name": "Tilda", + "last_name": "Neumann", + "email": "tilda.neumann@club.de", + "birthday": "2007-03-27", + "phone_number": "+49 162 2699126", + "address": "Parkstraße 68, 80335 München", + "joining_date": "2024-12-18", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0080-0008-1bbc-0000004f1b80", + "first_name": "Noah", + "last_name": "Richter", + "email": "noah.richter@club.de", + "birthday": "2008-02-15", + "phone_number": "+49 177 1606912", + "address": "Bergstraße 65, 80331 München", + "joining_date": "2020-02-01", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0081-0008-b9f4-0000004fb9b7", + "first_name": "Leon", + "last_name": "Busch", + "email": "leon.busch@club.de", + "birthday": "2011-12-08", + "phone_number": "+49 179 2209294", + "address": "Gartenweg 132, 80335 München", + "joining_date": "2025-10-26", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0082-0008-582b-0000005057ee", + "first_name": "Aaron", + "last_name": "Sauer", + "email": "aaron.sauer@club.de", + "birthday": "2010-04-06", + "phone_number": "+49 178 2484127", + "address": "Bergstraße 96, 80801 München", + "joining_date": "2024-04-28", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0083-0008-f663-00000050f625", + "first_name": "Mats", + "last_name": "Sommer", + "email": "mats.sommer@club.de", + "birthday": "2008-01-04", + "phone_number": "+49 150 9104256", + "address": "Mühlgasse 20, 81667 München", + "joining_date": "2022-03-25", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0084-0008-949a-00000051945c", + "first_name": "Juna", + "last_name": "Reil", + "email": "juna.reil@club.de", + "birthday": "2009-02-16", + "phone_number": "+49 172 9487383", + "address": "Sonnenweg 17, 80636 München", + "joining_date": "2023-01-06", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0085-0008-32d2-000000523293", + "first_name": "Juna", + "last_name": "Braun", + "email": "juna.braun@club.de", + "birthday": "2010-01-28", + "phone_number": "+49 175 9335406", + "address": "Rosenstraße 58, 80801 München", + "joining_date": "2021-12-12", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0086-0008-d109-00000052d0ca", + "first_name": "Johanna", + "last_name": "Kaiser", + "email": "johanna.kaiser@club.de", + "birthday": "2008-12-08", + "phone_number": "+49 164 2557479", + "address": "Bergstraße 98, 80333 München", + "joining_date": "2023-05-16", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0087-0008-6f41-000000536f01", + "first_name": "Sofia", + "last_name": "Brandt", + "email": "sofia.brandt@club.de", + "birthday": "2011-07-12", + "phone_number": "+49 150 5573752", + "address": "Gartenweg 85, 80469 München", + "joining_date": "2022-03-04", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0088-0008-0d78-000000540d38", + "first_name": "Samuel", + "last_name": "Vogel", + "email": "samuel.vogel@club.de", + "birthday": "2011-12-04", + "phone_number": "+49 159 2568978", + "address": "Lindenstraße 35, 80337 München", + "joining_date": "2022-11-21", + "information": "Basketball — Group B." + }, + { + "id": "99999999-0089-0008-abb0-00000054ab6f", + "first_name": "Hannah", + "last_name": "Pohl", + "email": "hannah.pohl@club.de", + "birthday": "2010-08-01", + "phone_number": "+49 163 7816461", + "address": "Sonnenweg 113, 80469 München", + "joining_date": "2020-03-28", + "information": "Swimming — Juniors." + }, + { + "id": "99999999-008a-0008-49e7-0000005549a6", + "first_name": "Fynn", + "last_name": "Reil", + "email": "fynn.reil@club.de", + "birthday": "2007-08-27", + "phone_number": "+49 169 5417531", + "address": "Feldweg 33, 81667 München", + "joining_date": "2024-05-24", + "information": "Swimming — Juniors." + }, + { + "id": "99999999-008b-0008-e81f-00000055e7dd", + "first_name": "Toni", + "last_name": "Neumann", + "email": "toni.neumann@club.de", + "birthday": "2007-02-19", + "phone_number": "+49 160 4892082", + "address": "Wiesenweg 84, 80331 München", + "joining_date": "2019-06-12", + "information": "Swimming — Juniors." + }, + { + "id": "99999999-008c-0008-8656-000000568614", + "first_name": "Moritz", + "last_name": "Wolf", + "email": "moritz.wolf@club.de", + "birthday": "2007-06-26", + "phone_number": "+49 160 8875638", + "address": "Kirchplatz 38, 80801 München", + "joining_date": "2019-06-26", + "information": "Swimming — Juniors." + }, + { + "id": "99999999-008d-0008-248e-00000057244b", + "first_name": "Frieda", + "last_name": "Winter", + "email": "frieda.winter@club.de", + "birthday": "2007-04-08", + "phone_number": "+49 161 7801498", + "address": "Sonnenweg 121, 80538 München", + "joining_date": "2021-06-16", + "information": "Swimming — Juniors." + }, + { + "id": "99999999-008e-0008-c2c5-00000057c282", + "first_name": "Charlotte", + "last_name": "Schwarz", + "email": "charlotte.schwarz@club.de", + "birthday": "2009-02-06", + "phone_number": "+49 157 5757270", + "address": "Uferweg 68, 80331 München", + "joining_date": "2024-07-17", + "information": "Swimming — Juniors." + }, + { + "id": "99999999-008f-0008-60fc-0000005860b9", + "first_name": "Moritz", + "last_name": "Krause", + "email": "moritz.krause@club.de", + "birthday": "2008-03-10", + "phone_number": "+49 162 9242631", + "address": "Ahornweg 78, 80331 München", + "joining_date": "2019-10-20", + "information": "Swimming — Juniors." + }, + { + "id": "99999999-0090-0009-ff34-00000058fef0", + "first_name": "Hannah", + "last_name": "Lange", + "email": "hannah.lange@club.de", + "birthday": "2011-03-03", + "phone_number": "+49 179 5207579", + "address": "Parkstraße 82, 80335 München", + "joining_date": "2022-11-12", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0091-0009-9d6b-000000599d27", + "first_name": "Smilla", + "last_name": "Busch", + "email": "smilla.busch@club.de", + "birthday": "2009-06-09", + "phone_number": "+49 173 4270389", + "address": "Schulstraße 75, 80636 München", + "joining_date": "2023-01-05", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0092-0009-3ba3-0000005a3b5e", + "first_name": "Ida", + "last_name": "Neumann", + "email": "ida.neumann@club.de", + "birthday": "2010-04-03", + "phone_number": "+49 164 8273739", + "address": "Talstraße 88, 80636 München", + "joining_date": "2019-03-16", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0093-0009-d9da-0000005ad995", + "first_name": "Finn", + "last_name": "Vogel", + "email": "finn.vogel@club.de", + "birthday": "2007-04-19", + "phone_number": "+49 164 9504540", + "address": "Feldweg 128, 80469 München", + "joining_date": "2020-12-19", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0094-0009-7812-0000005b77cc", + "first_name": "Greta", + "last_name": "Pohl", + "email": "greta.pohl@club.de", + "birthday": "2010-04-02", + "phone_number": "+49 179 2068975", + "address": "Rosenstraße 103, 80469 München", + "joining_date": "2020-04-07", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0095-0009-1649-0000005c1603", + "first_name": "Lea", + "last_name": "Park", + "email": "lea.park@club.de", + "birthday": "2010-03-11", + "phone_number": "+49 159 6052086", + "address": "Lindenstraße 29, 80636 München", + "joining_date": "2023-04-05", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0096-0009-b481-0000005cb43a", + "first_name": "Frieda", + "last_name": "Richter", + "email": "frieda.richter@club.de", + "birthday": "2011-04-25", + "phone_number": "+49 159 9212875", + "address": "Mühlgasse 99, 80636 München", + "joining_date": "2022-07-18", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0097-0009-52b8-0000005d5271", + "first_name": "Stella", + "last_name": "Krüger", + "email": "stella.krüger@club.de", + "birthday": "2010-02-27", + "phone_number": "+49 174 1832730", + "address": "Sonnenweg 77, 80331 München", + "joining_date": "2018-12-21", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0098-0009-f0f0-0000005df0a8", + "first_name": "Aaron", + "last_name": "Sommer", + "email": "aaron.sommer@club.de", + "birthday": "2008-01-27", + "phone_number": "+49 177 4543331", + "address": "Lindenstraße 22, 80801 München", + "joining_date": "2018-05-21", + "information": "Swimming — Group A." + }, + { + "id": "99999999-0099-0009-8f27-0000005e8edf", + "first_name": "Bela", + "last_name": "Arnold", + "email": "bela.arnold@club.de", + "birthday": "2009-10-19", + "phone_number": "+49 157 8064162", + "address": "Kirchplatz 80, 81667 München", + "joining_date": "2020-03-17", + "information": "Swimming — Group A." + }, + { + "id": "99999999-009a-0009-2d5f-0000005f2d16", + "first_name": "Mathilda", + "last_name": "Kaiser", + "email": "mathilda.kaiser@club.de", + "birthday": "2009-08-13", + "phone_number": "+49 172 4805071", + "address": "Sonnenweg 135, 80636 München", + "joining_date": "2025-11-09", + "information": "Swimming — Group A." + }, + { + "id": "99999999-009b-0009-cb96-0000005fcb4d", + "first_name": "Jonas", + "last_name": "Krause", + "email": "jonas.krause@club.de", + "birthday": "2007-05-21", + "phone_number": "+49 152 2225180", + "address": "Feldweg 18, 80538 München", + "joining_date": "2022-07-01", + "information": "Swimming — Group A." + }, + { + "id": "99999999-009c-0009-69ce-000000606984", + "first_name": "Carla", + "last_name": "Albrecht", + "email": "carla.albrecht@club.de", + "birthday": "2010-12-02", + "phone_number": "+49 177 2234109", + "address": "Talstraße 77, 80333 München", + "joining_date": "2025-08-24", + "information": "Swimming — Group A." + }, + { + "id": "99999999-009d-0009-0805-0000006107bb", + "first_name": "Lena", + "last_name": "Kaiser", + "email": "lena.kaiser@club.de", + "birthday": "2010-09-26", + "phone_number": "+49 167 1337547", + "address": "Mühlgasse 123, 80337 München", + "joining_date": "2024-02-28", + "information": "Swimming — Group A." + }, + { + "id": "99999999-009e-0009-a63d-00000061a5f2", + "first_name": "Joris", + "last_name": "Schulz", + "email": "joris.schulz@club.de", + "birthday": "2009-02-25", + "phone_number": "+49 179 7691096", + "address": "Uferweg 96, 80469 München", + "joining_date": "2025-09-20", + "information": "Swimming — Group A." + }, + { + "id": "99999999-009f-0009-4474-000000624429", + "first_name": "Wilma", + "last_name": "Otto", + "email": "wilma.otto@club.de", + "birthday": "2007-10-05", + "phone_number": "+49 162 6392208", + "address": "Feldweg 112, 80469 München", + "joining_date": "2023-10-15", + "information": "Swimming — Group A." + }, + { + "id": "99999999-00a0-000a-e2ac-00000062e260", + "first_name": "Jonah", + "last_name": "Peters", + "email": "jonah.peters@club.de", + "birthday": "2008-02-15", + "phone_number": "+49 155 3461143", + "address": "Birkenallee 84, 81667 München", + "joining_date": "2022-05-16", + "information": "Swimming — Group A." + }, + { + "id": "99999999-00a1-000a-80e3-000000638097", + "first_name": "Amelie", + "last_name": "Lange", + "email": "amelie.lange@club.de", + "birthday": "2010-08-15", + "phone_number": "+49 151 2308645", + "address": "Bergstraße 2, 80636 München", + "joining_date": "2020-03-01", + "information": "Swimming — Group A." + }, + { + "id": "99999999-00a2-000a-1f1b-000000641ece", + "first_name": "Jonas", + "last_name": "Nowak", + "email": "jonas.nowak@club.de", + "birthday": "2007-04-08", + "phone_number": "+49 168 5831665", + "address": "Bergstraße 81, 80538 München", + "joining_date": "2023-09-10", + "information": "Swimming — Group A." + }, + { + "id": "99999999-00a3-000a-bd52-00000064bd05", + "first_name": "Emil", + "last_name": "Krause", + "email": "emil.krause@club.de", + "birthday": "2011-08-10", + "phone_number": "+49 173 3592844", + "address": "Talstraße 12, 80333 München", + "joining_date": "2018-01-12", + "information": "Swimming — Group A." + }, + { + "id": "99999999-00a4-000a-5b89-000000655b3c", + "first_name": "Smilla", + "last_name": "Hoffmann", + "email": "smilla.hoffmann@club.de", + "birthday": "2010-05-28", + "phone_number": "+49 153 5990252", + "address": "Birkenallee 7, 80335 München", + "joining_date": "2024-03-25", + "information": "Swimming — Group A." + }, + { + "id": "99999999-00a5-000a-f9c1-00000065f973", + "first_name": "Toni", + "last_name": "Huber", + "email": "toni.huber@club.de", + "birthday": "2011-06-13", + "phone_number": "+49 158 5316585", + "address": "Lindenstraße 15, 80335 München", + "joining_date": "2021-12-07", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00a6-000a-97f8-0000006697aa", + "first_name": "Jan", + "last_name": "Lange", + "email": "jan.lange@club.de", + "birthday": "2011-03-19", + "phone_number": "+49 160 8555811", + "address": "Kirchplatz 96, 80538 München", + "joining_date": "2019-05-26", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00a7-000a-3630-0000006735e1", + "first_name": "Carla", + "last_name": "Arnold", + "email": "carla.arnold@club.de", + "birthday": "2008-03-05", + "phone_number": "+49 162 5177533", + "address": "Ahornweg 85, 80469 München", + "joining_date": "2022-02-18", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00a8-000a-d467-00000067d418", + "first_name": "Noah", + "last_name": "Braun", + "email": "noah.braun@club.de", + "birthday": "2007-03-23", + "phone_number": "+49 156 4720776", + "address": "Rosenstraße 134, 80337 München", + "joining_date": "2021-02-01", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00a9-000a-729f-00000068724f", + "first_name": "Alma", + "last_name": "Busch", + "email": "alma.busch@club.de", + "birthday": "2007-09-10", + "phone_number": "+49 152 2598758", + "address": "Rosenstraße 119, 80333 München", + "joining_date": "2023-10-23", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00aa-000a-10d6-000000691086", + "first_name": "Bela", + "last_name": "Klein", + "email": "bela.klein@club.de", + "birthday": "2010-12-06", + "phone_number": "+49 157 5600940", + "address": "Schulstraße 89, 80333 München", + "joining_date": "2024-11-20", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00ab-000a-af0e-00000069aebd", + "first_name": "Bruno", + "last_name": "Berger", + "email": "bruno.berger@club.de", + "birthday": "2007-07-04", + "phone_number": "+49 178 9050951", + "address": "Kirchplatz 111, 80331 München", + "joining_date": "2021-02-21", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00ac-000a-4d45-0000006a4cf4", + "first_name": "Romy", + "last_name": "Beck", + "email": "romy.beck@club.de", + "birthday": "2010-04-25", + "phone_number": "+49 154 1177886", + "address": "Wiesenweg 60, 80337 München", + "joining_date": "2023-11-14", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00ad-000a-eb7d-0000006aeb2b", + "first_name": "Joris", + "last_name": "Hoffmann", + "email": "joris.hoffmann@club.de", + "birthday": "2009-03-15", + "phone_number": "+49 170 7106078", + "address": "Mühlgasse 139, 80469 München", + "joining_date": "2023-05-12", + "information": "Swimming — Group B." + }, + { + "id": "99999999-00ae-000a-89b4-0000006b8962", + "first_name": "Jonah", + "last_name": "König", + "email": "jonah.könig@club.de", + "birthday": "1991-07-08", + "phone_number": "+49 173 4720203", + "address": "Ahornweg 8, 80801 München", + "joining_date": "2018-04-20", + "information": "Swimming — Seniors." + }, + { + "id": "99999999-00af-000a-27ec-0000006c2799", + "first_name": "Emil", + "last_name": "Stein", + "email": "emil.stein@club.de", + "birthday": "1977-12-14", + "phone_number": "+49 168 1731997", + "address": "Schulstraße 100, 80538 München", + "joining_date": "2021-11-22", + "information": "Swimming — Seniors." + }, + { + "id": "99999999-00b0-000b-c623-0000006cc5d0", + "first_name": "Mira", + "last_name": "Kaiser", + "email": "mira.kaiser@club.de", + "birthday": "1998-04-26", + "phone_number": "+49 154 1534057", + "address": "Talstraße 65, 80469 München", + "joining_date": "2020-04-11", + "information": "Swimming — Seniors." + }, + { + "id": "99999999-00b1-000b-645b-0000006d6407", + "first_name": "Elias", + "last_name": "Braun", + "email": "elias.braun@club.de", + "birthday": "1992-03-06", + "phone_number": "+49 153 4376393", + "address": "Wiesenweg 83, 80636 München", + "joining_date": "2022-05-01", + "information": "Swimming — Seniors." + }, + { + "id": "99999999-00b2-000b-0292-0000006e023e", + "first_name": "Noah", + "last_name": "Beck", + "email": "noah.beck@club.de", + "birthday": "1990-03-05", + "phone_number": "+49 162 9934877", + "address": "Lindenstraße 126, 81667 München", + "joining_date": "2019-07-23", + "information": "Swimming — Seniors." + }, + { + "id": "99999999-00b3-000b-a0ca-0000006ea075", + "first_name": "David", + "last_name": "Klein", + "email": "david.klein@club.de", + "birthday": "1988-05-23", + "phone_number": "+49 162 9248865", + "address": "Kirchplatz 82, 81243 München", + "joining_date": "2022-10-07", + "information": "Swimming — Seniors." + }, + { + "id": "99999999-00b4-000b-3f01-0000006f3eac", + "first_name": "Leon", + "last_name": "Berger", + "email": "leon.berger@club.de", + "birthday": "1981-11-18", + "phone_number": "+49 161 5754807", + "address": "Kirchplatz 103, 80801 München", + "joining_date": "2023-10-08", + "information": "Swimming — Seniors." + }, + { + "id": "99999999-00b5-000b-dd39-0000006fdce3", + "first_name": "Marco", + "last_name": "Bauer", + "email": "marco.bauer@club.de", + "birthday": "2010-02-22", + "phone_number": "+49 165 6568917", + "address": "Rosenstraße 121, 80538 München", + "joining_date": "2020-04-05", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00b6-000b-7b70-000000707b1a", + "first_name": "Finn", + "last_name": "Neumann", + "email": "finn.neumann@club.de", + "birthday": "2010-07-01", + "phone_number": "+49 175 5419922", + "address": "Feldweg 106, 80331 München", + "joining_date": "2019-03-24", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00b7-000b-19a7-000000711951", + "first_name": "Konrad", + "last_name": "Klein", + "email": "konrad.klein@club.de", + "birthday": "2009-08-05", + "phone_number": "+49 169 8726425", + "address": "Rosenstraße 36, 80331 München", + "joining_date": "2020-03-03", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00b8-000b-b7df-00000071b788", + "first_name": "Ben", + "last_name": "Frank", + "email": "ben.frank@club.de", + "birthday": "2009-08-09", + "phone_number": "+49 157 5080894", + "address": "Feldweg 100, 80801 München", + "joining_date": "2021-01-26", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00b9-000b-5616-0000007255bf", + "first_name": "Frida", + "last_name": "Brandt", + "email": "frida.brandt@club.de", + "birthday": "2010-06-25", + "phone_number": "+49 160 6648626", + "address": "Ahornweg 82, 80801 München", + "joining_date": "2020-01-15", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00ba-000b-f44e-00000072f3f6", + "first_name": "Lea", + "last_name": "Brandt", + "email": "lea.brandt@club.de", + "birthday": "2010-07-15", + "phone_number": "+49 161 9659637", + "address": "Bergstraße 26, 80801 München", + "joining_date": "2025-05-08", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00bb-000b-9285-00000073922d", + "first_name": "Sofia", + "last_name": "Pohl", + "email": "sofia.pohl@club.de", + "birthday": "2010-01-03", + "phone_number": "+49 169 4669214", + "address": "Feldweg 139, 80333 München", + "joining_date": "2024-02-20", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00bc-000b-30bd-000000743064", + "first_name": "Jonah", + "last_name": "Park", + "email": "jonah.park@club.de", + "birthday": "2009-07-08", + "phone_number": "+49 160 7213633", + "address": "Gartenweg 134, 80469 München", + "joining_date": "2019-06-03", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00bd-000b-cef4-00000074ce9b", + "first_name": "Mara", + "last_name": "Engel", + "email": "mara.engel@club.de", + "birthday": "2007-11-25", + "phone_number": "+49 175 7910880", + "address": "Parkstraße 24, 80331 München", + "joining_date": "2018-08-03", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00be-000b-6d2c-000000756cd2", + "first_name": "Emil", + "last_name": "Diaz", + "email": "emil.diaz@club.de", + "birthday": "2011-03-23", + "phone_number": "+49 167 8022352", + "address": "Bergstraße 13, 80469 München", + "joining_date": "2021-09-07", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00bf-000b-0b63-000000760b09", + "first_name": "David", + "last_name": "Braun", + "email": "david.braun@club.de", + "birthday": "2011-11-07", + "phone_number": "+49 175 3087954", + "address": "Schulstraße 23, 80469 München", + "joining_date": "2020-02-04", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00c0-000c-a99b-00000076a940", + "first_name": "Aaron", + "last_name": "Hoffmann", + "email": "aaron.hoffmann@club.de", + "birthday": "2010-03-06", + "phone_number": "+49 164 9414778", + "address": "Bergstraße 18, 80469 München", + "joining_date": "2025-12-20", + "information": "Swimming — Squad 1." + }, + { + "id": "99999999-00c1-000c-47d2-000000774777", + "first_name": "Emil", + "last_name": "Schwarz", + "email": "emil.schwarz@club.de", + "birthday": "2007-12-17", + "phone_number": "+49 171 5400687", + "address": "Rosenstraße 106, 80333 München", + "joining_date": "2023-04-22", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00c2-000c-e60a-00000077e5ae", + "first_name": "Bela", + "last_name": "Kaiser", + "email": "bela.kaiser@club.de", + "birthday": "2011-03-02", + "phone_number": "+49 171 5379369", + "address": "Birkenallee 16, 80331 München", + "joining_date": "2020-12-28", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00c3-000c-8441-0000007883e5", + "first_name": "Rosa", + "last_name": "Frank", + "email": "rosa.frank@club.de", + "birthday": "2007-08-13", + "phone_number": "+49 156 5470797", + "address": "Kirchplatz 62, 80801 München", + "joining_date": "2020-08-15", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00c4-000c-2279-00000079221c", + "first_name": "Frida", + "last_name": "Neumann", + "email": "frida.neumann@club.de", + "birthday": "2007-05-24", + "phone_number": "+49 154 8264395", + "address": "Rosenstraße 14, 81667 München", + "joining_date": "2025-08-03", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00c5-000c-c0b0-00000079c053", + "first_name": "Clara", + "last_name": "Hartmann", + "email": "clara.hartmann@club.de", + "birthday": "2007-06-23", + "phone_number": "+49 151 2817960", + "address": "Talstraße 15, 80636 München", + "joining_date": "2023-04-26", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00c6-000c-5ee8-0000007a5e8a", + "first_name": "Edda", + "last_name": "Vogt", + "email": "edda.vogt@club.de", + "birthday": "2009-11-17", + "phone_number": "+49 166 6339561", + "address": "Birkenallee 89, 80333 München", + "joining_date": "2020-12-18", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00c7-000c-fd1f-0000007afcc1", + "first_name": "Leon", + "last_name": "Beck", + "email": "leon.beck@club.de", + "birthday": "2009-07-17", + "phone_number": "+49 176 4209908", + "address": "Gartenweg 135, 80801 München", + "joining_date": "2018-07-16", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00c8-000c-9b57-0000007b9af8", + "first_name": "Emil", + "last_name": "Klein", + "email": "emil.klein@club.de", + "birthday": "2009-01-12", + "phone_number": "+49 165 6758734", + "address": "Birkenallee 37, 80337 München", + "joining_date": "2024-02-20", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00c9-000c-398e-0000007c392f", + "first_name": "Jonas", + "last_name": "Stein", + "email": "jonas.stein@club.de", + "birthday": "2011-02-19", + "phone_number": "+49 165 9034112", + "address": "Rosenstraße 69, 80331 München", + "joining_date": "2018-08-17", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00ca-000c-d7c6-0000007cd766", + "first_name": "Nele", + "last_name": "Seidel", + "email": "nele.seidel@club.de", + "birthday": "2010-08-05", + "phone_number": "+49 158 4059901", + "address": "Lindenstraße 104, 80801 München", + "joining_date": "2018-09-19", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00cb-000c-75fd-0000007d759d", + "first_name": "Moritz", + "last_name": "Busch", + "email": "moritz.busch@club.de", + "birthday": "2011-05-01", + "phone_number": "+49 166 5446439", + "address": "Parkstraße 138, 80333 München", + "joining_date": "2022-07-28", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00cc-000c-1434-0000007e13d4", + "first_name": "Rosa", + "last_name": "Klein", + "email": "rosa.klein@club.de", + "birthday": "2007-09-13", + "phone_number": "+49 166 5018764", + "address": "Kirchplatz 94, 80335 München", + "joining_date": "2023-05-24", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00cd-000c-b26c-0000007eb20b", + "first_name": "Samuel", + "last_name": "Winter", + "email": "samuel.winter@club.de", + "birthday": "2008-04-28", + "phone_number": "+49 157 4142605", + "address": "Lindenstraße 90, 81667 München", + "joining_date": "2024-03-20", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00ce-000c-50a3-0000007f5042", + "first_name": "Bruno", + "last_name": "Hartmann", + "email": "bruno.hartmann@club.de", + "birthday": "2010-03-09", + "phone_number": "+49 170 1006442", + "address": "Wiesenweg 47, 80331 München", + "joining_date": "2022-04-20", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00cf-000c-eedb-0000007fee79", + "first_name": "Toni", + "last_name": "Krause", + "email": "toni.krause@club.de", + "birthday": "2008-10-08", + "phone_number": "+49 151 9796361", + "address": "Bergstraße 4, 80335 München", + "joining_date": "2018-08-04", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00d0-000d-8d12-000000808cb0", + "first_name": "Lotte", + "last_name": "Richter", + "email": "lotte.richter@club.de", + "birthday": "2008-02-25", + "phone_number": "+49 162 8018035", + "address": "Schulstraße 47, 80538 München", + "joining_date": "2025-08-19", + "information": "Athletics — Group A." + }, + { + "id": "99999999-00d1-000d-2b4a-000000812ae7", + "first_name": "Lotte", + "last_name": "Frank", + "email": "lotte.frank@club.de", + "birthday": "2008-05-27", + "phone_number": "+49 155 3538941", + "address": "Lindenstraße 95, 81243 München", + "joining_date": "2019-03-26", + "information": "Athletics — Development." + }, + { + "id": "99999999-00d2-000d-c981-00000081c91e", + "first_name": "Mara", + "last_name": "Seidel", + "email": "mara.seidel@club.de", + "birthday": "2007-04-03", + "phone_number": "+49 171 9983323", + "address": "Rosenstraße 6, 80333 München", + "joining_date": "2023-01-04", + "information": "Athletics — Development." + }, + { + "id": "99999999-00d3-000d-67b9-000000826755", + "first_name": "Ella", + "last_name": "Pohl", + "email": "ella.pohl@club.de", + "birthday": "2008-12-22", + "phone_number": "+49 179 6701710", + "address": "Uferweg 64, 80333 München", + "joining_date": "2023-08-20", + "information": "Athletics — Development." + }, + { + "id": "99999999-00d4-000d-05f0-00000083058c", + "first_name": "Martha", + "last_name": "Engel", + "email": "martha.engel@club.de", + "birthday": "2011-07-06", + "phone_number": "+49 159 9668338", + "address": "Birkenallee 79, 80333 München", + "joining_date": "2021-06-09", + "information": "Athletics — Development." + }, + { + "id": "99999999-00d5-000d-a428-00000083a3c3", + "first_name": "Alma", + "last_name": "Vogel", + "email": "alma.vogel@club.de", + "birthday": "2010-12-20", + "phone_number": "+49 150 5940434", + "address": "Rosenstraße 111, 80337 München", + "joining_date": "2025-10-25", + "information": "Athletics — Development." + }, + { + "id": "99999999-00d6-000d-425f-0000008441fa", + "first_name": "Nele", + "last_name": "Scholz", + "email": "nele.scholz@club.de", + "birthday": "2011-04-18", + "phone_number": "+49 162 4396149", + "address": "Lindenstraße 7, 81667 München", + "joining_date": "2021-06-01", + "information": "Athletics — Development." + }, + { + "id": "99999999-00d7-000d-e097-00000084e031", + "first_name": "Oskar", + "last_name": "Stein", + "email": "oskar.stein@club.de", + "birthday": "2009-04-11", + "phone_number": "+49 173 6381949", + "address": "Uferweg 17, 80469 München", + "joining_date": "2023-12-15", + "information": "Athletics — Development." + }, + { + "id": "99999999-00d8-000d-7ece-000000857e68", + "first_name": "Juna", + "last_name": "Diaz", + "email": "juna.diaz@club.de", + "birthday": "2008-03-02", + "phone_number": "+49 155 7030696", + "address": "Parkstraße 112, 80335 München", + "joining_date": "2021-11-17", + "information": "Athletics — Development." + }, + { + "id": "99999999-00d9-000d-1d06-000000861c9f", + "first_name": "Wilma", + "last_name": "Stein", + "email": "wilma.stein@club.de", + "birthday": "2011-02-10", + "phone_number": "+49 175 4345761", + "address": "Mühlgasse 15, 80335 München", + "joining_date": "2020-04-14", + "information": "Athletics — Development." + }, + { + "id": "99999999-00da-000d-bb3d-00000086bad6", + "first_name": "Fynn", + "last_name": "Hoffmann", + "email": "fynn.hoffmann@club.de", + "birthday": "2010-02-14", + "phone_number": "+49 175 7544906", + "address": "Wiesenweg 24, 80331 München", + "joining_date": "2021-05-03", + "information": "Athletics — Development." + }, + { + "id": "99999999-00db-000d-5975-00000087590d", + "first_name": "Ida", + "last_name": "Vogel", + "email": "ida.vogel@club.de", + "birthday": "2008-05-11", + "phone_number": "+49 163 4330454", + "address": "Kirchplatz 45, 80469 München", + "joining_date": "2024-12-19", + "information": "Athletics — Development." + }, + { + "id": "99999999-00dc-000d-f7ac-00000087f744", + "first_name": "Levi", + "last_name": "Beck", + "email": "levi.beck@club.de", + "birthday": "2009-12-06", + "phone_number": "+49 164 3711237", + "address": "Wiesenweg 100, 80337 München", + "joining_date": "2025-05-13", + "information": "Athletics — Development." + }, + { + "id": "99999999-00dd-000d-95e4-00000088957b", + "first_name": "Felix", + "last_name": "Krause", + "email": "felix.krause@club.de", + "birthday": "2009-05-02", + "phone_number": "+49 170 1959705", + "address": "Feldweg 86, 80337 München", + "joining_date": "2024-09-12", + "information": "Athletics — Development." + }, + { + "id": "99999999-00de-000d-341b-0000008933b2", + "first_name": "Helena", + "last_name": "Koch", + "email": "helena.koch@club.de", + "birthday": "2009-08-10", + "phone_number": "+49 173 9604027", + "address": "Lindenstraße 101, 80636 München", + "joining_date": "2024-12-03", + "information": "Athletics — Development." + }, + { + "id": "99999999-00df-000d-d253-00000089d1e9", + "first_name": "Toni", + "last_name": "Seidel", + "email": "toni.seidel@club.de", + "birthday": "2007-07-14", + "phone_number": "+49 153 8864404", + "address": "Rosenstraße 81, 80801 München", + "joining_date": "2023-12-01", + "information": "Athletics — Development." + }, + { + "id": "99999999-00e0-000e-708a-0000008a7020", + "first_name": "Nele", + "last_name": "Braun", + "email": "nele.braun@club.de", + "birthday": "2011-06-21", + "phone_number": "+49 150 2667687", + "address": "Wiesenweg 134, 80469 München", + "joining_date": "2024-07-19", + "information": "Athletics — Development." + }, + { + "id": "99999999-00e1-000e-0ec1-0000008b0e57", + "first_name": "Ella", + "last_name": "Nowak", + "email": "ella.nowak@club.de", + "birthday": "2007-10-16", + "phone_number": "+49 176 1416968", + "address": "Ahornweg 10, 80331 München", + "joining_date": "2022-04-24", + "information": "Athletics — Development." + }, + { + "id": "99999999-00e2-000e-acf9-0000008bac8e", + "first_name": "Ben", + "last_name": "Busch", + "email": "ben.busch@club.de", + "birthday": "2010-05-06", + "phone_number": "+49 173 6630403", + "address": "Mühlgasse 1, 80469 München", + "joining_date": "2024-03-14", + "information": "Athletics — Development." + }, + { + "id": "99999999-00e3-000e-4b30-0000008c4ac5", + "first_name": "Nele", + "last_name": "Brandt", + "email": "nele.brandt@club.de", + "birthday": "1980-02-22", + "phone_number": "+49 160 5323238", + "address": "Birkenallee 133, 80333 München", + "joining_date": "2019-02-03", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00e4-000e-e968-0000008ce8fc", + "first_name": "Jonah", + "last_name": "Frank", + "email": "jonah.frank@club.de", + "birthday": "1994-04-04", + "phone_number": "+49 154 2822960", + "address": "Gartenweg 8, 81243 München", + "joining_date": "2021-05-13", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00e5-000e-879f-0000008d8733", + "first_name": "Aaron", + "last_name": "Arnold", + "email": "aaron.arnold@club.de", + "birthday": "1991-12-13", + "phone_number": "+49 170 2540772", + "address": "Mühlgasse 52, 80636 München", + "joining_date": "2019-03-07", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00e6-000e-25d7-0000008e256a", + "first_name": "Romi", + "last_name": "König", + "email": "romi.könig@club.de", + "birthday": "1997-07-15", + "phone_number": "+49 175 5307953", + "address": "Parkstraße 13, 80333 München", + "joining_date": "2023-02-03", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00e7-000e-c40e-0000008ec3a1", + "first_name": "Amelie", + "last_name": "Seidel", + "email": "amelie.seidel@club.de", + "birthday": "1975-10-07", + "phone_number": "+49 151 9046601", + "address": "Uferweg 46, 80801 München", + "joining_date": "2025-04-11", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00e8-000e-6246-0000008f61d8", + "first_name": "Lea", + "last_name": "Stein", + "email": "lea.stein@club.de", + "birthday": "1990-08-22", + "phone_number": "+49 179 6854315", + "address": "Ahornweg 25, 80469 München", + "joining_date": "2021-07-06", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00e9-000e-007d-00000090000f", + "first_name": "Arne", + "last_name": "Horn", + "email": "arne.horn@club.de", + "birthday": "1997-12-03", + "phone_number": "+49 166 6768412", + "address": "Wiesenweg 132, 80636 München", + "joining_date": "2023-03-14", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00ea-000e-9eb5-000000909e46", + "first_name": "Mira", + "last_name": "Klein", + "email": "mira.klein@club.de", + "birthday": "1978-09-13", + "phone_number": "+49 165 6316156", + "address": "Ahornweg 117, 81243 München", + "joining_date": "2019-04-15", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00eb-000e-3cec-000000913c7d", + "first_name": "Emil", + "last_name": "Sauer", + "email": "emil.sauer@club.de", + "birthday": "1985-11-21", + "phone_number": "+49 170 6203902", + "address": "Wiesenweg 58, 80636 München", + "joining_date": "2022-01-26", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00ec-000e-db24-00000091dab4", + "first_name": "Romi", + "last_name": "Park", + "email": "romi.park@club.de", + "birthday": "1994-03-27", + "phone_number": "+49 178 8814370", + "address": "Sonnenweg 30, 80331 München", + "joining_date": "2019-07-05", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00ed-000e-795b-0000009278eb", + "first_name": "Mats", + "last_name": "Horn", + "email": "mats.horn@club.de", + "birthday": "1985-07-09", + "phone_number": "+49 175 9861516", + "address": "Uferweg 99, 80331 München", + "joining_date": "2023-04-27", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00ee-000e-1793-000000931722", + "first_name": "Lina", + "last_name": "Krüger", + "email": "lina.krüger@club.de", + "birthday": "1984-09-28", + "phone_number": "+49 162 6134815", + "address": "Ahornweg 89, 80333 München", + "joining_date": "2021-06-24", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00ef-000e-b5ca-00000093b559", + "first_name": "Henry", + "last_name": "Hartmann", + "email": "henry.hartmann@club.de", + "birthday": "1994-10-28", + "phone_number": "+49 152 7962872", + "address": "Schulstraße 45, 81243 München", + "joining_date": "2022-06-20", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00f0-000f-5402-000000945390", + "first_name": "Jonah", + "last_name": "Braun", + "email": "jonah.braun@club.de", + "birthday": "1990-07-08", + "phone_number": "+49 178 6247588", + "address": "Sonnenweg 9, 80636 München", + "joining_date": "2024-08-01", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00f1-000f-f239-00000094f1c7", + "first_name": "Charlotte", + "last_name": "Ziegler", + "email": "charlotte.ziegler@club.de", + "birthday": "1987-02-02", + "phone_number": "+49 156 8451917", + "address": "Uferweg 34, 80335 München", + "joining_date": "2019-04-06", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00f2-000f-9071-000000958ffe", + "first_name": "Rosa", + "last_name": "Brandt", + "email": "rosa.brandt@club.de", + "birthday": "1995-02-06", + "phone_number": "+49 151 7355688", + "address": "Birkenallee 99, 80331 München", + "joining_date": "2022-03-07", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00f3-000f-2ea8-000000962e35", + "first_name": "Marie", + "last_name": "Nowak", + "email": "marie.nowak@club.de", + "birthday": "1990-05-11", + "phone_number": "+49 169 2682995", + "address": "Wiesenweg 88, 81667 München", + "joining_date": "2024-04-25", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00f4-000f-ccdf-00000096cc6c", + "first_name": "Stella", + "last_name": "Frank", + "email": "stella.frank@club.de", + "birthday": "1992-10-16", + "phone_number": "+49 157 3240540", + "address": "Gartenweg 104, 80469 München", + "joining_date": "2021-03-27", + "information": "Athletics — Varsity." + }, + { + "id": "99999999-00f5-000f-6b17-000000976aa3", + "first_name": "Til", + "last_name": "Lehmann", + "email": "til.lehmann@club.de", + "birthday": "1992-07-01", + "phone_number": "+49 178 6164865", + "address": "Birkenallee 46, 81243 München", + "joining_date": "2025-03-08", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00f6-000f-094e-0000009808da", + "first_name": "Anton", + "last_name": "Vogt", + "email": "anton.vogt@club.de", + "birthday": "1991-08-13", + "phone_number": "+49 170 5380140", + "address": "Talstraße 68, 80337 München", + "joining_date": "2021-03-10", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00f7-000f-a786-00000098a711", + "first_name": "Marco", + "last_name": "Krüger", + "email": "marco.krüger@club.de", + "birthday": "1998-02-04", + "phone_number": "+49 169 6554947", + "address": "Sonnenweg 3, 80636 München", + "joining_date": "2018-04-16", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00f8-000f-45bd-000000994548", + "first_name": "Til", + "last_name": "Bauer", + "email": "til.bauer@club.de", + "birthday": "1978-01-05", + "phone_number": "+49 158 8536018", + "address": "Feldweg 87, 80337 München", + "joining_date": "2019-09-26", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00f9-000f-e3f5-00000099e37f", + "first_name": "Joris", + "last_name": "Huber", + "email": "joris.huber@club.de", + "birthday": "1983-11-26", + "phone_number": "+49 168 5986124", + "address": "Ahornweg 56, 80331 München", + "joining_date": "2019-03-19", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00fa-000f-822c-0000009a81b6", + "first_name": "Mara", + "last_name": "Vogel", + "email": "mara.vogel@club.de", + "birthday": "1989-12-04", + "phone_number": "+49 174 7028791", + "address": "Bergstraße 44, 80333 München", + "joining_date": "2023-02-05", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00fb-000f-2064-0000009b1fed", + "first_name": "Martha", + "last_name": "Vogel", + "email": "martha.vogel@club.de", + "birthday": "1997-07-12", + "phone_number": "+49 170 7462741", + "address": "Rosenstraße 99, 80636 München", + "joining_date": "2021-11-18", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00fc-000f-be9b-0000009bbe24", + "first_name": "Mats", + "last_name": "Kaiser", + "email": "mats.kaiser@club.de", + "birthday": "1998-08-05", + "phone_number": "+49 178 8046516", + "address": "Schulstraße 61, 81243 München", + "joining_date": "2020-04-02", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00fd-000f-5cd3-0000009c5c5b", + "first_name": "Linus", + "last_name": "Hartmann", + "email": "linus.hartmann@club.de", + "birthday": "1979-09-05", + "phone_number": "+49 151 9670171", + "address": "Wiesenweg 65, 81667 München", + "joining_date": "2018-04-24", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00fe-000f-fb0a-0000009cfa92", + "first_name": "Erik", + "last_name": "Schulz", + "email": "erik.schulz@club.de", + "birthday": "1995-05-10", + "phone_number": "+49 163 5958496", + "address": "Uferweg 32, 80333 München", + "joining_date": "2020-09-08", + "information": "Athletics — Masters." + }, + { + "id": "99999999-00ff-000f-9942-0000009d98c9", + "first_name": "Ida", + "last_name": "Kaiser", + "email": "ida.kaiser@club.de", + "birthday": "1989-01-04", + "phone_number": "+49 176 3238243", + "address": "Mühlgasse 105, 80636 München", + "joining_date": "2020-01-26", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0100-0010-3779-0000009e3700", + "first_name": "Felix", + "last_name": "Brandt", + "email": "felix.brandt@club.de", + "birthday": "1998-03-06", + "phone_number": "+49 170 8422223", + "address": "Uferweg 135, 80335 München", + "joining_date": "2020-08-12", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0101-0010-d5b1-0000009ed537", + "first_name": "Clara", + "last_name": "Pohl", + "email": "clara.pohl@club.de", + "birthday": "1997-10-14", + "phone_number": "+49 169 6000192", + "address": "Mühlgasse 68, 81243 München", + "joining_date": "2021-07-15", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0102-0010-73e8-0000009f736e", + "first_name": "Niklas", + "last_name": "Fuchs", + "email": "niklas.fuchs@club.de", + "birthday": "1993-11-28", + "phone_number": "+49 155 4338734", + "address": "Feldweg 92, 80469 München", + "joining_date": "2022-06-26", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0103-0010-1220-000000a011a5", + "first_name": "Leon", + "last_name": "Roth", + "email": "leon.roth@club.de", + "birthday": "1990-12-19", + "phone_number": "+49 154 6685076", + "address": "Ahornweg 76, 81667 München", + "joining_date": "2022-11-09", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0104-0010-b057-000000a0afdc", + "first_name": "Alma", + "last_name": "Roth", + "email": "alma.roth@club.de", + "birthday": "1990-11-28", + "phone_number": "+49 171 8387967", + "address": "Bergstraße 133, 80636 München", + "joining_date": "2020-11-23", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0105-0010-4e8f-000000a14e13", + "first_name": "Levi", + "last_name": "Kaiser", + "email": "levi.kaiser@club.de", + "birthday": "1975-06-27", + "phone_number": "+49 167 2045378", + "address": "Mühlgasse 14, 80636 München", + "joining_date": "2025-11-09", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0106-0010-ecc6-000000a1ec4a", + "first_name": "Nele", + "last_name": "Kaiser", + "email": "nele.kaiser@club.de", + "birthday": "1980-07-04", + "phone_number": "+49 171 5201919", + "address": "Bergstraße 26, 80636 München", + "joining_date": "2024-11-07", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0107-0010-8afe-000000a28a81", + "first_name": "Greta", + "last_name": "Sommer", + "email": "greta.sommer@club.de", + "birthday": "1982-09-23", + "phone_number": "+49 151 5033588", + "address": "Kirchplatz 37, 80801 München", + "joining_date": "2025-01-09", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0108-0010-2935-000000a328b8", + "first_name": "Helena", + "last_name": "Park", + "email": "helena.park@club.de", + "birthday": "1986-04-21", + "phone_number": "+49 167 3219419", + "address": "Parkstraße 37, 80333 München", + "joining_date": "2020-06-16", + "information": "Athletics — Masters." + }, + { + "id": "99999999-0109-0010-c76c-000000a3c6ef", + "first_name": "Alma", + "last_name": "Frank", + "email": "alma.frank@club.de", + "birthday": "1979-11-07", + "phone_number": "+49 161 1368605", + "address": "Ahornweg 61, 80333 München", + "joining_date": "2025-10-12", + "information": "Athletics — Masters." + }, + { + "id": "99999999-010a-0010-65a4-000000a46526", + "first_name": "Ida", + "last_name": "Voigt", + "email": "ida.voigt@club.de", + "birthday": "2010-10-08", + "phone_number": "+49 179 7538699", + "address": "Lindenstraße 42, 80801 München", + "joining_date": "2021-02-17", + "information": "Volleyball — Juniors." + }, + { + "id": "99999999-010b-0010-03db-000000a5035d", + "first_name": "Theo", + "last_name": "Roth", + "email": "theo.roth@club.de", + "birthday": "2007-03-26", + "phone_number": "+49 165 7867496", + "address": "Bergstraße 80, 80333 München", + "joining_date": "2025-05-20", + "information": "Volleyball — Juniors." + }, + { + "id": "99999999-010c-0010-a213-000000a5a194", + "first_name": "Joris", + "last_name": "Krause", + "email": "joris.krause@club.de", + "birthday": "2011-08-15", + "phone_number": "+49 150 9152043", + "address": "Sonnenweg 85, 80801 München", + "joining_date": "2022-11-23", + "information": "Volleyball — Juniors." + }, + { + "id": "99999999-010d-0010-404a-000000a63fcb", + "first_name": "Mia", + "last_name": "Braun", + "email": "mia.braun@club.de", + "birthday": "2010-12-16", + "phone_number": "+49 168 9876177", + "address": "Gartenweg 21, 80636 München", + "joining_date": "2021-04-21", + "information": "Volleyball — Juniors." + }, + { + "id": "99999999-010e-0010-de82-000000a6de02", + "first_name": "Magda", + "last_name": "Bauer", + "email": "magda.bauer@club.de", + "birthday": "2007-02-15", + "phone_number": "+49 164 8673212", + "address": "Schulstraße 67, 80331 München", + "joining_date": "2018-05-04", + "information": "Volleyball — Juniors." + }, + { + "id": "99999999-010f-0010-7cb9-000000a77c39", + "first_name": "Martha", + "last_name": "Diaz", + "email": "martha.diaz@club.de", + "birthday": "2011-01-01", + "phone_number": "+49 152 9614206", + "address": "Ahornweg 130, 80331 München", + "joining_date": "2022-07-22", + "information": "Volleyball — Juniors." + }, + { + "id": "99999999-0110-0011-1af1-000000a81a70", + "first_name": "Mira", + "last_name": "Roth", + "email": "mira.roth@club.de", + "birthday": "2007-03-03", + "phone_number": "+49 177 5782052", + "address": "Talstraße 4, 80331 München", + "joining_date": "2022-11-06", + "information": "Volleyball — Juniors." + }, + { + "id": "99999999-0111-0011-b928-000000a8b8a7", + "first_name": "Romy", + "last_name": "Park", + "email": "romy.park@club.de", + "birthday": "2007-06-04", + "phone_number": "+49 157 5804857", + "address": "Talstraße 73, 80333 München", + "joining_date": "2020-06-13", + "information": "Volleyball — Juniors." + }, + { + "id": "99999999-0112-0011-5760-000000a956de", + "first_name": "Paul", + "last_name": "Reil", + "email": "paul.reil@club.de", + "birthday": "2007-07-18", + "phone_number": "+49 172 7659422", + "address": "Parkstraße 129, 80337 München", + "joining_date": "2023-03-25", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0113-0011-f597-000000a9f515", + "first_name": "Nora", + "last_name": "Diaz", + "email": "nora.diaz@club.de", + "birthday": "2010-12-19", + "phone_number": "+49 167 9367727", + "address": "Uferweg 122, 81667 München", + "joining_date": "2025-01-09", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0114-0011-93cf-000000aa934c", + "first_name": "Samuel", + "last_name": "Koch", + "email": "samuel.koch@club.de", + "birthday": "2009-06-02", + "phone_number": "+49 167 6215263", + "address": "Bergstraße 55, 80333 München", + "joining_date": "2022-02-09", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0115-0011-3206-000000ab3183", + "first_name": "Wilma", + "last_name": "Braun", + "email": "wilma.braun@club.de", + "birthday": "2007-08-21", + "phone_number": "+49 155 1869535", + "address": "Lindenstraße 38, 80335 München", + "joining_date": "2022-08-26", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0116-0011-d03e-000000abcfba", + "first_name": "Pia", + "last_name": "Zimmermann", + "email": "pia.zimmermann@club.de", + "birthday": "2009-11-18", + "phone_number": "+49 165 5689979", + "address": "Mühlgasse 54, 80469 München", + "joining_date": "2025-08-28", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0117-0011-6e75-000000ac6df1", + "first_name": "Sofia", + "last_name": "Wolf", + "email": "sofia.wolf@club.de", + "birthday": "2007-04-17", + "phone_number": "+49 157 4447943", + "address": "Birkenallee 5, 80636 München", + "joining_date": "2020-09-09", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0118-0011-0cad-000000ad0c28", + "first_name": "Joris", + "last_name": "Arnold", + "email": "joris.arnold@club.de", + "birthday": "2009-03-26", + "phone_number": "+49 151 5645306", + "address": "Uferweg 15, 80801 München", + "joining_date": "2018-01-02", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0119-0011-aae4-000000adaa5f", + "first_name": "Elias", + "last_name": "Busch", + "email": "elias.busch@club.de", + "birthday": "2010-08-27", + "phone_number": "+49 151 1301094", + "address": "Kirchplatz 106, 80333 München", + "joining_date": "2019-09-26", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-011a-0011-491c-000000ae4896", + "first_name": "Jonah", + "last_name": "Diaz", + "email": "jonah.diaz@club.de", + "birthday": "2011-12-12", + "phone_number": "+49 174 9669654", + "address": "Gartenweg 100, 80331 München", + "joining_date": "2022-02-02", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-011b-0011-e753-000000aee6cd", + "first_name": "Mats", + "last_name": "Fuchs", + "email": "mats.fuchs@club.de", + "birthday": "2008-02-16", + "phone_number": "+49 162 6748456", + "address": "Sonnenweg 108, 80337 München", + "joining_date": "2020-07-04", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-011c-0011-858b-000000af8504", + "first_name": "Greta", + "last_name": "Koch", + "email": "greta.koch@club.de", + "birthday": "2008-11-25", + "phone_number": "+49 154 9935488", + "address": "Rosenstraße 70, 80469 München", + "joining_date": "2020-02-26", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-011d-0011-23c2-000000b0233b", + "first_name": "Janne", + "last_name": "Vogel", + "email": "janne.vogel@club.de", + "birthday": "2009-08-28", + "phone_number": "+49 167 4365904", + "address": "Bergstraße 37, 80636 München", + "joining_date": "2025-05-02", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-011e-0011-c1f9-000000b0c172", + "first_name": "Amelie", + "last_name": "Wolf", + "email": "amelie.wolf@club.de", + "birthday": "2010-10-01", + "phone_number": "+49 161 4402525", + "address": "Lindenstraße 117, 80801 München", + "joining_date": "2025-11-03", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-011f-0011-6031-000000b15fa9", + "first_name": "Leon", + "last_name": "Sommer", + "email": "leon.sommer@club.de", + "birthday": "2007-07-16", + "phone_number": "+49 152 6085370", + "address": "Wiesenweg 123, 81243 München", + "joining_date": "2023-11-22", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0120-0012-fe68-000000b1fde0", + "first_name": "Lea", + "last_name": "Engel", + "email": "lea.engel@club.de", + "birthday": "2011-10-24", + "phone_number": "+49 173 1196960", + "address": "Ahornweg 139, 80335 München", + "joining_date": "2023-05-14", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0121-0012-9ca0-000000b29c17", + "first_name": "Stella", + "last_name": "Braun", + "email": "stella.braun@club.de", + "birthday": "2009-12-05", + "phone_number": "+49 166 8240631", + "address": "Rosenstraße 127, 80337 München", + "joining_date": "2020-03-13", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0122-0012-3ad7-000000b33a4e", + "first_name": "Helena", + "last_name": "König", + "email": "helena.könig@club.de", + "birthday": "2011-11-20", + "phone_number": "+49 178 4807857", + "address": "Sonnenweg 59, 80335 München", + "joining_date": "2025-08-19", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0123-0012-d90f-000000b3d885", + "first_name": "Edda", + "last_name": "Nowak", + "email": "edda.nowak@club.de", + "birthday": "2009-02-16", + "phone_number": "+49 161 1564456", + "address": "Feldweg 11, 80331 München", + "joining_date": "2025-05-10", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0124-0012-7746-000000b476bc", + "first_name": "Nora", + "last_name": "Hoffmann", + "email": "nora.hoffmann@club.de", + "birthday": "2007-05-02", + "phone_number": "+49 159 7674178", + "address": "Feldweg 100, 81243 München", + "joining_date": "2022-10-13", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0125-0012-157e-000000b514f3", + "first_name": "Nele", + "last_name": "Krause", + "email": "nele.krause@club.de", + "birthday": "2008-10-25", + "phone_number": "+49 157 4430908", + "address": "Rosenstraße 81, 81243 München", + "joining_date": "2022-01-22", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0126-0012-b3b5-000000b5b32a", + "first_name": "Johanna", + "last_name": "Frank", + "email": "johanna.frank@club.de", + "birthday": "2011-05-24", + "phone_number": "+49 153 2880010", + "address": "Talstraße 56, 81667 München", + "joining_date": "2019-05-10", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0127-0012-51ed-000000b65161", + "first_name": "Emil", + "last_name": "Schulz", + "email": "emil.schulz@club.de", + "birthday": "2011-09-15", + "phone_number": "+49 179 6105086", + "address": "Ahornweg 93, 80538 München", + "joining_date": "2018-07-13", + "information": "Volleyball — Squad 1." + }, + { + "id": "99999999-0128-0012-f024-000000b6ef98", + "first_name": "Linus", + "last_name": "Scholz", + "email": "linus.scholz@club.de", + "birthday": "2009-02-05", + "phone_number": "+49 176 9081560", + "address": "Kirchplatz 105, 81667 München", + "joining_date": "2019-01-09", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-0129-0012-8e5c-000000b78dcf", + "first_name": "Luca", + "last_name": "Schulz", + "email": "luca.schulz@club.de", + "birthday": "2011-09-06", + "phone_number": "+49 172 7113718", + "address": "Mühlgasse 21, 80801 München", + "joining_date": "2021-01-06", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-012a-0012-2c93-000000b82c06", + "first_name": "Clara", + "last_name": "Voigt", + "email": "clara.voigt@club.de", + "birthday": "2011-12-07", + "phone_number": "+49 172 1887876", + "address": "Birkenallee 121, 80337 München", + "joining_date": "2019-05-05", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-012b-0012-cacb-000000b8ca3d", + "first_name": "Noah", + "last_name": "Schulz", + "email": "noah.schulz@club.de", + "birthday": "2011-07-13", + "phone_number": "+49 155 9370803", + "address": "Schulstraße 28, 80331 München", + "joining_date": "2024-11-24", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-012c-0012-6902-000000b96874", + "first_name": "Linus", + "last_name": "Graf", + "email": "linus.graf@club.de", + "birthday": "2008-12-13", + "phone_number": "+49 163 9953644", + "address": "Ahornweg 83, 80335 München", + "joining_date": "2018-08-27", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-012d-0012-073a-000000ba06ab", + "first_name": "Mats", + "last_name": "Voigt", + "email": "mats.voigt@club.de", + "birthday": "2007-07-09", + "phone_number": "+49 164 5126628", + "address": "Uferweg 92, 80335 München", + "joining_date": "2022-04-18", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-012e-0012-a571-000000baa4e2", + "first_name": "Janne", + "last_name": "Albrecht", + "email": "janne.albrecht@club.de", + "birthday": "2008-04-10", + "phone_number": "+49 153 4278125", + "address": "Rosenstraße 109, 80335 München", + "joining_date": "2025-08-12", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-012f-0012-43a9-000000bb4319", + "first_name": "Nora", + "last_name": "Bauer", + "email": "nora.bauer@club.de", + "birthday": "2008-05-08", + "phone_number": "+49 166 9841413", + "address": "Birkenallee 75, 80333 München", + "joining_date": "2021-09-13", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-0130-0013-e1e0-000000bbe150", + "first_name": "Luca", + "last_name": "Wolf", + "email": "luca.wolf@club.de", + "birthday": "2007-01-24", + "phone_number": "+49 152 9951678", + "address": "Feldweg 82, 80337 München", + "joining_date": "2018-05-07", + "information": "Volleyball — Squad 2." + }, + { + "id": "99999999-0131-0013-8017-000000bc7f87", + "first_name": "Ada", + "last_name": "Kaiser", + "email": "ada.kaiser@club.de", + "birthday": "2010-04-14", + "phone_number": "+49 174 9584179", + "address": "Lindenstraße 12, 80801 München", + "joining_date": "2025-08-23", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0132-0013-1e4f-000000bd1dbe", + "first_name": "Emil", + "last_name": "Engel", + "email": "emil.engel@club.de", + "birthday": "2010-03-19", + "phone_number": "+49 157 4775515", + "address": "Schulstraße 43, 81667 München", + "joining_date": "2021-11-03", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0133-0013-bc86-000000bdbbf5", + "first_name": "Max", + "last_name": "Ziegler", + "email": "max.ziegler@club.de", + "birthday": "2011-03-09", + "phone_number": "+49 166 1513579", + "address": "Talstraße 66, 80636 München", + "joining_date": "2022-04-04", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0134-0013-5abe-000000be5a2c", + "first_name": "Linus", + "last_name": "Vogt", + "email": "linus.vogt@club.de", + "birthday": "2007-05-14", + "phone_number": "+49 165 2119798", + "address": "Uferweg 31, 80636 München", + "joining_date": "2021-09-10", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0135-0013-f8f5-000000bef863", + "first_name": "Romi", + "last_name": "Vogt", + "email": "romi.vogt@club.de", + "birthday": "2010-10-11", + "phone_number": "+49 167 7729457", + "address": "Wiesenweg 102, 81667 München", + "joining_date": "2018-06-19", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0136-0013-972d-000000bf969a", + "first_name": "Moritz", + "last_name": "Albrecht", + "email": "moritz.albrecht@club.de", + "birthday": "2007-11-18", + "phone_number": "+49 173 6677944", + "address": "Gartenweg 118, 81243 München", + "joining_date": "2019-07-18", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0137-0013-3564-000000c034d1", + "first_name": "Juna", + "last_name": "Schulz", + "email": "juna.schulz@club.de", + "birthday": "2007-04-01", + "phone_number": "+49 155 8625126", + "address": "Gartenweg 117, 81243 München", + "joining_date": "2023-07-15", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0138-0013-d39c-000000c0d308", + "first_name": "Rosa", + "last_name": "Koch", + "email": "rosa.koch@club.de", + "birthday": "2011-11-02", + "phone_number": "+49 157 7751161", + "address": "Gartenweg 102, 80636 München", + "joining_date": "2023-12-11", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0139-0013-71d3-000000c1713f", + "first_name": "Janne", + "last_name": "Park", + "email": "janne.park@club.de", + "birthday": "2010-01-24", + "phone_number": "+49 159 5595123", + "address": "Ahornweg 98, 81667 München", + "joining_date": "2021-01-18", + "information": "Volleyball — U16." + }, + { + "id": "99999999-013a-0013-100b-000000c20f76", + "first_name": "Romy", + "last_name": "Sauer", + "email": "romy.sauer@club.de", + "birthday": "2007-05-17", + "phone_number": "+49 171 3627246", + "address": "Sonnenweg 93, 80333 München", + "joining_date": "2018-06-07", + "information": "Volleyball — U16." + }, + { + "id": "99999999-013b-0013-ae42-000000c2adad", + "first_name": "Lina", + "last_name": "Beck", + "email": "lina.beck@club.de", + "birthday": "2011-03-03", + "phone_number": "+49 175 4322013", + "address": "Rosenstraße 42, 80331 München", + "joining_date": "2021-08-16", + "information": "Volleyball — U16." + }, + { + "id": "99999999-013c-0013-4c7a-000000c34be4", + "first_name": "Theo", + "last_name": "Hoffmann", + "email": "theo.hoffmann@club.de", + "birthday": "2011-08-26", + "phone_number": "+49 155 4105577", + "address": "Lindenstraße 64, 80636 München", + "joining_date": "2024-05-06", + "information": "Volleyball — U16." + }, + { + "id": "99999999-013d-0013-eab1-000000c3ea1b", + "first_name": "Alma", + "last_name": "Klein", + "email": "alma.klein@club.de", + "birthday": "2008-06-28", + "phone_number": "+49 177 9869038", + "address": "Gartenweg 122, 80333 München", + "joining_date": "2018-05-12", + "information": "Volleyball — U16." + }, + { + "id": "99999999-013e-0013-88e9-000000c48852", + "first_name": "Martha", + "last_name": "Lange", + "email": "martha.lange@club.de", + "birthday": "2008-01-13", + "phone_number": "+49 153 7597799", + "address": "Parkstraße 49, 81667 München", + "joining_date": "2024-03-02", + "information": "Volleyball — U16." + }, + { + "id": "99999999-013f-0013-2720-000000c52689", + "first_name": "Levi", + "last_name": "Brandt", + "email": "levi.brandt@club.de", + "birthday": "2010-03-06", + "phone_number": "+49 157 8965394", + "address": "Sonnenweg 32, 80331 München", + "joining_date": "2024-02-07", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0140-0014-c558-000000c5c4c0", + "first_name": "Mats", + "last_name": "Hartmann", + "email": "mats.hartmann@club.de", + "birthday": "2007-02-21", + "phone_number": "+49 155 2536084", + "address": "Feldweg 120, 81243 München", + "joining_date": "2024-03-14", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0141-0014-638f-000000c662f7", + "first_name": "Amelie", + "last_name": "Diaz", + "email": "amelie.diaz@club.de", + "birthday": "2008-06-24", + "phone_number": "+49 162 4518317", + "address": "Lindenstraße 84, 80335 München", + "joining_date": "2025-12-15", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0142-0014-01c7-000000c7012e", + "first_name": "Anton", + "last_name": "Braun", + "email": "anton.braun@club.de", + "birthday": "2007-09-13", + "phone_number": "+49 172 7715228", + "address": "Sonnenweg 57, 80331 München", + "joining_date": "2019-08-28", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0143-0014-9ffe-000000c79f65", + "first_name": "Emil", + "last_name": "Busch", + "email": "emil.busch@club.de", + "birthday": "2008-05-05", + "phone_number": "+49 176 4845215", + "address": "Feldweg 26, 80801 München", + "joining_date": "2020-11-02", + "information": "Volleyball — U16." + }, + { + "id": "99999999-0144-0014-3e36-000000c83d9c", + "first_name": "Fynn", + "last_name": "Bauer", + "email": "fynn.bauer@club.de", + "birthday": "1992-03-18", + "phone_number": "+49 156 6592991", + "address": "Kirchplatz 122, 81243 München", + "joining_date": "2021-12-13", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-0145-0014-dc6d-000000c8dbd3", + "first_name": "David", + "last_name": "Zimmermann", + "email": "david.zimmermann@club.de", + "birthday": "1975-06-20", + "phone_number": "+49 151 7134501", + "address": "Lindenstraße 31, 80337 München", + "joining_date": "2025-07-25", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-0146-0014-7aa4-000000c97a0a", + "first_name": "Noah", + "last_name": "Klein", + "email": "noah.klein@club.de", + "birthday": "1990-05-27", + "phone_number": "+49 173 7352369", + "address": "Feldweg 40, 80335 München", + "joining_date": "2022-08-14", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-0147-0014-18dc-000000ca1841", + "first_name": "Henry", + "last_name": "Huber", + "email": "henry.huber@club.de", + "birthday": "1993-11-06", + "phone_number": "+49 173 7198372", + "address": "Rosenstraße 36, 80333 München", + "joining_date": "2025-02-12", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-0148-0014-b713-000000cab678", + "first_name": "Rosa", + "last_name": "Schulz", + "email": "rosa.schulz@club.de", + "birthday": "1996-03-09", + "phone_number": "+49 154 8799398", + "address": "Parkstraße 129, 80636 München", + "joining_date": "2019-06-03", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-0149-0014-554b-000000cb54af", + "first_name": "Lotte", + "last_name": "Engel", + "email": "lotte.engel@club.de", + "birthday": "1987-11-19", + "phone_number": "+49 170 1996265", + "address": "Rosenstraße 52, 80331 München", + "joining_date": "2020-08-01", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-014a-0014-f382-000000cbf2e6", + "first_name": "Samuel", + "last_name": "Wolf", + "email": "samuel.wolf@club.de", + "birthday": "1985-02-28", + "phone_number": "+49 155 3531057", + "address": "Rosenstraße 83, 80335 München", + "joining_date": "2019-11-08", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-014b-0014-91ba-000000cc911d", + "first_name": "Konrad", + "last_name": "Sommer", + "email": "konrad.sommer@club.de", + "birthday": "1978-04-21", + "phone_number": "+49 152 6233132", + "address": "Wiesenweg 60, 81243 München", + "joining_date": "2018-06-13", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-014c-0014-2ff1-000000cd2f54", + "first_name": "Elias", + "last_name": "Wolf", + "email": "elias.wolf@club.de", + "birthday": "1988-03-08", + "phone_number": "+49 158 6218100", + "address": "Rosenstraße 103, 80333 München", + "joining_date": "2019-12-21", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-014d-0014-ce29-000000cdcd8b", + "first_name": "Konrad", + "last_name": "Beck", + "email": "konrad.beck@club.de", + "birthday": "1975-12-26", + "phone_number": "+49 166 8789920", + "address": "Uferweg 119, 80335 München", + "joining_date": "2018-02-06", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-014e-0014-6c60-000000ce6bc2", + "first_name": "Hannah", + "last_name": "Arnold", + "email": "hannah.arnold@club.de", + "birthday": "1990-06-18", + "phone_number": "+49 171 4827942", + "address": "Uferweg 3, 80333 München", + "joining_date": "2021-12-25", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-014f-0014-0a98-000000cf09f9", + "first_name": "Bruno", + "last_name": "Krüger", + "email": "bruno.krüger@club.de", + "birthday": "1976-03-06", + "phone_number": "+49 172 8236867", + "address": "Bergstraße 124, 80333 München", + "joining_date": "2021-10-17", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-0150-0015-a8cf-000000cfa830", + "first_name": "Luca", + "last_name": "Pohl", + "email": "luca.pohl@club.de", + "birthday": "1991-05-28", + "phone_number": "+49 150 5932971", + "address": "Birkenallee 61, 80335 München", + "joining_date": "2021-03-20", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-0151-0015-4707-000000d04667", + "first_name": "Aaron", + "last_name": "Huber", + "email": "aaron.huber@club.de", + "birthday": "1987-08-01", + "phone_number": "+49 154 3415877", + "address": "Schulstraße 16, 81243 München", + "joining_date": "2020-02-07", + "information": "Volleyball — Varsity." + }, + { + "id": "99999999-0152-0015-e53e-000000d0e49e", + "first_name": "Paul", + "last_name": "Engel", + "email": "paul.engel@club.de", + "birthday": "1995-12-10", + "phone_number": "+49 170 1233101", + "address": "Lindenstraße 69, 80469 München", + "joining_date": "2023-05-15", + "information": "Volleyball — Varsity." + } +] + +export const memberSummaryFixtures: MemberSummary[] = memberFixtures.map( + ({ id, first_name, last_name, email }) => ({ id, first_name, last_name, email }), +) + +/** uuid -> "First Last", mirroring the planned useMemberNames() resolver. */ +export const memberNamesById: Record = Object.fromEntries( + memberFixtures.map((m) => [m.id, `${m.first_name} ${m.last_name}`]), +) diff --git a/web-client/src/mocks/fixtures/organization.ts b/web-client/src/mocks/fixtures/organization.ts new file mode 100644 index 0000000..49e51b3 --- /dev/null +++ b/web-client/src/mocks/fixtures/organization.ts @@ -0,0 +1,2142 @@ +import type { Sport, Team } from '@/types' +import { CURRENT_MEMBER_ID } from './members' + +// Sport is keyed by name; Team.sport is a sport name; member FKs are resolved refs. +export const sportFixtures: Sport[] = [ + { + "name": "Football", + "description": "Eleven-a-side football across youth and senior squads.", + "created_at": "2021-10-08", + "directors": [ + { + "id": "99999999-0003-0000-daa6-00000001daa5", + "first_name": "Director", + "last_name": "Devoops" + }, + { + "id": "99999999-0001-0000-9e37-000000009e37", + "first_name": "Johanna", + "last_name": "Horn" + } + ] + }, + { + "name": "Basketball", + "description": "Indoor basketball for juniors through varsity level.", + "created_at": "2022-06-09", + "directors": [ + { + "id": "99999999-0001-0000-9e37-000000009e37", + "first_name": "Johanna", + "last_name": "Horn" + }, + { + "id": "99999999-0003-0000-daa6-00000001daa5", + "first_name": "Director", + "last_name": "Devoops" + } + ] + }, + { + "name": "Swimming", + "description": "Lane swimming, technique and competitive squads.", + "created_at": "2020-12-11", + "directors": [ + { + "id": "99999999-0001-0000-9e37-000000009e37", + "first_name": "Johanna", + "last_name": "Horn" + }, + { + "id": "99999999-0002-0000-3c6e-000000013c6e", + "first_name": "Tilda", + "last_name": "Huber" + } + ] + }, + { + "name": "Athletics", + "description": "Track and field — sprints, distance, jumps and throws.", + "created_at": "2018-02-22", + "directors": [ + { + "id": "99999999-0002-0000-3c6e-000000013c6e", + "first_name": "Tilda", + "last_name": "Huber" + } + ] + }, + { + "name": "Volleyball", + "description": "Six-a-side indoor volleyball, mixed and youth groups.", + "created_at": "2022-06-26", + "directors": [ + { + "id": "99999999-0001-0000-9e37-000000009e37", + "first_name": "Johanna", + "last_name": "Horn" + } + ] + } +] + +export const teamFixtures: Team[] = [ + { + "id": "bbbbbbbb-0001-0000-9e37-000000009e37", + "name": "Football Juniors", + "description": "Football Juniors squad.", + "created_at": "2020-08-04", + "address": "Birkenallee 36, 81243 München", + "sport": "Football", + "trainers": [ + { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + ], + "trainees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0013-0001-be1e-0000000bbe15", + "first_name": "Marie", + "last_name": "Wolf" + }, + { + "id": "99999999-0014-0001-5c55-0000000c5c4c", + "first_name": "Linus", + "last_name": "Koch" + }, + { + "id": "99999999-0015-0001-fa8c-0000000cfa83", + "first_name": "Linus", + "last_name": "Beck" + }, + { + "id": "99999999-0016-0001-98c4-0000000d98ba", + "first_name": "Clara", + "last_name": "Frank" + }, + { + "id": "99999999-0017-0001-36fb-0000000e36f1", + "first_name": "Edda", + "last_name": "Frank" + }, + { + "id": "99999999-0018-0001-d533-0000000ed528", + "first_name": "Mia", + "last_name": "Werner" + }, + { + "id": "99999999-0019-0001-736a-0000000f735f", + "first_name": "Charlotte", + "last_name": "Wagner" + }, + { + "id": "99999999-001a-0001-11a2-000000101196", + "first_name": "Jakob", + "last_name": "Seidel" + }, + { + "id": "99999999-001b-0001-afd9-00000010afcd", + "first_name": "Ella", + "last_name": "Krüger" + }, + { + "id": "99999999-001c-0001-4e11-000000114e04", + "first_name": "Erik", + "last_name": "Lange" + }, + { + "id": "99999999-001d-0001-ec48-00000011ec3b", + "first_name": "Janne", + "last_name": "Roth" + }, + { + "id": "99999999-001e-0001-8a80-000000128a72", + "first_name": "Theo", + "last_name": "Diaz" + }, + { + "id": "99999999-001f-0001-28b7-0000001328a9", + "first_name": "Samuel", + "last_name": "Neumann" + }, + { + "id": "99999999-0020-0002-c6ef-00000013c6e0", + "first_name": "Levi", + "last_name": "Voigt" + }, + { + "id": "99999999-0021-0002-6526-000000146517", + "first_name": "Mia", + "last_name": "Albrecht" + }, + { + "id": "99999999-0022-0002-035e-00000015034e", + "first_name": "Ida", + "last_name": "Krüger" + }, + { + "id": "99999999-0023-0002-a195-00000015a185", + "first_name": "Oskar", + "last_name": "Schulz" + }, + { + "id": "99999999-0024-0002-3fcd-000000163fbc", + "first_name": "Clara", + "last_name": "Koch" + }, + { + "id": "99999999-0025-0002-de04-00000016ddf3", + "first_name": "Fynn", + "last_name": "Vogt" + }, + { + "id": "99999999-0026-0002-7c3c-000000177c2a", + "first_name": "Moritz", + "last_name": "Seidel" + }, + { + "id": "99999999-0027-0002-1a73-000000181a61", + "first_name": "Nora", + "last_name": "Krause" + }, + { + "id": "99999999-0028-0002-b8ab-00000018b898", + "first_name": "Mats", + "last_name": "Huber" + }, + { + "id": "99999999-0029-0002-56e2-0000001956cf", + "first_name": "Oskar", + "last_name": "Werner" + }, + { + "id": "99999999-002a-0002-f519-00000019f506", + "first_name": "Erik", + "last_name": "Richter" + } + ] + }, + { + "id": "bbbbbbbb-0002-0000-3c6e-000000013c6e", + "name": "Football Group A", + "description": "Football Group A squad.", + "created_at": "2022-06-01", + "address": "Mühlgasse 25, 81667 München", + "sport": "Football", + "trainers": [ + { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + } + ], + "trainees": [ + { + "id": "99999999-002b-0002-9351-0000001a933d", + "first_name": "David", + "last_name": "Arnold" + }, + { + "id": "99999999-002c-0002-3188-0000001b3174", + "first_name": "Marie", + "last_name": "Vogel" + }, + { + "id": "99999999-002d-0002-cfc0-0000001bcfab", + "first_name": "Romi", + "last_name": "Werner" + }, + { + "id": "99999999-002e-0002-6df7-0000001c6de2", + "first_name": "Wilma", + "last_name": "Kaiser" + }, + { + "id": "99999999-002f-0002-0c2f-0000001d0c19", + "first_name": "Romi", + "last_name": "Fuchs" + }, + { + "id": "99999999-0030-0003-aa66-0000001daa50", + "first_name": "Ben", + "last_name": "Vogel" + }, + { + "id": "99999999-0031-0003-489e-0000001e4887", + "first_name": "Edda", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0032-0003-e6d5-0000001ee6be", + "first_name": "Toni", + "last_name": "Brandt" + }, + { + "id": "99999999-0033-0003-850d-0000001f84f5", + "first_name": "Ida", + "last_name": "Arnold" + }, + { + "id": "99999999-0034-0003-2344-00000020232c", + "first_name": "Stella", + "last_name": "Zimmermann" + } + ] + }, + { + "id": "bbbbbbbb-0003-0000-daa6-00000001daa5", + "name": "Football Squad 2", + "description": "Football Squad 2 squad.", + "created_at": "2024-05-14", + "address": "Sonnenweg 49, 80331 München", + "sport": "Football", + "trainers": [ + { + "id": "99999999-000b-0000-cc62-00000006cc5d", + "first_name": "Felix", + "last_name": "Voigt" + } + ], + "trainees": [ + { + "id": "99999999-0035-0003-c17c-00000020c163", + "first_name": "Helena", + "last_name": "Berger" + }, + { + "id": "99999999-0036-0003-5fb3-000000215f9a", + "first_name": "Vincent", + "last_name": "Richter" + }, + { + "id": "99999999-0037-0003-fdeb-00000021fdd1", + "first_name": "Anton", + "last_name": "Frank" + }, + { + "id": "99999999-0038-0003-9c22-000000229c08", + "first_name": "Greta", + "last_name": "Nowak" + }, + { + "id": "99999999-0039-0003-3a5a-000000233a3f", + "first_name": "Clara", + "last_name": "Stein" + }, + { + "id": "99999999-003a-0003-d891-00000023d876", + "first_name": "Joris", + "last_name": "Stein" + }, + { + "id": "99999999-003b-0003-76c9-0000002476ad", + "first_name": "Frieda", + "last_name": "Bauer" + }, + { + "id": "99999999-003c-0003-1500-0000002514e4", + "first_name": "Martha", + "last_name": "Schwarz" + }, + { + "id": "99999999-003d-0003-b337-00000025b31b", + "first_name": "Fynn", + "last_name": "Koch" + }, + { + "id": "99999999-003e-0003-516f-000000265152", + "first_name": "Marie", + "last_name": "Fuchs" + }, + { + "id": "99999999-003f-0003-efa6-00000026ef89", + "first_name": "Joris", + "last_name": "Lehmann" + }, + { + "id": "99999999-0040-0004-8dde-000000278dc0", + "first_name": "Helena", + "last_name": "Graf" + }, + { + "id": "99999999-0041-0004-2c15-000000282bf7", + "first_name": "Smilla", + "last_name": "Krause" + }, + { + "id": "99999999-0042-0004-ca4d-00000028ca2e", + "first_name": "Konrad", + "last_name": "Schwarz" + }, + { + "id": "99999999-0043-0004-6884-000000296865", + "first_name": "Rosa", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0044-0004-06bc-0000002a069c", + "first_name": "Arne", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0045-0004-a4f3-0000002aa4d3", + "first_name": "Mats", + "last_name": "Graf" + }, + { + "id": "99999999-0046-0004-432b-0000002b430a", + "first_name": "Martha", + "last_name": "Voigt" + }, + { + "id": "99999999-0047-0004-e162-0000002be141", + "first_name": "Stella", + "last_name": "Horn" + } + ] + }, + { + "id": "bbbbbbbb-0004-0000-78dd-0000000278dc", + "name": "Football Seniors", + "description": "Football Seniors squad.", + "created_at": "2023-05-18", + "address": "Birkenallee 109, 80333 München", + "sport": "Football", + "trainers": [ + { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + ], + "trainees": [ + { + "id": "99999999-0048-0004-7f9a-0000002c7f78", + "first_name": "Levi", + "last_name": "Lange" + }, + { + "id": "99999999-0049-0004-1dd1-0000002d1daf", + "first_name": "Henry", + "last_name": "Richter" + }, + { + "id": "99999999-004a-0004-bc09-0000002dbbe6", + "first_name": "Liv", + "last_name": "Sommer" + }, + { + "id": "99999999-004b-0004-5a40-0000002e5a1d", + "first_name": "Vincent", + "last_name": "Vogt" + }, + { + "id": "99999999-004c-0004-f878-0000002ef854", + "first_name": "Tomas", + "last_name": "Hartmann" + } + ] + }, + { + "id": "bbbbbbbb-0005-0000-1715-000000031713", + "name": "Basketball Masters", + "description": "Basketball Masters squad.", + "created_at": "2019-10-15", + "address": "Kirchplatz 104, 80337 München", + "sport": "Basketball", + "trainers": [ + { + "id": "99999999-0008-0000-f1bb-00000004f1b8", + "first_name": "Theo", + "last_name": "Albrecht" + } + ], + "trainees": [ + { + "id": "99999999-004d-0004-96af-0000002f968b", + "first_name": "Frida", + "last_name": "Fuchs" + }, + { + "id": "99999999-004e-0004-34e7-0000003034c2", + "first_name": "Luca", + "last_name": "Ziegler" + }, + { + "id": "99999999-004f-0004-d31e-00000030d2f9", + "first_name": "Til", + "last_name": "Sommer" + }, + { + "id": "99999999-0050-0005-7156-000000317130", + "first_name": "Finn", + "last_name": "Seidel" + }, + { + "id": "99999999-0051-0005-0f8d-000000320f67", + "first_name": "Paul", + "last_name": "Busch" + }, + { + "id": "99999999-0052-0005-adc4-00000032ad9e", + "first_name": "Martha", + "last_name": "Braun" + }, + { + "id": "99999999-0053-0005-4bfc-000000334bd5", + "first_name": "Johanna", + "last_name": "Hartmann" + }, + { + "id": "99999999-0054-0005-ea33-00000033ea0c", + "first_name": "Marie", + "last_name": "Pohl" + }, + { + "id": "99999999-0055-0005-886b-000000348843", + "first_name": "Tomas", + "last_name": "Brandt" + }, + { + "id": "99999999-0056-0005-26a2-00000035267a", + "first_name": "Lina", + "last_name": "Nowak" + }, + { + "id": "99999999-0057-0005-c4da-00000035c4b1", + "first_name": "Helena", + "last_name": "Neumann" + }, + { + "id": "99999999-0058-0005-6311-0000003662e8", + "first_name": "Leon", + "last_name": "Hartmann" + }, + { + "id": "99999999-0059-0005-0149-00000037011f", + "first_name": "Paul", + "last_name": "Werner" + }, + { + "id": "99999999-005a-0005-9f80-000000379f56", + "first_name": "Alma", + "last_name": "Beck" + }, + { + "id": "99999999-005b-0005-3db8-000000383d8d", + "first_name": "Romy", + "last_name": "Voigt" + }, + { + "id": "99999999-005c-0005-dbef-00000038dbc4", + "first_name": "Felix", + "last_name": "Frank" + }, + { + "id": "99999999-005d-0005-7a27-0000003979fb", + "first_name": "Jakob", + "last_name": "Klein" + }, + { + "id": "99999999-005e-0005-185e-0000003a1832", + "first_name": "Ben", + "last_name": "Horn" + }, + { + "id": "99999999-005f-0005-b696-0000003ab669", + "first_name": "Jonah", + "last_name": "Krüger" + }, + { + "id": "99999999-0060-0006-54cd-0000003b54a0", + "first_name": "Lina", + "last_name": "Graf" + } + ] + }, + { + "id": "bbbbbbbb-0006-0000-b54c-00000003b54a", + "name": "Basketball Juniors", + "description": "Basketball Juniors squad.", + "created_at": "2019-01-22", + "address": "Ahornweg 41, 80331 München", + "sport": "Basketball", + "trainers": [ + { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + ], + "trainees": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "first_name": "Lena", + "last_name": "Roth" + }, + { + "id": "99999999-0061-0006-f305-0000003bf2d7", + "first_name": "Leon", + "last_name": "Braun" + }, + { + "id": "99999999-0062-0006-913c-0000003c910e", + "first_name": "Lotte", + "last_name": "Albrecht" + }, + { + "id": "99999999-0063-0006-2f74-0000003d2f45", + "first_name": "Lena", + "last_name": "Beck" + }, + { + "id": "99999999-0064-0006-cdab-0000003dcd7c", + "first_name": "Greta", + "last_name": "Roth" + }, + { + "id": "99999999-0065-0006-6be3-0000003e6bb3", + "first_name": "Frida", + "last_name": "Werner" + } + ] + }, + { + "id": "bbbbbbbb-0007-0000-5384-000000045381", + "name": "Basketball U14", + "description": "Basketball U14 squad.", + "created_at": "2020-08-16", + "address": "Kirchplatz 131, 80337 München", + "sport": "Basketball", + "trainers": [ + { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + }, + { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + ], + "trainees": [ + { + "id": "99999999-0066-0006-0a1a-0000003f09ea", + "first_name": "Jonah", + "last_name": "Nowak" + }, + { + "id": "99999999-0067-0006-a851-0000003fa821", + "first_name": "Luca", + "last_name": "Peters" + }, + { + "id": "99999999-0068-0006-4689-000000404658", + "first_name": "Clara", + "last_name": "Seidel" + }, + { + "id": "99999999-0069-0006-e4c0-00000040e48f", + "first_name": "Edda", + "last_name": "Pohl" + }, + { + "id": "99999999-006a-0006-82f8-0000004182c6", + "first_name": "Ben", + "last_name": "Park" + }, + { + "id": "99999999-006b-0006-212f-0000004220fd", + "first_name": "Felix", + "last_name": "Koch" + }, + { + "id": "99999999-006c-0006-bf67-00000042bf34", + "first_name": "Toni", + "last_name": "Sauer" + }, + { + "id": "99999999-006d-0006-5d9e-000000435d6b", + "first_name": "Tilda", + "last_name": "Albrecht" + }, + { + "id": "99999999-006e-0006-fbd6-00000043fba2", + "first_name": "Ben", + "last_name": "Lehmann" + }, + { + "id": "99999999-006f-0006-9a0d-0000004499d9", + "first_name": "Liv", + "last_name": "Brandt" + } + ] + }, + { + "id": "bbbbbbbb-0008-0000-f1bb-00000004f1b8", + "name": "Basketball Squad 1", + "description": "Basketball Squad 1 squad.", + "created_at": "2019-08-24", + "address": "Mühlgasse 134, 80337 München", + "sport": "Basketball", + "trainers": [ + { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + }, + { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + ], + "trainees": [ + { + "id": "99999999-0070-0007-3845-000000453810", + "first_name": "Paul", + "last_name": "Albrecht" + }, + { + "id": "99999999-0071-0007-d67c-00000045d647", + "first_name": "Nele", + "last_name": "Schwarz" + }, + { + "id": "99999999-0072-0007-74b4-00000046747e", + "first_name": "Lena", + "last_name": "Pohl" + }, + { + "id": "99999999-0073-0007-12eb-0000004712b5", + "first_name": "Helena", + "last_name": "Vogel" + }, + { + "id": "99999999-0074-0007-b123-00000047b0ec", + "first_name": "Helena", + "last_name": "Wagner" + }, + { + "id": "99999999-0075-0007-4f5a-000000484f23", + "first_name": "Emil", + "last_name": "Kaiser" + }, + { + "id": "99999999-0076-0007-ed92-00000048ed5a", + "first_name": "Leon", + "last_name": "Diaz" + }, + { + "id": "99999999-0077-0007-8bc9-000000498b91", + "first_name": "Ada", + "last_name": "Hoffmann" + }, + { + "id": "99999999-0078-0007-2a01-0000004a29c8", + "first_name": "Oskar", + "last_name": "Nowak" + }, + { + "id": "99999999-0079-0007-c838-0000004ac7ff", + "first_name": "Charlotte", + "last_name": "Berger" + }, + { + "id": "99999999-007a-0007-666f-0000004b6636", + "first_name": "Leon", + "last_name": "Neumann" + }, + { + "id": "99999999-007b-0007-04a7-0000004c046d", + "first_name": "Jonah", + "last_name": "Wagner" + } + ] + }, + { + "id": "bbbbbbbb-0009-0000-8ff3-000000058fef", + "name": "Basketball Group B", + "description": "Basketball Group B squad.", + "created_at": "2020-05-08", + "address": "Sonnenweg 93, 80333 München", + "sport": "Basketball", + "trainers": [ + { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + } + ], + "trainees": [ + { + "id": "99999999-007c-0007-a2de-0000004ca2a4", + "first_name": "Erik", + "last_name": "Scholz" + }, + { + "id": "99999999-007d-0007-4116-0000004d40db", + "first_name": "Mia", + "last_name": "Neumann" + }, + { + "id": "99999999-007e-0007-df4d-0000004ddf12", + "first_name": "Elias", + "last_name": "Diaz" + }, + { + "id": "99999999-007f-0007-7d85-0000004e7d49", + "first_name": "Tilda", + "last_name": "Neumann" + }, + { + "id": "99999999-0080-0008-1bbc-0000004f1b80", + "first_name": "Noah", + "last_name": "Richter" + }, + { + "id": "99999999-0081-0008-b9f4-0000004fb9b7", + "first_name": "Leon", + "last_name": "Busch" + }, + { + "id": "99999999-0082-0008-582b-0000005057ee", + "first_name": "Aaron", + "last_name": "Sauer" + }, + { + "id": "99999999-0083-0008-f663-00000050f625", + "first_name": "Mats", + "last_name": "Sommer" + }, + { + "id": "99999999-0084-0008-949a-00000051945c", + "first_name": "Juna", + "last_name": "Reil" + }, + { + "id": "99999999-0085-0008-32d2-000000523293", + "first_name": "Juna", + "last_name": "Braun" + }, + { + "id": "99999999-0086-0008-d109-00000052d0ca", + "first_name": "Johanna", + "last_name": "Kaiser" + }, + { + "id": "99999999-0087-0008-6f41-000000536f01", + "first_name": "Sofia", + "last_name": "Brandt" + }, + { + "id": "99999999-0088-0008-0d78-000000540d38", + "first_name": "Samuel", + "last_name": "Vogel" + } + ] + }, + { + "id": "bbbbbbbb-000a-0000-2e2a-000000062e26", + "name": "Swimming Juniors", + "description": "Swimming Juniors squad.", + "created_at": "2022-09-13", + "address": "Rosenstraße 77, 80801 München", + "sport": "Swimming", + "trainers": [ + { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + }, + { + "id": "99999999-0012-0001-1fe6-0000000b1fde", + "first_name": "Mats", + "last_name": "Klein" + } + ], + "trainees": [ + { + "id": "99999999-0089-0008-abb0-00000054ab6f", + "first_name": "Hannah", + "last_name": "Pohl" + }, + { + "id": "99999999-008a-0008-49e7-0000005549a6", + "first_name": "Fynn", + "last_name": "Reil" + }, + { + "id": "99999999-008b-0008-e81f-00000055e7dd", + "first_name": "Toni", + "last_name": "Neumann" + }, + { + "id": "99999999-008c-0008-8656-000000568614", + "first_name": "Moritz", + "last_name": "Wolf" + }, + { + "id": "99999999-008d-0008-248e-00000057244b", + "first_name": "Frieda", + "last_name": "Winter" + }, + { + "id": "99999999-008e-0008-c2c5-00000057c282", + "first_name": "Charlotte", + "last_name": "Schwarz" + }, + { + "id": "99999999-008f-0008-60fc-0000005860b9", + "first_name": "Moritz", + "last_name": "Krause" + } + ] + }, + { + "id": "bbbbbbbb-000b-0000-cc62-00000006cc5d", + "name": "Swimming Group A", + "description": "Swimming Group A squad.", + "created_at": "2020-02-08", + "address": "Rosenstraße 77, 80333 München", + "sport": "Swimming", + "trainers": [ + { + "id": "99999999-000d-0000-08d1-0000000808cb", + "first_name": "Coach", + "last_name": "Devoops" + } + ], + "trainees": [ + { + "id": "99999999-0090-0009-ff34-00000058fef0", + "first_name": "Hannah", + "last_name": "Lange" + }, + { + "id": "99999999-0091-0009-9d6b-000000599d27", + "first_name": "Smilla", + "last_name": "Busch" + }, + { + "id": "99999999-0092-0009-3ba3-0000005a3b5e", + "first_name": "Ida", + "last_name": "Neumann" + }, + { + "id": "99999999-0093-0009-d9da-0000005ad995", + "first_name": "Finn", + "last_name": "Vogel" + }, + { + "id": "99999999-0094-0009-7812-0000005b77cc", + "first_name": "Greta", + "last_name": "Pohl" + }, + { + "id": "99999999-0095-0009-1649-0000005c1603", + "first_name": "Lea", + "last_name": "Park" + }, + { + "id": "99999999-0096-0009-b481-0000005cb43a", + "first_name": "Frieda", + "last_name": "Richter" + }, + { + "id": "99999999-0097-0009-52b8-0000005d5271", + "first_name": "Stella", + "last_name": "Krüger" + }, + { + "id": "99999999-0098-0009-f0f0-0000005df0a8", + "first_name": "Aaron", + "last_name": "Sommer" + }, + { + "id": "99999999-0099-0009-8f27-0000005e8edf", + "first_name": "Bela", + "last_name": "Arnold" + }, + { + "id": "99999999-009a-0009-2d5f-0000005f2d16", + "first_name": "Mathilda", + "last_name": "Kaiser" + }, + { + "id": "99999999-009b-0009-cb96-0000005fcb4d", + "first_name": "Jonas", + "last_name": "Krause" + }, + { + "id": "99999999-009c-0009-69ce-000000606984", + "first_name": "Carla", + "last_name": "Albrecht" + }, + { + "id": "99999999-009d-0009-0805-0000006107bb", + "first_name": "Lena", + "last_name": "Kaiser" + }, + { + "id": "99999999-009e-0009-a63d-00000061a5f2", + "first_name": "Joris", + "last_name": "Schulz" + }, + { + "id": "99999999-009f-0009-4474-000000624429", + "first_name": "Wilma", + "last_name": "Otto" + }, + { + "id": "99999999-00a0-000a-e2ac-00000062e260", + "first_name": "Jonah", + "last_name": "Peters" + }, + { + "id": "99999999-00a1-000a-80e3-000000638097", + "first_name": "Amelie", + "last_name": "Lange" + }, + { + "id": "99999999-00a2-000a-1f1b-000000641ece", + "first_name": "Jonas", + "last_name": "Nowak" + }, + { + "id": "99999999-00a3-000a-bd52-00000064bd05", + "first_name": "Emil", + "last_name": "Krause" + }, + { + "id": "99999999-00a4-000a-5b89-000000655b3c", + "first_name": "Smilla", + "last_name": "Hoffmann" + } + ] + }, + { + "id": "bbbbbbbb-000c-0000-6a99-000000076a94", + "name": "Swimming Group B", + "description": "Swimming Group B squad.", + "created_at": "2024-08-24", + "address": "Kirchplatz 46, 80333 München", + "sport": "Swimming", + "trainers": [ + { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + }, + { + "id": "99999999-000f-0000-4540-000000094539", + "first_name": "Mara", + "last_name": "Koch" + } + ], + "trainees": [ + { + "id": "99999999-00a5-000a-f9c1-00000065f973", + "first_name": "Toni", + "last_name": "Huber" + }, + { + "id": "99999999-00a6-000a-97f8-0000006697aa", + "first_name": "Jan", + "last_name": "Lange" + }, + { + "id": "99999999-00a7-000a-3630-0000006735e1", + "first_name": "Carla", + "last_name": "Arnold" + }, + { + "id": "99999999-00a8-000a-d467-00000067d418", + "first_name": "Noah", + "last_name": "Braun" + }, + { + "id": "99999999-00a9-000a-729f-00000068724f", + "first_name": "Alma", + "last_name": "Busch" + }, + { + "id": "99999999-00aa-000a-10d6-000000691086", + "first_name": "Bela", + "last_name": "Klein" + }, + { + "id": "99999999-00ab-000a-af0e-00000069aebd", + "first_name": "Bruno", + "last_name": "Berger" + }, + { + "id": "99999999-00ac-000a-4d45-0000006a4cf4", + "first_name": "Romy", + "last_name": "Beck" + }, + { + "id": "99999999-00ad-000a-eb7d-0000006aeb2b", + "first_name": "Joris", + "last_name": "Hoffmann" + } + ] + }, + { + "id": "bbbbbbbb-000d-0000-08d1-0000000808cb", + "name": "Swimming Seniors", + "description": "Swimming Seniors squad.", + "created_at": "2024-10-28", + "address": "Birkenallee 88, 80333 München", + "sport": "Swimming", + "trainers": [ + { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + ], + "trainees": [ + { + "id": "99999999-00ae-000a-89b4-0000006b8962", + "first_name": "Jonah", + "last_name": "König" + }, + { + "id": "99999999-00af-000a-27ec-0000006c2799", + "first_name": "Emil", + "last_name": "Stein" + }, + { + "id": "99999999-00b0-000b-c623-0000006cc5d0", + "first_name": "Mira", + "last_name": "Kaiser" + }, + { + "id": "99999999-00b1-000b-645b-0000006d6407", + "first_name": "Elias", + "last_name": "Braun" + }, + { + "id": "99999999-00b2-000b-0292-0000006e023e", + "first_name": "Noah", + "last_name": "Beck" + }, + { + "id": "99999999-00b3-000b-a0ca-0000006ea075", + "first_name": "David", + "last_name": "Klein" + }, + { + "id": "99999999-00b4-000b-3f01-0000006f3eac", + "first_name": "Leon", + "last_name": "Berger" + } + ] + }, + { + "id": "bbbbbbbb-000e-0000-a708-00000008a702", + "name": "Swimming Squad 1", + "description": "Swimming Squad 1 squad.", + "created_at": "2021-05-05", + "address": "Sonnenweg 24, 80636 München", + "sport": "Swimming", + "trainers": [ + { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + }, + { + "id": "99999999-0006-0000-b54c-00000003b54a", + "first_name": "Erik", + "last_name": "Berger" + } + ], + "trainees": [ + { + "id": "99999999-00b5-000b-dd39-0000006fdce3", + "first_name": "Marco", + "last_name": "Bauer" + }, + { + "id": "99999999-00b6-000b-7b70-000000707b1a", + "first_name": "Finn", + "last_name": "Neumann" + }, + { + "id": "99999999-00b7-000b-19a7-000000711951", + "first_name": "Konrad", + "last_name": "Klein" + }, + { + "id": "99999999-00b8-000b-b7df-00000071b788", + "first_name": "Ben", + "last_name": "Frank" + }, + { + "id": "99999999-00b9-000b-5616-0000007255bf", + "first_name": "Frida", + "last_name": "Brandt" + }, + { + "id": "99999999-00ba-000b-f44e-00000072f3f6", + "first_name": "Lea", + "last_name": "Brandt" + }, + { + "id": "99999999-00bb-000b-9285-00000073922d", + "first_name": "Sofia", + "last_name": "Pohl" + }, + { + "id": "99999999-00bc-000b-30bd-000000743064", + "first_name": "Jonah", + "last_name": "Park" + }, + { + "id": "99999999-00bd-000b-cef4-00000074ce9b", + "first_name": "Mara", + "last_name": "Engel" + }, + { + "id": "99999999-00be-000b-6d2c-000000756cd2", + "first_name": "Emil", + "last_name": "Diaz" + }, + { + "id": "99999999-00bf-000b-0b63-000000760b09", + "first_name": "David", + "last_name": "Braun" + }, + { + "id": "99999999-00c0-000c-a99b-00000076a940", + "first_name": "Aaron", + "last_name": "Hoffmann" + } + ] + }, + { + "id": "bbbbbbbb-000f-0000-4540-000000094539", + "name": "Athletics Group A", + "description": "Athletics Group A squad.", + "created_at": "2022-09-24", + "address": "Lindenstraße 37, 81667 München", + "sport": "Athletics", + "trainers": [ + { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + } + ], + "trainees": [ + { + "id": "99999999-00c1-000c-47d2-000000774777", + "first_name": "Emil", + "last_name": "Schwarz" + }, + { + "id": "99999999-00c2-000c-e60a-00000077e5ae", + "first_name": "Bela", + "last_name": "Kaiser" + }, + { + "id": "99999999-00c3-000c-8441-0000007883e5", + "first_name": "Rosa", + "last_name": "Frank" + }, + { + "id": "99999999-00c4-000c-2279-00000079221c", + "first_name": "Frida", + "last_name": "Neumann" + }, + { + "id": "99999999-00c5-000c-c0b0-00000079c053", + "first_name": "Clara", + "last_name": "Hartmann" + }, + { + "id": "99999999-00c6-000c-5ee8-0000007a5e8a", + "first_name": "Edda", + "last_name": "Vogt" + }, + { + "id": "99999999-00c7-000c-fd1f-0000007afcc1", + "first_name": "Leon", + "last_name": "Beck" + }, + { + "id": "99999999-00c8-000c-9b57-0000007b9af8", + "first_name": "Emil", + "last_name": "Klein" + }, + { + "id": "99999999-00c9-000c-398e-0000007c392f", + "first_name": "Jonas", + "last_name": "Stein" + }, + { + "id": "99999999-00ca-000c-d7c6-0000007cd766", + "first_name": "Nele", + "last_name": "Seidel" + }, + { + "id": "99999999-00cb-000c-75fd-0000007d759d", + "first_name": "Moritz", + "last_name": "Busch" + }, + { + "id": "99999999-00cc-000c-1434-0000007e13d4", + "first_name": "Rosa", + "last_name": "Klein" + }, + { + "id": "99999999-00cd-000c-b26c-0000007eb20b", + "first_name": "Samuel", + "last_name": "Winter" + }, + { + "id": "99999999-00ce-000c-50a3-0000007f5042", + "first_name": "Bruno", + "last_name": "Hartmann" + }, + { + "id": "99999999-00cf-000c-eedb-0000007fee79", + "first_name": "Toni", + "last_name": "Krause" + }, + { + "id": "99999999-00d0-000d-8d12-000000808cb0", + "first_name": "Lotte", + "last_name": "Richter" + } + ] + }, + { + "id": "bbbbbbbb-0010-0001-e377-00000009e370", + "name": "Athletics Development", + "description": "Athletics Development squad.", + "created_at": "2019-10-14", + "address": "Birkenallee 116, 80331 München", + "sport": "Athletics", + "trainers": [ + { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + } + ], + "trainees": [ + { + "id": "99999999-00d1-000d-2b4a-000000812ae7", + "first_name": "Lotte", + "last_name": "Frank" + }, + { + "id": "99999999-00d2-000d-c981-00000081c91e", + "first_name": "Mara", + "last_name": "Seidel" + }, + { + "id": "99999999-00d3-000d-67b9-000000826755", + "first_name": "Ella", + "last_name": "Pohl" + }, + { + "id": "99999999-00d4-000d-05f0-00000083058c", + "first_name": "Martha", + "last_name": "Engel" + }, + { + "id": "99999999-00d5-000d-a428-00000083a3c3", + "first_name": "Alma", + "last_name": "Vogel" + }, + { + "id": "99999999-00d6-000d-425f-0000008441fa", + "first_name": "Nele", + "last_name": "Scholz" + }, + { + "id": "99999999-00d7-000d-e097-00000084e031", + "first_name": "Oskar", + "last_name": "Stein" + }, + { + "id": "99999999-00d8-000d-7ece-000000857e68", + "first_name": "Juna", + "last_name": "Diaz" + }, + { + "id": "99999999-00d9-000d-1d06-000000861c9f", + "first_name": "Wilma", + "last_name": "Stein" + }, + { + "id": "99999999-00da-000d-bb3d-00000086bad6", + "first_name": "Fynn", + "last_name": "Hoffmann" + }, + { + "id": "99999999-00db-000d-5975-00000087590d", + "first_name": "Ida", + "last_name": "Vogel" + }, + { + "id": "99999999-00dc-000d-f7ac-00000087f744", + "first_name": "Levi", + "last_name": "Beck" + }, + { + "id": "99999999-00dd-000d-95e4-00000088957b", + "first_name": "Felix", + "last_name": "Krause" + }, + { + "id": "99999999-00de-000d-341b-0000008933b2", + "first_name": "Helena", + "last_name": "Koch" + }, + { + "id": "99999999-00df-000d-d253-00000089d1e9", + "first_name": "Toni", + "last_name": "Seidel" + }, + { + "id": "99999999-00e0-000e-708a-0000008a7020", + "first_name": "Nele", + "last_name": "Braun" + }, + { + "id": "99999999-00e1-000e-0ec1-0000008b0e57", + "first_name": "Ella", + "last_name": "Nowak" + }, + { + "id": "99999999-00e2-000e-acf9-0000008bac8e", + "first_name": "Ben", + "last_name": "Busch" + } + ] + }, + { + "id": "bbbbbbbb-0011-0001-81af-0000000a81a7", + "name": "Athletics Varsity", + "description": "Athletics Varsity squad.", + "created_at": "2024-10-07", + "address": "Schulstraße 53, 80333 München", + "sport": "Athletics", + "trainers": [ + { + "id": "99999999-0010-0001-e377-00000009e370", + "first_name": "Wilma", + "last_name": "Vogt" + } + ], + "trainees": [ + { + "id": "99999999-00e3-000e-4b30-0000008c4ac5", + "first_name": "Nele", + "last_name": "Brandt" + }, + { + "id": "99999999-00e4-000e-e968-0000008ce8fc", + "first_name": "Jonah", + "last_name": "Frank" + }, + { + "id": "99999999-00e5-000e-879f-0000008d8733", + "first_name": "Aaron", + "last_name": "Arnold" + }, + { + "id": "99999999-00e6-000e-25d7-0000008e256a", + "first_name": "Romi", + "last_name": "König" + }, + { + "id": "99999999-00e7-000e-c40e-0000008ec3a1", + "first_name": "Amelie", + "last_name": "Seidel" + }, + { + "id": "99999999-00e8-000e-6246-0000008f61d8", + "first_name": "Lea", + "last_name": "Stein" + }, + { + "id": "99999999-00e9-000e-007d-00000090000f", + "first_name": "Arne", + "last_name": "Horn" + }, + { + "id": "99999999-00ea-000e-9eb5-000000909e46", + "first_name": "Mira", + "last_name": "Klein" + }, + { + "id": "99999999-00eb-000e-3cec-000000913c7d", + "first_name": "Emil", + "last_name": "Sauer" + }, + { + "id": "99999999-00ec-000e-db24-00000091dab4", + "first_name": "Romi", + "last_name": "Park" + }, + { + "id": "99999999-00ed-000e-795b-0000009278eb", + "first_name": "Mats", + "last_name": "Horn" + }, + { + "id": "99999999-00ee-000e-1793-000000931722", + "first_name": "Lina", + "last_name": "Krüger" + }, + { + "id": "99999999-00ef-000e-b5ca-00000093b559", + "first_name": "Henry", + "last_name": "Hartmann" + }, + { + "id": "99999999-00f0-000f-5402-000000945390", + "first_name": "Jonah", + "last_name": "Braun" + }, + { + "id": "99999999-00f1-000f-f239-00000094f1c7", + "first_name": "Charlotte", + "last_name": "Ziegler" + }, + { + "id": "99999999-00f2-000f-9071-000000958ffe", + "first_name": "Rosa", + "last_name": "Brandt" + }, + { + "id": "99999999-00f3-000f-2ea8-000000962e35", + "first_name": "Marie", + "last_name": "Nowak" + }, + { + "id": "99999999-00f4-000f-ccdf-00000096cc6c", + "first_name": "Stella", + "last_name": "Frank" + } + ] + }, + { + "id": "bbbbbbbb-0012-0001-1fe6-0000000b1fde", + "name": "Athletics Masters", + "description": "Athletics Masters squad.", + "created_at": "2021-03-22", + "address": "Birkenallee 84, 80469 München", + "sport": "Athletics", + "trainers": [ + { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + ], + "trainees": [ + { + "id": "99999999-00f5-000f-6b17-000000976aa3", + "first_name": "Til", + "last_name": "Lehmann" + }, + { + "id": "99999999-00f6-000f-094e-0000009808da", + "first_name": "Anton", + "last_name": "Vogt" + }, + { + "id": "99999999-00f7-000f-a786-00000098a711", + "first_name": "Marco", + "last_name": "Krüger" + }, + { + "id": "99999999-00f8-000f-45bd-000000994548", + "first_name": "Til", + "last_name": "Bauer" + }, + { + "id": "99999999-00f9-000f-e3f5-00000099e37f", + "first_name": "Joris", + "last_name": "Huber" + }, + { + "id": "99999999-00fa-000f-822c-0000009a81b6", + "first_name": "Mara", + "last_name": "Vogel" + }, + { + "id": "99999999-00fb-000f-2064-0000009b1fed", + "first_name": "Martha", + "last_name": "Vogel" + }, + { + "id": "99999999-00fc-000f-be9b-0000009bbe24", + "first_name": "Mats", + "last_name": "Kaiser" + }, + { + "id": "99999999-00fd-000f-5cd3-0000009c5c5b", + "first_name": "Linus", + "last_name": "Hartmann" + }, + { + "id": "99999999-00fe-000f-fb0a-0000009cfa92", + "first_name": "Erik", + "last_name": "Schulz" + }, + { + "id": "99999999-00ff-000f-9942-0000009d98c9", + "first_name": "Ida", + "last_name": "Kaiser" + }, + { + "id": "99999999-0100-0010-3779-0000009e3700", + "first_name": "Felix", + "last_name": "Brandt" + }, + { + "id": "99999999-0101-0010-d5b1-0000009ed537", + "first_name": "Clara", + "last_name": "Pohl" + }, + { + "id": "99999999-0102-0010-73e8-0000009f736e", + "first_name": "Niklas", + "last_name": "Fuchs" + }, + { + "id": "99999999-0103-0010-1220-000000a011a5", + "first_name": "Leon", + "last_name": "Roth" + }, + { + "id": "99999999-0104-0010-b057-000000a0afdc", + "first_name": "Alma", + "last_name": "Roth" + }, + { + "id": "99999999-0105-0010-4e8f-000000a14e13", + "first_name": "Levi", + "last_name": "Kaiser" + }, + { + "id": "99999999-0106-0010-ecc6-000000a1ec4a", + "first_name": "Nele", + "last_name": "Kaiser" + }, + { + "id": "99999999-0107-0010-8afe-000000a28a81", + "first_name": "Greta", + "last_name": "Sommer" + }, + { + "id": "99999999-0108-0010-2935-000000a328b8", + "first_name": "Helena", + "last_name": "Park" + }, + { + "id": "99999999-0109-0010-c76c-000000a3c6ef", + "first_name": "Alma", + "last_name": "Frank" + } + ] + }, + { + "id": "bbbbbbbb-0013-0001-be1e-0000000bbe15", + "name": "Volleyball Juniors", + "description": "Volleyball Juniors squad.", + "created_at": "2024-06-15", + "address": "Birkenallee 28, 80538 München", + "sport": "Volleyball", + "trainers": [ + { + "id": "99999999-000a-0000-2e2a-000000062e26", + "first_name": "Ella", + "last_name": "Frank" + }, + { + "id": "99999999-000c-0000-6a99-000000076a94", + "first_name": "Liv", + "last_name": "Scholz" + } + ], + "trainees": [ + { + "id": "99999999-010a-0010-65a4-000000a46526", + "first_name": "Ida", + "last_name": "Voigt" + }, + { + "id": "99999999-010b-0010-03db-000000a5035d", + "first_name": "Theo", + "last_name": "Roth" + }, + { + "id": "99999999-010c-0010-a213-000000a5a194", + "first_name": "Joris", + "last_name": "Krause" + }, + { + "id": "99999999-010d-0010-404a-000000a63fcb", + "first_name": "Mia", + "last_name": "Braun" + }, + { + "id": "99999999-010e-0010-de82-000000a6de02", + "first_name": "Magda", + "last_name": "Bauer" + }, + { + "id": "99999999-010f-0010-7cb9-000000a77c39", + "first_name": "Martha", + "last_name": "Diaz" + }, + { + "id": "99999999-0110-0011-1af1-000000a81a70", + "first_name": "Mira", + "last_name": "Roth" + }, + { + "id": "99999999-0111-0011-b928-000000a8b8a7", + "first_name": "Romy", + "last_name": "Park" + } + ] + }, + { + "id": "bbbbbbbb-0014-0001-5c55-0000000c5c4c", + "name": "Volleyball Squad 1", + "description": "Volleyball Squad 1 squad.", + "created_at": "2022-04-11", + "address": "Uferweg 19, 80333 München", + "sport": "Volleyball", + "trainers": [ + { + "id": "99999999-0007-0000-5384-000000045381", + "first_name": "Lina", + "last_name": "Zimmermann" + } + ], + "trainees": [ + { + "id": "99999999-0112-0011-5760-000000a956de", + "first_name": "Paul", + "last_name": "Reil" + }, + { + "id": "99999999-0113-0011-f597-000000a9f515", + "first_name": "Nora", + "last_name": "Diaz" + }, + { + "id": "99999999-0114-0011-93cf-000000aa934c", + "first_name": "Samuel", + "last_name": "Koch" + }, + { + "id": "99999999-0115-0011-3206-000000ab3183", + "first_name": "Wilma", + "last_name": "Braun" + }, + { + "id": "99999999-0116-0011-d03e-000000abcfba", + "first_name": "Pia", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0117-0011-6e75-000000ac6df1", + "first_name": "Sofia", + "last_name": "Wolf" + }, + { + "id": "99999999-0118-0011-0cad-000000ad0c28", + "first_name": "Joris", + "last_name": "Arnold" + }, + { + "id": "99999999-0119-0011-aae4-000000adaa5f", + "first_name": "Elias", + "last_name": "Busch" + }, + { + "id": "99999999-011a-0011-491c-000000ae4896", + "first_name": "Jonah", + "last_name": "Diaz" + }, + { + "id": "99999999-011b-0011-e753-000000aee6cd", + "first_name": "Mats", + "last_name": "Fuchs" + }, + { + "id": "99999999-011c-0011-858b-000000af8504", + "first_name": "Greta", + "last_name": "Koch" + }, + { + "id": "99999999-011d-0011-23c2-000000b0233b", + "first_name": "Janne", + "last_name": "Vogel" + }, + { + "id": "99999999-011e-0011-c1f9-000000b0c172", + "first_name": "Amelie", + "last_name": "Wolf" + }, + { + "id": "99999999-011f-0011-6031-000000b15fa9", + "first_name": "Leon", + "last_name": "Sommer" + }, + { + "id": "99999999-0120-0012-fe68-000000b1fde0", + "first_name": "Lea", + "last_name": "Engel" + }, + { + "id": "99999999-0121-0012-9ca0-000000b29c17", + "first_name": "Stella", + "last_name": "Braun" + }, + { + "id": "99999999-0122-0012-3ad7-000000b33a4e", + "first_name": "Helena", + "last_name": "König" + }, + { + "id": "99999999-0123-0012-d90f-000000b3d885", + "first_name": "Edda", + "last_name": "Nowak" + }, + { + "id": "99999999-0124-0012-7746-000000b476bc", + "first_name": "Nora", + "last_name": "Hoffmann" + }, + { + "id": "99999999-0125-0012-157e-000000b514f3", + "first_name": "Nele", + "last_name": "Krause" + }, + { + "id": "99999999-0126-0012-b3b5-000000b5b32a", + "first_name": "Johanna", + "last_name": "Frank" + }, + { + "id": "99999999-0127-0012-51ed-000000b65161", + "first_name": "Emil", + "last_name": "Schulz" + } + ] + }, + { + "id": "bbbbbbbb-0015-0001-fa8c-0000000cfa83", + "name": "Volleyball Squad 2", + "description": "Volleyball Squad 2 squad.", + "created_at": "2024-10-15", + "address": "Bergstraße 75, 80333 München", + "sport": "Volleyball", + "trainers": [ + { + "id": "99999999-0011-0001-81af-0000000a81a7", + "first_name": "Niklas", + "last_name": "Engel" + } + ], + "trainees": [ + { + "id": "99999999-0128-0012-f024-000000b6ef98", + "first_name": "Linus", + "last_name": "Scholz" + }, + { + "id": "99999999-0129-0012-8e5c-000000b78dcf", + "first_name": "Luca", + "last_name": "Schulz" + }, + { + "id": "99999999-012a-0012-2c93-000000b82c06", + "first_name": "Clara", + "last_name": "Voigt" + }, + { + "id": "99999999-012b-0012-cacb-000000b8ca3d", + "first_name": "Noah", + "last_name": "Schulz" + }, + { + "id": "99999999-012c-0012-6902-000000b96874", + "first_name": "Linus", + "last_name": "Graf" + }, + { + "id": "99999999-012d-0012-073a-000000ba06ab", + "first_name": "Mats", + "last_name": "Voigt" + }, + { + "id": "99999999-012e-0012-a571-000000baa4e2", + "first_name": "Janne", + "last_name": "Albrecht" + }, + { + "id": "99999999-012f-0012-43a9-000000bb4319", + "first_name": "Nora", + "last_name": "Bauer" + }, + { + "id": "99999999-0130-0013-e1e0-000000bbe150", + "first_name": "Luca", + "last_name": "Wolf" + } + ] + }, + { + "id": "bbbbbbbb-0016-0001-98c4-0000000d98ba", + "name": "Volleyball U16", + "description": "Volleyball U16 squad.", + "created_at": "2021-09-20", + "address": "Rosenstraße 25, 80331 München", + "sport": "Volleyball", + "trainers": [ + { + "id": "99999999-0009-0000-8ff3-000000058fef", + "first_name": "Magda", + "last_name": "Huber" + }, + { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + } + ], + "trainees": [ + { + "id": "99999999-0131-0013-8017-000000bc7f87", + "first_name": "Ada", + "last_name": "Kaiser" + }, + { + "id": "99999999-0132-0013-1e4f-000000bd1dbe", + "first_name": "Emil", + "last_name": "Engel" + }, + { + "id": "99999999-0133-0013-bc86-000000bdbbf5", + "first_name": "Max", + "last_name": "Ziegler" + }, + { + "id": "99999999-0134-0013-5abe-000000be5a2c", + "first_name": "Linus", + "last_name": "Vogt" + }, + { + "id": "99999999-0135-0013-f8f5-000000bef863", + "first_name": "Romi", + "last_name": "Vogt" + }, + { + "id": "99999999-0136-0013-972d-000000bf969a", + "first_name": "Moritz", + "last_name": "Albrecht" + }, + { + "id": "99999999-0137-0013-3564-000000c034d1", + "first_name": "Juna", + "last_name": "Schulz" + }, + { + "id": "99999999-0138-0013-d39c-000000c0d308", + "first_name": "Rosa", + "last_name": "Koch" + }, + { + "id": "99999999-0139-0013-71d3-000000c1713f", + "first_name": "Janne", + "last_name": "Park" + }, + { + "id": "99999999-013a-0013-100b-000000c20f76", + "first_name": "Romy", + "last_name": "Sauer" + }, + { + "id": "99999999-013b-0013-ae42-000000c2adad", + "first_name": "Lina", + "last_name": "Beck" + }, + { + "id": "99999999-013c-0013-4c7a-000000c34be4", + "first_name": "Theo", + "last_name": "Hoffmann" + }, + { + "id": "99999999-013d-0013-eab1-000000c3ea1b", + "first_name": "Alma", + "last_name": "Klein" + }, + { + "id": "99999999-013e-0013-88e9-000000c48852", + "first_name": "Martha", + "last_name": "Lange" + }, + { + "id": "99999999-013f-0013-2720-000000c52689", + "first_name": "Levi", + "last_name": "Brandt" + }, + { + "id": "99999999-0140-0014-c558-000000c5c4c0", + "first_name": "Mats", + "last_name": "Hartmann" + }, + { + "id": "99999999-0141-0014-638f-000000c662f7", + "first_name": "Amelie", + "last_name": "Diaz" + }, + { + "id": "99999999-0142-0014-01c7-000000c7012e", + "first_name": "Anton", + "last_name": "Braun" + }, + { + "id": "99999999-0143-0014-9ffe-000000c79f65", + "first_name": "Emil", + "last_name": "Busch" + } + ] + }, + { + "id": "bbbbbbbb-0017-0001-36fb-0000000e36f1", + "name": "Volleyball Varsity", + "description": "Volleyball Varsity squad.", + "created_at": "2024-08-12", + "address": "Uferweg 126, 80636 München", + "sport": "Volleyball", + "trainers": [ + { + "id": "99999999-000e-0000-a708-00000008a702", + "first_name": "Smilla", + "last_name": "Frank" + } + ], + "trainees": [ + { + "id": "99999999-0144-0014-3e36-000000c83d9c", + "first_name": "Fynn", + "last_name": "Bauer" + }, + { + "id": "99999999-0145-0014-dc6d-000000c8dbd3", + "first_name": "David", + "last_name": "Zimmermann" + }, + { + "id": "99999999-0146-0014-7aa4-000000c97a0a", + "first_name": "Noah", + "last_name": "Klein" + }, + { + "id": "99999999-0147-0014-18dc-000000ca1841", + "first_name": "Henry", + "last_name": "Huber" + }, + { + "id": "99999999-0148-0014-b713-000000cab678", + "first_name": "Rosa", + "last_name": "Schulz" + }, + { + "id": "99999999-0149-0014-554b-000000cb54af", + "first_name": "Lotte", + "last_name": "Engel" + }, + { + "id": "99999999-014a-0014-f382-000000cbf2e6", + "first_name": "Samuel", + "last_name": "Wolf" + }, + { + "id": "99999999-014b-0014-91ba-000000cc911d", + "first_name": "Konrad", + "last_name": "Sommer" + }, + { + "id": "99999999-014c-0014-2ff1-000000cd2f54", + "first_name": "Elias", + "last_name": "Wolf" + }, + { + "id": "99999999-014d-0014-ce29-000000cdcd8b", + "first_name": "Konrad", + "last_name": "Beck" + }, + { + "id": "99999999-014e-0014-6c60-000000ce6bc2", + "first_name": "Hannah", + "last_name": "Arnold" + }, + { + "id": "99999999-014f-0014-0a98-000000cf09f9", + "first_name": "Bruno", + "last_name": "Krüger" + }, + { + "id": "99999999-0150-0015-a8cf-000000cfa830", + "first_name": "Luca", + "last_name": "Pohl" + }, + { + "id": "99999999-0151-0015-4707-000000d04667", + "first_name": "Aaron", + "last_name": "Huber" + }, + { + "id": "99999999-0152-0015-e53e-000000d0e49e", + "first_name": "Paul", + "last_name": "Engel" + } + ] + } +] + +/** First team the signed-in member belongs to, for convenience. */ +export const TEAM_U16 = 'bbbbbbbb-0001-0000-9e37-000000009e37' + +/** name -> Sport. */ +export const sportsByName: Record = Object.fromEntries( + sportFixtures.map((s) => [s.name, s]), +) + +/** sport name -> its teams (one-to-many). */ +export const teamsBySport: Record = sportFixtures.reduce( + (acc, s) => { + acc[s.name] = teamFixtures.filter((t) => t.sport === s.name) + return acc + }, + {} as Record, +) + +/** Teams the signed-in member belongs to (trainees are resolved MemberRefs). */ +export const myTeamFixtures: Team[] = teamFixtures.filter((t) => + t.trainees.some((m) => m.id === CURRENT_MEMBER_ID), +) diff --git a/web-client/src/mocks/fixtures/report.ts b/web-client/src/mocks/fixtures/report.ts new file mode 100644 index 0000000..53c738b --- /dev/null +++ b/web-client/src/mocks/fixtures/report.ts @@ -0,0 +1,7 @@ +// Freeform report prose keyed by member id; rendered as markdown. +export const reportTextById: Record = { + "11111111-1111-1111-1111-111111111111": "# Development report — Lena Roth\n\n## Attendance\nLena has attended **10 of 14** sessions this term (71%).\n\n## Technical progress\nCoach feedback over the last month highlights steady improvement in core skills:\n\n- Consistency under pressure is the main *growth area*.\n- Footwork and first touch are trending up.\n- Match awareness noted as a strength.\n\n## Suggested focus\n- Maintain attendance momentum.\n- Dedicate warm-up drills to the highlighted growth area.\n- Revisit in **4 weeks**.", + "99999999-0013-0001-be1e-0000000bbe15": "Development report — Marie Wolf\n\nAttendance\nMarie has attended 10 of 14 sessions this term (71%).\n\nTechnical progress\nCoach feedback over the last month highlights steady improvement in core skills, with consistency under pressure noted as the main growth area.\n\nMatch involvement\nFeatured in recent fixtures with feedback trending positive.\n\nSuggested focus\nMaintain attendance momentum and dedicate warm-up drills to the highlighted growth area. Revisit in 4 weeks.", + "99999999-0014-0001-5c55-0000000c5c4c": "Development report — Linus Koch\n\nAttendance\nLinus has attended 12 of 14 sessions this term (86%).\n\nTechnical progress\nCoach feedback over the last month highlights steady improvement in core skills, with consistency under pressure noted as the main growth area.\n\nMatch involvement\nFeatured in recent fixtures with feedback trending positive.\n\nSuggested focus\nMaintain attendance momentum and dedicate warm-up drills to the highlighted growth area. Revisit in 4 weeks.", + "99999999-0015-0001-fa8c-0000000cfa83": "Development report — Linus Beck\n\nAttendance\nLinus has attended 10 of 14 sessions this term (71%).\n\nTechnical progress\nCoach feedback over the last month highlights steady improvement in core skills, with consistency under pressure noted as the main growth area.\n\nMatch involvement\nFeatured in recent fixtures with feedback trending positive.\n\nSuggested focus\nMaintain attendance momentum and dedicate warm-up drills to the highlighted growth area. Revisit in 4 weeks." +} diff --git a/web-client/src/mocks/scope.test.ts b/web-client/src/mocks/scope.test.ts new file mode 100644 index 0000000..60e3457 --- /dev/null +++ b/web-client/src/mocks/scope.test.ts @@ -0,0 +1,205 @@ +import { describe, expect, it } from 'vitest' + +import type { AuthUser, EventSummary, SportEvent } from '@/types' +import { + balanceFixtures, + eventDetailsById, + eventSummaryFixtures, + feedbackSummaryFixtures, + memberSummaryFixtures, + sportFixtures, + teamFixtures, + transactionFixtures, +} from './fixtures' +import { MOCK_PERSONAS } from './personas' +import { + scopeBalances, + scopeEvents, + scopeFeedback, + scopeMembers, + scopeReport, + scopeTransactions, +} from './scope' + +type EventRow = EventSummary | SportEvent + +const users = { + member: MOCK_PERSONAS.member, + trainer: MOCK_PERSONAS.coach, + director: MOCK_PERSONAS.director, + admin: MOCK_PERSONAS.admin, +} satisfies Record + +function ids(rows: { id: string }[]): string[] { + return rows.map((row) => row.id) +} + +function memberTeamIds(userId: string): Set { + return new Set( + teamFixtures + .filter((team) => team.trainees.some((member) => member.id === userId)) + .map((team) => team.id), + ) +} + +function trainerTeamIds(userId: string): Set { + return new Set( + teamFixtures + .filter((team) => team.trainers.some((trainer) => trainer.id === userId)) + .map((team) => team.id), + ) +} + +function directorSports(userId: string): Set { + return new Set( + sportFixtures + .filter((sport) => sport.directors.some((director) => director.id === userId)) + .map((sport) => sport.name), + ) +} + +function sportTeamIds(sports: Set): Set { + return new Set(teamFixtures.filter((team) => sports.has(team.sport)).map((team) => team.id)) +} + +function teamMemberIds(teamIds: Set): Set { + return new Set( + teamFixtures + .filter((team) => teamIds.has(team.id)) + .flatMap((team) => team.trainees.map((member) => member.id)), + ) +} + +function directorMemberIds(user: AuthUser): Set { + return teamMemberIds(sportTeamIds(directorSports(user.id))) +} + +function trainerMemberIds(user: AuthUser): Set { + return teamMemberIds(trainerTeamIds(user.id)) +} + +function eventCreatorId(row: EventRow): string | undefined { + return 'creator' in row ? row.creator.id : eventDetailsById[row.id]?.creator.id +} + +function eventSports(row: EventRow): string[] { + return 'sports_linked' in row ? (row.sports_linked ?? []) : (eventDetailsById[row.id]?.sports_linked ?? []) +} + +function eventTeamIds(row: EventRow): string[] { + return row.teams_linked?.map((team) => team.id) ?? [] +} + +function firstOutOfScopeMember(memberIds: Set): string { + const found = memberSummaryFixtures.find((member) => !memberIds.has(member.id)) + if (!found) throw new Error('Expected at least one out-of-scope member fixture') + return found.id +} + +describe('scopeFeedback', () => { + it('scopes feedback for every role', () => { + expect(ids(scopeFeedback(feedbackSummaryFixtures, users.admin))).toEqual(ids(feedbackSummaryFixtures)) + expect(ids(scopeFeedback(feedbackSummaryFixtures, users.member))).toEqual( + ids(feedbackSummaryFixtures.filter((row) => row.member.id === users.member.id)), + ) + expect(ids(scopeFeedback(feedbackSummaryFixtures, users.trainer))).toEqual( + ids(feedbackSummaryFixtures.filter((row) => row.creator.id === users.trainer.id)), + ) + expect(scopeFeedback(feedbackSummaryFixtures, users.director)).toEqual([]) + }) +}) + +describe('scopeTransactions', () => { + it('scopes transactions for every role', () => { + const directorIds = directorMemberIds(users.director) + + expect(ids(scopeTransactions(transactionFixtures, users.admin))).toEqual(ids(transactionFixtures)) + expect(ids(scopeTransactions(transactionFixtures, users.member))).toEqual( + ids(transactionFixtures.filter((row) => row.member.id === users.member.id)), + ) + expect(scopeTransactions(transactionFixtures, users.trainer)).toEqual([]) + expect(ids(scopeTransactions(transactionFixtures, users.director))).toEqual( + ids(transactionFixtures.filter((row) => directorIds.has(row.member.id))), + ) + }) +}) + +describe('scopeBalances', () => { + it('scopes balances for every role', () => { + const directorIds = directorMemberIds(users.director) + + expect(scopeBalances(balanceFixtures, users.admin)).toEqual(balanceFixtures) + expect(scopeBalances(balanceFixtures, users.member)).toEqual( + balanceFixtures.filter((row) => row.member.id === users.member.id), + ) + expect(scopeBalances(balanceFixtures, users.trainer)).toEqual([]) + expect(scopeBalances(balanceFixtures, users.director)).toEqual( + balanceFixtures.filter((row) => directorIds.has(row.member.id)), + ) + }) +}) + +describe('scopeEvents', () => { + it('scopes events for every role', () => { + const memberTeams = memberTeamIds(users.member.id) + const trainerTeams = trainerTeamIds(users.trainer.id) + const directorSportNames = directorSports(users.director.id) + const directorTeams = sportTeamIds(directorSportNames) + + expect(ids(scopeEvents(eventSummaryFixtures, users.admin))).toEqual(ids(eventSummaryFixtures)) + expect(ids(scopeEvents(eventSummaryFixtures, users.member))).toEqual( + ids(eventSummaryFixtures.filter((row) => eventTeamIds(row).some((teamId) => memberTeams.has(teamId)))), + ) + expect(ids(scopeEvents(eventSummaryFixtures, users.trainer))).toEqual( + ids( + eventSummaryFixtures.filter( + (row) => + eventCreatorId(row) === users.trainer.id || + eventTeamIds(row).some((teamId) => trainerTeams.has(teamId)), + ), + ), + ) + expect(ids(scopeEvents(eventSummaryFixtures, users.director))).toEqual( + ids( + eventSummaryFixtures.filter( + (row) => + eventSports(row).some((sport) => directorSportNames.has(sport)) || + eventTeamIds(row).some((teamId) => directorTeams.has(teamId)), + ), + ), + ) + }) +}) + +describe('scopeMembers', () => { + it('scopes members for every role', () => { + const trainerIds = trainerMemberIds(users.trainer) + const directorIds = directorMemberIds(users.director) + + expect(ids(scopeMembers(memberSummaryFixtures, users.admin))).toEqual(ids(memberSummaryFixtures)) + expect(ids(scopeMembers(memberSummaryFixtures, users.member))).toEqual([users.member.id]) + expect(ids(scopeMembers(memberSummaryFixtures, users.trainer))).toEqual( + ids(memberSummaryFixtures.filter((row) => trainerIds.has(row.id))), + ) + expect(ids(scopeMembers(memberSummaryFixtures, users.director))).toEqual( + ids(memberSummaryFixtures.filter((row) => directorIds.has(row.id))), + ) + }) +}) + +describe('scopeReport', () => { + it('allows reports for every role according to member scope', () => { + const trainerIds = trainerMemberIds(users.trainer) + const directorIds = directorMemberIds(users.director) + const trainerMemberId = [...trainerIds][0] + const directorMemberId = [...directorIds][0] + + expect(scopeReport(users.member.id, users.admin)).toBe(true) + expect(scopeReport(users.member.id, users.member)).toBe(true) + expect(scopeReport(firstOutOfScopeMember(new Set([users.member.id])), users.member)).toBe(false) + expect(scopeReport(trainerMemberId, users.trainer)).toBe(true) + expect(scopeReport(firstOutOfScopeMember(trainerIds), users.trainer)).toBe(false) + expect(scopeReport(directorMemberId, users.director)).toBe(true) + expect(scopeReport(firstOutOfScopeMember(directorIds), users.director)).toBe(false) + }) +}) diff --git a/web-client/src/mocks/scope.ts b/web-client/src/mocks/scope.ts new file mode 100644 index 0000000..dcf1a22 --- /dev/null +++ b/web-client/src/mocks/scope.ts @@ -0,0 +1,175 @@ +import type { + AuthUser, + Balance, + EventSummary, + FeedbackSummary, + Member, + MemberSummary, + SportEvent, + Transaction, +} from '@/types' +import { eventDetailsById, sportFixtures, teamFixtures } from './fixtures' + +type MemberRow = Member | MemberSummary +type EventRow = EventSummary | SportEvent + +function memberTeamIds(userId: string): Set { + return new Set( + teamFixtures + .filter((team) => team.trainees.some((member) => member.id === userId)) + .map((team) => team.id), + ) +} + +function trainerTeamIds(userId: string): Set { + return new Set( + teamFixtures + .filter((team) => team.trainers.some((trainer) => trainer.id === userId)) + .map((team) => team.id), + ) +} + +function directorSports(userId: string): Set { + return new Set( + sportFixtures + .filter((sport) => sport.directors.some((director) => director.id === userId)) + .map((sport) => sport.name), + ) +} + +function sportTeamIds(sports: Set): Set { + return new Set(teamFixtures.filter((team) => sports.has(team.sport)).map((team) => team.id)) +} + +function teamMemberIds(teamIds: Set): Set { + return new Set( + teamFixtures + .filter((team) => teamIds.has(team.id)) + .flatMap((team) => team.trainees.map((member) => member.id)), + ) +} + +function memberIdsInDirectorScope(user: AuthUser): Set { + return teamMemberIds(sportTeamIds(directorSports(user.id))) +} + +function memberIdsInTrainerScope(user: AuthUser): Set { + return teamMemberIds(trainerTeamIds(user.id)) +} + +function eventHasTeam(row: EventRow, teamIds: Set): boolean { + return row.teams_linked?.some((team) => teamIds.has(team.id)) ?? false +} + +function eventHasSport(row: EventRow, sports: Set): boolean { + if ('sports_linked' in row) { + return row.sports_linked?.some((sport) => sports.has(sport)) ?? false + } + + const detail = eventDetailsById[row.id] + return detail?.sports_linked?.some((sport) => sports.has(sport)) ?? false +} + +function eventCreatorId(row: EventRow): string | undefined { + if ('creator' in row) return row.creator.id + return eventDetailsById[row.id]?.creator.id +} + +function eventInMemberScope(row: EventRow, user: AuthUser): boolean { + return eventHasTeam(row, memberTeamIds(user.id)) +} + +function eventInTrainerScope(row: EventRow, user: AuthUser): boolean { + return eventCreatorId(row) === user.id || eventHasTeam(row, trainerTeamIds(user.id)) +} + +function eventInDirectorScope(row: EventRow, user: AuthUser): boolean { + const sports = directorSports(user.id) + return eventHasSport(row, sports) || eventHasTeam(row, sportTeamIds(sports)) +} + +export function scopeFeedback(rows: T[], user: AuthUser): T[] { + switch (user.role) { + case 'admin': + return rows + case 'trainer': + return rows.filter((row) => row.creator.id === user.id) + case 'member': + return rows.filter((row) => row.member.id === user.id) + case 'director': + return [] + } +} + +export function scopeTransactions(rows: T[], user: AuthUser): T[] { + switch (user.role) { + case 'admin': + return rows + case 'member': + return rows.filter((row) => row.member.id === user.id) + case 'director': { + const memberIds = memberIdsInDirectorScope(user) + return rows.filter((row) => memberIds.has(row.member.id)) + } + case 'trainer': + return [] + } +} + +export function scopeBalances(rows: T[], user: AuthUser): T[] { + switch (user.role) { + case 'admin': + return rows + case 'member': + return rows.filter((row) => row.member.id === user.id) + case 'director': { + const memberIds = memberIdsInDirectorScope(user) + return rows.filter((row) => memberIds.has(row.member.id)) + } + case 'trainer': + return [] + } +} + +export function scopeEvents(rows: T[], user: AuthUser): T[] { + switch (user.role) { + case 'admin': + return rows + case 'member': + return rows.filter((row) => eventInMemberScope(row, user)) + case 'trainer': + return rows.filter((row) => eventInTrainerScope(row, user)) + case 'director': + return rows.filter((row) => eventInDirectorScope(row, user)) + } +} + +export function scopeMembers(rows: T[], user: AuthUser): T[] { + switch (user.role) { + case 'admin': + return rows + case 'member': + return rows.filter((row) => row.id === user.id) + case 'trainer': { + const memberIds = memberIdsInTrainerScope(user) + return rows.filter((row) => memberIds.has(row.id)) + } + case 'director': { + const memberIds = memberIdsInDirectorScope(user) + return rows.filter((row) => memberIds.has(row.id)) + } + } +} + +export function scopeReport(memberId: string, user: AuthUser): boolean { + switch (user.role) { + case 'admin': + return true + case 'member': + return memberId === user.id + case 'trainer': + return memberIdsInTrainerScope(user).has(memberId) + case 'director': + return memberIdsInDirectorScope(user).has(memberId) + } +} diff --git a/web-client/src/types.ts b/web-client/src/types.ts index 1c03b51..d00832b 100644 --- a/web-client/src/types.ts +++ b/web-client/src/types.ts @@ -68,13 +68,15 @@ export type Balance = Omit & { member: MemberRef } +// Role-scoped superset from GET /members/dashboard: sections by entitlement. export interface DashboardAggregate { member: MemberSummary events: EventSummary[] feedback: FeedbackSummary[] balance: Balance - transactions: Transaction[] report: string + sports: Sport[] + teams: Team[] } export type Role = 'member' | 'trainer' | 'director' | 'admin' From afda7e4ce99619980628b3df6aa295332bb9526c Mon Sep 17 00:00:00 2001 From: FadyGergesRezk <84906847+FadyGergesRezk@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:08:28 +0200 Subject: [PATCH 03/15] feat: shared UI components and formatting helpers --- web-client/src/components/ui/badge.tsx | 36 +++++ web-client/src/components/ui/calendar.tsx | 88 ++++++++++ web-client/src/components/ui/data-table.tsx | 40 +++++ .../src/components/ui/date-range-filter.tsx | 97 +++++++++++ web-client/src/components/ui/page-header.tsx | 25 +++ web-client/src/components/ui/popover.tsx | 38 +++++ web-client/src/components/ui/select.tsx | 150 ++++++++++++++++++ web-client/src/components/ui/sidebar.tsx | 44 ++--- web-client/src/components/ui/stat-card.tsx | 27 ++++ .../src/components/ui/table-toolbar.tsx | 72 +++++++++ web-client/src/index.css | 5 +- web-client/src/lib/format.ts | 65 ++++++++ 12 files changed, 664 insertions(+), 23 deletions(-) create mode 100644 web-client/src/components/ui/badge.tsx create mode 100644 web-client/src/components/ui/calendar.tsx create mode 100644 web-client/src/components/ui/data-table.tsx create mode 100644 web-client/src/components/ui/date-range-filter.tsx create mode 100644 web-client/src/components/ui/page-header.tsx create mode 100644 web-client/src/components/ui/popover.tsx create mode 100644 web-client/src/components/ui/select.tsx create mode 100644 web-client/src/components/ui/stat-card.tsx create mode 100644 web-client/src/components/ui/table-toolbar.tsx create mode 100644 web-client/src/lib/format.ts diff --git a/web-client/src/components/ui/badge.tsx b/web-client/src/components/ui/badge.tsx new file mode 100644 index 0000000..8c87a83 --- /dev/null +++ b/web-client/src/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import { cn } from '@/lib/utils' + +type BadgeTone = 'default' | 'positive' | 'negative' | 'accent' +type BadgeSize = 'default' | 'sm' + +const toneClass: Record = { + default: 'bg-muted/70 text-text-secondary', + positive: + 'bg-[oklch(0.55_0.17_145_/_0.16)] text-[oklch(0.5_0.17_145)] dark:text-[oklch(0.72_0.17_145)]', + negative: 'bg-destructive/15 text-destructive', + accent: 'bg-primary/10 text-text-secondary', +} + +const sizeClass: Record = { + default: 'min-h-7 px-2.5 py-1 text-caption font-medium', + sm: 'min-h-6 px-2 py-0.5 text-[0.6875rem] font-medium', +} + +interface BadgeProps extends React.ComponentProps<'span'> { + tone?: BadgeTone + size?: BadgeSize +} + +export function Badge({ tone = 'default', size = 'default', className, ...props }: BadgeProps) { + return ( + + ) +} diff --git a/web-client/src/components/ui/calendar.tsx b/web-client/src/components/ui/calendar.tsx new file mode 100644 index 0000000..aa39128 --- /dev/null +++ b/web-client/src/components/ui/calendar.tsx @@ -0,0 +1,88 @@ +import * as React from 'react' +import { + ChevronDownIcon, + ChevronLeftIcon, + ChevronRightIcon, +} from 'lucide-react' +import { DayPicker, getDefaultClassNames } from 'react-day-picker' + +import { Button, buttonVariants } from '@/components/ui/button' +import { cn } from '@/lib/utils' + +export type CalendarProps = React.ComponentProps + +function Calendar({ + className, + classNames, + showOutsideDays = true, + captionLayout = 'label', + buttonVariant = 'ghost', + ...props +}: CalendarProps & { + buttonVariant?: React.ComponentProps['variant'] +}) { + const defaultClassNames = getDefaultClassNames() + + return ( + button]:bg-primary [&>button]:text-primary-foreground'), + range_end: cn('bg-primary [&>button]:bg-primary [&>button]:text-primary-foreground'), + range_middle: cn('bg-primary/20 [&>button]:bg-transparent [&>button]:!text-foreground'), + selected: cn('[&>button]:bg-primary [&>button]:text-primary-foreground'), + today: cn('[&>button]:border [&>button]:border-primary'), + outside: cn('text-text-tertiary opacity-60'), + disabled: cn('text-text-tertiary opacity-50'), + hidden: cn('invisible'), + ...classNames, + }} + components={{ + Chevron: ({ orientation, className, ...chevronProps }) => { + if (orientation === 'left') { + return + } + + if (orientation === 'right') { + return + } + + return + }, + }} + {...props} + /> + ) +} + +export { Calendar } diff --git a/web-client/src/components/ui/data-table.tsx b/web-client/src/components/ui/data-table.tsx new file mode 100644 index 0000000..d749864 --- /dev/null +++ b/web-client/src/components/ui/data-table.tsx @@ -0,0 +1,40 @@ +import { cn } from '@/lib/utils' + +// Shared table shell; scrolls horizontally before columns collapse too far. +export function DataTable({ className, ...props }: React.ComponentProps<'table'>) { + return ( +
+ + + ) +} + +export function THead({ className, ...props }: React.ComponentProps<'th'>) { + return ( + + ) +} diff --git a/web-client/src/components/ui/date-range-filter.tsx b/web-client/src/components/ui/date-range-filter.tsx new file mode 100644 index 0000000..7ae5f40 --- /dev/null +++ b/web-client/src/components/ui/date-range-filter.tsx @@ -0,0 +1,97 @@ +import { CalendarIcon, XIcon } from 'lucide-react' +import type { DateRange } from 'react-day-picker' + +import { Button } from '@/components/ui/button' +import { Calendar } from '@/components/ui/calendar' +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' +import { cn } from '@/lib/utils' + +interface DateRangeFilterProps { + fromDate: string + toDate: string + onChange: (range: { fromDate: string; toDate: string }) => void + ariaLabel: string +} + +export function DateRangeFilter({ + fromDate, + toDate, + onChange, + ariaLabel, +}: DateRangeFilterProps) { + const hasRange = fromDate !== '' || toDate !== '' + + return ( +
+ + + + + + + onChange({ + fromDate: range?.from ? dateToInputValue(range.from) : '', + toDate: range?.to ? dateToInputValue(range.to) : '', + }) + } + aria-label={ariaLabel} + /> + + + + {hasRange && ( + + )} +
+ ) +} + +function dateToInputValue(date: Date): string { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + + return `${year}-${month}-${day}` +} + +function dateRangeFromFilters(fromDate: string, toDate: string): DateRange | undefined { + if (!fromDate && !toDate) return undefined + + return { + from: fromDate ? new Date(`${fromDate}T00:00:00`) : undefined, + to: toDate ? new Date(`${toDate}T00:00:00`) : undefined, + } +} + +function dateRangeLabel(fromDate: string, toDate: string): string { + if (fromDate && toDate) return `${fromDate} - ${toDate}` + if (fromDate) return `From ${fromDate}` + if (toDate) return `Until ${toDate}` + + return 'Date range' +} diff --git a/web-client/src/components/ui/page-header.tsx b/web-client/src/components/ui/page-header.tsx new file mode 100644 index 0000000..6d42067 --- /dev/null +++ b/web-client/src/components/ui/page-header.tsx @@ -0,0 +1,25 @@ +interface PageHeaderProps { + eyebrow?: string + title: string + subtitle?: string + action?: React.ReactNode +} + +export function PageHeader({ eyebrow, title, subtitle, action }: PageHeaderProps) { + return ( +
+
+ {eyebrow && ( +

+ {eyebrow} +

+ )} +

+ {title} +

+ {subtitle &&

{subtitle}

} +
+ {action &&
{action}
} +
+ ) +} diff --git a/web-client/src/components/ui/popover.tsx b/web-client/src/components/ui/popover.tsx new file mode 100644 index 0000000..9b28551 --- /dev/null +++ b/web-client/src/components/ui/popover.tsx @@ -0,0 +1,38 @@ +import * as React from 'react' +import { Popover as PopoverPrimitive } from 'radix-ui' + +import { cn } from '@/lib/utils' + +function Popover({ ...props }: React.ComponentProps) { + return +} + +function PopoverTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function PopoverContent({ + className, + align = 'start', + sideOffset = 4, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +export { Popover, PopoverContent, PopoverTrigger } diff --git a/web-client/src/components/ui/select.tsx b/web-client/src/components/ui/select.tsx new file mode 100644 index 0000000..2662998 --- /dev/null +++ b/web-client/src/components/ui/select.tsx @@ -0,0 +1,150 @@ +import * as React from 'react' +import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react' +import { Select as SelectPrimitive } from 'radix-ui' + +import { cn } from '@/lib/utils' + +function Select({ ...props }: React.ComponentProps) { + return +} + +function SelectGroup({ ...props }: React.ComponentProps) { + return +} + +function SelectValue({ ...props }: React.ComponentProps) { + return +} + +function SelectTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + span]:truncate', + className, + )} + {...props} + > + {children} + + + + + ) +} + +function SelectScrollUpButton({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function SelectScrollDownButton({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function SelectContent({ + className, + children, + position = 'popper', + ...props +}: React.ComponentProps) { + return ( + + + + {children} + + + + ) +} + +function SelectLabel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function SelectItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function SelectSeparator({ + className, + ...props +}: React.ComponentProps) { + return +} + +export { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectScrollDownButton, + SelectScrollUpButton, + SelectSeparator, + SelectTrigger, + SelectValue, +} diff --git a/web-client/src/components/ui/sidebar.tsx b/web-client/src/components/ui/sidebar.tsx index fe60eec..57fc31a 100644 --- a/web-client/src/components/ui/sidebar.tsx +++ b/web-client/src/components/ui/sidebar.tsx @@ -20,6 +20,7 @@ import { Skeleton } from "@/components/ui/skeleton" import { Tooltip, TooltipContent, + TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" import { PanelLeftIcon } from "lucide-react" @@ -127,23 +128,25 @@ function SidebarProvider({ return ( -
- {children} -
+ +
+ {children} +
+
) } @@ -462,14 +465,17 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
  • [data-sidebar=menu-button]]:mx-auto", + className + )} {...props} /> ) } const sidebarMenuButtonVariants = cva( - "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-none px-3 py-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate", + "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-none px-3 py-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:gap-0 group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground aria-[current=page]:bg-sidebar-accent aria-[current=page]:font-medium aria-[current=page]:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate", { variants: { variant: { diff --git a/web-client/src/components/ui/stat-card.tsx b/web-client/src/components/ui/stat-card.tsx new file mode 100644 index 0000000..f2d247e --- /dev/null +++ b/web-client/src/components/ui/stat-card.tsx @@ -0,0 +1,27 @@ +import { cn } from '@/lib/utils' + +interface StatCardProps { + label: string + value: string + meta?: string + tone?: 'default' | 'positive' | 'negative' +} + +const toneClass: Record, string> = { + default: 'text-text-primary', + positive: 'text-[oklch(0.55_0.17_145)] dark:text-[oklch(0.72_0.17_145)]', + negative: 'text-destructive', +} + +/** KPI tile: small label, prominent value (sans, not display), optional sub-line. */ +export function StatCard({ label, value, meta, tone = 'default' }: StatCardProps) { + return ( +
    +

    {label}

    +

    + {value} +

    + {meta &&

    {meta}

    } +
    + ) +} diff --git a/web-client/src/components/ui/table-toolbar.tsx b/web-client/src/components/ui/table-toolbar.tsx new file mode 100644 index 0000000..15983ef --- /dev/null +++ b/web-client/src/components/ui/table-toolbar.tsx @@ -0,0 +1,72 @@ +import { SearchIcon } from 'lucide-react' +import { useEffect, useId, useState } from 'react' + +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { cn } from '@/lib/utils' + +interface TableToolbarProps { + searchValue: string + onSearchChange: (value: string) => void + searchLabel: string + searchPlaceholder: string + children?: React.ReactNode + className?: string +} + +export function TableToolbar({ + searchValue, + onSearchChange, + searchLabel, + searchPlaceholder, + children, + className, +}: TableToolbarProps) { + const searchId = useId() + const [draftSearch, setDraftSearch] = useState(searchValue) + + useEffect(() => { + const timeout = window.setTimeout(() => onSearchChange(draftSearch), 250) + + return () => window.clearTimeout(timeout) + }, [draftSearch, onSearchChange]) + + return ( +
    +
    {children}
    + +
    + + setDraftSearch(event.target.value)} + /> + +
    +
    + ) +} diff --git a/web-client/src/index.css b/web-client/src/index.css index 0682d5d..d0503f3 100644 --- a/web-client/src/index.css +++ b/web-client/src/index.css @@ -70,7 +70,7 @@ --popover: oklch(0.21 0.006 285.885); --popover-foreground: oklch(0.985 0 0); --primary: oklch(0.768 0.233 130.85); - --primary-foreground: oklch(0.405 0.101 131.063); + --primary-foreground: oklch(1 0 0); --secondary: oklch(0.274 0.006 286.033); --secondary-foreground: oklch(0.985 0 0); --muted: oklch(0.274 0.006 286.033); @@ -227,9 +227,6 @@ body { @apply min-h-screen bg-background font-sans text-foreground antialiased; letter-spacing: -0.01em; - background-image: - radial-gradient(circle at top left, var(--gradient-spot-1), transparent 28%), - radial-gradient(circle at bottom right, var(--gradient-spot-2), transparent 32%); } #root { diff --git a/web-client/src/lib/format.ts b/web-client/src/lib/format.ts new file mode 100644 index 0000000..907696d --- /dev/null +++ b/web-client/src/lib/format.ts @@ -0,0 +1,65 @@ +// Money is integer cents with no currency field; we display the agreed EUR. +const EUR = new Intl.NumberFormat('en-IE', { + style: 'currency', + currency: 'EUR', +}) + +/** -2000 -> "-€20.00". Sign is preserved so charges/credits read correctly. */ +export function formatCents(amountCents: number): string { + return EUR.format(amountCents / 100) +} + +export const formatEuroCents = formatCents + +/** Absolute amount, no sign — for places that show direction separately. */ +export function formatCentsAbs(amountCents: number): string { + return EUR.format(Math.abs(amountCents) / 100) +} + +const DATE = new Intl.DateTimeFormat('en-GB', { + day: '2-digit', + month: 'short', + year: 'numeric', +}) + +const DATE_SHORT = new Intl.DateTimeFormat('en-GB', { + day: '2-digit', + month: 'short', +}) + +const TIME = new Intl.DateTimeFormat('en-GB', { + hour: '2-digit', + minute: '2-digit', + hour12: false, +}) + +const WEEKDAY = new Intl.DateTimeFormat('en-GB', { weekday: 'short' }) + +/** "18 Jun 2026" */ +export function formatDate(iso: string): string { + return DATE.format(new Date(iso)) +} + +/** "18 Jun" */ +export function formatDateShort(iso: string): string { + return DATE_SHORT.format(new Date(iso)) +} + +/** "Sat 21 Jun · 10:00" */ +export function formatDateTime(iso: string): string { + const d = new Date(iso) + return `${WEEKDAY.format(d)} ${DATE_SHORT.format(d)} · ${TIME.format(d)}` +} + +/** "10:00" */ +export function formatTime(iso: string): string { + return TIME.format(new Date(iso)) +} + +/** Whole minutes between two ISO timestamps, e.g. "90 min". */ +export function formatDuration(startIso: string, endIso: string): string { + const minutes = Math.round( + (new Date(endIso).getTime() - new Date(startIso).getTime()) / 60000, + ) + return `${minutes} min` +} From 1bddabdb93cd01dfd984defc7e21b4fce3f2615b Mon Sep 17 00:00:00 2001 From: FadyGergesRezk <84906847+FadyGergesRezk@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:12:46 +0200 Subject: [PATCH 04/15] feat: per-page view-models, stores, and query layers --- .../src/app/pages/api/dashboardQueries.ts | 24 ++ .../app/pages/model/useDashboardViewModel.ts | 254 ++++++++++++++++++ .../src/features/feedback/api/queries.ts | 25 +- .../feedback/model/feedbackUiStore.ts | 53 ++++ .../feedback/model/useFeedbackViewModel.ts | 207 ++++++++++++++ web-client/src/features/helper/api/queries.ts | 14 +- .../helper/model/useReportViewModel.ts | 14 + .../src/features/letters/api/queries.ts | 7 +- .../src/features/members/api/queries.ts | 21 +- .../features/members/model/membersUiStore.ts | 29 ++ .../members/model/useMembersViewModel.ts | 102 +++++++ .../src/features/organization/api/queries.ts | 46 +++- .../organization/model/useTeamsViewModel.ts | 100 +++++++ .../src/features/payments/api/queries.ts | 45 +++- .../payments/model/paymentsUiStore.ts | 39 +++ .../payments/model/usePaymentsViewModel.ts | 133 +++++++++ .../src/features/sport-events/api/queries.ts | 55 +++- .../sport-events/model/eventsUiStore.ts | 47 ++++ .../model/useEventsViewModel.test.ts | 93 +++++++ .../sport-events/model/useEventsViewModel.ts | 192 +++++++++++++ 20 files changed, 1470 insertions(+), 30 deletions(-) create mode 100644 web-client/src/app/pages/api/dashboardQueries.ts create mode 100644 web-client/src/app/pages/model/useDashboardViewModel.ts create mode 100644 web-client/src/features/feedback/model/feedbackUiStore.ts create mode 100644 web-client/src/features/feedback/model/useFeedbackViewModel.ts create mode 100644 web-client/src/features/helper/model/useReportViewModel.ts create mode 100644 web-client/src/features/members/model/membersUiStore.ts create mode 100644 web-client/src/features/members/model/useMembersViewModel.ts create mode 100644 web-client/src/features/organization/model/useTeamsViewModel.ts create mode 100644 web-client/src/features/payments/model/paymentsUiStore.ts create mode 100644 web-client/src/features/payments/model/usePaymentsViewModel.ts create mode 100644 web-client/src/features/sport-events/model/eventsUiStore.ts create mode 100644 web-client/src/features/sport-events/model/useEventsViewModel.test.ts create mode 100644 web-client/src/features/sport-events/model/useEventsViewModel.ts diff --git a/web-client/src/app/pages/api/dashboardQueries.ts b/web-client/src/app/pages/api/dashboardQueries.ts new file mode 100644 index 0000000..64b59d4 --- /dev/null +++ b/web-client/src/app/pages/api/dashboardQueries.ts @@ -0,0 +1,24 @@ +import { useQuery } from '@tanstack/react-query' + +import { getCurrentUser } from '@/features/auth/currentUser' +import { membersClient } from '@/features/members/api/client' +import { dashboardForUser } from '@/mocks/fixtures/dashboard' +import { mockOr } from '@/mocks/mockSwitch' +import type { DashboardAggregate } from '@/types' + +export const dashboardKeys = { + me: ['dashboard', 'me'] as const, +} + +export function useDashboard(enabled = true) { + return useQuery({ + queryKey: dashboardKeys.me, + staleTime: 30_000, + enabled, + queryFn: () => + mockOr( + () => Promise.resolve(dashboardForUser(getCurrentUser())), + () => membersClient.get('/dashboard').then((r) => r.data), + ), + }) +} diff --git a/web-client/src/app/pages/model/useDashboardViewModel.ts b/web-client/src/app/pages/model/useDashboardViewModel.ts new file mode 100644 index 0000000..4a19f8f --- /dev/null +++ b/web-client/src/app/pages/model/useDashboardViewModel.ts @@ -0,0 +1,254 @@ +import { useMemo } from 'react' + +import { useDashboard } from '@/app/pages/api/dashboardQueries' +import { useAuth } from '@/features/auth' +import { formatCents, formatDateShort, formatTime } from '@/lib/format' +import { memberRefName, type Balance, type EventSummary, type FeedbackSummary, type Role, type Sport, type Team } from '@/types' + +export interface DashboardEventItem { + id: string + name: string + date: string + time: string +} + +export interface DashboardEventsSection { + upcomingCount: number + nextEvent?: DashboardEventItem + items: DashboardEventItem[] +} + +export interface DashboardBalanceSection { + balanceCents: number + balanceFormatted: string + status: 'clear' | 'overdue' +} + +export interface DashboardFeedbackItem { + id: string + from: string + about: string + eventName: string + date: string +} + +export interface DashboardFeedbackSection { + total: number + items: DashboardFeedbackItem[] +} + +export interface DashboardAdminCountsSection { + totalTeams: number + directors: number + trainers: number +} + +export interface DashboardSportTeam { + id: string + name: string + trainers: string + members: number +} + +export interface DashboardSportSection { + name: string + description: string + directors: string + teams: DashboardSportTeam[] +} + +export interface DashboardView { + role: Role + userName: string + myEvents?: DashboardEventsSection + myBalance?: DashboardBalanceSection + myFeedback?: DashboardFeedbackSection + adminCounts?: DashboardAdminCountsSection + sports?: DashboardSportSection[] +} + +export interface DashboardSectionState { + isLoading: boolean + error: Error | null +} + +export interface DashboardViewModel { + view: DashboardView + states: { + myEvents?: DashboardSectionState + myBalance?: DashboardSectionState + myFeedback?: DashboardSectionState + adminCounts?: DashboardSectionState + sports?: DashboardSectionState + } +} + +const DASHBOARD_NOW = new Date('2026-06-19T00:00:00Z') + +// "Recent" = latest N by created_at, no time window (decision 2026-06-26). +const RECENT_FEEDBACK_COUNT = 3 + +function shouldShowEvents(role: Role): boolean { + return role !== 'admin' +} + +function shouldShowBalance(role: Role): boolean { + return role === 'member' || role === 'director' +} + +function shouldShowFeedback(role: Role): boolean { + return role === 'member' || role === 'trainer' +} + +function shouldShowSports(role: Role): boolean { + return role === 'admin' +} + +function eventItem(event: EventSummary): DashboardEventItem { + return { + id: event.id, + name: event.name, + date: formatDateShort(event.start_time), + time: formatTime(event.start_time), + } +} + +function buildEventsSection(events: EventSummary[]): DashboardEventsSection { + const upcoming = events + .filter((event) => new Date(event.start_time) >= DASHBOARD_NOW) + .toSorted((a, b) => new Date(a.start_time).getTime() - new Date(b.start_time).getTime()) + + return { + upcomingCount: upcoming.length, + nextEvent: upcoming[0] ? eventItem(upcoming[0]) : undefined, + items: upcoming.slice(0, 3).map(eventItem), + } +} + +function buildBalanceSection(balance: Balance): DashboardBalanceSection { + const balanceCents = balance.balance_cents + + return { + balanceCents, + balanceFormatted: formatCents(balanceCents), + status: balanceCents < 0 ? 'overdue' : 'clear', + } +} + +function buildFeedbackSection( + feedback: FeedbackSummary[], + events: EventSummary[], + role: Role, + memberId: string, +): DashboardFeedbackSection { + const eventNamesById = new Map(events.map((event) => [event.id, event.name])) + const scopedFeedback = feedback.filter((entry) => + role === 'trainer' ? entry.creator.id === memberId : entry.member.id === memberId, + ) + const items = scopedFeedback + .toSorted((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()) + .slice(0, RECENT_FEEDBACK_COUNT) + .map((entry) => ({ + id: entry.id, + from: memberRefName(entry.creator), + about: memberRefName(entry.member), + eventName: eventNamesById.get(entry.event) ?? 'Unknown event', + date: formatDateShort(entry.created_at), + })) + + return { + total: scopedFeedback.length, + items, + } +} + +function teamSportName(team: Team): string | undefined { + return team.sport +} + +function buildSportsSections(sports: Sport[], teams: Team[]): DashboardSportSection[] { + const teamsBySport = new Map() + + for (const team of teams) { + const sportName = teamSportName(team) + if (!sportName) continue + + teamsBySport.set(sportName, [...(teamsBySport.get(sportName) ?? []), team]) + } + + return sports.map((sport) => ({ + name: sport.name, + description: sport.description, + directors: sport.directors.map(memberRefName).join(', ') || '--', + teams: (teamsBySport.get(sport.name) ?? []).map((team) => ({ + id: team.id, + name: team.name, + trainers: team.trainers.map(memberRefName).join(', ') || '--', + members: team.trainees.length, + })), + })) +} + +function buildAdminCounts(sports: Sport[], teams: Team[]): DashboardAdminCountsSection { + return { + totalTeams: teams.length, + directors: new Set(sports.flatMap((sport) => sport.directors.map((director) => director.id))).size, + trainers: new Set(teams.flatMap((team) => team.trainers.map((trainer) => trainer.id))).size, + } +} + +export function useDashboardViewModel(): DashboardViewModel { + const { user } = useAuth() + const dashboardQuery = useDashboard() + + return useMemo(() => { + const view: DashboardView = { + role: user.role, + userName: user.name, + } + const states: DashboardViewModel['states'] = {} + const data = dashboardQuery.data + const state: DashboardSectionState = { + isLoading: dashboardQuery.isLoading, + error: dashboardQuery.error, + } + + if (shouldShowEvents(user.role)) { + view.myEvents = buildEventsSection(data?.events ?? []) + states.myEvents = state + } + + if (shouldShowBalance(user.role) && data?.balance) { + view.myBalance = buildBalanceSection(data.balance) + states.myBalance = state + } else if (shouldShowBalance(user.role)) { + states.myBalance = state + } + + if (shouldShowFeedback(user.role)) { + view.myFeedback = buildFeedbackSection( + data?.feedback ?? [], + data?.events ?? [], + user.role, + user.id, + ) + states.myFeedback = state + } + + if (shouldShowSports(user.role)) { + view.adminCounts = buildAdminCounts(data?.sports ?? [], data?.teams ?? []) + view.sports = buildSportsSections(data?.sports ?? [], data?.teams ?? []) + states.adminCounts = state + states.sports = state + } + + return { view, states } + }, [ + dashboardQuery.data, + dashboardQuery.error, + dashboardQuery.isLoading, + user.id, + user.name, + user.role, + ]) +} diff --git a/web-client/src/features/feedback/api/queries.ts b/web-client/src/features/feedback/api/queries.ts index d53af6d..7a26cb4 100644 --- a/web-client/src/features/feedback/api/queries.ts +++ b/web-client/src/features/feedback/api/queries.ts @@ -1,5 +1,9 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { getCurrentUser } from '@/features/auth/currentUser' +import { feedbackDetailsById, feedbackSummaryFixtures } from '@/mocks/fixtures' +import { mockOr } from '@/mocks/mockSwitch' +import { scopeFeedback } from '@/mocks/scope' import { feedbackClient } from './client' import type { Feedback, FeedbackCreate, FeedbackPartialUpdate, FeedbackSummary } from '../types' @@ -16,17 +20,32 @@ export function useFeedbackHello() { }) } -export function useFeedbackList() { +export function useFeedbackList(enabled = true) { return useQuery({ queryKey: feedbackKeys.all, - queryFn: () => feedbackClient.get('/').then(r => r.data), + staleTime: 30_000, + enabled, + queryFn: () => + mockOr( + () => Promise.resolve(scopeFeedback(feedbackSummaryFixtures, getCurrentUser())), + () => feedbackClient.get('/').then(r => r.data), + ), }) } export function useFeedback(id: string) { return useQuery({ queryKey: feedbackKeys.detail(id), - queryFn: () => feedbackClient.get(`/${id}`).then(r => r.data), + queryFn: () => + mockOr( + () => { + const found = feedbackDetailsById[id] + const scoped = found ? scopeFeedback([found], getCurrentUser()) : [] + if (!scoped[0]) throw new Error('Feedback not found') + return Promise.resolve(scoped[0]) + }, + () => feedbackClient.get(`/${id}`).then(r => r.data), + ), enabled: !!id, }) } diff --git a/web-client/src/features/feedback/model/feedbackUiStore.ts b/web-client/src/features/feedback/model/feedbackUiStore.ts new file mode 100644 index 0000000..fcc64f5 --- /dev/null +++ b/web-client/src/features/feedback/model/feedbackUiStore.ts @@ -0,0 +1,53 @@ +import { create } from 'zustand' + +export type FeedbackRatingFilter = 'all' | 'high' | 'medium' | 'low' | 'none' +export type FeedbackSort = 'date-desc' | 'date-asc' | 'event-asc' | 'event-desc' | 'rating-desc' | 'rating-asc' + +export interface FeedbackFilters { + search: string + rating: FeedbackRatingFilter + eventId: string + coachId: string + fromDate: string + toDate: string + sort: FeedbackSort +} + +const defaultFilters: FeedbackFilters = { + search: '', + rating: 'all', + eventId: 'all', + coachId: 'all', + fromDate: '', + toDate: '', + sort: 'date-desc', +} + +interface FeedbackUiState { + openFeedbackId: string | null + filters: FeedbackFilters + open: (id: string) => void + close: () => void + setSearch: (search: string) => void + setRating: (rating: FeedbackRatingFilter) => void + setEventId: (eventId: string) => void + setCoachId: (coachId: string) => void + setDateRange: (range: Pick) => void + setSort: (sort: FeedbackSort) => void + resetFilters: () => void +} + +export const useFeedbackUiStore = create((set) => ({ + openFeedbackId: null, + filters: defaultFilters, + open: (id) => set({ openFeedbackId: id }), + close: () => set({ openFeedbackId: null }), + setSearch: (search) => set((state) => ({ filters: { ...state.filters, search } })), + setRating: (rating) => set((state) => ({ filters: { ...state.filters, rating } })), + setEventId: (eventId) => set((state) => ({ filters: { ...state.filters, eventId } })), + setCoachId: (coachId) => set((state) => ({ filters: { ...state.filters, coachId } })), + setDateRange: (range) => + set((state) => ({ filters: { ...state.filters, ...range } })), + setSort: (sort) => set((state) => ({ filters: { ...state.filters, sort } })), + resetFilters: () => set({ filters: defaultFilters }), +})) diff --git a/web-client/src/features/feedback/model/useFeedbackViewModel.ts b/web-client/src/features/feedback/model/useFeedbackViewModel.ts new file mode 100644 index 0000000..3583ca4 --- /dev/null +++ b/web-client/src/features/feedback/model/useFeedbackViewModel.ts @@ -0,0 +1,207 @@ +import { useMemo } from 'react' + +import { useEventsList } from '@/features/sport-events/api/queries' +import { formatDateShort } from '@/lib/format' +import { memberRefName } from '@/types' +import { useFeedback, useFeedbackList } from '../api/queries' +import type { Feedback, FeedbackSummary } from '../types' +import type { FeedbackFilters, FeedbackRatingFilter } from './feedbackUiStore' +import { useFeedbackUiStore } from './feedbackUiStore' + +export interface FeedbackRow { + id: string + eventId: string + coachId: string + memberName: string + creatorName: string + eventName: string + createdAt: string + rating?: number +} + +export interface FeedbackView { + rows: FeedbackRow[] + totalRows: number + hasRatings: boolean + eventOptions: { value: string; label: string }[] + coachOptions: { value: string; label: string }[] + stats: { + total: number + ratedCount: number + avgRatingLabel: string + latestLabel: string + } +} + +export interface FeedbackDetailView { + detail: Feedback | undefined + eventName: string | undefined + memberName: string | undefined + creatorName: string | undefined + rating: number | undefined + isLoading: boolean + error: Error | null +} + +function optionalRating(feedback: object): number | undefined { + const rating = (feedback as { rating?: unknown }).rating + + return typeof rating === 'number' ? rating : undefined +} + +function includesSearch(value: string, search: string): boolean { + return value.toLocaleLowerCase().includes(search) +} + +function matchesRating(rating: number | undefined, filter: FeedbackRatingFilter): boolean { + if (filter === 'all') return true + if (filter === 'none') return rating === undefined + if (rating === undefined) return false + if (filter === 'high') return rating >= 7 + if (filter === 'medium') return rating >= 4 && rating <= 6 + return rating <= 3 +} + +export function filterFeedbackRows( + rows: FeedbackRow[], + filters: FeedbackFilters, +): FeedbackRow[] { + const search = filters.search.trim().toLocaleLowerCase() + const fromTime = filters.fromDate ? new Date(`${filters.fromDate}T00:00:00`).getTime() : null + const toTime = filters.toDate ? new Date(`${filters.toDate}T23:59:59.999`).getTime() : null + + return rows.filter((feedback) => { + const feedbackTime = new Date(feedback.createdAt).getTime() + const matchesText = + search.length === 0 || + includesSearch(feedback.memberName, search) || + includesSearch(feedback.creatorName, search) || + includesSearch(feedback.eventName, search) + + return ( + matchesText && + matchesRating(feedback.rating, filters.rating) && + (filters.eventId === 'all' || feedback.eventId === filters.eventId) && + (filters.coachId === 'all' || feedback.coachId === filters.coachId) && + (fromTime === null || feedbackTime >= fromTime) && + (toTime === null || feedbackTime <= toTime) + ) + }) +} + +function sortFeedbackRows(rows: FeedbackRow[], sort: FeedbackFilters['sort']): FeedbackRow[] { + return rows.toSorted((a, b) => { + if (sort === 'date-asc') { + return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime() + } + if (sort === 'event-asc') { + return a.eventName.localeCompare(b.eventName) + } + if (sort === 'event-desc') { + return b.eventName.localeCompare(a.eventName) + } + if (sort === 'rating-desc') { + return (b.rating ?? -1) - (a.rating ?? -1) + } + if (sort === 'rating-asc') { + return (a.rating ?? 11) - (b.rating ?? 11) + } + + return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() + }) +} + +export function buildFeedbackView( + summaries: FeedbackSummary[], + eventNamesById: Map, + filters: FeedbackFilters, +): FeedbackView { + const rows = summaries.map((feedback) => ({ + id: feedback.id, + eventId: feedback.event, + coachId: feedback.creator.id, + memberName: memberRefName(feedback.member), + creatorName: memberRefName(feedback.creator), + eventName: eventNamesById.get(feedback.event) ?? 'Unknown event', + createdAt: feedback.created_at, + rating: optionalRating(feedback), + })) + const eventOptions = Array.from( + new Map(rows.map((row) => [row.eventId, row.eventName])).entries(), + ([value, label]) => ({ value, label }), + ).toSorted((a, b) => a.label.localeCompare(b.label)) + const coachOptions = Array.from( + new Map(rows.map((row) => [row.coachId, row.creatorName])).entries(), + ([value, label]) => ({ value, label }), + ).toSorted((a, b) => a.label.localeCompare(b.label)) + const filteredRows = sortFeedbackRows(filterFeedbackRows(rows, filters), filters.sort) + + const ratedRows = rows.filter((feedback) => feedback.rating !== undefined) + const avgRating = + ratedRows.length === 0 + ? null + : ratedRows.reduce((sum, feedback) => sum + (feedback.rating ?? 0), 0) / ratedRows.length + const latestCreatedAt = rows.reduce( + (latest, feedback) => + latest === null || new Date(feedback.createdAt).getTime() > new Date(latest).getTime() + ? feedback.createdAt + : latest, + null, + ) + + return { + rows: filteredRows, + totalRows: rows.length, + hasRatings: ratedRows.length > 0, + eventOptions, + coachOptions, + stats: { + total: rows.length, + ratedCount: ratedRows.length, + avgRatingLabel: avgRating === null ? '--' : `${avgRating.toFixed(1)} / 10`, + latestLabel: latestCreatedAt === null ? '--' : formatDateShort(latestCreatedAt), + }, + } +} + +export function useFeedbackViewModel() { + const feedbackQuery = useFeedbackList() + const eventsQuery = useEventsList() + const filters = useFeedbackUiStore((state) => state.filters) + + const eventNamesById = useMemo( + () => new Map((eventsQuery.data ?? []).map((event) => [event.id, event.name])), + [eventsQuery.data], + ) + + const view = useMemo( + () => buildFeedbackView(feedbackQuery.data ?? [], eventNamesById, filters), + [feedbackQuery.data, eventNamesById, filters], + ) + + return { + view, + isLoading: feedbackQuery.isLoading || eventsQuery.isLoading, + error: feedbackQuery.error ?? eventsQuery.error, + } +} + +export function useFeedbackDetailView(id: string | null): FeedbackDetailView { + const feedbackQuery = useFeedback(id ?? '') + const eventsQuery = useEventsList() + const detail = feedbackQuery.data + const eventName = detail + ? eventsQuery.data?.find((event) => event.id === detail.event)?.name ?? 'Unknown event' + : undefined + + return { + detail, + eventName, + memberName: detail ? memberRefName(detail.member) : undefined, + creatorName: detail ? memberRefName(detail.creator) : undefined, + rating: detail ? optionalRating(detail) : undefined, + isLoading: + feedbackQuery.isLoading || (feedbackQuery.data !== undefined && eventsQuery.isLoading), + error: feedbackQuery.error ?? eventsQuery.error, + } +} diff --git a/web-client/src/features/helper/api/queries.ts b/web-client/src/features/helper/api/queries.ts index 68abbd3..c756447 100644 --- a/web-client/src/features/helper/api/queries.ts +++ b/web-client/src/features/helper/api/queries.ts @@ -1,5 +1,9 @@ import { useQuery } from '@tanstack/react-query' +import { getCurrentUser } from '@/features/auth/currentUser' +import { reportTextById } from '@/mocks/fixtures' +import { mockOr } from '@/mocks/mockSwitch' +import { scopeReport } from '@/mocks/scope' import { helperClient } from './client' export const helperKeys = { @@ -17,7 +21,15 @@ export function useHelperHello() { export function useMemberReport(memberId: string) { return useQuery({ queryKey: helperKeys.report(memberId), - queryFn: () => helperClient.get(`/report/${memberId}`).then(r => r.data), + queryFn: () => + mockOr( + () => { + if (!scopeReport(memberId, getCurrentUser())) throw new Error('Report not found') + return Promise.resolve(reportTextById[memberId] ?? '') + }, + // NOTE: report retrieval endpoint is not shipped yet; path is a placeholder. + () => helperClient.get(`/report/${memberId}`).then(r => r.data), + ), enabled: !!memberId, }) } diff --git a/web-client/src/features/helper/model/useReportViewModel.ts b/web-client/src/features/helper/model/useReportViewModel.ts new file mode 100644 index 0000000..67da904 --- /dev/null +++ b/web-client/src/features/helper/model/useReportViewModel.ts @@ -0,0 +1,14 @@ +import { useAuth } from '@/features/auth' +import { useMemberReport } from '../api/queries' + +export function useReportViewModel(memberId?: string) { + const { user } = useAuth() + const resolvedMemberId = memberId ?? user.id + const reportQuery = useMemberReport(resolvedMemberId) + + return { + text: reportQuery.data ?? '', + isLoading: reportQuery.isLoading, + isError: reportQuery.isError, + } +} diff --git a/web-client/src/features/letters/api/queries.ts b/web-client/src/features/letters/api/queries.ts index 6701028..c374054 100644 --- a/web-client/src/features/letters/api/queries.ts +++ b/web-client/src/features/letters/api/queries.ts @@ -1,5 +1,6 @@ import { useMutation, useQuery } from '@tanstack/react-query' +import { mockOr } from '@/mocks/mockSwitch' import { lettersClient } from './client' import type { GeneratePdfRequest, SendMailRequest } from '../types' @@ -10,7 +11,11 @@ export const lettersKeys = { export function useLettersHello() { return useQuery({ queryKey: lettersKeys.hello, - queryFn: () => lettersClient.get('/hello').then(r => r.data), + queryFn: () => + mockOr( + () => Promise.resolve('Letters service mock'), + () => lettersClient.get('/hello').then(r => r.data), + ), }) } diff --git a/web-client/src/features/members/api/queries.ts b/web-client/src/features/members/api/queries.ts index 7a1d1d7..9a968f1 100644 --- a/web-client/src/features/members/api/queries.ts +++ b/web-client/src/features/members/api/queries.ts @@ -1,5 +1,9 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { getCurrentUser } from '@/features/auth/currentUser' +import { memberFixtures, memberSummaryFixtures } from '@/mocks/fixtures' +import { mockOr } from '@/mocks/mockSwitch' +import { scopeMembers } from '@/mocks/scope' import { membersClient } from './client' import type { Member, MemberCreate, MemberPartialUpdate, MemberSummary } from '../types' @@ -19,14 +23,27 @@ export function useMembersHello() { export function useMembers() { return useQuery({ queryKey: membersKeys.all, - queryFn: () => membersClient.get('/').then(r => r.data), + queryFn: () => + mockOr( + () => Promise.resolve(scopeMembers(memberSummaryFixtures, getCurrentUser())), + () => membersClient.get('/').then(r => r.data), + ), }) } export function useMember(id: string) { return useQuery({ queryKey: membersKeys.detail(id), - queryFn: () => membersClient.get(`/${id}`).then(r => r.data), + queryFn: () => + mockOr( + () => { + const found = memberFixtures.find(m => m.id === id) + const scoped = found ? scopeMembers([found], getCurrentUser()) : [] + if (!scoped[0]) throw new Error('Member not found') + return Promise.resolve(scoped[0]) + }, + () => membersClient.get(`/${id}`).then(r => r.data), + ), enabled: !!id, }) } diff --git a/web-client/src/features/members/model/membersUiStore.ts b/web-client/src/features/members/model/membersUiStore.ts new file mode 100644 index 0000000..09b9333 --- /dev/null +++ b/web-client/src/features/members/model/membersUiStore.ts @@ -0,0 +1,29 @@ +import { create } from 'zustand' + +export interface MembersFilters { + search: string + teamId: string + sport: string +} + +const defaultFilters: MembersFilters = { + search: '', + teamId: 'all', + sport: 'all', +} + +interface MembersUiState { + filters: MembersFilters + setSearch: (search: string) => void + setTeamId: (teamId: string) => void + setSport: (sport: string) => void + resetFilters: () => void +} + +export const useMembersUiStore = create((set) => ({ + filters: defaultFilters, + setSearch: (search) => set((state) => ({ filters: { ...state.filters, search } })), + setTeamId: (teamId) => set((state) => ({ filters: { ...state.filters, teamId } })), + setSport: (sport) => set((state) => ({ filters: { ...state.filters, sport } })), + resetFilters: () => set({ filters: defaultFilters }), +})) diff --git a/web-client/src/features/members/model/useMembersViewModel.ts b/web-client/src/features/members/model/useMembersViewModel.ts new file mode 100644 index 0000000..1d3d04f --- /dev/null +++ b/web-client/src/features/members/model/useMembersViewModel.ts @@ -0,0 +1,102 @@ +import { useMemo } from 'react' + +import { useTeamsList } from '@/features/organization/api/queries' +import { memberRefName, type MemberSummary, type Team } from '@/types' +import { useMembers } from '../api/queries' +import type { MembersFilters } from './membersUiStore' +import { useMembersUiStore } from './membersUiStore' + +export interface MemberRow { + id: string + name: string + email: string + teamIds: string[] + teamNames: string[] + sports: string[] +} + +export interface MembersView { + rows: MemberRow[] + totalRows: number + teamOptions: { value: string; label: string }[] + sportOptions: { value: string; label: string }[] +} + +function memberName(member: MemberSummary): string { + return memberRefName(member) +} + +function memberTeamRows(members: MemberSummary[], teams: Team[]): MemberRow[] { + return members.map((member) => { + const memberTeams = teams.filter( + (team) => + team.trainees.some((trainee) => trainee.id === member.id) || + team.trainers.some((trainer) => trainer.id === member.id), + ) + + return { + id: member.id, + name: memberName(member), + email: member.email, + teamIds: memberTeams.map((team) => team.id), + teamNames: memberTeams.map((team) => team.name), + sports: Array.from(new Set(memberTeams.map((team) => team.sport))).toSorted(), + } + }) +} + +export function filterMemberRows(rows: MemberRow[], filters: MembersFilters): MemberRow[] { + const search = filters.search.trim().toLocaleLowerCase() + + return rows.filter((member) => { + const matchesText = + search.length === 0 || + member.name.toLocaleLowerCase().includes(search) || + member.email.toLocaleLowerCase().includes(search) + + return ( + matchesText && + (filters.teamId === 'all' || member.teamIds.includes(filters.teamId)) && + (filters.sport === 'all' || member.sports.includes(filters.sport)) + ) + }) +} + +export function buildMembersView( + members: MemberSummary[], + teams: Team[], + filters: MembersFilters, +): MembersView { + const rows = memberTeamRows(members, teams).toSorted((a, b) => a.name.localeCompare(b.name)) + const teamOptions = teams + .map((team) => ({ value: team.id, label: team.name })) + .toSorted((a, b) => a.label.localeCompare(b.label)) + const sportOptions = Array.from(new Set(teams.map((team) => team.sport)), (sport) => ({ + value: sport, + label: sport, + })).toSorted((a, b) => a.label.localeCompare(b.label)) + + return { + rows: filterMemberRows(rows, filters), + totalRows: rows.length, + teamOptions, + sportOptions, + } +} + +export function useMembersViewModel() { + const membersQuery = useMembers() + const teamsQuery = useTeamsList() + const filters = useMembersUiStore((state) => state.filters) + + const view = useMemo( + () => buildMembersView(membersQuery.data ?? [], teamsQuery.data ?? [], filters), + [filters, membersQuery.data, teamsQuery.data], + ) + + return { + view, + isLoading: membersQuery.isLoading || teamsQuery.isLoading, + error: membersQuery.error ?? teamsQuery.error, + } +} diff --git a/web-client/src/features/organization/api/queries.ts b/web-client/src/features/organization/api/queries.ts index cbb4378..6659c54 100644 --- a/web-client/src/features/organization/api/queries.ts +++ b/web-client/src/features/organization/api/queries.ts @@ -1,5 +1,7 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { sportFixtures, sportsByName, teamFixtures } from '@/mocks/fixtures' +import { mockOr } from '@/mocks/mockSwitch' import { organizationClient } from './client' import type { Sport, @@ -26,16 +28,34 @@ export function useOrganizationHello() { } export function useSports() { + return useSportsList() +} + +export function useSportsList(enabled = true) { return useQuery({ queryKey: organizationKeys.sports, - queryFn: () => organizationClient.get('/sports').then(r => r.data), + queryFn: () => + mockOr( + () => Promise.resolve(sportFixtures), + () => organizationClient.get('/sports').then(r => r.data), + ), + enabled, + staleTime: 5 * 60_000, }) } export function useSport(name: string) { return useQuery({ queryKey: organizationKeys.sport(name), - queryFn: () => organizationClient.get(`/sports/${name}`).then(r => r.data), + queryFn: () => + mockOr( + () => { + const found = sportsByName[name] + if (!found) throw new Error('Sport not found') + return Promise.resolve(found) + }, + () => organizationClient.get(`/sports/${name}`).then(r => r.data), + ), enabled: !!name, }) } @@ -74,16 +94,34 @@ export function useDeleteSport() { } export function useTeams() { + return useTeamsList() +} + +export function useTeamsList(enabled = true) { return useQuery({ queryKey: organizationKeys.teams, - queryFn: () => organizationClient.get('/teams').then(r => r.data), + queryFn: () => + mockOr( + () => Promise.resolve(teamFixtures), + () => organizationClient.get('/teams').then(r => r.data), + ), + enabled, + staleTime: 5 * 60_000, }) } export function useTeam(id: string) { return useQuery({ queryKey: organizationKeys.team(id), - queryFn: () => organizationClient.get(`/teams/${id}`).then(r => r.data), + queryFn: () => + mockOr( + () => { + const found = teamFixtures.find(t => t.id === id) + if (!found) throw new Error('Team not found') + return Promise.resolve(found) + }, + () => organizationClient.get(`/teams/${id}`).then(r => r.data), + ), enabled: !!id, }) } diff --git a/web-client/src/features/organization/model/useTeamsViewModel.ts b/web-client/src/features/organization/model/useTeamsViewModel.ts new file mode 100644 index 0000000..92a054b --- /dev/null +++ b/web-client/src/features/organization/model/useTeamsViewModel.ts @@ -0,0 +1,100 @@ +import { useMemo } from 'react' + +import { useAuth } from '@/features/auth' +import type { MemberRef, Sport, Team } from '@/types' +import { useSportsList, useTeamsList } from '../api/queries' + +export interface TeamView { + id: string + name: string + description: string + address: string + trainers: MemberRef[] + trainees: MemberRef[] +} + +export interface SportTeamsView { + name: string + description: string + directors: MemberRef[] + teams: TeamView[] +} + +export interface TeamsView { + sports: SportTeamsView[] + myTeams: Array + stats: { + myTeams: number + sports: number + teams: number + mySports: number + } +} + +export function buildTeamsView( + sports: Sport[], + teams: Team[], + currentUserId: string, +): TeamsView { + const teamsBySportName = new Map() + + for (const team of teams) { + const sportName = team.sport + if (!sportName) continue + + const teamView: TeamView = { + id: team.id, + name: team.name, + description: team.description, + address: team.address, + trainers: team.trainers, + trainees: team.trainees, + } + + const sportTeams = teamsBySportName.get(sportName) ?? [] + sportTeams.push(teamView) + teamsBySportName.set(sportName, sportTeams) + } + + const joinedSports = sports.map((sport) => ({ + name: sport.name, + description: sport.description, + directors: sport.directors, + teams: teamsBySportName.get(sport.name) ?? [], + })) + + const myTeams = joinedSports.flatMap((sport) => + sport.teams + .filter((team) => team.trainees.some((trainee) => trainee.id === currentUserId)) + .map((team) => ({ ...team, sportName: sport.name })), + ) + + return { + sports: joinedSports, + myTeams, + stats: { + myTeams: myTeams.length, + sports: joinedSports.length, + teams: teams.length, + mySports: new Set(myTeams.map((team) => team.sportName)).size, + }, + } +} + +export function useTeamsViewModel() { + const { user } = useAuth() + const sportsQuery = useSportsList() + const teamsQuery = useTeamsList() + + const view = useMemo( + () => buildTeamsView(sportsQuery.data ?? [], teamsQuery.data ?? [], user.id), + [sportsQuery.data, teamsQuery.data, user.id], + ) + + return { + view, + currentUserId: user.id, + isLoading: sportsQuery.isLoading || teamsQuery.isLoading, + error: sportsQuery.error ?? teamsQuery.error, + } +} diff --git a/web-client/src/features/payments/api/queries.ts b/web-client/src/features/payments/api/queries.ts index 0ef75cf..6031c5f 100644 --- a/web-client/src/features/payments/api/queries.ts +++ b/web-client/src/features/payments/api/queries.ts @@ -1,5 +1,9 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { getCurrentUser } from '@/features/auth/currentUser' +import { balanceFixtures, transactionFixtures } from '@/mocks/fixtures' +import { mockOr } from '@/mocks/mockSwitch' +import { scopeBalances, scopeTransactions } from '@/mocks/scope' import { paymentsClient } from './client' import type { Balance, Transaction, TransactionCreate, TransactionPartialUpdate } from '../types' @@ -21,29 +25,60 @@ export function usePaymentsHello() { export function useBalances() { return useQuery({ queryKey: paymentsKeys.balances, - queryFn: () => paymentsClient.get('/balances').then(r => r.data), + staleTime: 30_000, + queryFn: () => + mockOr( + () => Promise.resolve(scopeBalances(balanceFixtures, getCurrentUser())), + () => paymentsClient.get('/balances').then(r => r.data), + ), }) } export function useMemberBalance(memberId: string) { return useQuery({ queryKey: paymentsKeys.balance(memberId), - queryFn: () => paymentsClient.get(`/balances/${memberId}`).then(r => r.data), + staleTime: 30_000, + queryFn: () => + mockOr( + () => { + const found = balanceFixtures.find(balance => balance.member.id === memberId) + const scoped = found ? scopeBalances([found], getCurrentUser()) : [] + if (!scoped[0]) throw new Error('Balance not found') + return Promise.resolve(scoped[0]) + }, + () => paymentsClient.get(`/balances/${memberId}`).then(r => r.data), + ), enabled: !!memberId, }) } -export function useTransactions() { +export function useTransactions(enabled = true) { return useQuery({ queryKey: paymentsKeys.transactions, - queryFn: () => paymentsClient.get('/transactions').then(r => r.data), + staleTime: 30_000, + enabled, + queryFn: () => + mockOr( + () => Promise.resolve(scopeTransactions(transactionFixtures, getCurrentUser())), + () => paymentsClient.get('/transactions').then(r => r.data), + ), }) } export function useTransaction(id: string) { return useQuery({ queryKey: paymentsKeys.transaction(id), - queryFn: () => paymentsClient.get(`/transactions/${id}`).then(r => r.data), + staleTime: 30_000, + queryFn: () => + mockOr( + () => { + const found = transactionFixtures.find(transaction => transaction.id === id) + const scoped = found ? scopeTransactions([found], getCurrentUser()) : [] + if (!scoped[0]) throw new Error('Transaction not found') + return Promise.resolve(scoped[0]) + }, + () => paymentsClient.get(`/transactions/${id}`).then(r => r.data), + ), enabled: !!id, }) } diff --git a/web-client/src/features/payments/model/paymentsUiStore.ts b/web-client/src/features/payments/model/paymentsUiStore.ts new file mode 100644 index 0000000..0769bb5 --- /dev/null +++ b/web-client/src/features/payments/model/paymentsUiStore.ts @@ -0,0 +1,39 @@ +import { create } from 'zustand' + +export type PaymentKindFilter = 'all' | 'charge' | 'payment' +export type PaymentsSort = 'date-desc' | 'date-asc' + +export interface PaymentsFilters { + search: string + kind: PaymentKindFilter + fromDate: string + toDate: string + sort: PaymentsSort +} + +const defaultFilters: PaymentsFilters = { + search: '', + kind: 'all', + fromDate: '', + toDate: '', + sort: 'date-desc', +} + +interface PaymentsUiState { + filters: PaymentsFilters + setSearch: (search: string) => void + setKind: (kind: PaymentKindFilter) => void + setDateRange: (range: Pick) => void + setSort: (sort: PaymentsSort) => void + resetFilters: () => void +} + +export const usePaymentsUiStore = create((set) => ({ + filters: defaultFilters, + setSearch: (search) => set((state) => ({ filters: { ...state.filters, search } })), + setKind: (kind) => set((state) => ({ filters: { ...state.filters, kind } })), + setDateRange: (range) => + set((state) => ({ filters: { ...state.filters, ...range } })), + setSort: (sort) => set((state) => ({ filters: { ...state.filters, sort } })), + resetFilters: () => set({ filters: defaultFilters }), +})) diff --git a/web-client/src/features/payments/model/usePaymentsViewModel.ts b/web-client/src/features/payments/model/usePaymentsViewModel.ts new file mode 100644 index 0000000..7ab72de --- /dev/null +++ b/web-client/src/features/payments/model/usePaymentsViewModel.ts @@ -0,0 +1,133 @@ +import { useMemo } from 'react' + +import { useAuth } from '@/features/auth' +import { formatDateShort, formatEuroCents } from '@/lib/format' +import { memberRefName } from '@/types' +import { useTransactions } from '../api/queries' +import type { Transaction } from '../types' +import type { PaymentsFilters } from './paymentsUiStore' +import { usePaymentsUiStore } from './paymentsUiStore' + +type PaymentStatus = 'clear' | 'overdue' +type PaymentKind = 'charge' | 'payment' + +export interface PaymentRow { + createdAt: string + date: string + title: string + rawDescription: string + description: string + amountFormatted: string + kind: PaymentKind + creatorName: string +} + +export interface PaymentsView { + balanceCents: number + balanceFormatted: string + paidInCents: number + paidInFormatted: string + chargedCents: number + chargedFormatted: string + status: PaymentStatus + rows: PaymentRow[] + totalRows: number +} + +function includesSearch(value: string, search: string): boolean { + return value.toLocaleLowerCase().includes(search) +} + +export function filterPaymentRows( + rows: PaymentRow[], + filters: PaymentsFilters, +): PaymentRow[] { + const search = filters.search.trim().toLocaleLowerCase() + const fromTime = filters.fromDate ? new Date(`${filters.fromDate}T00:00:00`).getTime() : null + const toTime = filters.toDate ? new Date(`${filters.toDate}T23:59:59.999`).getTime() : null + + return rows.filter((transaction) => { + const transactionTime = new Date(transaction.createdAt).getTime() + const matchesText = + search.length === 0 || + includesSearch(transaction.title, search) || + includesSearch(transaction.rawDescription, search) || + includesSearch(transaction.description, search) + + return ( + matchesText && + (filters.kind === 'all' || transaction.kind === filters.kind) && + (fromTime === null || transactionTime >= fromTime) && + (toTime === null || transactionTime <= toTime) + ) + }) +} + +function sortPaymentRows(rows: PaymentRow[], sort: PaymentsFilters['sort']): PaymentRow[] { + return rows.toSorted((a, b) => { + const aTime = new Date(a.createdAt).getTime() + const bTime = new Date(b.createdAt).getTime() + + return sort === 'date-asc' ? aTime - bTime : bTime - aTime + }) +} + +export function buildPaymentsView( + transactions: Transaction[], + memberId: string, + filters: PaymentsFilters, +): PaymentsView { + const memberTransactions = transactions.filter((transaction) => transaction.member.id === memberId) + const balanceCents = memberTransactions.reduce( + (sum, transaction) => sum + transaction.amount_cents, + 0, + ) + const paidInCents = memberTransactions.reduce( + (sum, transaction) => (transaction.amount_cents > 0 ? sum + transaction.amount_cents : sum), + 0, + ) + const chargedCents = memberTransactions.reduce( + (sum, transaction) => (transaction.amount_cents < 0 ? sum + transaction.amount_cents : sum), + 0, + ) + + return { + balanceCents, + balanceFormatted: formatEuroCents(balanceCents), + paidInCents, + paidInFormatted: formatEuroCents(paidInCents), + chargedCents, + chargedFormatted: formatEuroCents(Math.abs(chargedCents)), + status: balanceCents < 0 ? 'overdue' : 'clear', + rows: sortPaymentRows(filterPaymentRows(memberTransactions.map((transaction) => ({ + createdAt: transaction.created_at, + date: formatDateShort(transaction.created_at), + title: transaction.title, + rawDescription: transaction.description ?? '', + description: transaction.description + ? `${transaction.title} - ${transaction.description}` + : transaction.title, + amountFormatted: `${transaction.amount_cents > 0 ? '+' : ''}${formatEuroCents(transaction.amount_cents)}`, + kind: transaction.amount_cents < 0 ? 'charge' : 'payment', + creatorName: memberRefName(transaction.creator), + })), filters), filters.sort), + totalRows: memberTransactions.length, + } +} + +export function usePaymentsViewModel() { + const { user } = useAuth() + const transactionsQuery = useTransactions() + const filters = usePaymentsUiStore((state) => state.filters) + + const view = useMemo( + () => buildPaymentsView(transactionsQuery.data ?? [], user.id, filters), + [transactionsQuery.data, user.id, filters], + ) + + return { + view, + isLoading: transactionsQuery.isLoading, + error: transactionsQuery.error, + } +} diff --git a/web-client/src/features/sport-events/api/queries.ts b/web-client/src/features/sport-events/api/queries.ts index 97794bc..688881d 100644 --- a/web-client/src/features/sport-events/api/queries.ts +++ b/web-client/src/features/sport-events/api/queries.ts @@ -1,42 +1,69 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { getCurrentUser } from '@/features/auth/currentUser' +import { eventDetailsById, eventSummaryFixtures } from '@/mocks/fixtures' +import { mockOr } from '@/mocks/mockSwitch' +import { scopeEvents } from '@/mocks/scope' import { sportEventsClient } from './client' import type { SportEvent, EventCreate, EventPartialUpdate, EventSummary } from '../types' -export const sportEventsKeys = { +export const eventKeys = { hello: ['sport-events', 'hello'] as const, all: ['sport-events'] as const, - detail: (id: string) => ['sport-events', id] as const, + list: () => ['sport-events', 'list'] as const, + detail: (id: string | null | undefined) => ['sport-events', 'detail', id] as const, } +export const sportEventsKeys = eventKeys + export function useSportEventsHello() { return useQuery({ - queryKey: sportEventsKeys.hello, + queryKey: eventKeys.hello, queryFn: () => sportEventsClient.get('/hello').then(r => r.data), }) } -export function useSportEvents() { +export function useEventsList(enabled = true) { return useQuery({ - queryKey: sportEventsKeys.all, - queryFn: () => sportEventsClient.get('/').then(r => r.data), + queryKey: eventKeys.list(), + staleTime: 30_000, + enabled, + queryFn: () => + mockOr( + () => Promise.resolve(scopeEvents(eventSummaryFixtures, getCurrentUser())), + () => sportEventsClient.get('/').then(r => r.data), + ), }) } -export function useSportEvent(id: string) { +export function useEvent(id: string | null | undefined) { return useQuery({ - queryKey: sportEventsKeys.detail(id), - queryFn: () => sportEventsClient.get(`/${id}`).then(r => r.data), + queryKey: eventKeys.detail(id), + queryFn: () => + mockOr( + () => { + const found = id ? eventDetailsById[id] : undefined + const scoped = found ? scopeEvents([found], getCurrentUser()) : [] + if (!scoped[0]) { + throw new Error('Event not found') + } + return Promise.resolve(scoped[0]) + }, + () => sportEventsClient.get(`/${id}`).then(r => r.data), + ), enabled: !!id, }) } +export const useSportEvents = useEventsList +export const useSportEvent = useEvent + export function useCreateSportEvent() { const qc = useQueryClient() return useMutation({ mutationFn: data => sportEventsClient.post('/', data).then(r => r.data), - onSuccess: () => qc.invalidateQueries({ queryKey: sportEventsKeys.all }), + onSuccess: () => qc.invalidateQueries({ queryKey: eventKeys.all }), }) } @@ -46,8 +73,8 @@ export function useUpdateSportEvent() { return useMutation({ mutationFn: ({ id, ...data }) => sportEventsClient.patch(`/${id}`, data).then(r => r.data), onSuccess: (_, { id }) => { - qc.invalidateQueries({ queryKey: sportEventsKeys.all }) - qc.invalidateQueries({ queryKey: sportEventsKeys.detail(id) }) + qc.invalidateQueries({ queryKey: eventKeys.all }) + qc.invalidateQueries({ queryKey: eventKeys.detail(id) }) }, }) } @@ -58,8 +85,8 @@ export function useDeleteSportEvent() { return useMutation({ mutationFn: id => sportEventsClient.delete(`/${id}`).then(() => undefined), onSuccess: (_, id) => { - qc.invalidateQueries({ queryKey: sportEventsKeys.all }) - qc.removeQueries({ queryKey: sportEventsKeys.detail(id) }) + qc.invalidateQueries({ queryKey: eventKeys.all }) + qc.removeQueries({ queryKey: eventKeys.detail(id) }) }, }) } diff --git a/web-client/src/features/sport-events/model/eventsUiStore.ts b/web-client/src/features/sport-events/model/eventsUiStore.ts new file mode 100644 index 0000000..59f8854 --- /dev/null +++ b/web-client/src/features/sport-events/model/eventsUiStore.ts @@ -0,0 +1,47 @@ +import { create } from 'zustand' + +import type { EventStatus } from './useEventsViewModel' + +export type EventsStatusFilter = 'all' | Extract +export type EventsSort = 'date-asc' | 'date-desc' | 'duration-asc' | 'duration-desc' + +export interface EventsFilters { + search: string + status: EventsStatusFilter + fromDate: string + toDate: string + sort: EventsSort +} + +const defaultFilters: EventsFilters = { + search: '', + status: 'all', + fromDate: '', + toDate: '', + sort: 'date-asc', +} + +interface EventsUiState { + openEventId: string | null + filters: EventsFilters + open: (id: string) => void + close: () => void + setSearch: (search: string) => void + setStatus: (status: EventsStatusFilter) => void + setDateRange: (range: Pick) => void + setSort: (sort: EventsSort) => void + resetFilters: () => void +} + +export const useEventsUiStore = create((set) => ({ + openEventId: null, + filters: defaultFilters, + open: (id) => set({ openEventId: id }), + close: () => set({ openEventId: null }), + setSearch: (search) => set((state) => ({ filters: { ...state.filters, search } })), + setStatus: (status) => set((state) => ({ filters: { ...state.filters, status } })), + setDateRange: (range) => + set((state) => ({ filters: { ...state.filters, ...range } })), + setSort: (sort) => set((state) => ({ filters: { ...state.filters, sort } })), + resetFilters: () => set({ filters: defaultFilters }), +})) diff --git a/web-client/src/features/sport-events/model/useEventsViewModel.test.ts b/web-client/src/features/sport-events/model/useEventsViewModel.test.ts new file mode 100644 index 0000000..3a9c469 --- /dev/null +++ b/web-client/src/features/sport-events/model/useEventsViewModel.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it } from 'vitest' + +import { eventSummaryFixtures, teamFixtures } from '@/mocks/fixtures' +import { MOCK_PERSONAS } from '@/mocks/personas' +import { scopeEvents } from '@/mocks/scope' +import type { EventSummary } from '@/types' +import { buildEventsView, eventAttendanceStatus, userTeamIds } from './useEventsViewModel' + +const now = new Date('2026-06-26T12:00:00.000Z') +const memberId = 'member-1' +const teamId = 'team-1' +const user = { + id: memberId, + teamIds: new Set([teamId]), +} + +function event(overrides: Partial): EventSummary { + return { + id: 'event-1', + name: 'Training', + start_time: '2026-06-20T10:00:00.000Z', + end_time: '2026-06-20T11:00:00.000Z', + ...overrides, + } +} + +describe('eventAttendanceStatus', () => { + it('marks past events attended when the user is in attendees', () => { + expect( + eventAttendanceStatus( + event({ + attendees: [{ id: memberId, first_name: 'Lena', last_name: 'Roth' }], + teams_linked: [{ id: teamId, name: 'Juniors' }], + }), + user, + now, + ), + ).toBe('attended') + }) + + it('marks past enrolled events missed when the user is absent from attendees', () => { + expect( + eventAttendanceStatus( + event({ + attendees: [], + teams_linked: [{ id: teamId, name: 'Juniors' }], + }), + user, + now, + ), + ).toBe('missed') + }) + + it('marks future events upcoming before considering attendance', () => { + expect( + eventAttendanceStatus( + event({ + start_time: '2026-07-01T10:00:00.000Z', + end_time: '2026-07-01T11:00:00.000Z', + attendees: [], + teams_linked: [{ id: teamId, name: 'Juniors' }], + }), + user, + now, + ), + ).toBe('upcoming') + }) + + it('falls back to past when enrollment is unknown and the user did not attend', () => { + expect( + eventAttendanceStatus( + event({ + attendees: [], + teams_linked: undefined, + }), + user, + now, + ), + ).toBe('past') + }) + + it('derives missed, attended and upcoming rows for the member persona fixtures', () => { + const member = MOCK_PERSONAS.member + const view = buildEventsView(scopeEvents(eventSummaryFixtures, member), now, { + id: member.id, + teamIds: userTeamIds(teamFixtures, member.id), + }) + + expect(view.rows.filter((row) => row.status === 'missed')).toHaveLength(2) + expect(view.rows.some((row) => row.status === 'attended')).toBe(true) + expect(view.rows.some((row) => row.status === 'upcoming')).toBe(true) + }) +}) diff --git a/web-client/src/features/sport-events/model/useEventsViewModel.ts b/web-client/src/features/sport-events/model/useEventsViewModel.ts new file mode 100644 index 0000000..b41118d --- /dev/null +++ b/web-client/src/features/sport-events/model/useEventsViewModel.ts @@ -0,0 +1,192 @@ +import { useMemo } from 'react' + +import { useAuth } from '@/features/auth' +import { useTeamsList } from '@/features/organization/api/queries' +import { formatDateTime, formatDuration } from '@/lib/format' +import type { AuthUser, Team } from '@/types' +import type { EventSummary, SportEvent } from '../types' +import { useEvent, useEventsList } from '../api/queries' +import type { EventsFilters } from './eventsUiStore' +import { useEventsUiStore } from './eventsUiStore' + +export type EventStatus = 'attended' | 'missed' | 'upcoming' | 'past' +type AttendanceUser = Pick & { + teamIds?: ReadonlySet +} + +export interface EventRow extends EventSummary { + status: EventStatus + formattedWhen: string + duration: string +} + +export interface EventsView { + rows: EventRow[] + totalRows: number + stats: { + upcoming: number + thisWeek: number + total: number + } + missedCount?: number +} + +export interface EventDetailView { + detail: SportEvent | undefined + status: EventStatus | undefined + missed: boolean + isLoading: boolean + error: Error | null +} + +export function eventAttendanceStatus( + event: EventSummary | SportEvent, + user: AttendanceUser, + now: Date, +): EventStatus { + if (new Date(event.start_time) >= now) { + return 'upcoming' + } + + if (event.attendees?.some((attendee) => attendee.id === user.id)) { + return 'attended' + } + + const hasLinkedTeams = event.teams_linked !== undefined + const hasAttendees = event.attendees !== undefined + const isEnrolled = + hasLinkedTeams && event.teams_linked?.some((team) => user.teamIds?.has(team.id)) === true + + if (isEnrolled && hasAttendees) { + return 'missed' + } + + return 'past' +} + +export function userTeamIds(teams: Team[], userId: string): ReadonlySet { + return new Set( + teams + .filter( + (team) => + team.trainees.some((trainee) => trainee.id === userId) || + team.trainers.some((trainer) => trainer.id === userId), + ) + .map((team) => team.id), + ) +} + +export function buildEventsView( + summaries: EventSummary[], + now: Date, + user: AttendanceUser, + filters: EventsFilters = { + search: '', + status: 'all', + fromDate: '', + toDate: '', + sort: 'date-asc', + }, +): EventsView { + const weekEnd = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000) + const rows = summaries.map((event) => { + const status = eventAttendanceStatus(event, user, now) + + return { + ...event, + status, + formattedWhen: formatDateTime(event.start_time), + duration: formatDuration(event.start_time, event.end_time), + } + }) + const search = filters.search.trim().toLocaleLowerCase() + const fromTime = filters.fromDate ? new Date(`${filters.fromDate}T00:00:00`).getTime() : null + const toTime = filters.toDate ? new Date(`${filters.toDate}T23:59:59.999`).getTime() : null + const filteredRows = rows + .filter((event) => { + const eventTime = new Date(event.start_time).getTime() + const matchesText = search.length === 0 || event.name.toLocaleLowerCase().includes(search) + const matchesStatus = filters.status === 'all' || event.status === filters.status + + return ( + matchesText && + matchesStatus && + (fromTime === null || eventTime >= fromTime) && + (toTime === null || eventTime <= toTime) + ) + }) + .toSorted((a, b) => { + if (filters.sort === 'duration-asc' || filters.sort === 'duration-desc') { + const aDuration = new Date(a.end_time).getTime() - new Date(a.start_time).getTime() + const bDuration = new Date(b.end_time).getTime() - new Date(b.start_time).getTime() + + return filters.sort === 'duration-asc' ? aDuration - bDuration : bDuration - aDuration + } + + const aStart = new Date(a.start_time).getTime() + const bStart = new Date(b.start_time).getTime() + + return filters.sort === 'date-desc' ? bStart - aStart : aStart - bStart + }) + const upcoming = rows.filter((event) => event.status === 'upcoming') + const thisWeek = upcoming.filter((event) => new Date(event.start_time) < weekEnd) + + return { + rows: filteredRows, + totalRows: rows.length, + stats: { + upcoming: upcoming.length, + thisWeek: thisWeek.length, + total: summaries.length, + }, + } +} + +export function useEventsViewModel(now = new Date()) { + const { user } = useAuth() + const eventsQuery = useEventsList() + const teamsQuery = useTeamsList() + const filters = useEventsUiStore((state) => state.filters) + const nowTime = now.getTime() + + const view = useMemo( + () => + buildEventsView(eventsQuery.data ?? [], new Date(nowTime), { + id: user.id, + teamIds: userTeamIds(teamsQuery.data ?? [], user.id), + }, filters), + [eventsQuery.data, nowTime, teamsQuery.data, user.id, filters], + ) + + return { + view, + isLoading: eventsQuery.isLoading || teamsQuery.isLoading, + error: eventsQuery.error ?? teamsQuery.error, + } +} + +export function useEventDetailView(id: string | null, now = new Date()): EventDetailView { + const { user } = useAuth() + const eventQuery = useEvent(id) + const teamsQuery = useTeamsList() + const detail = eventQuery.data + const status = detail + ? eventAttendanceStatus( + detail, + { + id: user.id, + teamIds: userTeamIds(teamsQuery.data ?? [], user.id), + }, + now, + ) + : undefined + const missed = status === 'missed' + + return { + detail, + status, + missed, + isLoading: eventQuery.isLoading || teamsQuery.isLoading, + error: eventQuery.error ?? teamsQuery.error, + } +} From 9c7c468eb43b2816311823f8ce15aab12abce78c Mon Sep 17 00:00:00 2001 From: FadyGergesRezk <84906847+FadyGergesRezk@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:16:54 +0200 Subject: [PATCH 05/15] feat: rebuild feature pages on view-model layer --- web-client/src/app/pages/DashboardPage.tsx | 324 ++++++++++++++++ web-client/src/app/router/routes.tsx | 5 +- .../features/feedback/pages/FeedbackPage.tsx | 302 ++++++++++++++- .../src/features/helper/pages/HelperPage.tsx | 40 +- .../helper/pages/ReportMarkdown.test.tsx | 79 ++++ .../features/helper/pages/ReportMarkdown.tsx | 140 +++++++ .../features/members/pages/MembersPage.tsx | 143 ++++++- .../organization/pages/OrganizationPage.tsx | 357 +++++++++++++++++- .../features/payments/pages/PaymentsPage.tsx | 169 ++++++++- .../sport-events/pages/SportEventsPage.tsx | 288 +++++++++++++- 10 files changed, 1817 insertions(+), 30 deletions(-) create mode 100644 web-client/src/app/pages/DashboardPage.tsx create mode 100644 web-client/src/features/helper/pages/ReportMarkdown.test.tsx create mode 100644 web-client/src/features/helper/pages/ReportMarkdown.tsx diff --git a/web-client/src/app/pages/DashboardPage.tsx b/web-client/src/app/pages/DashboardPage.tsx new file mode 100644 index 0000000..9d02da9 --- /dev/null +++ b/web-client/src/app/pages/DashboardPage.tsx @@ -0,0 +1,324 @@ +import { ArrowRight } from 'lucide-react' +import { Link } from 'react-router-dom' + +import { Avatar, AvatarFallback } from '@/components/ui/avatar' +import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { PageHeader } from '@/components/ui/page-header' +import { Skeleton } from '@/components/ui/skeleton' +import { StatCard } from '@/components/ui/stat-card' +import { + type DashboardFeedbackItem, + type DashboardSectionState, + type DashboardSportSection, + useDashboardViewModel, +} from './model/useDashboardViewModel' + +const initials = (name: string) => + name + .split(' ') + .map((part) => part[0]) + .join('') + .slice(0, 2) + .toUpperCase() + +export function DashboardPage() { + const { view, states } = useDashboardViewModel() + + return ( +
    + + + {view.adminCounts && ( + + )} + + {(view.myBalance || view.myEvents || view.myFeedback) && ( +
    + {view.myBalance && } + {view.myEvents && } + {view.myFeedback && ( + + )} +
    + )} + + {view.myEvents && } + {view.myFeedback && ( + + )} + {view.sports && } +
    + ) +} + +function AdminCountsSection({ + counts, + state, +}: { + counts: NonNullable['view']['adminCounts']> + state?: DashboardSectionState +}) { + if (state?.isLoading) { + return ( +
    + {['teams', 'directors', 'trainers'].map((key) => ( + + ))} +
    + ) + } + + return ( +
    + + + +
    + ) +} + +function BalanceCard({ + balance, + state, +}: { + balance: NonNullable['view']['myBalance']> + state?: DashboardSectionState +}) { + if (state?.isLoading) return + + return ( + + ) +} + +function EventsCards({ + events, + state, +}: { + events: NonNullable['view']['myEvents']> + state?: DashboardSectionState +}) { + if (state?.isLoading) { + return ( + <> + + + + ) + } + + return ( + <> + + + + ) +} + +function FeedbackStat({ + feedback, + state, +}: { + feedback: NonNullable['view']['myFeedback']> + state?: DashboardSectionState +}) { + if (state?.isLoading) return + + return ( + 0 ? 'positive' : 'default'} + meta="Entries in scope" + /> + ) +} + +function EventsSection({ + events, + state, +}: { + events: NonNullable['view']['myEvents']> + state?: DashboardSectionState +}) { + return ( +
    + + {sectionBody(state, events.items.length === 0, 'No upcoming events.', ( +
      + {events.items.map((event) => ( +
    • + +
      +

      + {event.name} +

      +

      + {event.date} - {event.time} +

      +
      + + +
    • + ))} +
    + ))} +
    + ) +} + +function FeedbackSection({ + feedback, + state, +}: { + feedback: DashboardFeedbackItem[] + state?: DashboardSectionState +}) { + return ( +
    + + {sectionBody(state, feedback.length === 0, 'No feedback is listed yet.', ( +
      + {feedback.map((entry) => ( +
    • + + + + {initials(entry.from)} + + +
      +

      + {entry.from} +

      +

      + {entry.eventName} - {entry.date} +

      +

      About {entry.about}

      +
      + +
    • + ))} +
    + ))} +
    + ) +} + +function SportsSection({ + sports, + state, +}: { + sports: DashboardSportSection[] + state?: DashboardSectionState +}) { + return ( +
    + + {sectionBody(state, sports.length === 0, 'No sports are listed yet.', ( +
    + {sports.map((sport) => ( +
    +
    +
    +

    {sport.name}

    +

    {sport.description}

    +

    + Directors {sport.directors} +

    +
    + + {sport.teams.length} teams + +
    +
    + {sport.teams.length === 0 ? ( +

    No teams in this sport yet.

    + ) : ( + sport.teams.map((team) => ( +
    +

    + {team.name} +

    +

    + Coach {team.trainers} - {team.members} members +

    +
    + )) + )} +
    +
    + ))} +
    + ))} +
    + ) +} + +function SectionHeader({ title, to }: { title: string; to: string }) { + return ( +
    +

    + {title} +

    + +
    + ) +} + +function sectionBody( + state: DashboardSectionState | undefined, + isEmpty: boolean, + emptyText: string, + content: React.ReactNode, +) { + if (state?.isLoading) { + return ( +
    + {Array.from({ length: 3 }).map((_, index) => ( + + ))} +
    + ) + } + + if (state?.error) { + return

    {state.error.message}

    + } + + if (isEmpty) { + return

    {emptyText}

    + } + + return content +} diff --git a/web-client/src/app/router/routes.tsx b/web-client/src/app/router/routes.tsx index 668fe74..18e8e3e 100644 --- a/web-client/src/app/router/routes.tsx +++ b/web-client/src/app/router/routes.tsx @@ -1,5 +1,6 @@ -import { createBrowserRouter, Navigate } from 'react-router-dom' +import { createBrowserRouter } from 'react-router-dom' import { AppShell } from '@/app/layout/AppShell' +import { DashboardPage } from '@/app/pages/DashboardPage' import { MembersPage } from '@/features/members' import { SportEventsPage } from '@/features/sport-events' import { PaymentsPage } from '@/features/payments' @@ -14,7 +15,7 @@ export const router = createBrowserRouter([ path: '/', element: , children: [ - { index: true, element: }, + { index: true, element: }, { path: 'members', element: }, { path: 'sport-events', element: }, { path: 'payments', element: }, diff --git a/web-client/src/features/feedback/pages/FeedbackPage.tsx b/web-client/src/features/feedback/pages/FeedbackPage.tsx index 9ac09d2..3741588 100644 --- a/web-client/src/features/feedback/pages/FeedbackPage.tsx +++ b/web-client/src/features/feedback/pages/FeedbackPage.tsx @@ -1,12 +1,306 @@ -import { useFeedbackHello } from '../api' +import { useEffect } from 'react' + +import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { DataTable, TCell, THead, TRow } from '@/components/ui/data-table' +import { DateRangeFilter } from '@/components/ui/date-range-filter' +import { PageHeader } from '@/components/ui/page-header' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { Separator } from '@/components/ui/separator' +import { + Sheet, + SheetContent, + SheetHeader, + SheetTitle, +} from '@/components/ui/sheet' +import { Skeleton } from '@/components/ui/skeleton' +import { StatCard } from '@/components/ui/stat-card' +import { TableToolbar } from '@/components/ui/table-toolbar' +import { formatDate, formatDateShort } from '@/lib/format' +import { useFeedbackUiStore } from '../model/feedbackUiStore' +import { useFeedbackDetailView, useFeedbackViewModel } from '../model/useFeedbackViewModel' + +const ratingOptions = [ + { value: 'all', label: 'All ratings' }, + { value: 'high', label: '7+' }, + { value: 'medium', label: '4-6' }, + { value: 'low', label: '0-3' }, + { value: 'none', label: 'No rating' }, +] as const export function FeedbackPage() { - const { data: hello } = useFeedbackHello() + const { view, isLoading, error } = useFeedbackViewModel() + const filters = useFeedbackUiStore((state) => state.filters) + const setSearch = useFeedbackUiStore((state) => state.setSearch) + const setRating = useFeedbackUiStore((state) => state.setRating) + const setEventId = useFeedbackUiStore((state) => state.setEventId) + const setCoachId = useFeedbackUiStore((state) => state.setCoachId) + const setDateRange = useFeedbackUiStore((state) => state.setDateRange) + const setSort = useFeedbackUiStore((state) => state.setSort) + const resetFilters = useFeedbackUiStore((state) => state.resetFilters) + const openFeedbackId = useFeedbackUiStore((state) => state.openFeedbackId) + const openFeedback = useFeedbackUiStore((state) => state.open) + const closeFeedback = useFeedbackUiStore((state) => state.close) + const detailView = useFeedbackDetailView(openFeedbackId) + + useEffect(() => resetFilters, [resetFilters]) + + return ( +
    + + +
    + + + +
    + + {isLoading ? ( + + ) : error ? ( +

    + {error.message} +

    + ) : view.totalRows === 0 ? ( +

    + No feedback is listed yet. +

    + ) : ( + <> + + + + + + + + + + + + + {view.rows.length === 0 ? ( +

    + No feedback matches the current filters. +

    + ) : ( + +
  • + + Date + Event + Trainee + From + {view.hasRatings && Rating} + + + + + {view.rows.map((feedback) => ( + + + {formatDateShort(feedback.createdAt)} + + {feedback.eventName} + {feedback.memberName} + {feedback.creatorName} + {view.hasRatings && ( + + {feedback.rating === undefined ? ( + -- + ) : ( + {feedback.rating}/10 + )} + + )} + + + + + ))} + + + )} + + )} + +

    + The feedback text is not in the list response - open an entry to read it. +

    + + !open && closeFeedback()}> + + + + + + ) +} + +function FeedbackDetailSheet({ + detailView, +}: { + detailView: ReturnType +}) { + const { detail, eventName, memberName, creatorName, rating, isLoading, error } = detailView + + if (isLoading) { + return ( +
    + + + + +
    + ) + } + + if (error) { + return ( +

    + {error.message} +

    + ) + } + + if (!detail) { + return ( +

    + Select feedback to view details. +

    + ) + } + + return ( + <> + +

    + Feedback detail +

    + + {eventName ?? 'Event'} + +
    + +
    +
    + + + {rating !== undefined && } +
    + + + +

    + {detail.feedback} +

    + + About: {memberName ?? '--'} +
    + + ) +} + +function FeedbackTableSkeleton() { + return ( +
    +
    + {Array.from({ length: 5 }).map((_, index) => ( + + ))} +
    +
    + ) +} + +function FieldLabel({ children }: { children: React.ReactNode }) { + return ( +

    {children}

    + ) +} +function Field({ label, value }: { label: string; value: string }) { return (
    -

    Feedback

    - {hello &&

    {hello}

    } + {label} +

    {value}

    ) } diff --git a/web-client/src/features/helper/pages/HelperPage.tsx b/web-client/src/features/helper/pages/HelperPage.tsx index 3fd9cc3..c114c37 100644 --- a/web-client/src/features/helper/pages/HelperPage.tsx +++ b/web-client/src/features/helper/pages/HelperPage.tsx @@ -1,12 +1,42 @@ -import { useHelperHello } from '../api' +import { PageHeader } from '@/components/ui/page-header' +import { Card, CardContent } from '@/components/ui/card' +import { Skeleton } from '@/components/ui/skeleton' +import { useReportViewModel } from '../model/useReportViewModel' +import { ReportMarkdown } from './ReportMarkdown' export function HelperPage() { - const { data: hello } = useHelperHello() + const { text, isLoading, isError } = useReportViewModel() return ( -
    -

    GenAI Helper

    - {hello &&

    {hello}

    } +
    + + + + + {isLoading ? ( +
    + + + + +
    + ) : isError ? ( +

    + We couldn’t load your development report. Please try again later. +

    + ) : text.trim() ? ( + + ) : ( +

    + No development report is available yet. +

    + )} +
    +
    ) } diff --git a/web-client/src/features/helper/pages/ReportMarkdown.test.tsx b/web-client/src/features/helper/pages/ReportMarkdown.test.tsx new file mode 100644 index 0000000..749f64f --- /dev/null +++ b/web-client/src/features/helper/pages/ReportMarkdown.test.tsx @@ -0,0 +1,79 @@ +import { act } from 'react' +import { createRoot, type Root } from 'react-dom/client' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { ReportMarkdown } from './ReportMarkdown' + +describe('ReportMarkdown', () => { + let container: HTMLDivElement + let root: Root + + beforeEach(() => { + document.body.innerHTML = '
    ' + container = document.getElementById('root') as HTMLDivElement + root = createRoot(container) + }) + + afterEach(async () => { + await act(async () => { + root.unmount() + }) + document.body.innerHTML = '' + }) + + async function render(text: string) { + await act(async () => { + root.render() + }) + } + + it('renders headings at the right level', async () => { + await render('# Title\n\n## Section') + + expect(container.querySelector('h1')?.textContent).toBe('Title') + expect(container.querySelector('h2')?.textContent).toBe('Section') + }) + + it('renders bullet lists', async () => { + await render('- first\n- second\n* third') + + const items = container.querySelectorAll('li') + expect(items.length).toBe(3) + expect(items[0].textContent).toBe('first') + expect(items[2].textContent).toBe('third') + }) + + it('renders bold and italic inline emphasis', async () => { + await render('Plain **bold** and *italic* text') + + expect(container.querySelector('strong')?.textContent).toBe('bold') + expect(container.querySelector('em')?.textContent).toBe('italic') + }) + + it('splits paragraphs on blank lines', async () => { + await render('First para.\n\nSecond para.') + + const paragraphs = container.querySelectorAll('p') + expect(paragraphs.length).toBe(2) + expect(paragraphs[0].textContent).toBe('First para.') + expect(paragraphs[1].textContent).toBe('Second para.') + }) + + it('renders plain prose without headings or lists as paragraphs', async () => { + await render('Just a line of prose with no markup at all.') + + expect(container.querySelector('h1')).toBeNull() + expect(container.querySelector('ul')).toBeNull() + expect(container.querySelector('p')?.textContent).toBe( + 'Just a line of prose with no markup at all.', + ) + }) + + it('does not inject raw HTML from the report text', async () => { + await render(' & ') + + // No element was created from the malicious markup — it is escaped text. + expect(container.querySelector('img')).toBeNull() + expect(container.querySelector('script')).toBeNull() + expect(container.textContent).toContain('') + }) +}) diff --git a/web-client/src/features/helper/pages/ReportMarkdown.tsx b/web-client/src/features/helper/pages/ReportMarkdown.tsx new file mode 100644 index 0000000..a4becfd --- /dev/null +++ b/web-client/src/features/helper/pages/ReportMarkdown.tsx @@ -0,0 +1,140 @@ +import { Fragment, type ReactNode } from 'react' + +// Safe renderer for untrusted AI report text: a tiny markdown subset (headings, +// bullets, bold/italic), everything else React-escaped. No dangerouslySetInnerHTML. +type Block = + | { kind: 'heading'; level: 1 | 2 | 3; text: string } + | { kind: 'list'; items: string[] } + | { kind: 'paragraph'; lines: string[] } + +const headingClass: Record<1 | 2 | 3, string> = { + 1: 'mt-6 first:mt-0 text-display-sm font-display uppercase tracking-wide text-text-primary', + 2: 'mt-5 first:mt-0 text-body-lg font-semibold text-text-primary', + 3: 'mt-4 first:mt-0 text-body font-semibold text-text-primary', +} + +function parseBlocks(source: string): Block[] { + // Normalise line endings, then walk line by line grouping into blocks. + const lines = source.replace(/\r\n?/g, '\n').split('\n') + const blocks: Block[] = [] + + let paragraph: string[] = [] + let listItems: string[] = [] + + const flushParagraph = () => { + if (paragraph.length) { + blocks.push({ kind: 'paragraph', lines: paragraph }) + paragraph = [] + } + } + const flushList = () => { + if (listItems.length) { + blocks.push({ kind: 'list', items: listItems }) + listItems = [] + } + } + + for (const raw of lines) { + const line = raw.trimEnd() + + if (line.trim() === '') { + flushParagraph() + flushList() + continue + } + + const heading = /^(#{1,3})\s+(.*)$/.exec(line) + if (heading) { + flushParagraph() + flushList() + blocks.push({ + kind: 'heading', + level: heading[1].length as 1 | 2 | 3, + text: heading[2].trim(), + }) + continue + } + + const bullet = /^\s*[-*]\s+(.*)$/.exec(line) + if (bullet) { + flushParagraph() + listItems.push(bullet[1].trim()) + continue + } + + // Plain text line — part of the current paragraph. + flushList() + paragraph.push(line.trim()) + } + + flushParagraph() + flushList() + return blocks +} + +// Render `**bold**` / `*italic*`; the rest stays React-escaped plain text. +function renderInline(text: string, keyPrefix: string): ReactNode[] { + const nodes: ReactNode[] = [] + // Order matters: match the longer `**` delimiter before `*`. + const pattern = /\*\*([^*]+)\*\*|\*([^*]+)\*/g + let lastIndex = 0 + let match: RegExpExecArray | null + let i = 0 + + while ((match = pattern.exec(text)) !== null) { + if (match.index > lastIndex) { + nodes.push({text.slice(lastIndex, match.index)}) + } + if (match[1] !== undefined) { + nodes.push({match[1]}) + } else { + nodes.push({match[2]}) + } + lastIndex = pattern.lastIndex + i += 1 + } + + if (lastIndex < text.length) { + nodes.push({text.slice(lastIndex)}) + } + return nodes +} + +export function ReportMarkdown({ text }: { text: string }) { + const blocks = parseBlocks(text) + + return ( +
    + {blocks.map((block, index) => { + const key = `block-${index}` + if (block.kind === 'heading') { + const Tag = (`h${block.level}`) as 'h1' | 'h2' | 'h3' + return ( + + {renderInline(block.text, key)} + + ) + } + if (block.kind === 'list') { + return ( +
      + {block.items.map((item, itemIndex) => ( +
    • {renderInline(item, `${key}-i${itemIndex}`)}
    • + ))} +
    + ) + } + return ( +

    + {block.lines.map((line, lineIndex) => ( + + {lineIndex > 0 &&
    } + {renderInline(line, `${key}-l${lineIndex}`)} +
    + ))} +

    + ) + })} +
    + ) +} diff --git a/web-client/src/features/members/pages/MembersPage.tsx b/web-client/src/features/members/pages/MembersPage.tsx index c12ffd7..d3c51ae 100644 --- a/web-client/src/features/members/pages/MembersPage.tsx +++ b/web-client/src/features/members/pages/MembersPage.tsx @@ -1,12 +1,145 @@ -import { useMembersHello } from '../api' +import { useEffect } from 'react' + +import { Badge } from '@/components/ui/badge' +import { DataTable, TCell, THead, TRow } from '@/components/ui/data-table' +import { PageHeader } from '@/components/ui/page-header' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { Skeleton } from '@/components/ui/skeleton' +import { TableToolbar } from '@/components/ui/table-toolbar' +import { useMembersUiStore } from '../model/membersUiStore' +import { useMembersViewModel } from '../model/useMembersViewModel' export function MembersPage() { - const { data: hello } = useMembersHello() + const { view, isLoading, error } = useMembersViewModel() + const filters = useMembersUiStore((state) => state.filters) + const setSearch = useMembersUiStore((state) => state.setSearch) + const setTeamId = useMembersUiStore((state) => state.setTeamId) + const setSport = useMembersUiStore((state) => state.setSport) + const resetFilters = useMembersUiStore((state) => state.resetFilters) + + useEffect(() => resetFilters, [resetFilters]) + + return ( +
    + + + {isLoading ? ( + + ) : error ? ( +

    + {error.message} +

    + ) : view.totalRows === 0 ? ( +

    + No members are listed yet. +

    + ) : ( + <> + + + + + + + {view.rows.length === 0 ? ( +

    + No members match the current filters. +

    + ) : ( + +
    + + Name + Email + Teams + Sports + + + + {view.rows.map((member) => ( + + {member.name} + {member.email} + + + + + + + + ))} + + + )} + + )} + + ) +} + +function FacetBadges({ values, emptyLabel }: { values: string[]; emptyLabel: string }) { + if (values.length === 0) { + return {emptyLabel} + } + + return ( +
    + {values.map((value) => ( + + {value} + + ))} +
    + ) +} +function MembersTableSkeleton() { return ( -
    -

    Members

    - {hello &&

    {hello}

    } +
    +
    + {Array.from({ length: 5 }).map((_, index) => ( + + ))} +
    ) } diff --git a/web-client/src/features/organization/pages/OrganizationPage.tsx b/web-client/src/features/organization/pages/OrganizationPage.tsx index 0b180d8..9def49c 100644 --- a/web-client/src/features/organization/pages/OrganizationPage.tsx +++ b/web-client/src/features/organization/pages/OrganizationPage.tsx @@ -1,12 +1,359 @@ -import { useOrganizationHello } from '../api' +import { useState } from 'react' +import { ChevronRight } from 'lucide-react' + +import { Badge } from '@/components/ui/badge' +import { PageHeader } from '@/components/ui/page-header' +import { Separator } from '@/components/ui/separator' +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, +} from '@/components/ui/sheet' +import { Skeleton } from '@/components/ui/skeleton' +import { StatCard } from '@/components/ui/stat-card' +import { memberRefName } from '@/types' +import { + type SportTeamsView, + type TeamView, + useTeamsViewModel, +} from '../model/useTeamsViewModel' + +const nameList = (refs: Parameters[0][]) => + refs.map(memberRefName).join(', ') || '--' export function OrganizationPage() { - const { data: hello } = useOrganizationHello() + const { view, currentUserId, isLoading, error } = useTeamsViewModel() + const [openSport, setOpenSport] = useState(null) + const [rosterTeamId, setRosterTeamId] = useState(null) + const activeOpenSport = openSport ?? view.sports[0]?.name ?? '' + const rosterTeam = findRosterTeam(view.sports, rosterTeamId) return ( -
    -

    Organization

    - {hello &&

    {hello}

    } +
    + + + {error && ( +
    + Teams could not be loaded. Please try again later. +
    + )} + + + + {isLoading ? ( + + ) : view.sports.length === 0 ? ( + + ) : ( + <> + {view.myTeams.length > 0 && ( +
    +

    + My Teams +

    +
    + {view.myTeams.map((team) => ( + setRosterTeamId(team.id)} + /> + ))} +
    +
    + )} + +
    +

    + Sports +

    +
    + {view.sports.map((sport, index) => { + const expanded = activeOpenSport === sport.name + + return ( + 0} + onToggle={() => setOpenSport(expanded ? '' : sport.name)} + onOpenTeam={setRosterTeamId} + /> + ) + })} +
    +
    + + )} + + !open && setRosterTeamId(null)}> + + {rosterTeam && } + +
    ) } + +function StatsRow({ + view, + isLoading, +}: { + view: ReturnType['view'] + isLoading: boolean +}) { + if (isLoading) { + return ( +
    + {['my-teams', 'sports', 'teams', 'my-sports'].map((key) => ( + + ))} +
    + ) + } + + return ( +
    + 0 ? 'positive' : 'default'} + meta="You're a member" + /> + + + +
    + ) +} + +function findRosterTeam(sports: SportTeamsView[], teamId: string | null) { + if (!teamId) return null + + for (const sport of sports) { + const team = sport.teams.find((candidate) => candidate.id === teamId) + if (team) return { ...team, sportName: sport.name } + } + + return null +} + +function SportSection({ + sport, + currentUserId, + expanded, + withTopBorder, + onToggle, + onOpenTeam, +}: { + sport: SportTeamsView + currentUserId: string + expanded: boolean + withTopBorder: boolean + onToggle: () => void + onOpenTeam: (id: string) => void +}) { + return ( +
    + + + {expanded && ( +
      + {sport.teams.length === 0 ? ( +
    • + No teams in this sport yet. +
    • + ) : ( + sport.teams.map((team) => ( +
    • + +
    • + )) + )} +
    + )} +
    + ) +} + +function TeamSummaryCard({ + team, + sportName, + isMine, + onOpen, +}: { + team: TeamView + sportName: string + isMine: boolean + onOpen: () => void +}) { + return ( + + ) +} + +function RosterSheet({ + team, + currentUserId, +}: { + team: TeamView & { sportName: string } + currentUserId: string +}) { + return ( + <> + +

    + {team.sportName} team +

    + + {team.name} + + {team.description} +
    + +
    +
    + Address +

    {team.address}

    +
    + +
    + Coaches ({team.trainers.length}) + +
    + + + +
    + Roster ({team.trainees.length}) + +
    +
    + + ) +} + +function MemberBadges({ + members, + currentUserId, + tone = 'default', + emptyText = 'No members yet.', +}: { + members: Parameters[0][] + currentUserId?: string + tone?: React.ComponentProps['tone'] + emptyText?: string +}) { + if (members.length === 0) { + return

    {emptyText}

    + } + + return ( +
    + {members.map((member) => { + const isCurrentUser = member.id === currentUserId + + return ( + + {isCurrentUser ? `${memberRefName(member)} (you)` : memberRefName(member)} + + ) + })} +
    + ) +} + +function LoadingState() { + return ( +
    + +
    + + + +
    +
    + ) +} + +function EmptyState() { + return ( +
    +

    No sports yet.

    +

    + Sports and teams will appear here after they are created. +

    +
    + ) +} + +function FieldLabel({ children }: { children: React.ReactNode }) { + return ( +

    {children}

    + ) +} diff --git a/web-client/src/features/payments/pages/PaymentsPage.tsx b/web-client/src/features/payments/pages/PaymentsPage.tsx index 9ca646b..1070d9d 100644 --- a/web-client/src/features/payments/pages/PaymentsPage.tsx +++ b/web-client/src/features/payments/pages/PaymentsPage.tsx @@ -1,12 +1,171 @@ -import { usePaymentsHello } from '../api' +import { useEffect } from 'react' + +import { Badge } from '@/components/ui/badge' +import { DataTable, TCell, THead, TRow } from '@/components/ui/data-table' +import { DateRangeFilter } from '@/components/ui/date-range-filter' +import { PageHeader } from '@/components/ui/page-header' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { Skeleton } from '@/components/ui/skeleton' +import { StatCard } from '@/components/ui/stat-card' +import { TableToolbar } from '@/components/ui/table-toolbar' +import { usePaymentsUiStore } from '../model/paymentsUiStore' +import { usePaymentsViewModel } from '../model/usePaymentsViewModel' export function PaymentsPage() { - const { data: hello } = usePaymentsHello() + const { view, isLoading, error } = usePaymentsViewModel() + const filters = usePaymentsUiStore((state) => state.filters) + const setSearch = usePaymentsUiStore((state) => state.setSearch) + const setKind = usePaymentsUiStore((state) => state.setKind) + const setDateRange = usePaymentsUiStore((state) => state.setDateRange) + const setSort = usePaymentsUiStore((state) => state.setSort) + const resetFilters = usePaymentsUiStore((state) => state.resetFilters) + const isOverdue = view.status === 'overdue' + + useEffect(() => resetFilters, [resetFilters]) + + return ( +
    + + +
    + + + +
    + + {isLoading ? ( + + ) : error ? ( +

    + {error.message} +

    + ) : view.totalRows === 0 ? ( +

    + No transactions are listed yet. +

    + ) : ( + <> + + + + + + + + + {view.rows.length === 0 ? ( +

    + No transactions match the current filters. +

    + ) : ( + +
    + + Date + Description + Recorded by + Type + Amount + + + + {view.rows.map((transaction, index) => ( + + + {transaction.date} + + {transaction.description} + + {transaction.creatorName} + + + + {transaction.kind === 'payment' ? 'Payment' : 'Charge'} + + + + {transaction.amountFormatted} + + + ))} + + + )} + + )} + + ) +} +function PaymentsTableSkeleton() { return ( -
    -

    Payments

    - {hello &&

    {hello}

    } +
    +
    + {Array.from({ length: 5 }).map((_, index) => ( + + ))} +
    ) } diff --git a/web-client/src/features/sport-events/pages/SportEventsPage.tsx b/web-client/src/features/sport-events/pages/SportEventsPage.tsx index 52b70cf..ff0a1d6 100644 --- a/web-client/src/features/sport-events/pages/SportEventsPage.tsx +++ b/web-client/src/features/sport-events/pages/SportEventsPage.tsx @@ -1,12 +1,292 @@ -import { useSportEventsHello } from '../api' +import { useEffect } from 'react' + +import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { DataTable, TCell, THead, TRow } from '@/components/ui/data-table' +import { DateRangeFilter } from '@/components/ui/date-range-filter' +import { PageHeader } from '@/components/ui/page-header' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { Separator } from '@/components/ui/separator' +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, +} from '@/components/ui/sheet' +import { Skeleton } from '@/components/ui/skeleton' +import { StatCard } from '@/components/ui/stat-card' +import { TableToolbar } from '@/components/ui/table-toolbar' +import { formatDateShort, formatTime } from '@/lib/format' +import { memberRefName } from '@/types' +import { useEventsUiStore } from '../model/eventsUiStore' +import { + type EventStatus, + useEventDetailView, + useEventsViewModel, +} from '../model/useEventsViewModel' + +const statusLabel: Record = { + attended: 'Attended', + missed: 'Missed', + upcoming: 'Upcoming', + past: 'Past', +} + +const statusTone: Record['tone']> = { + attended: 'positive', + missed: 'negative', + upcoming: 'accent', + past: 'default', +} export function SportEventsPage() { - const { data: hello } = useSportEventsHello() + const { view, isLoading, error } = useEventsViewModel() + const filters = useEventsUiStore((state) => state.filters) + const setSearch = useEventsUiStore((state) => state.setSearch) + const setStatus = useEventsUiStore((state) => state.setStatus) + const setDateRange = useEventsUiStore((state) => state.setDateRange) + const setSort = useEventsUiStore((state) => state.setSort) + const resetFilters = useEventsUiStore((state) => state.resetFilters) + const openEventId = useEventsUiStore((state) => state.openEventId) + const openEvent = useEventsUiStore((state) => state.open) + const closeEvent = useEventsUiStore((state) => state.close) + const detailView = useEventDetailView(openEventId) + + useEffect(() => resetFilters, [resetFilters]) + + return ( +
    + + +
    + + + +
    + + {isLoading ? ( + + ) : error ? ( +

    + {error.message} +

    + ) : view.totalRows === 0 ? ( +

    + No events are listed yet. +

    + ) : ( + <> + + + + + + + + + {view.rows.length === 0 ? ( +

    + No events match the current filters. +

    + ) : ( + +
    + + When + Event + Status + Duration + Details + + + + {view.rows.map((event) => ( + + + {event.formattedWhen} + + {event.name} + + + {statusLabel[event.status]} + + + {event.duration} + + + + + ))} + + + )} + + )} + +

    + Sport, description and attendees load when you open an event. +

    + + !open && closeEvent()}> + + + + + + ) +} + +function EventDetailSheet({ detailView }: { detailView: ReturnType }) { + const { detail, isLoading, error, missed } = detailView + + if (isLoading) { + return ( +
    + + + + +
    + ) + } + + if (error) { + return ( +

    + {error.message} +

    + ) + } + + if (!detail) { + return ( +

    + Select an event to view details. +

    + ) + } + + return ( + <> + +

    + Event details +

    + + {detail.name} + + {detail.description} +
    + +
    +
    + + + +
    + +
    + Sports +
    + {detail.sports_linked?.map((sport) => ( + + {sport} + + ))} +
    +
    + +
    + Attendees ({detail.attendees?.length ?? 0}) +
    + {detail.attendees?.map((member) => ( + {memberRefName(member)} + ))} +
    +
    + + {missed && ( + <> + +

    + You missed this session. +

    + + )} +
    + + ) +} + +function EventsTableSkeleton() { + return ( +
    +
    + {Array.from({ length: 5 }).map((_, index) => ( + + ))} +
    +
    + ) +} + +function FieldLabel({ children }: { children: React.ReactNode }) { + return ( +

    {children}

    + ) +} +function Field({ label, value }: { label: string; value: string }) { return (
    -

    Events

    - {hello &&

    {hello}

    } + {label} +

    {value}

    ) } From 487e29255804f1ca024df16f469eb6b3cc8aa058 Mon Sep 17 00:00:00 2001 From: FadyGergesRezk <84906847+FadyGergesRezk@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:24:15 +0200 Subject: [PATCH 06/15] feat: roost branding, role-filtered sidebar, and theme picker --- web-client/index.html | 5 +- web-client/public/RoostFavIcon.svg | 16 ++ web-client/public/RoostIcon.svg | 15 ++ web-client/public/favicon.svg | 1 - web-client/src/app/layout/AppShell.tsx | 265 +++++++++++++++++-------- 5 files changed, 217 insertions(+), 85 deletions(-) create mode 100644 web-client/public/RoostFavIcon.svg create mode 100644 web-client/public/RoostIcon.svg delete mode 100644 web-client/public/favicon.svg diff --git a/web-client/index.html b/web-client/index.html index caea363..458851e 100644 --- a/web-client/index.html +++ b/web-client/index.html @@ -2,9 +2,10 @@ - + - web-client + Roost +
    + ) +} + +export function TCell({ className, ...props }: React.ComponentProps<'td'>) { + return ( + + ) +} + +export function TRow({ className, ...props }: React.ComponentProps<'tr'>) { + return ( +