170 lines
4.0 KiB
TypeScript
170 lines
4.0 KiB
TypeScript
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 = "https://fltr-app.de/api/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)
|
|
);
|
|
}
|