final: added personHistory

This commit is contained in:
Cron1cle
2025-10-23 03:17:46 +02:00
parent 73d883ae29
commit d40b90de41
7 changed files with 603 additions and 97 deletions

169
apis/personHistoryApi.ts Normal file
View File

@@ -0,0 +1,169 @@
export type PersonMini = {
personId: number;
name: string;
birthDate: string | null;
imageUrl?: string | null;
};
export type PersonHistoryRecord = {
seasonId: number;
showId: number;
startDate: string | null;
endDate: string | null;
seasonNumber: number;
partner: PersonMini | null;
seasonParticipants: (PersonMini & { partner?: PersonMini | null })[];
};
type RawSeasonNew = {
seasonId: number;
showId?: number;
show?: number;
seasonNumber: number;
startDate: string | null;
endDate: string | null;
partner?: {
personId: number;
name: string;
birthDate?: string | null;
imageUrl?: string | null;
} | null;
seasonParticipants?: {
personId: number;
name: string;
birthDate?: string | null;
imageUrl?: string | null;
}[];
};
type RawPersonOld = {
personId: number;
name: string;
birthDate?: string | null;
imageUrl?: string | null;
};
type RawSeasonOld = {
seasonId: number;
show?: number;
showId?: number;
seasonNumber: number;
startDate: string | null;
endDate: string | null;
seasonParticipants?:
| {
id?: { seasonId?: number; personId?: number };
person?: RawPersonOld | null;
partner?: RawPersonOld | null;
}[]
| null;
};
const PERSONS_BASE_URL = "http://45.157.177.99:8080/persons";
function toMini(p: any | undefined | null): PersonMini | null {
if (!p || !p.personId || !p.name) return null;
return {
personId: Number(p.personId),
name: String(p.name),
birthDate: p.birthDate ?? null,
imageUrl: p.imageUrl ?? null,
};
}
function isFlatSeason(s: any): s is RawSeasonNew {
const sp = s?.seasonParticipants;
return Array.isArray(sp) && (sp.length === 0 || "personId" in (sp[0] ?? {}));
}
function mapSeason(
s: RawSeasonNew | RawSeasonOld,
requestedPersonId: number
): PersonHistoryRecord {
const showId = Number((s as any).showId ?? (s as any).show ?? 0) || 0;
const base = {
seasonId: s.seasonId,
showId,
startDate: s.startDate ?? null,
endDate: s.endDate ?? null,
seasonNumber: s.seasonNumber,
};
if (isFlatSeason(s)) {
const seasonParticipants = Array.isArray(s.seasonParticipants)
? s.seasonParticipants
.map((p) => toMini(p))
.filter((x): x is PersonMini => !!x)
: [];
const partner = toMini(s.partner ?? null);
return {
...base,
partner,
seasonParticipants,
};
}
const spOld = (s as RawSeasonOld).seasonParticipants;
const seasonParticipantsOld = Array.isArray(spOld)
? spOld
.map((p) => {
const pid = p.person?.personId ?? p.id?.personId;
const name = p.person?.name ?? null;
if (!pid || !name) return null;
const me: PersonMini = {
personId: Number(pid),
name: String(name),
birthDate: p.person?.birthDate ?? null,
imageUrl: p.person?.imageUrl ?? null,
};
const partnerMini = toMini(p.partner ?? null);
return {
...me,
partner: partnerMini,
};
})
.filter((x): x is NonNullable<typeof x> => !!x)
: [];
const me =
seasonParticipantsOld.find((pp) => pp.personId === requestedPersonId) ||
null;
const partner = (me?.partner ?? null) as PersonMini | null;
return {
...base,
partner,
seasonParticipants: seasonParticipantsOld,
};
}
export async function getPersonHistory(
personId: number,
signal?: AbortSignal
): Promise<PersonHistoryRecord[]> {
const apiKey = process.env.EXPO_PUBLIC_API_KEY;
const url = `${PERSONS_BASE_URL}/${personId}/history`;
const res = await fetch(url, {
signal,
headers: {
"Content-Type": "application/json",
"X-API-Key": apiKey ?? "",
},
});
if (!res.ok) throw new Error("GetPersonHistory failed " + res.status);
const data: unknown = await res.json();
if (!Array.isArray(data)) return [];
return (data as (RawSeasonNew | RawSeasonOld)[]).map((s) =>
mapSeason(s, personId)
);
}