mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-30 15:17:43 -05:00
Exported images w/ SQ season summary downloadable (#3272)
This commit is contained in:
@@ -51,6 +51,20 @@ import { SubNav, SubNavLink } from "~/components/SubNav";
|
||||
import { Table } from "~/components/Table";
|
||||
import { TierPill } from "~/components/TierPill";
|
||||
import { WeaponSelect } from "~/components/WeaponSelect";
|
||||
import {
|
||||
SeasonSummaryGraphic,
|
||||
type SeasonSummaryGraphicActivity,
|
||||
type SeasonSummaryGraphicBestSet,
|
||||
type SeasonSummaryGraphicStats,
|
||||
} from "~/features/img-export/components/SeasonSummaryGraphic";
|
||||
import {
|
||||
TournamentResultsGraphic,
|
||||
type TournamentResultsGraphicTeam,
|
||||
} from "~/features/img-export/components/TournamentResultsGraphic";
|
||||
import {
|
||||
TournamentRunGraphic,
|
||||
type TournamentRunGraphicMatch,
|
||||
} from "~/features/img-export/components/TournamentRunGraphic";
|
||||
import {
|
||||
Trophy,
|
||||
TrophyContextProvider,
|
||||
@@ -66,7 +80,7 @@ import { EXAMPLE_TROPHY_MODEL } from "../example-trophy-model";
|
||||
import { formFieldsShowcaseSchema } from "../form-examples-schema";
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["user", "q"],
|
||||
i18n: ["user", "q", "calendar", "tournament"],
|
||||
};
|
||||
|
||||
export const SECTIONS = [
|
||||
@@ -93,6 +107,21 @@ export const SECTIONS = [
|
||||
{ title: "Pagination", id: "pagination", component: PaginationSection },
|
||||
{ title: "Avatar", id: "avatar", component: AvatarSection },
|
||||
{ title: "User Card", id: "user-card", component: UserCardSection },
|
||||
{
|
||||
title: "Tournament Results Graphic",
|
||||
id: "tournament-results-graphic",
|
||||
component: TournamentResultsGraphicSection,
|
||||
},
|
||||
{
|
||||
title: "Tournament Run Graphic",
|
||||
id: "tournament-run-graphic",
|
||||
component: TournamentRunGraphicSection,
|
||||
},
|
||||
{
|
||||
title: "Season Summary Graphic",
|
||||
id: "season-summary-graphic",
|
||||
component: SeasonSummaryGraphicSection,
|
||||
},
|
||||
{
|
||||
title: "Form Messages",
|
||||
id: "form-messages",
|
||||
@@ -1634,6 +1663,432 @@ function UserCardSection({ id }: { id: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
const RESULTS_GRAPHIC_IMG_ROOT =
|
||||
"https://sendou.nyc3.cdn.digitaloceanspaces.com";
|
||||
|
||||
const RESULTS_GRAPHIC_TEAMS: TournamentResultsGraphicTeam[] = [
|
||||
{
|
||||
placement: 1,
|
||||
name: "Besto Friendo",
|
||||
players: [
|
||||
{ name: "Yeti" },
|
||||
{ name: "まるお", countryCode: "JP" },
|
||||
{ name: "🪄", countryCode: "FR" },
|
||||
{ name: "Grey", countryCode: "FR" },
|
||||
],
|
||||
weapons: [40, 2070, 8010, 5030],
|
||||
},
|
||||
{
|
||||
placement: 2,
|
||||
name: "輝く",
|
||||
players: [
|
||||
{ name: "Ali", countryCode: "CA" },
|
||||
{ name: "w" },
|
||||
{ name: "へでる" },
|
||||
{ name: "メガチャーレム" },
|
||||
],
|
||||
weapons: [210, 40, 2010, 1120],
|
||||
},
|
||||
{
|
||||
placement: 3,
|
||||
name: "Small Bubbler",
|
||||
logoUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/pickup-logo-867qQb75XxqndbJDbJzk3-1774655417856.webp`,
|
||||
players: [
|
||||
{ name: "Omegα" },
|
||||
{ name: "shadowind", countryCode: "US" },
|
||||
{ name: "Max", countryCode: "US" },
|
||||
{ name: "y0shell", countryCode: "GB" },
|
||||
],
|
||||
weapons: [5010, 2030, 1010, 0],
|
||||
},
|
||||
{
|
||||
placement: 4,
|
||||
name: "For fun.",
|
||||
players: [
|
||||
{ name: "Len. 🕷", countryCode: "VN" },
|
||||
{ name: "Jovan", countryCode: "NG" },
|
||||
{ name: "swish", countryCode: "US" },
|
||||
{ name: "prosper", countryCode: "NG" },
|
||||
],
|
||||
weapons: [240, 5040, 1030, 2070],
|
||||
},
|
||||
{
|
||||
placement: 5,
|
||||
name: "It’s too much",
|
||||
logoUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/pickup-logo-1R_1LhuEk6jecMsRWwCl--1774679643780.webp`,
|
||||
players: [
|
||||
{ name: "Coolaceeeee ^_^", countryCode: "JP" },
|
||||
{ name: "illusion" },
|
||||
{ name: "sunni" },
|
||||
{ name: "Chiva", countryCode: "MX" },
|
||||
],
|
||||
weapons: [1001, 220, 40, 2010],
|
||||
},
|
||||
{
|
||||
placement: 5,
|
||||
name: "ezmd",
|
||||
logoUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/Yu_tgElCa5D48CcyFPF3Y-1756077173431.webp`,
|
||||
players: [
|
||||
{ name: "Silver", countryCode: "FR" },
|
||||
{ name: "Devin", countryCode: "DE" },
|
||||
{ name: "kiki", countryCode: "IE" },
|
||||
{ name: "Reiyu", countryCode: "DO" },
|
||||
],
|
||||
weapons: [5011, 2000, 8020, 260],
|
||||
},
|
||||
{
|
||||
placement: 7,
|
||||
name: "healthy diet food groups",
|
||||
logoUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/OYhoGpd7lIRyyBawAfRx9-1673646086021.webp`,
|
||||
players: [
|
||||
{ name: "zyf", countryCode: "US" },
|
||||
{ name: "Blopwher", countryCode: "US" },
|
||||
{ name: "Stans", countryCode: "US" },
|
||||
{ name: "Miner", countryCode: "ET" },
|
||||
],
|
||||
weapons: [1100, 2040, 10, 5000],
|
||||
},
|
||||
{
|
||||
placement: 7,
|
||||
name: "WIT CHECK",
|
||||
players: [
|
||||
{ name: "Andre", countryCode: "TT" },
|
||||
{ name: "Isabel T.J.", countryCode: "ES" },
|
||||
{ name: "Chara", countryCode: "US" },
|
||||
{ name: "Basil", countryCode: "US" },
|
||||
],
|
||||
weapons: [200, 1020, 2060, 5020],
|
||||
},
|
||||
];
|
||||
|
||||
function TournamentResultsGraphicSection({ id }: { id: string }) {
|
||||
return (
|
||||
<Section>
|
||||
<SectionTitle id={id}>Tournament Results Graphic</SectionTitle>
|
||||
|
||||
<div className="stack md">
|
||||
<ComponentRow label="Top 8 export image">
|
||||
<TournamentResultsGraphic
|
||||
tournamentId={3435}
|
||||
tournamentName="In The Zone 50"
|
||||
startTime={new Date(1774720800 * 1000)}
|
||||
tier={2}
|
||||
logoUrl={`${RESULTS_GRAPHIC_IMG_ROOT}/tournament-logo-itz.png`}
|
||||
organization={{
|
||||
name: "sendou.ink",
|
||||
avatarUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/dBYwiLjlhVBwW-oyyNJkC-1721997877357.webp`,
|
||||
}}
|
||||
teams={RESULTS_GRAPHIC_TEAMS}
|
||||
teamsCount={32}
|
||||
playersCount={130}
|
||||
/>
|
||||
</ComponentRow>
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
const RUN_GRAPHIC_SWISS = "Day 1 - Swiss";
|
||||
const RUN_GRAPHIC_ALPHA = "Day 2 - Alpha Bracket";
|
||||
|
||||
const RUN_GRAPHIC_MATCHES: TournamentRunGraphicMatch[] = [
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[7], seed: 48 },
|
||||
ownScore: 2,
|
||||
opponentScore: 0,
|
||||
roundName: "Swiss 1",
|
||||
bracketName: RUN_GRAPHIC_SWISS,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[5], seed: 3 },
|
||||
ownScore: 2,
|
||||
opponentScore: 1,
|
||||
roundName: "Swiss 2",
|
||||
bracketName: RUN_GRAPHIC_SWISS,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[1], seed: 6 },
|
||||
ownScore: 1,
|
||||
opponentScore: 2,
|
||||
roundName: "Swiss 3",
|
||||
bracketName: RUN_GRAPHIC_SWISS,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[3], seed: 15 },
|
||||
ownScore: 2,
|
||||
opponentScore: 0,
|
||||
roundName: "Swiss 4",
|
||||
bracketName: RUN_GRAPHIC_SWISS,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[6], seed: 19 },
|
||||
ownScore: 2,
|
||||
opponentScore: 1,
|
||||
roundName: "Swiss 5",
|
||||
bracketName: RUN_GRAPHIC_SWISS,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[4], seed: 26 },
|
||||
ownScore: 2,
|
||||
opponentScore: 0,
|
||||
roundName: "Swiss 6",
|
||||
bracketName: RUN_GRAPHIC_SWISS,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[2], seed: 22 },
|
||||
ownScore: 2,
|
||||
opponentScore: 0,
|
||||
roundName: "WB Round 1",
|
||||
bracketName: RUN_GRAPHIC_ALPHA,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[5], seed: 3 },
|
||||
ownScore: 2,
|
||||
opponentScore: 1,
|
||||
roundName: "WB Round 2",
|
||||
bracketName: RUN_GRAPHIC_ALPHA,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[6], seed: 19 },
|
||||
ownScore: 2,
|
||||
opponentScore: 0,
|
||||
roundName: "WB Semis",
|
||||
bracketName: RUN_GRAPHIC_ALPHA,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[3], seed: 15 },
|
||||
ownScore: 2,
|
||||
opponentScore: 1,
|
||||
roundName: "WB Finals",
|
||||
bracketName: RUN_GRAPHIC_ALPHA,
|
||||
},
|
||||
{
|
||||
opponent: { ...RESULTS_GRAPHIC_TEAMS[1], seed: 6 },
|
||||
ownScore: 3,
|
||||
opponentScore: 1,
|
||||
roundName: "Grand Finals",
|
||||
bracketName: RUN_GRAPHIC_ALPHA,
|
||||
},
|
||||
];
|
||||
|
||||
function TournamentRunGraphicSection({ id }: { id: string }) {
|
||||
return (
|
||||
<Section>
|
||||
<SectionTitle id={id}>Tournament Run Graphic</SectionTitle>
|
||||
|
||||
<div className="stack md">
|
||||
<ComponentRow label="Team run export image">
|
||||
<TournamentRunGraphic
|
||||
tournamentId={3938}
|
||||
tournamentTeamId={73362}
|
||||
tournamentName="Low Ink June 2026"
|
||||
startTime={new Date(1781974800 * 1000)}
|
||||
tier={5}
|
||||
logoUrl={`${RESULTS_GRAPHIC_IMG_ROOT}/tournament-logo-zWk5C1kvQtEWrd7d2c_KS-1735836299376.webp`}
|
||||
organization={{
|
||||
name: "Inkling Performance Labs",
|
||||
avatarUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/fZrToLQrkqV3UZkdgwp0Q-1722263644749.webp`,
|
||||
}}
|
||||
team={RESULTS_GRAPHIC_TEAMS[0]}
|
||||
seed={11}
|
||||
matches={RUN_GRAPHIC_MATCHES}
|
||||
teamsCount={74}
|
||||
playersCount={349}
|
||||
seriesWins={{
|
||||
totalCount: 4,
|
||||
first: {
|
||||
name: "Low Ink May 2023",
|
||||
startTime: new Date("2023-05-20T18:00:00Z"),
|
||||
},
|
||||
latest: {
|
||||
name: "Low Ink February 2026",
|
||||
startTime: new Date("2026-02-21T18:00:00Z"),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</ComponentRow>
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
const SEASON_SUMMARY_DAYS: Array<
|
||||
[date: string, sp: number, activity: SeasonSummaryGraphicActivity]
|
||||
> = [
|
||||
["2026-03-02", 1875.2, "sq"],
|
||||
["2026-03-03", 1922.7, "sq"],
|
||||
["2026-03-06", 1898.4, "sq"],
|
||||
["2026-03-08", 1961.3, "tournament"],
|
||||
["2026-03-10", 2004.9, "sq"],
|
||||
["2026-03-12", 1987.1, "sq"],
|
||||
["2026-03-14", 2043.6, "sq"],
|
||||
["2026-03-17", 2071.2, "sq"],
|
||||
["2026-03-19", 2055.8, "sq"],
|
||||
["2026-03-22", 2102.4, "both"],
|
||||
["2026-03-25", 2138.9, "sq"],
|
||||
["2026-03-26", 2117.3, "sq"],
|
||||
["2026-03-29", 2164.0, "tournament"],
|
||||
["2026-04-02", 2189.5, "sq"],
|
||||
["2026-04-05", 2151.2, "tournament"],
|
||||
["2026-04-06", 2208.8, "sq"],
|
||||
["2026-04-09", 2247.3, "sq"],
|
||||
["2026-04-12", 2231.6, "both"],
|
||||
["2026-04-15", 2278.1, "sq"],
|
||||
["2026-04-16", 2296.4, "sq"],
|
||||
["2026-04-19", 2263.7, "tournament"],
|
||||
["2026-04-21", 2312.9, "sq"],
|
||||
["2026-04-24", 2340.2, "sq"],
|
||||
["2026-04-26", 2371.8, "both"],
|
||||
["2026-04-28", 2355.4, "sq"],
|
||||
["2026-05-01", 2389.7, "sq"],
|
||||
["2026-05-03", 2410.8, "tournament"],
|
||||
["2026-05-05", 2384.2, "sq"],
|
||||
["2026-05-08", 2401.5, "sq"],
|
||||
["2026-05-10", 2368.9, "both"],
|
||||
["2026-05-11", 2352.6, "sq"],
|
||||
["2026-05-14", 2377.3, "sq"],
|
||||
["2026-05-16", 2341.5, "sq"],
|
||||
];
|
||||
|
||||
const SEASON_SUMMARY_BEST_SETS: SeasonSummaryGraphicBestSet[] = [
|
||||
{
|
||||
context: "SendouQ",
|
||||
ownScore: 4,
|
||||
opponentScore: 2,
|
||||
opponentSp: 2489.3,
|
||||
opponentPlayers: [
|
||||
{ name: "Yeti" },
|
||||
{ name: "まるお", countryCode: "JP" },
|
||||
{ name: "Silver", countryCode: "FR" },
|
||||
{ name: "Chara", countryCode: "US" },
|
||||
],
|
||||
},
|
||||
{
|
||||
context: "In The Zone 50",
|
||||
ownScore: 3,
|
||||
opponentScore: 2,
|
||||
opponentSp: 2451.0,
|
||||
opponentPlayers: [
|
||||
{ name: "zyf", countryCode: "US" },
|
||||
{ name: "Blopwher", countryCode: "US" },
|
||||
{ name: "Stans", countryCode: "US" },
|
||||
{ name: "Miner", countryCode: "ET" },
|
||||
],
|
||||
},
|
||||
{
|
||||
context: "SendouQ",
|
||||
ownScore: 4,
|
||||
opponentScore: 3,
|
||||
opponentSp: 2413.7,
|
||||
opponentPlayers: [
|
||||
{ name: "Andre", countryCode: "TT" },
|
||||
{ name: "Devin", countryCode: "DE" },
|
||||
{ name: "kiki", countryCode: "IE" },
|
||||
{ name: "Reiyu", countryCode: "DO" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const SEASON_SUMMARY_STATS: SeasonSummaryGraphicStats = {
|
||||
tier: { name: "DIAMOND", isPlus: true },
|
||||
sp: 2341.5,
|
||||
setsWon: 41,
|
||||
setsLost: 18,
|
||||
mapsWon: 132,
|
||||
mapsLost: 77,
|
||||
longestWinStreak: 9,
|
||||
clutch: { won: 8, total: 12 },
|
||||
soloRank: 14,
|
||||
teamRank: {
|
||||
rank: 12,
|
||||
sp: 2502.4,
|
||||
mates: [
|
||||
{ name: "Grey", countryCode: "FR" },
|
||||
{ name: "sunni" },
|
||||
{ name: "Isabel T.J.", countryCode: "ES" },
|
||||
],
|
||||
team: {
|
||||
name: "Alliance Rogue",
|
||||
logoUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/Yu_tgElCa5D48CcyFPF3Y-1756077173431.webp`,
|
||||
},
|
||||
},
|
||||
topMates: [
|
||||
{
|
||||
player: { name: "Grey", countryCode: "FR" },
|
||||
discordId: "289132480999030784",
|
||||
setsCount: 23,
|
||||
},
|
||||
{
|
||||
player: { name: "sunni" },
|
||||
discordId: "437750362188120075",
|
||||
setsCount: 17,
|
||||
},
|
||||
{
|
||||
player: { name: "まるお", countryCode: "JP" },
|
||||
discordId: "196628310288564224",
|
||||
setsCount: 9,
|
||||
},
|
||||
{
|
||||
player: { name: "Chara", countryCode: "US" },
|
||||
discordId: "455039198672814090",
|
||||
setsCount: 8,
|
||||
},
|
||||
{
|
||||
player: { name: "Silver", countryCode: "FR" },
|
||||
discordId: "224378380316540929",
|
||||
setsCount: 6,
|
||||
},
|
||||
{ player: { name: "Yeti" }, discordId: "153113232128507904", setsCount: 4 },
|
||||
],
|
||||
bestStage: { stageId: 14, winratePercentage: 78 },
|
||||
spProgression: SEASON_SUMMARY_DAYS.map(([date, sp]) => ({ date, sp })),
|
||||
activeDays: SEASON_SUMMARY_DAYS.map(([date, , activity]) => ({
|
||||
date,
|
||||
activity,
|
||||
})),
|
||||
bestSets: SEASON_SUMMARY_BEST_SETS,
|
||||
bestTournament: {
|
||||
name: "In The Zone 50",
|
||||
logoUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/tournament-logo-itz.png`,
|
||||
tier: 2,
|
||||
placement: 2,
|
||||
teamsCount: 32,
|
||||
},
|
||||
topWeapons: [
|
||||
{ weaponSplId: 40, usagePercentage: 46 },
|
||||
{ weaponSplId: 1001, usagePercentage: 31 },
|
||||
{ weaponSplId: 2070, usagePercentage: 12 },
|
||||
],
|
||||
};
|
||||
|
||||
function SeasonSummaryGraphicSection({ id }: { id: string }) {
|
||||
return (
|
||||
<Section>
|
||||
<SectionTitle id={id}>Season Summary Graphic</SectionTitle>
|
||||
|
||||
<div className="stack md">
|
||||
<ComponentRow label="Season summary export image">
|
||||
<SeasonSummaryGraphic
|
||||
user={{
|
||||
name: "Sendou",
|
||||
discordId: "79237403620945920",
|
||||
customUrl: "sendou",
|
||||
countryCode: "FI",
|
||||
avatarUrl: `${RESULTS_GRAPHIC_IMG_ROOT}/dBYwiLjlhVBwW-oyyNJkC-1721997877357.webp`,
|
||||
}}
|
||||
season={8}
|
||||
seasonDateRange={{
|
||||
starts: new Date("2026-03-02T17:00:00.000Z"),
|
||||
ends: new Date("2026-05-17T20:59:59.999Z"),
|
||||
}}
|
||||
stats={SEASON_SUMMARY_STATS}
|
||||
/>
|
||||
</ComponentRow>
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
function FormMessageSection({ id }: { id: string }) {
|
||||
return (
|
||||
<Section>
|
||||
|
||||
Reference in New Issue
Block a user