diff --git a/bun.lockb b/bun.lockb index e1f371ddd..f554250ad 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index ce7ce2fbe..ca9008dd1 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ "packages/*" ], "scripts": { - "build:assets": "bun scripts/buildAssets/index.ts", - "build:averages": "bun scripts/averages", + "build:assets": "bun --filter=@blitzkit/scripts run build:assets", + "build:averages": "bun --filter=@blitzkit/scripts run build:averages", "build:bot": "rm -rf dist/bot && mkdir -p dist/bot/prisma && bun build src/index.ts src/workers/bot.ts src/workers/render.ts --outdir dist/bot --target=bun --splitting --sourcemap=inline --external sharp && cp -R src/lang dist/bot/lang && prisma generate && cp prisma/schema.prisma dist/bot/prisma/schema.prisma && cp -R node_modules/prisma/*.node dist/bot/prisma && cd dist/bot && bun init -y && bun add sharp", "build:website": "prisma generate & bun build:sitemap && next build", "build:sitemap": "bun scripts/sitemap.ts", @@ -17,7 +17,8 @@ "build:ratingleaderboard": "bun --script scripts/buildRatingLeaderboard.ts", "dev:bot": "bun build:bot && bun start:bot", "dev:docs": "vitepress dev docs", - "dev:website": "next dev", + "dev:website": "bun --filter=@blitzkit/website run dev", + "dev:api": "bun --filter=@blitzkit/api run dev", "start:bot": "bun dist/bot/index.js", "start:website": "next start", "host:docs": "vitepress preview docs", diff --git a/packages/api/next-env.d.ts b/packages/api/next-env.d.ts new file mode 100644 index 000000000..40c3d6809 --- /dev/null +++ b/packages/api/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/packages/api/next.config.js b/packages/api/next.config.js new file mode 100644 index 000000000..4678774e6 --- /dev/null +++ b/packages/api/next.config.js @@ -0,0 +1,4 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = {}; + +export default nextConfig; diff --git a/packages/api/package.json b/packages/api/package.json new file mode 100644 index 000000000..071a58790 --- /dev/null +++ b/packages/api/package.json @@ -0,0 +1,17 @@ +{ + "name": "@blitzkit/api", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build" + }, + "dependencies": { + "react": "^18", + "react-dom": "^18", + "next": "14.2.8" + }, + "devDependencies": { + "@types/react": "^18", + "@types/react-dom": "^18" + } +} diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json new file mode 100644 index 000000000..4c3b321ed --- /dev/null +++ b/packages/api/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "plugins": [{ "name": "next" }] + }, + "include": ["src/**/*", "dist/website/types/**/*.ts"] +} diff --git a/packages/bot/package.json b/packages/bot/package.json index 6f5e0d645..626d16645 100644 --- a/packages/bot/package.json +++ b/packages/bot/package.json @@ -7,6 +7,7 @@ "satori": "^0.10.14", "@resvg/resvg-js": "^2.6.2", "discord.js": "^14.15.3", + "react": "^18.3.1", "@radix-ui/colors": "^3.0.0", "fuzzysort": "^2.0.4", "bepaint": "^0.1.0-beta.3", diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 362df4984..7c7ff9d4d 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -2,6 +2,10 @@ "name": "@blitzkit/scripts", "private": true, "type": "module", + "scripts": { + "build:assets": "bun src/buildAssets/index.ts", + "build:averages": "bun src/averages.ts" + }, "dependencies": { "progress": "^2.0.3", "@gltf-transform/core": "^3.10.1", diff --git a/packages/website/next.config.js b/packages/website/next.config.js index 08d77937f..98415da83 100644 --- a/packages/website/next.config.js +++ b/packages/website/next.config.js @@ -4,6 +4,8 @@ const withVanillaExtract = createVanillaExtractPlugin({ tests: /\.css$/ }); /** @type {import('next').NextConfig} */ const nextConfig = { + output: 'export', + ...withVanillaExtract({ webpack: (config) => { config.module.rules.push( @@ -21,15 +23,6 @@ const nextConfig = { }, }), - async headers() { - return [ - { - source: '/(.*)?', - headers: [{ key: 'X-Frame-Options', value: 'DENY' }], - }, - ]; - }, - distDir: 'dist/website', reactStrictMode: true, diff --git a/packages/website/package.json b/packages/website/package.json index 4ca157b56..ae6c64684 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -3,7 +3,8 @@ "private": true, "type": "module", "scripts": { - "dev": "next dev" + "dev": "next dev", + "build": "next build" }, "dependencies": { "@radix-ui/themes": "^3.1.3", @@ -31,6 +32,7 @@ "react-promise-suspense": "^0.3.4" }, "devDependencies": { + "@types/react-dom": "^18", "@types/lodash": "^4.17.7", "@types/three": "^0.160.0", "@vanilla-extract/next-plugin": "^2.4.5", diff --git a/packages/website/src/app/tools/tankopedia/[id]/components/Content.tsx b/packages/website/src/app/tools/tankopedia/[id]/components/Content.tsx new file mode 100644 index 000000000..fa5534f76 --- /dev/null +++ b/packages/website/src/app/tools/tankopedia/[id]/components/Content.tsx @@ -0,0 +1,107 @@ +'use client'; + +import { TIER_ROMAN_NUMERALS } from '@blitzkit/core'; +import strings from '@blitzkit/core/lang/en-US.json'; +import { invalidate } from '@react-three/fiber'; +import { useEffect } from 'react'; +import { AdMidSectionResponsive } from '../../../../../components/AdMidSectionResponsive'; +import PageWrapper from '../../../../../components/PageWrapper'; +import { useAdExempt } from '../../../../../hooks/useAdExempt'; +import * as Duel from '../../../../../stores/duel'; +import * as TankopediaEphemeral from '../../../../../stores/tankopediaEphemeral'; +import { CalloutsSection } from './CalloutsSection'; +import { HistorySection } from './HistorySection'; +import { CharacteristicsSection } from './Model/CharacteristicsSection'; +import { GameModeSection } from './Model/GameModeSection'; +import { HeroSection } from './Model/HeroSection'; +import { MetaSection } from './Model/MetaSection'; +import { TechTreeSection } from './Model/TechTreeSection'; +import { ShotDisplaySection } from './ShotDisplaySection'; +import { VideoSection } from './VideoSection'; + +export function Content() { + const exempt = useAdExempt(); + const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); + const mutateDuel = Duel.useMutation(); + const duelStore = Duel.useStore(); + const tank = Duel.use((state) => state.protagonist.tank); + const title = `${tank.name} - Tier ${TIER_ROMAN_NUMERALS[tank.tier]} ${ + (strings.common.nations_adjectives as Record)[tank.nation] + } ${strings.common.tank_class_short[tank.class]}`; + + useEffect(() => { + function handleKeyDown(event: KeyboardEvent) { + if (document.activeElement instanceof HTMLInputElement) return; + + function wipeShot() { + mutateTankopediaEphemeral((draft) => { + draft.shot = undefined; + }); + } + + if (event.key === '1') { + invalidate(); + wipeShot(); + mutateDuel((draft) => { + draft.antagonist.shell = draft.antagonist.gun.shells[0]; + }); + } else if (event.key === '2') { + invalidate(); + wipeShot(); + mutateDuel((draft) => { + if (draft.antagonist.gun.shells[1]) { + draft.antagonist.shell = draft.antagonist.gun.shells[1]; + } + }); + } else if (event.key === '3') { + invalidate(); + wipeShot(); + mutateDuel((draft) => { + if (draft.antagonist.gun.shells[2]) { + draft.antagonist.shell = draft.antagonist.gun.shells[2]; + } + }); + } + } + + window.addEventListener('keydown', handleKeyDown); + + return () => { + window.removeEventListener('keydown', handleKeyDown); + }; + }, []); + + useEffect(() => { + const unsubscribe = duelStore.subscribe( + (state) => state.protagonist?.tank.id, + () => { + mutateTankopediaEphemeral((draft) => { + draft.shot = undefined; + }); + }, + ); + + return unsubscribe; + }, []); + + return ( + <> + {title} + + + + + + + {!exempt && } + + + {!exempt && } + + + + {!exempt && } + + + ); +} diff --git a/packages/website/src/app/tools/tankopedia/[id]/layout.tsx b/packages/website/src/app/tools/tankopedia/[id]/layout.tsx index 68acdf667..11db19895 100644 --- a/packages/website/src/app/tools/tankopedia/[id]/layout.tsx +++ b/packages/website/src/app/tools/tankopedia/[id]/layout.tsx @@ -2,6 +2,7 @@ import { modelDefinitions, provisionDefinitions, tankDefinitions, + tankDefinitionsArray, tankIcon, TIER_ROMAN_NUMERALS, } from '@blitzkit/core'; @@ -10,6 +11,11 @@ import { ReactNode } from 'react'; import * as Duel from '../../../../stores/duel'; import * as TankopediaEphemeral from '../../../../stores/tankopediaEphemeral'; +export async function generateStaticParams() { + const tanks = await tankDefinitionsArray; + return tanks.map((tank) => ({ id: `${tank.id}` })); +} + export default async function Layout({ children, params, diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json index 95694aa6c..a549a9571 100644 --- a/packages/website/tsconfig.json +++ b/packages/website/tsconfig.json @@ -9,6 +9,7 @@ }, "include": [ "src/**/*", - "dist/website/types/**/*.ts" + "dist/website/types/**/*.ts", + ".next/types/**/*.ts" ] }