mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: home page
This commit is contained in:
1 parent
64d12bba8b
commit
4129a1964f
21 files changed
+425
-24
No files matched your search
@@ -0,0 +1,156 @@
|
||||
---
|
||||
import { Code, Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import { resolveBranchName } from '../core/blitzkit/branches';
|
||||
import { getStrings } from '../core/i18n/getStrings';
|
||||
import { literals } from '@blitzkit/i18n/src/literals';
|
||||
|
||||
interface Props {
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const { locale } = Astro.props;
|
||||
const strings = await getStrings(locale);
|
||||
const branchName = resolveBranchName();
|
||||
const isBranchNamed = branchName !== undefined;
|
||||
---
|
||||
|
||||
<style>
|
||||
#home-hero {
|
||||
--p-1: 0%;
|
||||
--p-2: 0%;
|
||||
--p-3: 0%;
|
||||
--p-4: 0%;
|
||||
--p-7: 0%;
|
||||
|
||||
--g-1-dark: var(--blue-3);
|
||||
--g-1-light: var(--blue-7);
|
||||
--g-2-dark: var(--violet-3);
|
||||
--g-2-light: var(--violet-7);
|
||||
--g-3-dark: var(--purple-3);
|
||||
--g-3-light: var(--purple-7);
|
||||
--g-4-dark: var(--crimson-3);
|
||||
--g-4-light: var(--crimson-7);
|
||||
--g-7-dark: var(--tomato-3);
|
||||
--g-7-light: var(--tomato-7);
|
||||
|
||||
--g-1: color-mix(in srgb, var(--g-1-dark), var(--g-1-light) var(--p-1));
|
||||
--g-2: color-mix(in srgb, var(--g-2-dark), var(--g-2-light) var(--p-2));
|
||||
--g-3: color-mix(in srgb, var(--g-3-dark), var(--g-3-light) var(--p-3));
|
||||
--g-4: color-mix(in srgb, var(--g-4-dark), var(--g-4-light) var(--p-4));
|
||||
--g-7: color-mix(in srgb, var(--g-7-dark), var(--g-7-light) var(--p-7));
|
||||
|
||||
background: linear-gradient(
|
||||
45deg,
|
||||
var(--g-1),
|
||||
var(--g-2),
|
||||
var(--g-3),
|
||||
var(--g-4),
|
||||
var(--g-7)
|
||||
);
|
||||
}
|
||||
|
||||
#home-hero[data-variant='pride'] {
|
||||
--g-1-dark: var(--crimson-3);
|
||||
--g-1-light: var(--crimson-7);
|
||||
--g-2-dark: var(--orange-3);
|
||||
--g-2-light: var(--orange-7);
|
||||
--g-3-dark: var(--yellow-3);
|
||||
--g-3-light: var(--yellow-7);
|
||||
--g-4-dark: var(--blue-3);
|
||||
--g-4-light: var(--blue-7);
|
||||
--g-7-dark: var(--purple-3);
|
||||
--g-7-light: var(--purple-7);
|
||||
}
|
||||
|
||||
#home-hero[data-variant='spooky'] {
|
||||
--g-1-dark: var(--orange-3);
|
||||
--g-1-light: var(--orange-7);
|
||||
--g-2-dark: var(--tomato-3);
|
||||
--g-2-light: var(--tomato-7);
|
||||
--g-3-dark: var(--orange-3);
|
||||
--g-3-light: var(--orange-7);
|
||||
--g-4-dark: var(--tomato-3);
|
||||
--g-4-light: var(--tomato-7);
|
||||
--g-7-dark: var(--orange-3);
|
||||
--g-7-light: var(--orange-7);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { clamp, times } from 'lodash-es';
|
||||
|
||||
const n = 5;
|
||||
const homeHero = document.getElementById('home-hero');
|
||||
|
||||
if (homeHero) {
|
||||
switch (new Date().getMonth()) {
|
||||
case 5:
|
||||
homeHero.dataset.variant = 'pride';
|
||||
break;
|
||||
|
||||
case 9:
|
||||
homeHero.dataset.variant = 'spooky';
|
||||
break;
|
||||
}
|
||||
|
||||
window.addEventListener('pointermove', (event) => {
|
||||
const x = event.clientX / window.innerWidth;
|
||||
const c = clamp(
|
||||
(1 -
|
||||
(event.clientY + homeHero.getBoundingClientRect().top) /
|
||||
window.innerHeight) **
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
);
|
||||
|
||||
// https://www.desmos.com/calculator/ndz2poxk32
|
||||
times(n, (i) => {
|
||||
const p = c * clamp(-n * Math.abs(x - i / (n - 1)) + 1, 0, 3);
|
||||
homeHero.style.setProperty(`--p-${i + 1}`, `${p * 100}%`);
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<Flex
|
||||
id="home-hero"
|
||||
align="center"
|
||||
justify="center"
|
||||
position="relative"
|
||||
px="4"
|
||||
py="9"
|
||||
overflow="hidden"
|
||||
>
|
||||
<Flex
|
||||
direction="column"
|
||||
gap="6"
|
||||
align="center"
|
||||
justify="center"
|
||||
position="relative"
|
||||
width="100%"
|
||||
>
|
||||
<Flex direction="column" align="center" gap="1">
|
||||
<Heading size={{ initial: '8', xs: '9' }} weight="bold" align="center">
|
||||
<Flex align="center" gap={{ initial: '2', xs: '4' }}>
|
||||
BlitzKit
|
||||
{
|
||||
isBranchNamed && (
|
||||
<Code
|
||||
size={{ initial: '7', xs: '8' }}
|
||||
color="gray"
|
||||
variant="outline"
|
||||
>
|
||||
{branchName}
|
||||
</Code>
|
||||
)
|
||||
}
|
||||
</Flex>
|
||||
</Heading>
|
||||
|
||||
<Text color="gray" align="center" size="4"
|
||||
>{literals(strings.website.home.hero.credit, ['TrèsAbhi'])}</Text
|
||||
>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
import { assertSecret } from '@blitzkit/core';
|
||||
import { CaretRightIcon } from '@radix-ui/react-icons';
|
||||
import { Box, Button, Code, Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import type { Tool } from '../constants/tools';
|
||||
import { getStrings } from '../core/i18n/getStrings';
|
||||
import { LinkI18n } from './LinkI18n';
|
||||
|
||||
interface Props {
|
||||
tool: Tool;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const { tool, locale } = Astro.props;
|
||||
const strings = await getStrings(locale);
|
||||
const disabled = false;
|
||||
const toolStrings =
|
||||
strings.website.tools[
|
||||
(tool.strings ?? tool.id) as keyof typeof strings.website.tools
|
||||
];
|
||||
---
|
||||
|
||||
<style>
|
||||
.container {
|
||||
border-radius: var(--radius-2);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
height: 16rem;
|
||||
|
||||
&[data-disabled='true'] {
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
&[data-significant='true'] {
|
||||
height: min(20rem, 50vh);
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
color: inherit;
|
||||
}
|
||||
</style>
|
||||
|
||||
<Flex
|
||||
style={{ backgroundImage: `url(/assets/tool-backgrounds/${tool.id}.webp)` }}
|
||||
data-disabled={disabled}
|
||||
data-significant={tool.significant}
|
||||
className="container"
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
flexGrow={tool.significant ? undefined : '1'}
|
||||
flexBasis={tool.significant ? undefined : { initial: undefined, sm: '0' }}
|
||||
>
|
||||
<LinkI18n
|
||||
{locale}
|
||||
className="link"
|
||||
underline="none"
|
||||
href={disabled ? '#' : `/${tool.id}`}
|
||||
>
|
||||
<Box
|
||||
flexGrow="1"
|
||||
style={{
|
||||
backgroundImage: `url(/assets/tool-backgrounds/${tool.id}.webp)`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Flex
|
||||
px={{ initial: '6', md: tool.significant ? '8' : '6' }}
|
||||
py={{ initial: '4', sm: tool.significant ? '6' : '4' }}
|
||||
gap="4"
|
||||
align="center"
|
||||
justify="between"
|
||||
width="100%"
|
||||
direction={{ initial: 'column', xs: 'row' }}
|
||||
style={{
|
||||
backgroundColor: 'var(--color-panel-translucent)',
|
||||
backdropFilter: 'blur(64px)',
|
||||
WebkitBackdropFilter: 'blur(64px)',
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
direction="column"
|
||||
justify="center"
|
||||
align={{ initial: 'center', xs: 'start' }}
|
||||
>
|
||||
<Heading
|
||||
align={{ initial: 'center', sm: 'left' }}
|
||||
size={{ initial: '6', sm: tool.significant ? '7' : '5' }}
|
||||
weight="medium"
|
||||
>
|
||||
{toolStrings.name}
|
||||
</Heading>
|
||||
<Text
|
||||
align={{ initial: 'center', sm: 'left' }}
|
||||
size={{ initial: '3', sm: tool.significant ? '4' : '3' }}
|
||||
color="gray"
|
||||
>
|
||||
{
|
||||
disabled ? (
|
||||
<>
|
||||
Unavailable on{' '}
|
||||
<Code>{assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH)}</Code>
|
||||
</>
|
||||
) : (
|
||||
toolStrings.description
|
||||
)
|
||||
}
|
||||
</Text>
|
||||
</Flex>
|
||||
|
||||
{
|
||||
!disabled && (
|
||||
<Button
|
||||
highContrast={tool.button.contrast}
|
||||
size={{
|
||||
initial: undefined,
|
||||
sm: tool.significant ? '3' : undefined,
|
||||
}}
|
||||
color={tool.button.color}
|
||||
style={{ cursor: 'inherit' }}
|
||||
>
|
||||
{toolStrings.button}
|
||||
<CaretRightIcon />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
</Flex>
|
||||
</LinkI18n>
|
||||
</Flex>
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ButtonProps } from '@radix-ui/themes';
|
||||
|
||||
interface Tool {
|
||||
export interface Tool {
|
||||
id: string;
|
||||
enabled: boolean;
|
||||
strings?: string;
|
||||
@@ -8,7 +8,7 @@ interface Tool {
|
||||
button: { color: ButtonProps['color']; contrast?: boolean };
|
||||
}
|
||||
|
||||
export const tanks: Tool = {
|
||||
export const tanksTool: Tool = {
|
||||
id: 'tanks',
|
||||
enabled: true,
|
||||
strings: 'tankopedia',
|
||||
@@ -16,70 +16,70 @@ export const tanks: Tool = {
|
||||
button: { color: 'purple' },
|
||||
};
|
||||
|
||||
export const compare: Tool = {
|
||||
export const compareTool: Tool = {
|
||||
id: 'compare',
|
||||
enabled: true,
|
||||
button: { color: 'crimson' },
|
||||
};
|
||||
|
||||
export const performance: Tool = {
|
||||
export const performanceTool: Tool = {
|
||||
id: 'performance',
|
||||
enabled: true,
|
||||
button: { color: 'jade' },
|
||||
};
|
||||
|
||||
export const guess: Tool = {
|
||||
export const guessTool: Tool = {
|
||||
id: 'guess',
|
||||
enabled: false,
|
||||
button: { color: 'bronze' },
|
||||
};
|
||||
|
||||
export const charts: Tool = {
|
||||
export const chartsTool: Tool = {
|
||||
id: 'charts',
|
||||
enabled: false,
|
||||
button: { color: 'bronze' },
|
||||
};
|
||||
|
||||
export const gallery: Tool = {
|
||||
export const galleryTool: Tool = {
|
||||
id: 'gallery',
|
||||
enabled: true,
|
||||
button: { color: 'gold' },
|
||||
};
|
||||
|
||||
export const session: Tool = {
|
||||
export const sessionTool: Tool = {
|
||||
id: 'session',
|
||||
enabled: true,
|
||||
button: { color: 'blue' },
|
||||
};
|
||||
|
||||
export const tierList: Tool = {
|
||||
export const tierListTool: Tool = {
|
||||
id: 'tier-list',
|
||||
enabled: true,
|
||||
strings: 'tier_list',
|
||||
button: { color: 'orange' },
|
||||
};
|
||||
|
||||
export const embed: Tool = {
|
||||
export const embedTool: Tool = {
|
||||
id: 'embed',
|
||||
enabled: true,
|
||||
button: { color: 'cyan' },
|
||||
};
|
||||
|
||||
export const rating: Tool = {
|
||||
export const ratingTool: Tool = {
|
||||
id: 'rating',
|
||||
enabled: false,
|
||||
button: { color: 'orange' },
|
||||
};
|
||||
|
||||
export const tools: Tool[] = [
|
||||
tanks,
|
||||
compare,
|
||||
performance,
|
||||
guess,
|
||||
charts,
|
||||
gallery,
|
||||
session,
|
||||
tierList,
|
||||
embed,
|
||||
rating,
|
||||
tanksTool,
|
||||
compareTool,
|
||||
performanceTool,
|
||||
guessTool,
|
||||
chartsTool,
|
||||
galleryTool,
|
||||
sessionTool,
|
||||
tierListTool,
|
||||
embedTool,
|
||||
ratingTool,
|
||||
];
|
||||
@@ -1,6 +1,6 @@
|
||||
import { assertSecret } from 'packages/core/src';
|
||||
|
||||
export function resolveBranchName(locale: string) {
|
||||
export function resolveBranchName() {
|
||||
if (assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH) === 'main') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
---
|
||||
import { AstroSeo } from '@astrolib/seo';
|
||||
import locales from '@blitzkit/i18n/locales.json';
|
||||
import { ExternalLinkIcon } from '@radix-ui/react-icons';
|
||||
import { Flex, Link } from '@radix-ui/themes';
|
||||
import type { GetStaticPaths } from 'astro';
|
||||
import { literals } from 'packages/i18n/src';
|
||||
import HomeHero from '../../components/HomeHero.astro';
|
||||
import ToolCard from '../../components/ToolCard.astro';
|
||||
import { type Tool, tools } from '../../constants/tools';
|
||||
import { getStrings } from '../../core/i18n/getStrings';
|
||||
import { Var } from '../../core/radix/var';
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
|
||||
const MAX_TOOLS_PER_ROW = 2;
|
||||
|
||||
export const getStaticPaths = (() => {
|
||||
return locales.supported.map(({ locale, blitz }) => ({
|
||||
@@ -10,6 +22,92 @@ export const getStaticPaths = (() => {
|
||||
}) satisfies GetStaticPaths;
|
||||
|
||||
const { locale } = Astro.props;
|
||||
const strings = await getStrings(locale);
|
||||
const rows: Tool[][] = [];
|
||||
|
||||
toolLoop: for (const tool of tools.filter((tool) => tool.enabled)) {
|
||||
if (tool.significant) {
|
||||
rows.push([tool]);
|
||||
} else {
|
||||
for (const row of rows) {
|
||||
if (!row[0]?.significant && row.length < MAX_TOOLS_PER_ROW) {
|
||||
row.push(tool);
|
||||
continue toolLoop;
|
||||
}
|
||||
}
|
||||
|
||||
rows.push([tool]);
|
||||
}
|
||||
}
|
||||
---
|
||||
|
||||
Hello in {locale}!
|
||||
<AstroSeo
|
||||
title="BlitzKit"
|
||||
description={strings.website.home.seo_description}
|
||||
canonical={Astro.url.href}
|
||||
openGraph={{
|
||||
url: Astro.url.href,
|
||||
title: 'BlitzKit',
|
||||
description: strings.website.home.seo_description,
|
||||
site_name: 'BlitzKit',
|
||||
}}
|
||||
twitter={{ cardType: 'summary_large_image' }}
|
||||
/>
|
||||
|
||||
<BaseLayout {locale}>
|
||||
<Flex direction="column" gap="8" pb="9">
|
||||
<HomeHero {locale} />
|
||||
|
||||
{
|
||||
locale !== locales.default && (
|
||||
<Flex justify="center">
|
||||
<Link
|
||||
href="https://crowdin.com/project/blitzkrieg"
|
||||
target="_blank"
|
||||
underline="hover"
|
||||
color="gray"
|
||||
highContrast
|
||||
style={{
|
||||
color: Var('gray-3'),
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
align="center"
|
||||
px="5"
|
||||
py="4"
|
||||
gap="3"
|
||||
style={{
|
||||
backgroundImage: 'url(/assets/morphing-diamonds.svg)',
|
||||
borderRadius: Var('radius-full'),
|
||||
boxShadow: Var('shadow-2'),
|
||||
}}
|
||||
>
|
||||
{literals(strings.website.home.help_translate, [
|
||||
'BlitzKit',
|
||||
strings.common.locales[
|
||||
locale as keyof typeof strings.common.locales
|
||||
],
|
||||
])}
|
||||
|
||||
<ExternalLinkIcon />
|
||||
</Flex>
|
||||
</Link>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
<Flex px="4" justify="center" gap="4">
|
||||
<Flex maxWidth="80rem" flexGrow="1" gap="4" direction="column">
|
||||
{
|
||||
rows.map((row) => (
|
||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||
{row.map((tool) => (
|
||||
<ToolCard {locale} tool={tool} />
|
||||
))}
|
||||
</Flex>
|
||||
))
|
||||
}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</BaseLayout>
|
||||
Reference in new issue
Block a user