feat: idk bro

This commit is contained in:
TrèsAbhi committed 2026-01-18 18:38:26 -06:00
1 parent 49f84db473
commit 323d624ec7
8 files changed
+191 -48

No files matched your search

+38
View File
@@ -40,6 +40,44 @@
"name": "API", "name": "API",
"action": "To docs", "action": "To docs",
"slogan": "BlitzKit hosted API" "slogan": "BlitzKit hosted API"
},
"settings": {
"name": "Settings"
},
"players": {
"name": "Players",
"slogan": "Player statistics",
"action": "Stalk player"
},
"compare": {
"name": "Compare",
"slogan": "Compare tanks characteristics",
"action": "Compare now"
},
"performance": {
"name": "Performance",
"slogan": "Tank performance statistics",
"action": "View tanks"
},
"playlist": {
"name": "Playlist",
"slogan": "Tank playlist generator",
"action": "Generate"
},
"mixer": {
"name": "Mixer",
"slogan": "Tank module mixer",
"action": "Mix and match"
},
"session": {
"name": "Session",
"slogan": "Live player statistics",
"action": "Track"
},
"guesser": {
"name": "Guesser",
"slogan": "Silhouette mini-game",
"action": "Play"
} }
}, },
+39 -29
View File
@@ -1,20 +1,24 @@
--- ---
import {
GearIcon,
HamburgerMenuIcon,
MagnifyingGlassIcon,
} from "@radix-ui/react-icons";
import { BlitzKitIcon } from "../icons/BlitzKit"; import { BlitzKitIcon } from "../icons/BlitzKit";
import { LinkI18n } from "./LinkI18n"; import { LinkI18n } from "./LinkI18n";
import { Text } from "./Text"; import { Text } from "./Text";
import { api } from "../core/api/dynamic"; import { api } from "../core/api/dynamic";
import { tools } from "../core/tools/tools";
import type { Tool } from "../core/tools/tools";
interface Props { interface Props {
locale: string; locale: string;
selectedTool?: Tool;
} }
const { locale } = Astro.props; const { locale, selectedTool } = Astro.props;
const strings = await api.strings(locale); const strings = await api.strings(locale);
const toolsArray = Object.values(tools);
const toolsSorted =
selectedTool === undefined
? toolsArray
: [selectedTool, ...toolsArray.filter((tool) => tool !== selectedTool)];
--- ---
<style> <style>
@@ -55,8 +59,8 @@ const strings = await api.strings(locale);
width: 100%; width: 100%;
max-width: calc(var(--page-width) + 2 * var(--space-4)); max-width: calc(var(--page-width) + 2 * var(--space-4));
display: flex; display: grid;
align-items: center; grid-template-columns: repeat(4, 1fr);
.action { .action {
flex: 1; flex: 1;
@@ -95,8 +99,8 @@ const strings = await api.strings(locale);
max-width: var(--space-6); max-width: var(--space-6);
.icon { .icon {
width: 1.25em;
height: 1.25em; height: 1.25em;
width: 100%;
vertical-align: top; vertical-align: top;
} }
} }
@@ -127,32 +131,38 @@ const strings = await api.strings(locale);
<div class="bar"></div> <div class="bar"></div>
<div class="content"> <div class="content">
<LinkI18n {locale} href="/" className="action" tabIndex={0} data-selected> <LinkI18n
{locale}
href="/"
className="action"
tabIndex={0}
data-selected={selectedTool === undefined}
>
<div class="selector"> <div class="selector">
<BlitzKitIcon className="icon" /> <BlitzKitIcon className="icon" />
</div> </div>
<Text lowContrast className="label">{strings.navbar.home}</Text> <Text lowContrast className="label">{strings.navbar.home}</Text>
</LinkI18n> </LinkI18n>
<LinkI18n {locale} href="/settings" className="action" tabIndex={0}> {
<div class="selector"> toolsSorted.map(({ id, Icon }) => (
<GearIcon className="icon" /> <LinkI18n
</div> key={id}
<Text lowContrast className="label">{strings.navbar.settings}</Text> {locale}
</LinkI18n> href={`/${id}`}
className="action"
tabIndex={0}
data-selected={selectedTool?.id === id}
>
<div class="selector">
<Icon className="icon" />
</div>
<LinkI18n {locale} href="/settings" className="action" tabIndex={0}> <Text lowContrast className="label">
<div class="selector"> {strings.tools[id as keyof typeof strings.tools].name}
<GearIcon className="icon" /> </Text>
</div> </LinkI18n>
<Text lowContrast className="label">{strings.navbar.settings}</Text> ))
</LinkI18n> }
<LinkI18n {locale} href="/settings" className="action" tabIndex={0}>
<div class="selector">
<GearIcon className="icon" />
</div>
<Text lowContrast className="label">{strings.navbar.settings}</Text>
</LinkI18n>
</div> </div>
</div> </div>
+86 -14
View File
@@ -1,46 +1,118 @@
import type { ButtonProps } from "@radix-ui/themes"; import {
ExclamationTriangleIcon,
GearIcon,
PersonIcon,
} from "@radix-ui/react-icons";
import type { IconProps } from "@radix-ui/react-icons/dist/types";
import type { ComponentProps, ReactNode } from "react";
import { TankIcon } from "../../icons/Tank";
import type { Color } from "../ui/color";
export interface Tool { export interface Tool {
id: string; id: string;
strings?: string;
button: ButtonProps["color"];
significant?: boolean;
disabled?: boolean;
href?: string;
accent: Color;
banner_background_position: "top" | "center" | "bottom"; banner_background_position: "top" | "center" | "bottom";
Icon:
| ((props: ComponentProps<"svg">) => ReactNode)
| ((props: IconProps) => ReactNode);
} }
export const tools: Record<string, Tool> = { export const tools: Record<string, Tool> = {
tanks: { tanks: {
id: "tanks", id: "tanks",
strings: "tankopedia",
button: "purple",
significant: true,
Icon: TankIcon,
accent: "purple",
banner_background_position: "top",
},
players: {
id: "players",
Icon: PersonIcon,
accent: "purple",
banner_background_position: "top",
},
settings: {
id: "settings",
Icon: GearIcon,
accent: "gray",
banner_background_position: "top", banner_background_position: "top",
}, },
avatars: { avatars: {
id: "avatars", id: "avatars",
button: "gold",
Icon: ExclamationTriangleIcon,
accent: "gold",
banner_background_position: "bottom", banner_background_position: "bottom",
}, },
backgrounds: { backgrounds: {
id: "backgrounds", id: "backgrounds",
button: "gold",
Icon: ExclamationTriangleIcon,
accent: "gold",
banner_background_position: "bottom", banner_background_position: "bottom",
}, },
api: { api: {
id: "api", id: "api",
disabled: true,
button: "lime",
Icon: ExclamationTriangleIcon,
accent: "lime",
banner_background_position: "bottom",
},
compare: {
id: "compare",
Icon: ExclamationTriangleIcon,
accent: "crimson",
banner_background_position: "bottom",
},
performance: {
id: "performance",
Icon: ExclamationTriangleIcon,
accent: "jade",
banner_background_position: "bottom",
},
playlist: {
id: "playlist",
Icon: ExclamationTriangleIcon,
accent: "tomato",
banner_background_position: "bottom",
},
mixer: {
id: "mixer",
Icon: ExclamationTriangleIcon,
accent: "gray",
banner_background_position: "bottom",
},
guesser: {
id: "guesser",
Icon: ExclamationTriangleIcon,
accent: "cyan",
banner_background_position: "bottom",
},
session: {
id: "session",
Icon: ExclamationTriangleIcon,
accent: "blue",
banner_background_position: "bottom", banner_background_position: "bottom",
}, },
}; };
+20
View File
@@ -0,0 +1,20 @@
import type { ComponentProps } from "react";
export function TankIcon(props: ComponentProps<"svg">) {
return (
<svg
width="64"
height="48"
viewBox="0 0 64 48"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M63 14.3344H42.7572M58.2615 31.6656C58.2615 37.0758 53.8954 38 48.5095 38H11.752C6.36612 38 2 37.0758 2 31.6656C2 26.2555 6.36612 21.8697 11.752 21.8697H23.8795V17.7959C23.8795 12.3858 28.2456 8 33.6315 8C39.0174 8 43.3835 12.3858 43.3835 17.7959V21.8697H48.5095C53.8954 21.8697 58.2615 26.2555 58.2615 31.6656Z"
stroke="currentColor"
stroke-width="4"
/>
</svg>
);
}
@@ -4,15 +4,17 @@ import BaseStyles from "../components/BaseStyles.astro";
import ColorAlias from "../components/ColorAlias.astro"; import ColorAlias from "../components/ColorAlias.astro";
import ColorScale from "../components/ColorScale.astro"; import ColorScale from "../components/ColorScale.astro";
import Navbar from "../components/Navbar.astro"; import Navbar from "../components/Navbar.astro";
import type { Tool } from "../core/tools/tools";
import type { Color } from "../core/ui/color"; import type { Color } from "../core/ui/color";
interface Props { interface Props {
locale: string; locale: string;
accent: Color; accent: Color;
noNavbar?: boolean; noNavbar?: boolean;
selectedTool?: Tool;
} }
const { accent, noNavbar, locale } = Astro.props; const { accent, noNavbar, locale, selectedTool } = Astro.props;
--- ---
<html lang={locale}> <html lang={locale}>
@@ -65,6 +67,6 @@ const { accent, noNavbar, locale } = Astro.props;
<slot /> <slot />
</div> </div>
{!noNavbar && <Navbar {locale} />} {!noNavbar && <Navbar {selectedTool} {locale} />}
</body> </body>
</html> </html>
@@ -1,6 +1,7 @@
--- ---
import "@radix-ui/colors/amber-dark.css"; import "@radix-ui/colors/amber-dark.css";
import { getCollection } from "astro:content"; import { getCollection } from "astro:content";
import { tools } from "../../../core/tools/tools";
import BaseLayout from "../../../layouts/BaseLayout.astro"; import BaseLayout from "../../../layouts/BaseLayout.astro";
export { getStaticPaths } from "../index.astro"; export { getStaticPaths } from "../index.astro";
@@ -18,7 +19,7 @@ const paths: {
paths.sort((a, b) => a.path.localeCompare(b.path)); paths.sort((a, b) => a.path.localeCompare(b.path));
--- ---
<BaseLayout {locale} accent="lime"> <BaseLayout selectedTool={tools.api} {locale} accent="lime">
<h1>api</h1> <h1>api</h1>
{ {
@@ -10,7 +10,7 @@ export { getStaticPaths } from "../index.astro";
const { locale } = Astro.props; const { locale } = Astro.props;
--- ---
<BaseLayout {locale} accent="gold"> <BaseLayout selectedTool={tools.avatars} {locale} accent="gold">
<ColorScale color="purple" /> <ColorScale color="purple" />
<ColorScale color="blue" /> <ColorScale color="blue" />
@@ -11,7 +11,7 @@ const { locale } = Astro.props;
const tankList = await api.tankList(); const tankList = await api.tankList();
--- ---
<BaseLayout {locale} accent="purple"> <BaseLayout selectedTool={tools.tanks} {locale} accent="purple">
<ToolBanner {locale} tool={tools.tanks} slot="pre-app" /> <ToolBanner {locale} tool={tools.tanks} slot="pre-app" />
<h1>tanks</h1> <h1>tanks</h1>