mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-11-01 23:10:37 +01:00
Compare commits
3
Commits
ca6973f529
...
0bc2d0aaf6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bc2d0aaf6 | ||
|
|
1dc9a341d1 | ||
|
|
2ad1e71176 |
No files matched your search
@@ -41,9 +41,6 @@
|
||||
"action": "To docs",
|
||||
"slogan": "BlitzKit hosted API"
|
||||
},
|
||||
"settings": {
|
||||
"name": "Settings"
|
||||
},
|
||||
"players": {
|
||||
"name": "Players",
|
||||
"slogan": "Player statistics",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 453 KiB |
File renamed without changes.
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 188 KiB |
@@ -1,5 +1,5 @@
|
||||
import { literals } from "@blitzkit/i18n";
|
||||
import { Grade } from "@protos/auto_items";
|
||||
import { Grade } from "@protos/blitz_static_standard_grades_enum";
|
||||
import { DownloadIcon, StarFilledIcon } from "@radix-ui/react-icons";
|
||||
import type { Color } from "../../core/ui/color";
|
||||
import { useGameStrings } from "../../hooks/useGameStrings";
|
||||
@@ -55,11 +55,11 @@ interface DetailsProps {
|
||||
}
|
||||
|
||||
const gradeColors: Record<Grade, Color> = {
|
||||
[Grade.GRADE_GRADE_UNSPECIFIED]: "gray",
|
||||
[Grade.GRADE_GRADE_COMMON]: "gray",
|
||||
[Grade.GRADE_GRADE_RARE]: "blue",
|
||||
[Grade.GRADE_GRADE_EPIC]: "purple",
|
||||
[Grade.GRADE_GRADE_LEGENDARY]: "amber",
|
||||
[Grade.GRADE_UNSPECIFIED]: "gray",
|
||||
[Grade.GRADE_COMMON]: "gray",
|
||||
[Grade.GRADE_RARE]: "blue",
|
||||
[Grade.GRADE_EPIC]: "purple",
|
||||
[Grade.GRADE_LEGENDARY]: "amber",
|
||||
};
|
||||
|
||||
function Details({ avatars }: DetailsProps) {
|
||||
|
||||
@@ -14,6 +14,11 @@ export const LIGHT_TEXT_COLORS = new Set<Color>([
|
||||
"teal",
|
||||
"grass",
|
||||
"amber",
|
||||
"plum",
|
||||
"pink",
|
||||
"brown",
|
||||
"crimson",
|
||||
"jade",
|
||||
]);
|
||||
|
||||
export function Button({
|
||||
|
||||
@@ -21,9 +21,11 @@ const strings = await api.strings(locale);
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
padding: 0 var(--space-4);
|
||||
position: relative;
|
||||
|
||||
padding: 0 var(--space-4);
|
||||
margin-bottom: var(--space-4);
|
||||
|
||||
.wallpaper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@@ -5,108 +5,77 @@ import { Text } from "./Text";
|
||||
import { api } from "../core/api/dynamic";
|
||||
import { tools } from "../core/tools/tools";
|
||||
import type { Tool } from "../core/tools/tools";
|
||||
import { HamburgerMenuIcon, MagnifyingGlassIcon } from "@radix-ui/react-icons";
|
||||
|
||||
interface Props {
|
||||
locale: string;
|
||||
selectedTool?: Tool;
|
||||
}
|
||||
|
||||
const { locale, selectedTool } = Astro.props;
|
||||
const strings = await api.strings(locale);
|
||||
const toolsArray = Object.values(tools);
|
||||
|
||||
const toolsSorted =
|
||||
selectedTool === undefined
|
||||
? toolsArray
|
||||
: [selectedTool, ...toolsArray.filter((tool) => tool !== selectedTool)];
|
||||
const { locale } = Astro.props;
|
||||
---
|
||||
|
||||
<style>
|
||||
#navbar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
z-index: 1;
|
||||
background-color: var(--gray-a5);
|
||||
background-color: var(--gray-a2);
|
||||
box-shadow: var(--shadow-none);
|
||||
backdrop-filter: var(--blur-glass) brightness(5%);
|
||||
border-radius: var(--space-4) var(--space-4) 0 0;
|
||||
backdrop-filter: var(--blur-glass) brightness(10%);
|
||||
box-shadow: var(--shadow-subtle);
|
||||
|
||||
transition-duration: var(--duration-brief);
|
||||
|
||||
&[data-sticky="true"] {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.bar {
|
||||
width: 100%;
|
||||
max-width: var(--space-6);
|
||||
height: var(--space-2);
|
||||
margin-top: var(--space-3);
|
||||
|
||||
background-color: var(--white-a2);
|
||||
|
||||
border-radius: var(--max-size);
|
||||
transform: translateY(-100%);
|
||||
box-shadow: var(--shadow-none);
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
width: 100%;
|
||||
max-width: calc(var(--page-width) + 2 * var(--space-4));
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
|
||||
.action {
|
||||
flex: 1;
|
||||
|
||||
.group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: var(--space-3);
|
||||
gap: var(--space-2);
|
||||
|
||||
cursor: pointer;
|
||||
color: var(--color-regular);
|
||||
text-decoration: none;
|
||||
color: var(--gray-11);
|
||||
.action {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: var(--space-3);
|
||||
gap: var(--space-2);
|
||||
|
||||
&[data-selected="true"] {
|
||||
color: var(--accent-12);
|
||||
cursor: pointer;
|
||||
color: var(--color-regular);
|
||||
text-decoration: none;
|
||||
color: var(--gray-11);
|
||||
|
||||
.selector {
|
||||
background-color: var(--accent-5);
|
||||
}
|
||||
padding: var(--space-2);
|
||||
border-radius: var(--max-size);
|
||||
|
||||
.label {
|
||||
color: var(--gray-12) !important;
|
||||
}
|
||||
}
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.selector {
|
||||
padding: var(--space-2);
|
||||
border-radius: var(--max-size);
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
width: 100%;
|
||||
max-width: var(--space-6);
|
||||
|
||||
.icon {
|
||||
height: 1.25em;
|
||||
width: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
max-width: var(--space-6);
|
||||
|
||||
.label {
|
||||
font-size: var(--font-size-minor);
|
||||
.icon {
|
||||
height: 1.25em;
|
||||
width: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +89,10 @@ const toolsSorted =
|
||||
function handleScroll() {
|
||||
const dy = window.scrollY - lastScrollY;
|
||||
lastScrollY = window.scrollY;
|
||||
navbar.dataset.sticky = `${dy > 0}`;
|
||||
|
||||
const hide = window.scrollY > navbar.clientHeight && dy > 0;
|
||||
|
||||
navbar.dataset.sticky = `${hide}`;
|
||||
}
|
||||
|
||||
handleScroll();
|
||||
@@ -128,41 +100,27 @@ const toolsSorted =
|
||||
</script>
|
||||
|
||||
<div id="navbar">
|
||||
<div class="bar"></div>
|
||||
|
||||
<div class="content">
|
||||
<LinkI18n
|
||||
{locale}
|
||||
href="/"
|
||||
className="action"
|
||||
tabIndex={0}
|
||||
data-selected={selectedTool === undefined}
|
||||
>
|
||||
<div class="selector">
|
||||
<BlitzKitIcon className="icon" />
|
||||
</div>
|
||||
<Text lowContrast className="label">{strings.navbar.home}</Text>
|
||||
</LinkI18n>
|
||||
<div class="group">
|
||||
<LinkI18n {locale} href="/" className="action" tabIndex={0}>
|
||||
<div class="selector">
|
||||
<BlitzKitIcon className="icon" />
|
||||
</div>
|
||||
</LinkI18n>
|
||||
</div>
|
||||
|
||||
{
|
||||
toolsSorted.map(({ id, Icon }) => (
|
||||
<LinkI18n
|
||||
key={id}
|
||||
{locale}
|
||||
href={`/${id}`}
|
||||
className="action"
|
||||
tabIndex={0}
|
||||
data-selected={selectedTool?.id === id}
|
||||
>
|
||||
<div class="selector">
|
||||
<Icon className="icon" />
|
||||
</div>
|
||||
<div class="group">
|
||||
<LinkI18n {locale} href="/" className="action" tabIndex={0}>
|
||||
<div class="selector">
|
||||
<MagnifyingGlassIcon className="icon" />
|
||||
</div>
|
||||
</LinkI18n>
|
||||
|
||||
<Text lowContrast className="label">
|
||||
{strings.tools[id as keyof typeof strings.tools].name}
|
||||
</Text>
|
||||
</LinkI18n>
|
||||
))
|
||||
}
|
||||
<LinkI18n {locale} href="/" className="action" tabIndex={0}>
|
||||
<div class="selector">
|
||||
<HamburgerMenuIcon className="icon" />
|
||||
</div>
|
||||
</LinkI18n>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,9 +1,7 @@
|
||||
---
|
||||
import { ArrowLeftIcon } from "@radix-ui/react-icons";
|
||||
import { api } from "../core/api/dynamic";
|
||||
import type { Tool } from "../core/tools/tools";
|
||||
import { Heading } from "./Heading";
|
||||
import { LinkI18n } from "./LinkI18n";
|
||||
import { Text } from "./Text";
|
||||
|
||||
interface Props {
|
||||
@@ -19,6 +17,7 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
<style>
|
||||
.tool-banner {
|
||||
background-size: cover;
|
||||
margin-bottom: var(--space-4);
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
@@ -26,7 +25,7 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: var(--space-4);
|
||||
padding: var(--space-5) var(--space-4);
|
||||
box-sizing: border-box;
|
||||
@@ -37,10 +36,6 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
padding: var(--space-6) var(--space-4);
|
||||
}
|
||||
|
||||
.back {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.centered {
|
||||
flex: 1;
|
||||
max-width: var(--page-width);
|
||||
@@ -77,10 +72,6 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
}}
|
||||
>
|
||||
<div class="content">
|
||||
<LinkI18n highContrast className="back" {locale} href="/">
|
||||
<ArrowLeftIcon />
|
||||
</LinkI18n>
|
||||
|
||||
<div
|
||||
class="pattern"
|
||||
style={{ backgroundImage: `url(/assets/patterns/${tool.id}.svg)` }}
|
||||
|
||||
@@ -29,6 +29,11 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
|
||||
&[data-significant="true"] {
|
||||
grid-column: 1 / -1;
|
||||
height: 15rem;
|
||||
}
|
||||
|
||||
.poster {
|
||||
flex: 1;
|
||||
|
||||
@@ -59,6 +64,7 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
style={{
|
||||
backgroundImage: `url(/assets/tools/${tool.id}.webp)`,
|
||||
}}
|
||||
data-significant={tool.significant}
|
||||
>
|
||||
<div
|
||||
class="poster"
|
||||
@@ -74,7 +80,7 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
<Text size="minor" lowContrast>{toolStrings.slogan}</Text>
|
||||
</div>
|
||||
|
||||
<Button color={tool.button}>
|
||||
<Button color={tool.accent}>
|
||||
{toolStrings.action}
|
||||
<CaretRightIcon />
|
||||
</Button>
|
||||
|
||||
@@ -1,77 +1,32 @@
|
||||
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 {
|
||||
id: string;
|
||||
|
||||
significant?: boolean;
|
||||
accent: Color;
|
||||
banner_background_position: "top" | "center" | "bottom";
|
||||
|
||||
Icon:
|
||||
| ((props: ComponentProps<"svg">) => ReactNode)
|
||||
| ((props: IconProps) => ReactNode);
|
||||
}
|
||||
|
||||
export const tools: Record<string, Tool> = {
|
||||
tanks: {
|
||||
id: "tanks",
|
||||
|
||||
Icon: TankIcon,
|
||||
accent: "purple",
|
||||
significant: true,
|
||||
accent: "plum",
|
||||
banner_background_position: "top",
|
||||
},
|
||||
|
||||
players: {
|
||||
id: "players",
|
||||
|
||||
Icon: PersonIcon,
|
||||
accent: "purple",
|
||||
accent: "pink",
|
||||
banner_background_position: "top",
|
||||
},
|
||||
|
||||
settings: {
|
||||
id: "settings",
|
||||
|
||||
Icon: GearIcon,
|
||||
accent: "gray",
|
||||
banner_background_position: "top",
|
||||
},
|
||||
|
||||
avatars: {
|
||||
id: "avatars",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "gold",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
|
||||
backgrounds: {
|
||||
id: "backgrounds",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "gold",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
|
||||
api: {
|
||||
id: "api",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "lime",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
|
||||
compare: {
|
||||
id: "compare",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "crimson",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
@@ -79,15 +34,34 @@ export const tools: Record<string, Tool> = {
|
||||
performance: {
|
||||
id: "performance",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "jade",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
|
||||
avatars: {
|
||||
id: "avatars",
|
||||
|
||||
accent: "gold",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
|
||||
backgrounds: {
|
||||
id: "backgrounds",
|
||||
|
||||
accent: "gold",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
|
||||
api: {
|
||||
id: "api",
|
||||
|
||||
accent: "brown",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
|
||||
playlist: {
|
||||
id: "playlist",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "tomato",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
@@ -95,7 +69,6 @@ export const tools: Record<string, Tool> = {
|
||||
mixer: {
|
||||
id: "mixer",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "gray",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
@@ -103,7 +76,6 @@ export const tools: Record<string, Tool> = {
|
||||
guesser: {
|
||||
id: "guesser",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "cyan",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
@@ -111,7 +83,6 @@ export const tools: Record<string, Tool> = {
|
||||
session: {
|
||||
id: "session",
|
||||
|
||||
Icon: ExclamationTriangleIcon,
|
||||
accent: "blue",
|
||||
banner_background_position: "bottom",
|
||||
},
|
||||
|
||||
@@ -4,17 +4,15 @@ import BaseStyles from "../components/BaseStyles.astro";
|
||||
import ColorAlias from "../components/ColorAlias.astro";
|
||||
import ColorScale from "../components/ColorScale.astro";
|
||||
import Navbar from "../components/Navbar.astro";
|
||||
import type { Tool } from "../core/tools/tools";
|
||||
import type { Color } from "../core/ui/color";
|
||||
|
||||
interface Props {
|
||||
locale: string;
|
||||
accent: Color;
|
||||
noNavbar?: boolean;
|
||||
selectedTool?: Tool;
|
||||
}
|
||||
|
||||
const { accent, noNavbar, locale, selectedTool } = Astro.props;
|
||||
const { accent, noNavbar, locale } = Astro.props;
|
||||
---
|
||||
|
||||
<html lang={locale}>
|
||||
@@ -43,7 +41,7 @@ const { accent, noNavbar, locale, selectedTool } = Astro.props;
|
||||
flex-direction: column;
|
||||
min-height: 100dvh;
|
||||
|
||||
background-color: var(--gray-3);
|
||||
background-color: var(--gray-1);
|
||||
color: var(--gray-12);
|
||||
font-family: var(--font-family-regular);
|
||||
|
||||
@@ -61,12 +59,12 @@ const { accent, noNavbar, locale, selectedTool } = Astro.props;
|
||||
</head>
|
||||
|
||||
<body class="dark">
|
||||
{!noNavbar && <Navbar {locale} />}
|
||||
|
||||
<slot name="pre-app" />
|
||||
|
||||
<div class="app">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
{!noNavbar && <Navbar {selectedTool} {locale} />}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,8 +1,11 @@
|
||||
---
|
||||
import locales from "@blitzkit/i18n/locales.json";
|
||||
import type { GetStaticPaths } from "astro";
|
||||
import ColorScale from "../../components/ColorScale.astro";
|
||||
import HomeHero from "../../components/HomeHero.astro";
|
||||
import { RecentItems } from "../../components/RecentItems";
|
||||
import { Section } from "../../components/Section";
|
||||
import ToolCard from "../../components/ToolCard.astro";
|
||||
import { tools } from "../../core/tools/tools";
|
||||
import BaseLayout from "../../layouts/BaseLayout.astro";
|
||||
|
||||
export const getStaticPaths = (() => {
|
||||
@@ -17,14 +20,26 @@ export const getStaticPaths = (() => {
|
||||
const { locale } = Astro.props;
|
||||
---
|
||||
|
||||
<style>
|
||||
.tools {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
</style>
|
||||
|
||||
<BaseLayout {locale} accent="amber">
|
||||
<HomeHero {locale} />
|
||||
|
||||
<RecentItems {locale} client:only="react">
|
||||
<RecentItems {locale} skeleton slot="fallback" />
|
||||
</RecentItems>
|
||||
{Object.values(tools).map((tool) => <ColorScale color={tool.accent} />)}
|
||||
|
||||
<!-- <Section>
|
||||
{Object.values(tools).map((tool) => <ToolCard {locale} {tool} />)}
|
||||
</Section> -->
|
||||
<!-- <RecentItems {locale} client:only="react">
|
||||
<RecentItems {locale} skeleton slot="fallback" />
|
||||
</RecentItems> -->
|
||||
|
||||
<Section>
|
||||
<div class="tools">
|
||||
{Object.values(tools).map((tool) => <ToolCard {locale} {tool} />)}
|
||||
</div>
|
||||
</Section>
|
||||
</BaseLayout>
|
||||
Reference in new issue
Block a user