From 8c8be5273b216c0182016bd191d56e780f6f5e8b Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Mon, 17 Feb 2025 20:59:50 +0100 Subject: [PATCH] Lib: Move data fetching functions to library --- src/lib/fetch.ts | 170 +++++++++++++++++++++++++++++++++ src/routes/+layout.ts | 94 +++--------------- src/routes/data/users/+page.ts | 17 +--- src/routes/racepicks/+page.ts | 42 +------- 4 files changed, 191 insertions(+), 132 deletions(-) create mode 100644 src/lib/fetch.ts diff --git a/src/lib/fetch.ts b/src/lib/fetch.ts new file mode 100644 index 0000000..aee4586 --- /dev/null +++ b/src/lib/fetch.ts @@ -0,0 +1,170 @@ +import { pb } from "./pocketbase"; +import type { + CurrentPickedUser, + Driver, + Graphic, + Race, + RacePick, + RaceResult, + Substitution, + Team, + User, +} from "./schema"; + +/** + * Fetch all [Graphics] from the database with file URLs + */ +export const fetch_graphics = async (fetch: (_: any) => Promise): Promise => { + const graphics: Graphic[] = await pb.collection("graphics").getFullList({ fetch: fetch }); + + graphics.map((graphic: Graphic) => { + graphic.file_url = pb.files.getURL(graphic, graphic.file); + }); + + return graphics; +}; + +/** + * Fetch all [Teams] (sorted ascending by name) from the database with file URLs for banners/logos + */ +export const fetch_teams = async (fetch: (_: any) => Promise): Promise => { + const teams: Team[] = await pb.collection("teams").getFullList({ + sort: "+name", + fetch: fetch, + }); + + teams.map((team: Team) => { + team.banner_url = pb.files.getURL(team, team.banner); + team.logo_url = pb.files.getURL(team, team.logo); + }); + + return teams; +}; + +/** + * Fetch all [Drivers] (sorted ascending by code) from the database with file URLs for headshots + */ +export const fetch_drivers = async (fetch: (_: any) => Promise): Promise => { + const drivers: Driver[] = await pb.collection("drivers").getFullList({ + sort: "+code", + fetch: fetch, + }); + + drivers.map((driver: Driver) => { + driver.headshot_url = pb.files.getURL(driver, driver.headshot); + }); + + return drivers; +}; + +/** + * Fetch all [Races] (sorted ascending by step) from the database with file URLs for pictograms + */ +export const fetch_races = async (fetch: (_: any) => Promise): Promise => { + const races: Race[] = await pb.collection("races").getFullList({ + sort: "+step", + fetch: fetch, + }); + + races.map((race: Race) => { + race.pictogram_url = pb.files.getURL(race, race.pictogram); + }); + + return races; +}; + +/** + * Fetch all [Substitutions] (sorted ascending by race step) from the database + */ +export const fetch_substitutions = async ( + fetch: (_: any) => Promise, +): Promise => { + const substitutions: Substitution[] = await pb.collection("substitutions").getFullList({ + expand: "race", + fetch: fetch, + }); + + // Sort by race step (ascending) + substitutions.sort((a: Substitution, b: Substitution) => a.expand.race.step - b.expand.race.step); + + return substitutions; +}; + +/** + * Fetch all [RaceResults] (sorted descending by race step - newest first) from the database + */ +export const fetch_raceresults = async ( + fetch: (_: any) => Promise, +): Promise => { + const raceresults: RaceResult[] = await pb + .collection("raceresultsdesc") + .getFullList({ fetch: fetch }); + + return raceresults; +}; + +/** + * Fetch all [Users] (sorted ascending by username) with file URLs for avatars + */ +export const fetch_users = async (fetch: (_: any) => Promise): Promise => { + const users: User[] = await pb + .collection("users") + .getFullList({ fetch: fetch, sort: "+username" }); + + users.map((user: User) => { + user.avatar_url = pb.files.getURL(user, user.avatar); + }); + + return users; +}; + +/** + * Fetch the first [Race] without result from the database with file URL for the pictogram + */ +export const fetch_currentrace = async ( + fetch: (_: any) => Promise, +): Promise => { + const currentrace: Race[] = await pb.collection("currentrace").getFullList({ fetch: fetch }); + + // The currentrace collection either has a single or no entries + if (currentrace.length == 0) return null; + + currentrace[0].pictogram_url = pb.files.getURL(currentrace[0], currentrace[0].pictogram); + + return currentrace[0]; +}; + +/** + * Fetch all [RacePicks] from the database + */ +export const fetch_racepicks = async ( + fetch: (_: any) => Promise, +): Promise => { + // Don't expand race/pxx/dnf since we already fetched those + const racepicks: RacePick[] = await pb + .collection("racepicks") + .getFullList({ fetch: fetch, expand: "user" }); + + return racepicks; +}; + +/** + * Fetch all [Users] (with the extra field "picked" that is truthy + * if the user already picked for the current race) + * for the current race with file URLs for the avatars + */ +export const fetch_currentpickedusers = async ( + fetch: (_: any) => Promise, +): Promise => { + const currentpickedusers: CurrentPickedUser[] = await pb + .collection("currentpickedusers") + .getFullList({ fetch: fetch }); + + currentpickedusers.map((currentpickeduser: CurrentPickedUser) => { + if (currentpickeduser.avatar) { + currentpickeduser.avatar_url = pb.files.getURL(currentpickeduser, currentpickeduser.avatar); + } + }); + + return currentpickedusers; +}; diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 04d8b43..2606ed1 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -1,4 +1,12 @@ -import { pb, pbUser } from "$lib/pocketbase"; +import { + fetch_drivers, + fetch_graphics, + fetch_raceresults, + fetch_races, + fetch_substitutions, + fetch_teams, +} from "$lib/fetch"; +import { pbUser } from "$lib/pocketbase"; // This makes the page client-side rendered export const ssr = false; @@ -12,91 +20,19 @@ import type { LayoutLoad } from "./$types"; // It will populate the "user" attribute of each page's "data" object, // so each page has access to the current user (or knows if no one is signed in). export const load: LayoutLoad = () => { - const fetch_graphics = async (): Promise => { - const graphics: Graphic[] = await pb.collection("graphics").getFullList({ fetch: fetch }); - - graphics.map((graphic: Graphic) => { - graphic.file_url = pb.files.getURL(graphic, graphic.file); - }); - - return graphics; - }; - - const fetch_teams = async (): Promise => { - const teams: Team[] = await pb.collection("teams").getFullList({ - sort: "+name", - fetch: fetch, - }); - - teams.map((team: Team) => { - team.banner_url = pb.files.getURL(team, team.banner); - team.logo_url = pb.files.getURL(team, team.logo); - }); - - return teams; - }; - - const fetch_drivers = async (): Promise => { - const drivers: Driver[] = await pb.collection("drivers").getFullList({ - sort: "+code", - fetch: fetch, - }); - - drivers.map((driver: Driver) => { - driver.headshot_url = pb.files.getURL(driver, driver.headshot); - }); - - return drivers; - }; - - const fetch_races = async (): Promise => { - const races: Race[] = await pb.collection("races").getFullList({ - sort: "+step", - fetch: fetch, - }); - - races.map((race: Race) => { - race.pictogram_url = pb.files.getURL(race, race.pictogram); - }); - - return races; - }; - - const fetch_substitutions = async (): Promise => { - const substitutions: Substitution[] = await pb.collection("substitutions").getFullList({ - expand: "race", - fetch: fetch, - }); - - // Sort by race step (ascending) - substitutions.sort( - (a: Substitution, b: Substitution) => a.expand.race.step - b.expand.race.step, - ); - - return substitutions; - }; - - const fetch_raceresults = async (): Promise => { - const raceresults: RaceResult[] = await pb - .collection("raceresultsdesc") - .getFullList({ fetch: fetch }); - - return raceresults; - }; - return { // User information (synchronous) user: pbUser, admin: pbUser?.admin ?? false, // Return static data - graphics: fetch_graphics(), - teams: fetch_teams(), - drivers: fetch_drivers(), - races: fetch_races(), - substitutions: fetch_substitutions(), + graphics: fetch_graphics(fetch), + teams: fetch_teams(fetch), + drivers: fetch_drivers(fetch), + races: fetch_races(fetch), + substitutions: fetch_substitutions(fetch), // Return other data - raceresults: fetch_raceresults(), + raceresults: fetch_raceresults(fetch), }; }; diff --git a/src/routes/data/users/+page.ts b/src/routes/data/users/+page.ts index 327d318..9832a8c 100644 --- a/src/routes/data/users/+page.ts +++ b/src/routes/data/users/+page.ts @@ -1,21 +1,8 @@ -import { pb } from "$lib/pocketbase"; -import type { User } from "$lib/schema"; +import { fetch_users } from "$lib/fetch"; import type { PageLoad } from "../../$types"; export const load: PageLoad = async ({ fetch }) => { - const fetch_users = async (): Promise => { - const users: User[] = await pb - .collection("users") - .getFullList({ fetch: fetch, sort: "+username" }); - - users.map((user: User) => { - user.avatar_url = pb.files.getURL(user, user.avatar); - }); - - return users; - }; - return { - users: await fetch_users(), + users: await fetch_users(fetch), }; }; diff --git a/src/routes/racepicks/+page.ts b/src/routes/racepicks/+page.ts index 20ca9eb..6e06327 100644 --- a/src/routes/racepicks/+page.ts +++ b/src/routes/racepicks/+page.ts @@ -1,45 +1,11 @@ -import { pb } from "$lib/pocketbase"; -import type { CurrentPickedUser, Race, RacePick } from "$lib/schema"; +import { fetch_currentpickedusers, fetch_currentrace, fetch_racepicks } from "$lib/fetch"; import type { PageLoad } from "../$types"; export const load: PageLoad = async ({ fetch }) => { - const fetch_currentrace = async (): Promise => { - const currentrace: Race[] = await pb.collection("currentrace").getFullList({ fetch: fetch }); - - // The currentrace collection either has a single or no entries - if (currentrace.length == 0) return null; - - currentrace[0].pictogram_url = pb.files.getURL(currentrace[0], currentrace[0].pictogram); - - return currentrace[0]; - }; - - const fetch_racepicks = async (): Promise => { - // Don't expand race/pxx/dnf since we already fetched those - const racepicks: RacePick[] = await pb - .collection("racepicks") - .getFullList({ fetch: fetch, expand: "user" }); - - return racepicks; - }; - - const fetch_currentpickedusers = async (): Promise => { - const currentpickedusers: CurrentPickedUser[] = await pb - .collection("currentpickedusers") - .getFullList({ fetch: fetch }); - - currentpickedusers.map((currentpickeduser: CurrentPickedUser) => { - if (currentpickeduser.avatar) { - currentpickeduser.avatar_url = pb.files.getURL(currentpickeduser, currentpickeduser.avatar); - } - }); - - return currentpickedusers; - }; return { - racepicks: fetch_racepicks(), - currentpickedusers: fetch_currentpickedusers(), + racepicks: fetch_racepicks(fetch), + currentpickedusers: fetch_currentpickedusers(fetch), - currentrace: await fetch_currentrace(), + currentrace: await fetch_currentrace(fetch), }; };