Compare commits

...

12 Commits

7 changed files with 160 additions and 125 deletions

12
flake.lock generated
View File

@ -5,11 +5,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1735644329, "lastModified": 1741473158,
"narHash": "sha256-tO3HrHriyLvipc4xr+Ewtdlo7wM1OjXNjlWRgmM7peY=", "narHash": "sha256-kWNaq6wQUbUMlPgw8Y+9/9wP0F8SHkjy24/mN3UAppg=",
"owner": "numtide", "owner": "numtide",
"repo": "devshell", "repo": "devshell",
"rev": "f7795ede5b02664b57035b3b757876703e2c3eac", "rev": "7c9e793ebe66bcba8292989a68c0419b737a22a0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -54,11 +54,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1737717945, "lastModified": 1741865919,
"narHash": "sha256-ET91TMkab3PmOZnqiJQYOtSGvSTvGeHoegAv4zcTefM=", "narHash": "sha256-4thdbnP6dlbdq+qZWTsm4ffAwoS8Tiq1YResB+RP6WE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "ecd26a469ac56357fd333946a99086e992452b6a", "rev": "573c650e8a14b2faa0041645ab18aed7e60f0c9a",
"type": "github" "type": "github"
}, },
"original": { "original": {

15
package-lock.json generated
View File

@ -31,6 +31,7 @@
"svelte-check": "^4.1.5", "svelte-check": "^4.1.5",
"tailwindcss": "^3.4.17", "tailwindcss": "^3.4.17",
"typescript": "^5.8.2", "typescript": "^5.8.2",
"uuid": "^11.1.0",
"vite": "^6.2.2" "vite": "^6.2.2"
} }
}, },
@ -3870,6 +3871,20 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/uuid": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
"dev": true,
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "6.2.2", "version": "6.2.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz",

View File

@ -30,6 +30,7 @@
"svelte-check": "^4.1.5", "svelte-check": "^4.1.5",
"tailwindcss": "^3.4.17", "tailwindcss": "^3.4.17",
"typescript": "^5.8.2", "typescript": "^5.8.2",
"uuid": "^11.1.0",
"vite": "^6.2.2" "vite": "^6.2.2"
}, },
"dependencies": { "dependencies": {

View File

@ -2,6 +2,8 @@
import type { HTMLImgAttributes } from "svelte/elements"; import type { HTMLImgAttributes } from "svelte/elements";
import { lazyload } from "$lib/lazyload"; import { lazyload } from "$lib/lazyload";
import { fetch_image_base64 } from "$lib/image"; import { fetch_image_base64 } from "$lib/image";
import { popup, type PopupSettings } from "@skeletonlabs/skeleton";
import { v4 as uuidv4 } from "uuid";
interface LazyImageProps extends HTMLImgAttributes { interface LazyImageProps extends HTMLImgAttributes {
/** The URL to the image resource to lazyload */ /** The URL to the image resource to lazyload */
@ -24,6 +26,9 @@
/** Slightly zoom the image on mouse-hover */ /** Slightly zoom the image on mouse-hover */
hoverzoom?: boolean; hoverzoom?: boolean;
/** Optional tooltip text */
tooltip?: string;
} }
let { let {
@ -34,6 +39,7 @@
containerstyle = undefined, containerstyle = undefined,
imgclass = "", imgclass = "",
hoverzoom = false, hoverzoom = false,
tooltip = undefined,
...restProps ...restProps
}: LazyImageProps = $props(); }: LazyImageProps = $props();
@ -49,6 +55,14 @@
const img_opacity_handler = (node: HTMLElement) => { const img_opacity_handler = (node: HTMLElement) => {
setTimeout(() => (node.style.opacity = "1"), 20); setTimeout(() => (node.style.opacity = "1"), 20);
}; };
// Tooltip handling
const tooltipId: string = uuidv4();
const popupTooltip: PopupSettings = {
event: "hover",
target: tooltipId,
placement: "top",
};
</script> </script>
<!-- Show a correctly sized div so the layout doesn't jump. --> <!-- Show a correctly sized div so the layout doesn't jump. -->
@ -67,8 +81,16 @@
class="bg-surface-100 transition-all {imgclass} {hoverzoom ? 'hover:scale-105' : ''}" class="bg-surface-100 transition-all {imgclass} {hoverzoom ? 'hover:scale-105' : ''}"
style="opacity: 0; transition-duration: 300ms; {imgstyle ?? ''}" style="opacity: 0; transition-duration: 300ms; {imgstyle ?? ''}"
draggable="false" draggable="false"
use:popup={popupTooltip}
{...restProps} {...restProps}
/> />
{/await} {/await}
{/if} {/if}
</div> </div>
{#if tooltip}
<div class="card variant-filled-surface p-2 shadow" data-popup={tooltipId}>
<p>{tooltip}</p>
<div class="variant-filled-surface arrow"></div>
</div>
{/if}

View File

@ -489,7 +489,7 @@
</Button> </Button>
</div> </div>
</div> </div>
{:else if $drawerStore.id === "profile_drawer" && pbUser} {:else if $drawerStore.id === "profile_drawer" && $pbUser}
<!-- Profile Drawer --> <!-- Profile Drawer -->
<!-- Profile Drawer --> <!-- Profile Drawer -->
<!-- Profile Drawer --> <!-- Profile Drawer -->

View File

@ -67,7 +67,8 @@
<title>Formula 11 - Race Picks</title> <title>Formula 11 - Race Picks</title>
</svelte:head> </svelte:head>
{#if data.currentrace} <!-- Only show the userguess if signed in and we have a next race -->
{#if $pbUser && data.currentrace}
{#await Promise.all( [data.drivers, data.currentpickedusers, pickedusers, outstandingusers], ) then [drivers, currentpicked, picked, outstanding]} {#await Promise.all( [data.drivers, data.currentpickedusers, pickedusers, outstandingusers], ) then [drivers, currentpicked, picked, outstanding]}
<Accordion class="card mx-auto bg-surface-500 shadow" regionPanel="pt-0" width="w-full"> <Accordion class="card mx-auto bg-surface-500 shadow" regionPanel="pt-0" width="w-full">
<AccordionItem> <AccordionItem>
@ -76,10 +77,7 @@
<span class="font-bold">Next Race Guess</span> <span class="font-bold">Next Race Guess</span>
</svelte:fragment> </svelte:fragment>
<svelte:fragment slot="content"> <svelte:fragment slot="content">
<div <div class="grid grid-cols-2 gap-2 lg:mx-auto lg:w-fit lg:grid-cols-6">
class="grid grid-cols-2 gap-2 lg:mx-auto lg:w-fit
{pbUser ? 'lg:grid-cols-6' : 'lg:grid-cols-4'}"
>
<!-- Show information about the next race --> <!-- Show information about the next race -->
<div class="card flex w-full min-w-40 flex-col p-2 shadow lg:max-w-40"> <div class="card flex w-full min-w-40 flex-col p-2 shadow lg:max-w-40">
<span class="font-bold"> <span class="font-bold">
@ -123,45 +121,42 @@
/> />
</div> </div>
<!-- Only show the userguess if signed in --> <!-- PXX pick -->
{#if pbUser} <div class="card w-full min-w-40 p-2 pb-0 shadow lg:max-w-40">
<!-- PXX pick --> <h1 class="mb-2 text-nowrap font-bold">Your P{data.currentrace.pxx} Pick:</h1>
<div class="card w-full min-w-40 p-2 pb-0 shadow lg:max-w-40"> <LazyImage
<h1 class="mb-2 text-nowrap font-bold">Your P{data.currentrace.pxx} Pick:</h1> src={get_by_value(drivers, "id", data.racepick?.pxx ?? "")?.headshot_url ??
<LazyImage get_driver_headshot_template(data.graphics)}
src={get_by_value(drivers, "id", data.racepick?.pxx ?? "")?.headshot_url ?? imgwidth={DRIVER_HEADSHOT_WIDTH}
get_driver_headshot_template(data.graphics)} imgheight={DRIVER_HEADSHOT_HEIGHT}
imgwidth={DRIVER_HEADSHOT_WIDTH} containerstyle="height: 115px; margin: auto;"
imgheight={DRIVER_HEADSHOT_HEIGHT} imgclass="bg-transparent cursor-pointer"
containerstyle="height: 115px; margin: auto;" hoverzoom
imgclass="bg-transparent cursor-pointer" onclick={racepick_handler}
hoverzoom />
onclick={racepick_handler} </div>
/>
</div>
<!-- DNF pick --> <!-- DNF pick -->
<div class="card w-full min-w-40 p-2 pb-0 shadow lg:max-w-40"> <div class="card w-full min-w-40 p-2 pb-0 shadow lg:max-w-40">
<h1 class="mb-2 text-nowrap font-bold">Your DNF Pick:</h1> <h1 class="mb-2 text-nowrap font-bold">Your DNF Pick:</h1>
<LazyImage <LazyImage
src={get_by_value(drivers, "id", data.racepick?.dnf ?? "")?.headshot_url ?? src={get_by_value(drivers, "id", data.racepick?.dnf ?? "")?.headshot_url ??
get_driver_headshot_template(data.graphics)} get_driver_headshot_template(data.graphics)}
imgwidth={DRIVER_HEADSHOT_WIDTH} imgwidth={DRIVER_HEADSHOT_WIDTH}
imgheight={DRIVER_HEADSHOT_HEIGHT} imgheight={DRIVER_HEADSHOT_HEIGHT}
containerstyle="height: 115px; margin: auto;" containerstyle="height: 115px; margin: auto;"
imgclass="bg-transparent cursor-pointer" imgclass="bg-transparent cursor-pointer"
hoverzoom hoverzoom
onclick={racepick_handler} onclick={racepick_handler}
/> />
</div> </div>
{/if}
<!-- Show users that have picked --> <!-- Show users that have picked -->
<div class="card w-full min-w-40 p-2 shadow lg:max-w-40"> <div class="card max-h-[155px] w-full min-w-40 p-2 shadow lg:max-w-40">
<h1 class="text-nowrap font-bold"> <h1 class="text-nowrap font-bold">
Picked ({picked.length}/{currentpicked.length}): Picked ({picked.length}/{currentpicked.length}):
</h1> </h1>
<div class="mt-1 grid grid-cols-4 gap-x-0 gap-y-0.5"> <div class="mt-1 grid max-h-[110px] grid-cols-4 gap-x-0 gap-y-0.5 overflow-y-scroll">
{#each picked as user} {#each picked as user}
<LazyImage <LazyImage
src={user.avatar_url ?? get_driver_headshot_template(data.graphics)} src={user.avatar_url ?? get_driver_headshot_template(data.graphics)}
@ -169,19 +164,18 @@
imgheight={AVATAR_HEIGHT} imgheight={AVATAR_HEIGHT}
containerstyle="height: 35px; width: 35px;" containerstyle="height: 35px; width: 35px;"
imgclass="bg-surface-400 rounded-full" imgclass="bg-surface-400 rounded-full"
tooltip={user.firstname}
/> />
{/each} {/each}
</div> </div>
</div> </div>
<!-- Show users that have not picked yet --> <!-- Show users that have not picked yet -->
<div <div class="card max-h-[155px] w-full min-w-40 p-2 shadow lg:max-w-40">
class="card max-h-[155px] w-full min-w-40 overflow-y-scroll p-2 shadow lg:max-w-40"
>
<h1 class="text-nowrap font-bold"> <h1 class="text-nowrap font-bold">
Missing ({outstanding.length}/{currentpicked.length}): Missing ({outstanding.length}/{currentpicked.length}):
</h1> </h1>
<div class="mt-1 grid grid-cols-4 gap-x-0 gap-y-0.5"> <div class="mt-1 grid max-h-[110px] grid-cols-4 gap-x-0 gap-y-0.5 overflow-y-scroll">
{#each outstanding as user} {#each outstanding as user}
<LazyImage <LazyImage
src={user.avatar_url ?? get_driver_headshot_template(data.graphics)} src={user.avatar_url ?? get_driver_headshot_template(data.graphics)}
@ -189,6 +183,7 @@
imgheight={AVATAR_HEIGHT} imgheight={AVATAR_HEIGHT}
containerstyle="height: 35px; width: 35px;" containerstyle="height: 35px; width: 35px;"
imgclass="bg-surface-400 rounded-full" imgclass="bg-surface-400 rounded-full"
tooltip={user.firstname}
/> />
{/each} {/each}
</div> </div>
@ -201,7 +196,7 @@
{/if} {/if}
<!-- The fookin table --> <!-- The fookin table -->
<div class="flex"> <div class="flex {!$pbUser ? 'mt-[-8px]' : ''}">
<div> <div>
<!-- Points color coding legend --> <!-- Points color coding legend -->
<!-- Use mt-3/mt-4 to account for 2x padding around the avatar. --> <!-- Use mt-3/mt-4 to account for 2x padding around the avatar. -->
@ -320,6 +315,7 @@
imgheight={AVATAR_HEIGHT} imgheight={AVATAR_HEIGHT}
containerstyle="height: 40px; width: 40px;" containerstyle="height: 40px; width: 40px;"
imgclass="bg-surface-400 rounded-full" imgclass="bg-surface-400 rounded-full"
tooltip={user.firstname}
/> />
<div <div
style="height: 40px; line-height: 40px;" style="height: 40px; line-height: 40px;"

View File

@ -61,33 +61,29 @@
</svelte:head> </svelte:head>
<!-- Await this here so the accordion doesn't lag when opening --> <!-- Await this here so the accordion doesn't lag when opening -->
{#await Promise.all( [data.drivers, data.teams, data.seasonpicks, data.seasonpickedusers, pickedusers, outstandingusers], ) then [drivers, teams, seasonpicks, currentpicked, picked, outstanding]} <!-- Only show the stuff if signed in -->
<Accordion class="card mx-auto bg-surface-500 shadow" regionPanel="pt-2" width="w-full"> {#if $pbUser}
<AccordionItem> {#await Promise.all( [data.drivers, data.teams, data.seasonpickedusers, pickedusers, outstandingusers], ) then [drivers, teams, currentpicked, picked, outstanding]}
<svelte:fragment slot="lead"><ChequeredFlagIcon /></svelte:fragment> {@const teamwinners = data.seasonpick
<svelte:fragment slot="summary"> ? data.seasonpick.teamwinners
<span class="font-bold">Your Season Pick</span> .map((id: string) => get_by_value(drivers, "id", id) as Driver)
</svelte:fragment> .sort((a: Driver, b: Driver) => a.team.localeCompare(b.team))
<svelte:fragment slot="content"> : undefined}
<div {@const podiums = data.seasonpick
class="grid grid-cols-2 gap-2 lg:mx-auto lg:w-fit {pbUser ? data.seasonpick.podiums
? 'lg:grid-cols-5 2xl:grid-cols-10' .map((id: string) => get_by_value(drivers, "id", id) as Driver)
: 'lg:grid-cols-2 2xl:grid-cols-2'}" .sort((a: Driver, b: Driver) => a.code.localeCompare(b.code))
> .sort((a: Driver, b: Driver) => a.team.localeCompare(b.team))
<!-- Only show the stuff if signed in --> : undefined}
{#if $pbUser}
{@const teamwinners = data.seasonpick
? data.seasonpick.teamwinners
.map((id: string) => get_by_value(drivers, "id", id) as Driver)
.sort((a: Driver, b: Driver) => a.team.localeCompare(b.team))
: [undefined]}
{@const podiums = data.seasonpick
? data.seasonpick.podiums
.map((id: string) => get_by_value(drivers, "id", id) as Driver)
.sort((a: Driver, b: Driver) => a.code.localeCompare(b.code))
.sort((a: Driver, b: Driver) => a.team.localeCompare(b.team))
: [undefined]}
<Accordion class="card mx-auto bg-surface-500 shadow" regionPanel="pt-2" width="w-full">
<AccordionItem>
<svelte:fragment slot="lead"><ChequeredFlagIcon /></svelte:fragment>
<svelte:fragment slot="summary">
<span class="font-bold">Your Season Pick</span>
</svelte:fragment>
<svelte:fragment slot="content">
<div class="grid grid-cols-2 gap-2 lg:mx-auto lg:w-fit lg:grid-cols-5 2xl:grid-cols-10">
<!-- Hottake --> <!-- Hottake -->
<div class="card w-full min-w-40 p-2 shadow lg:max-w-40"> <div class="card w-full min-w-40 p-2 shadow lg:max-w-40">
<h1 class="mb-2 text-nowrap font-bold">Hottake:</h1> <h1 class="mb-2 text-nowrap font-bold">Hottake:</h1>
@ -165,91 +161,89 @@
</div> </div>
<!-- Teamwinners --> <!-- Teamwinners -->
<div <div class="card max-h-[155px] w-full min-w-40 p-2 shadow lg:max-w-40">
class="card max-h-[155px] w-full min-w-40 overflow-y-scroll p-2 shadow lg:max-w-40"
>
<h1 class="text-nowrap font-bold">Teamwinners:</h1> <h1 class="text-nowrap font-bold">Teamwinners:</h1>
<div class="mt-1 grid grid-cols-4 gap-x-0 gap-y-0.5"> <div class="mt-1 grid max-h-[110px] grid-cols-4 gap-x-0 gap-y-0.5 overflow-y-scroll">
{#each teamwinners.slice(0, 12) as winner} {#if teamwinners}
<LazyImage {#each teamwinners as winner}
src={winner?.headshot_url ?? get_driver_headshot_template(data.graphics)} <LazyImage
imgwidth={AVATAR_WIDTH} src={winner.headshot_url ?? get_driver_headshot_template(data.graphics)}
imgheight={AVATAR_HEIGHT} imgwidth={AVATAR_WIDTH}
containerstyle="height: 35px; width: 35px;" imgheight={AVATAR_HEIGHT}
imgclass="bg-surface-400 rounded-full" containerstyle="height: 35px; width: 35px;"
/> imgclass="bg-surface-400 rounded-full"
{/each} tooltip={winner ? `${winner.firstname} ${winner.lastname}` : undefined}
/>
{/each}
{/if}
</div> </div>
</div> </div>
<!-- Podiums --> <!-- Podiums -->
<div <div class="card max-h-[155px] w-full min-w-40 p-2 shadow lg:max-w-40">
class="card max-h-[155px] w-full min-w-40 overflow-y-scroll p-2 shadow lg:max-w-40"
>
<h1 class="text-nowrap font-bold">Podiums:</h1> <h1 class="text-nowrap font-bold">Podiums:</h1>
<div class="mt-1 grid grid-cols-4 gap-x-0 gap-y-0.5"> <div class="mt-1 grid max-h-[110px] grid-cols-4 gap-x-0 gap-y-0.5 overflow-y-scroll">
{#each podiums as podium} {#if podiums}
<LazyImage {#each podiums as podium}
src={podium?.headshot_url ?? get_driver_headshot_template(data.graphics)} <LazyImage
imgwidth={AVATAR_WIDTH} src={podium.headshot_url ?? get_driver_headshot_template(data.graphics)}
imgheight={AVATAR_HEIGHT} imgwidth={AVATAR_WIDTH}
containerstyle="height: 35px; width: 35px;" imgheight={AVATAR_HEIGHT}
imgclass="bg-surface-400 rounded-full" containerstyle="height: 35px; width: 35px;"
/> imgclass="bg-surface-400 rounded-full"
{/each} tooltip={podium ? `${podium.firstname} ${podium.lastname}` : undefined}
/>
{/each}
{/if}
</div> </div>
</div> </div>
{/if}
<!-- Show users that have picked --> <!-- Show users that have picked -->
{#if seasonpicks.length === 0} <div class="card max-h-[155px] w-full min-w-40 p-2 shadow lg:max-w-40">
<div
class="card max-h-[155px] w-full min-w-40 overflow-y-scroll p-2 shadow lg:max-w-40"
>
<h1 class="text-nowrap font-bold"> <h1 class="text-nowrap font-bold">
Picked ({picked.length}/{currentpicked.length}): Picked ({picked.length}/{currentpicked.length}):
</h1> </h1>
<div class="mt-1 grid grid-cols-4 gap-x-0 gap-y-0.5"> <div class="mt-1 grid max-h-[110px] grid-cols-4 gap-x-0 gap-y-0.5 overflow-y-scroll">
{#each picked.slice(0, 16) as user} {#each picked as user}
<LazyImage <LazyImage
src={user.avatar_url ?? get_driver_headshot_template(data.graphics)} src={user.avatar_url ?? get_driver_headshot_template(data.graphics)}
imgwidth={AVATAR_WIDTH} imgwidth={AVATAR_WIDTH}
imgheight={AVATAR_HEIGHT} imgheight={AVATAR_HEIGHT}
containerstyle="height: 35px; width: 35px;" containerstyle="height: 35px; width: 35px;"
imgclass="bg-surface-400 rounded-full" imgclass="bg-surface-400 rounded-full"
tooltip={user.firstname}
/> />
{/each} {/each}
</div> </div>
</div> </div>
<!-- Show users that have not picked yet --> <!-- Show users that have not picked yet -->
<div <div class="card max-h-[155px] w-full min-w-40 p-2 shadow lg:max-w-40">
class="card max-h-[155px] w-full min-w-40 overflow-y-scroll p-2 shadow lg:max-w-40"
>
<h1 class="text-nowrap font-bold"> <h1 class="text-nowrap font-bold">
Missing ({outstanding.length}/{currentpicked.length}): Missing ({outstanding.length}/{currentpicked.length}):
</h1> </h1>
<div class="mt-1 grid grid-cols-4 gap-x-0 gap-y-0.5"> <div class="mt-1 grid max-h-[110px] grid-cols-4 gap-x-0 gap-y-0.5 overflow-y-scroll">
{#each outstanding.slice(0, 16) as user} {#each outstanding as user}
<LazyImage <LazyImage
src={user.avatar_url ?? get_driver_headshot_template(data.graphics)} src={user.avatar_url ?? get_driver_headshot_template(data.graphics)}
imgwidth={AVATAR_WIDTH} imgwidth={AVATAR_WIDTH}
imgheight={AVATAR_HEIGHT} imgheight={AVATAR_HEIGHT}
containerstyle="height: 35px; width: 35px;" containerstyle="height: 35px; width: 35px;"
imgclass="bg-surface-400 rounded-full" imgclass="bg-surface-400 rounded-full"
tooltip={user.firstname}
/> />
{/each} {/each}
</div> </div>
</div> </div>
{/if} </div>
</div> </svelte:fragment>
</svelte:fragment> </AccordionItem>
</AccordionItem> </Accordion>
</Accordion> {/await}
{/await} {/if}
<!-- The fookin table --> <!-- The fookin table -->
<div class="flex"> <div class="{!$pbUser ? 'mt-[-8px]' : ''} flex">
<div> <div>
<!-- TODO: Points popup? --> <!-- TODO: Points popup? -->
<div class="mt-4 h-10 w-7 lg:w-36"></div> <div class="mt-4 h-10 w-7 lg:w-36"></div>
@ -274,9 +268,9 @@
<div <div
class="card mt-2 flex h-20 w-7 flex-col !rounded-r-none bg-surface-300 p-2 shadow lg:w-36" class="card mt-2 flex h-20 w-7 flex-col !rounded-r-none bg-surface-300 p-2 shadow lg:w-36"
> >
<span class="hidden text-nowrap text-sm font-bold lg:block" <span class="hidden text-nowrap text-sm font-bold lg:block">
>Constructors<br />Champion</span Constructors<br />Champion
> </span>
<span class="block rotate-90 text-nowrap text-xs font-bold lg:hidden">WCC</span> <span class="block rotate-90 text-nowrap text-xs font-bold lg:hidden">WCC</span>
</div> </div>
@ -352,6 +346,7 @@
imgheight={AVATAR_HEIGHT} imgheight={AVATAR_HEIGHT}
containerstyle="height: 40px; width: 40px;" containerstyle="height: 40px; width: 40px;"
imgclass="bg-surface-400 rounded-full" imgclass="bg-surface-400 rounded-full"
tooltip={user.firstname}
/> />
<div <div
style="height: 40px; line-height: 40px;" style="height: 40px; line-height: 40px;"
@ -380,6 +375,7 @@
imgheight={DRIVER_HEADSHOT_WIDTH} imgheight={DRIVER_HEADSHOT_WIDTH}
containerstyle="height: 62px;" containerstyle="height: 62px;"
imgclass="bg-surface-400 rounded-md" imgclass="bg-surface-400 rounded-md"
tooltip={wdcwinner ? `${wdcwinner.firstname} ${wdcwinner.lastname}` : undefined}
/> />
</div> </div>
</div> </div>
@ -393,6 +389,7 @@
imgheight={TEAM_BANNER_HEIGHT} imgheight={TEAM_BANNER_HEIGHT}
containerstyle="height: 62px;" containerstyle="height: 62px;"
imgclass="bg-surface-400 rounded-md" imgclass="bg-surface-400 rounded-md"
tooltip={wccwinner?.name}
/> />
</div> </div>
</div> </div>
@ -406,6 +403,9 @@
imgheight={DRIVER_HEADSHOT_WIDTH} imgheight={DRIVER_HEADSHOT_WIDTH}
containerstyle="height: 62px;" containerstyle="height: 62px;"
imgclass="bg-surface-400 rounded-md" imgclass="bg-surface-400 rounded-md"
tooltip={mostovertakes
? `${mostovertakes.firstname} ${mostovertakes.lastname}`
: undefined}
/> />
</div> </div>
</div> </div>
@ -419,6 +419,7 @@
imgheight={DRIVER_HEADSHOT_WIDTH} imgheight={DRIVER_HEADSHOT_WIDTH}
containerstyle="height: 62px;" containerstyle="height: 62px;"
imgclass="bg-surface-400 rounded-md" imgclass="bg-surface-400 rounded-md"
tooltip={mostdnfs ? `${mostdnfs.firstname} ${mostdnfs.lastname}` : undefined}
/> />
</div> </div>
</div> </div>