Compare commits
7 Commits
50c0033f2f
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
191fe49c64 | ||
|
|
cc6a1a4c6a | ||
|
|
0338188e94 | ||
|
|
a60d309a66 | ||
|
|
203a5c0e2e | ||
|
|
cb50ade88f | ||
|
|
984a2e95ca |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
181
.github/dependabot.yml
vendored
@@ -4,135 +4,40 @@
|
|||||||
# Strategy:
|
# Strategy:
|
||||||
# - Weekly checks for faster vulnerability detection
|
# - Weekly checks for faster vulnerability detection
|
||||||
# - Separate patch/minor/major updates to prevent blocking
|
# - Separate patch/minor/major updates to prevent blocking
|
||||||
# - Group by crate (game vs server) for easier review
|
|
||||||
# - Auto-merge patches via GitHub branch protection rules
|
# - Auto-merge patches via GitHub branch protection rules
|
||||||
# - Limit concurrent PRs to avoid spam
|
# - Limit concurrent PRs to avoid spam
|
||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
# Game: Patch updates (auto-mergeable)
|
# Cargo workspace (all Rust crates)
|
||||||
- package-ecosystem: "cargo"
|
- package-ecosystem: "cargo"
|
||||||
directory: "/pacman"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
day: "monday"
|
day: "monday"
|
||||||
open-pull-requests-limit: 5
|
open-pull-requests-limit: 5
|
||||||
groups:
|
|
||||||
game-patches:
|
|
||||||
applies-to: "version-updates"
|
|
||||||
update-types:
|
|
||||||
- "patch"
|
|
||||||
ignore:
|
ignore:
|
||||||
# Bevy ECS 0.17+ requires API migration - ignore until manual update
|
# Bevy ECS 0.17+ requires API migration
|
||||||
- dependency-name: "bevy_ecs"
|
- dependency-name: "bevy_ecs"
|
||||||
versions: ["0.17.x", "0.18.x", "0.19.x"]
|
versions: ["0.17.x", "0.18.x", "0.19.x"]
|
||||||
labels:
|
# jsonwebtoken 10+ requires crypto backend feature flag
|
||||||
- "dependencies"
|
|
||||||
- "dependencies:patch"
|
|
||||||
- "game"
|
|
||||||
|
|
||||||
# Game: Minor updates (grouped, manual review)
|
|
||||||
- package-ecosystem: "cargo"
|
|
||||||
directory: "/pacman"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
day: "monday"
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
|
||||||
game-minor:
|
|
||||||
applies-to: "version-updates"
|
|
||||||
update-types:
|
|
||||||
- "minor"
|
|
||||||
ignore:
|
|
||||||
- dependency-name: "bevy_ecs"
|
|
||||||
versions: ["0.17.x", "0.18.x", "0.19.x"]
|
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- "dependencies:minor"
|
|
||||||
- "game"
|
|
||||||
|
|
||||||
# Game: Major updates (separate PRs, manual review)
|
|
||||||
- package-ecosystem: "cargo"
|
|
||||||
directory: "/pacman"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
day: "monday"
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
|
||||||
game-major:
|
|
||||||
applies-to: "version-updates"
|
|
||||||
update-types:
|
|
||||||
- "major"
|
|
||||||
ignore:
|
|
||||||
- dependency-name: "bevy_ecs"
|
|
||||||
versions: ["0.17.x", "0.18.x", "0.19.x"]
|
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- "dependencies:major"
|
|
||||||
- "game"
|
|
||||||
|
|
||||||
# Server: Patch updates (auto-mergeable)
|
|
||||||
- package-ecosystem: "cargo"
|
|
||||||
directory: "/pacman-server"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
day: "monday"
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
|
||||||
server-patches:
|
|
||||||
applies-to: "version-updates"
|
|
||||||
update-types:
|
|
||||||
- "patch"
|
|
||||||
ignore:
|
|
||||||
# jsonwebtoken 10+ requires crypto backend feature flag - ignore until manual migration
|
|
||||||
- dependency-name: "jsonwebtoken"
|
- dependency-name: "jsonwebtoken"
|
||||||
versions: ["10.x", "11.x"]
|
versions: ["10.x", "11.x"]
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- "dependencies:patch"
|
|
||||||
- "server"
|
|
||||||
|
|
||||||
# Server: Minor updates (grouped, manual review)
|
|
||||||
- package-ecosystem: "cargo"
|
|
||||||
directory: "/pacman-server"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
day: "monday"
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
groups:
|
||||||
server-minor:
|
rust-patches:
|
||||||
applies-to: "version-updates"
|
applies-to: "version-updates"
|
||||||
update-types:
|
update-types: ["patch"]
|
||||||
- "minor"
|
rust-minor:
|
||||||
ignore:
|
applies-to: "version-updates"
|
||||||
- dependency-name: "jsonwebtoken"
|
update-types: ["minor"]
|
||||||
versions: ["10.x", "11.x"]
|
rust-major:
|
||||||
|
applies-to: "version-updates"
|
||||||
|
update-types: ["major"]
|
||||||
labels:
|
labels:
|
||||||
- "dependencies"
|
- "dependencies"
|
||||||
- "dependencies:minor"
|
- "rust"
|
||||||
- "server"
|
|
||||||
|
|
||||||
# Server: Major updates (separate PRs, manual review)
|
# Frontend (web/)
|
||||||
- package-ecosystem: "cargo"
|
|
||||||
directory: "/pacman-server"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
day: "monday"
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
|
||||||
server-major:
|
|
||||||
applies-to: "version-updates"
|
|
||||||
update-types:
|
|
||||||
- "major"
|
|
||||||
ignore:
|
|
||||||
- dependency-name: "jsonwebtoken"
|
|
||||||
versions: ["10.x", "11.x"]
|
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- "dependencies:major"
|
|
||||||
- "server"
|
|
||||||
|
|
||||||
# Frontend: Patch updates (auto-mergeable)
|
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
directory: "/web"
|
directory: "/web"
|
||||||
schedule:
|
schedule:
|
||||||
@@ -142,65 +47,21 @@ updates:
|
|||||||
groups:
|
groups:
|
||||||
frontend-patches:
|
frontend-patches:
|
||||||
applies-to: "version-updates"
|
applies-to: "version-updates"
|
||||||
update-types:
|
update-types: ["patch"]
|
||||||
- "patch"
|
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- "dependencies:patch"
|
|
||||||
- "frontend"
|
|
||||||
|
|
||||||
# Frontend: Minor updates (grouped, manual review)
|
|
||||||
- package-ecosystem: "npm"
|
|
||||||
directory: "/web"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
day: "monday"
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
|
||||||
frontend-minor:
|
frontend-minor:
|
||||||
applies-to: "version-updates"
|
applies-to: "version-updates"
|
||||||
update-types:
|
update-types: ["minor"]
|
||||||
- "minor"
|
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- "dependencies:minor"
|
|
||||||
- "frontend"
|
|
||||||
|
|
||||||
# Frontend: Major updates (separate PRs for critical deps)
|
|
||||||
- package-ecosystem: "npm"
|
|
||||||
directory: "/web"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
day: "monday"
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
|
||||||
frontend-major-framework:
|
frontend-major-framework:
|
||||||
applies-to: "version-updates"
|
applies-to: "version-updates"
|
||||||
update-types:
|
update-types: ["major"]
|
||||||
- "major"
|
|
||||||
patterns:
|
patterns:
|
||||||
- "react"
|
- "react"
|
||||||
- "react-dom"
|
- "react-dom"
|
||||||
- "vike"
|
- "vike"
|
||||||
- "vite"
|
- "vite"
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- "dependencies:major"
|
|
||||||
- "frontend"
|
|
||||||
- "framework"
|
|
||||||
|
|
||||||
# Frontend: Other major updates (grouped)
|
|
||||||
- package-ecosystem: "npm"
|
|
||||||
directory: "/web"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
day: "monday"
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
|
||||||
frontend-major-other:
|
frontend-major-other:
|
||||||
applies-to: "version-updates"
|
applies-to: "version-updates"
|
||||||
update-types:
|
update-types: ["major"]
|
||||||
- "major"
|
|
||||||
exclude-patterns:
|
exclude-patterns:
|
||||||
- "react"
|
- "react"
|
||||||
- "react-dom"
|
- "react-dom"
|
||||||
@@ -208,10 +69,9 @@ updates:
|
|||||||
- "vite"
|
- "vite"
|
||||||
labels:
|
labels:
|
||||||
- "dependencies"
|
- "dependencies"
|
||||||
- "dependencies:major"
|
|
||||||
- "frontend"
|
- "frontend"
|
||||||
|
|
||||||
# GitHub Actions: All updates grouped (low risk)
|
# GitHub Actions
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
@@ -220,8 +80,7 @@ updates:
|
|||||||
open-pull-requests-limit: 5
|
open-pull-requests-limit: 5
|
||||||
groups:
|
groups:
|
||||||
github-actions:
|
github-actions:
|
||||||
patterns:
|
patterns: ["*"]
|
||||||
- "*"
|
|
||||||
labels:
|
labels:
|
||||||
- "dependencies"
|
- "dependencies"
|
||||||
- "github-actions"
|
- "github-actions"
|
||||||
|
|||||||
2
.github/workflows/build.yaml
vendored
@@ -38,7 +38,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup Rust Toolchain
|
- name: Setup Rust Toolchain
|
||||||
uses: dtolnay/rust-toolchain@master
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
|||||||
2
.github/workflows/checks.yaml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
uses: dtolnay/rust-toolchain@master
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
|||||||
11
.github/workflows/coverage.yaml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
uses: dtolnay/rust-toolchain@master
|
uses: dtolnay/rust-toolchain@master
|
||||||
@@ -56,7 +56,16 @@ jobs:
|
|||||||
just coverage
|
just coverage
|
||||||
working-directory: pacman
|
working-directory: pacman
|
||||||
|
|
||||||
|
- name: Check Coveralls Token
|
||||||
|
run: |
|
||||||
|
if [ -z "${{ secrets.COVERALLS_REPO_TOKEN }}" ]; then
|
||||||
|
echo "::warning::COVERALLS_REPO_TOKEN not available - coverage upload skipped (common for Dependabot PRs)"
|
||||||
|
else
|
||||||
|
echo "COVERALLS_REPO_TOKEN is available - will upload coverage"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Coveralls upload
|
- name: Coveralls upload
|
||||||
|
if: ${{ secrets.COVERALLS_REPO_TOKEN != '' }}
|
||||||
uses: coverallsapp/github-action@v2
|
uses: coverallsapp/github-action@v2
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.COVERALLS_REPO_TOKEN }}
|
github-token: ${{ secrets.COVERALLS_REPO_TOKEN }}
|
||||||
|
|||||||
11
.github/workflows/deploy.yaml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
digest: ${{ steps.docker_build.outputs.digest }}
|
digest: ${{ steps.docker_build.outputs.digest }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup Emscripten SDK
|
- name: Setup Emscripten SDK
|
||||||
uses: pyodide/setup-emsdk@v15
|
uses: pyodide/setup-emsdk@v15
|
||||||
@@ -132,8 +132,17 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
|
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Check Railway Token
|
||||||
|
run: |
|
||||||
|
if [ -z "$RAILWAY_TOKEN" ]; then
|
||||||
|
echo "::warning::RAILWAY_TOKEN not available - deployment skipped (common for Dependabot PRs)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Generate proxy Dockerfile
|
- name: Generate proxy Dockerfile
|
||||||
|
if: env.RAILWAY_TOKEN != ''
|
||||||
run: echo "FROM ghcr.io/xevion/pac-man@${{ needs.build-and-deploy.outputs.digest }}" > Dockerfile
|
run: echo "FROM ghcr.io/xevion/pac-man@${{ needs.build-and-deploy.outputs.digest }}" > Dockerfile
|
||||||
|
|
||||||
- name: Deploy to Railway
|
- name: Deploy to Railway
|
||||||
|
if: env.RAILWAY_TOKEN != ''
|
||||||
run: railway up --service pac-man
|
run: railway up --service pac-man
|
||||||
|
|||||||
2
.github/workflows/tests.yaml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
uses: dtolnay/rust-toolchain@master
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
|||||||
8
Cargo.lock
generated
@@ -2760,9 +2760,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mockall"
|
name = "mockall"
|
||||||
version = "0.13.1"
|
version = "0.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2"
|
checksum = "f58d964098a5f9c6b63d0798e5372fd04708193510a7af313c22e9f29b7b620b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.3",
|
"cfg-if 1.0.3",
|
||||||
"downcast",
|
"downcast",
|
||||||
@@ -2774,9 +2774,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mockall_derive"
|
name = "mockall_derive"
|
||||||
version = "0.13.1"
|
version = "0.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898"
|
checksum = "ca41ce716dda6a9be188b385aa78ee5260fc25cd3802cb2a8afdc6afbe6b6dbf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.3",
|
"cfg-if 1.0.3",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|||||||
2
Justfile
@@ -52,7 +52,7 @@ push:
|
|||||||
|
|
||||||
# Create a postgres container for the server
|
# Create a postgres container for the server
|
||||||
server-postgres:
|
server-postgres:
|
||||||
bun run .scripts/postgres.ts
|
bun run pacman-server/scripts/postgres.ts
|
||||||
|
|
||||||
# Build the server image
|
# Build the server image
|
||||||
server-image:
|
server-image:
|
||||||
|
|||||||
10
README.md
@@ -2,7 +2,7 @@
|
|||||||
<!-- markdownlint-disable MD041 -->
|
<!-- markdownlint-disable MD041 -->
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="assets/banner.png" alt="Pac-Man Banner Screenshot">
|
<img src=".github/assets/banner.png" alt="Pac-Man Banner Screenshot">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
# Pac-Man
|
# Pac-Man
|
||||||
@@ -49,16 +49,16 @@ However, every commit has build artifacts, so you can grab the [latest build art
|
|||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="assets/screenshots/0.png" alt="Screenshot 0 - Starting Game">
|
<img src=".github/assets/screenshots/0.png" alt="Screenshot 0 - Starting Game">
|
||||||
<p><em>Starting a new game</em></p>
|
<p><em>Starting a new game</em></p>
|
||||||
|
|
||||||
<img src="assets/screenshots/1.png" alt="Screenshot 1 - Eating Dots">
|
<img src=".github/assets/screenshots/1.png" alt="Screenshot 1 - Eating Dots">
|
||||||
<p><em>Pac-Man collecting dots and avoiding ghosts</em></p>
|
<p><em>Pac-Man collecting dots and avoiding ghosts</em></p>
|
||||||
|
|
||||||
<img src="assets/screenshots/2.png" alt="Screenshot 2 - Game Over">
|
<img src=".github/assets/screenshots/2.png" alt="Screenshot 2 - Game Over">
|
||||||
<p><em>Game over screen after losing all lives</em></p>
|
<p><em>Game over screen after losing all lives</em></p>
|
||||||
|
|
||||||
<img src="assets/screenshots/3.png" alt="Screenshot 3 - Debug Mode">
|
<img src=".github/assets/screenshots/3.png" alt="Screenshot 3 - Debug Mode">
|
||||||
<p><em>Debug mode showing hitboxes, node graph, and performance details.</em></p>
|
<p><em>Debug mode showing hitboxes, node graph, and performance details.</em></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ s3-tokio = { version = "0.39.6", default-features = false }
|
|||||||
rustls = { version = "0.23", features = ["ring"] }
|
rustls = { version = "0.23", features = ["ring"] }
|
||||||
image = { version = "0.25", features = ["png", "jpeg"] }
|
image = { version = "0.25", features = ["png", "jpeg"] }
|
||||||
sha2 = "0.10"
|
sha2 = "0.10"
|
||||||
mockall = "0.13.1"
|
mockall = "0.14.0"
|
||||||
# validator = { version = "0.16", features = ["derive"] }
|
# validator = { version = "0.16", features = ["derive"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
13
web/bun.lock
@@ -9,7 +9,6 @@
|
|||||||
"@tabler/icons-react": "^3.35.0",
|
"@tabler/icons-react": "^3.35.0",
|
||||||
"@vitejs/plugin-react": "^5.0.2",
|
"@vitejs/plugin-react": "^5.0.2",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-animated-numbers": "^1.1.1",
|
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
"vike": "^0.4.240",
|
"vike": "^0.4.240",
|
||||||
"vike-react": "^0.6.5",
|
"vike-react": "^0.6.5",
|
||||||
@@ -465,8 +464,6 @@
|
|||||||
|
|
||||||
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
||||||
|
|
||||||
"framer-motion": ["framer-motion@11.18.2", "", { "dependencies": { "motion-dom": "^11.18.1", "motion-utils": "^11.18.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w=="],
|
|
||||||
|
|
||||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||||
@@ -641,12 +638,6 @@
|
|||||||
|
|
||||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||||
|
|
||||||
"motion": ["motion@11.18.2", "", { "dependencies": { "framer-motion": "^11.18.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-JLjvFDuFr42NFtcVoMAyC2sEjnpA8xpy6qWPyzQvCloznAyQ8FIXioxWfHiLtgYhoVpfUqSWpn1h9++skj9+Wg=="],
|
|
||||||
|
|
||||||
"motion-dom": ["motion-dom@11.18.1", "", { "dependencies": { "motion-utils": "^11.18.1" } }, "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw=="],
|
|
||||||
|
|
||||||
"motion-utils": ["motion-utils@11.18.1", "", {}, "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA=="],
|
|
||||||
|
|
||||||
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
|
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
|
||||||
|
|
||||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
@@ -711,8 +702,6 @@
|
|||||||
|
|
||||||
"react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
|
"react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
|
||||||
|
|
||||||
"react-animated-numbers": ["react-animated-numbers@1.1.1", "", { "dependencies": { "motion": "^11.16.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-Jr2vbDWjo5wW+X8wBYRBACpuKdPkLa4A2ZYfxlAR0oc/gXWVeWyAmAWzZj73276IQxycxrTL7aGn4quWV7+l2Q=="],
|
|
||||||
|
|
||||||
"react-dom": ["react-dom@19.2.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="],
|
"react-dom": ["react-dom@19.2.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="],
|
||||||
|
|
||||||
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||||
@@ -803,8 +792,6 @@
|
|||||||
|
|
||||||
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
|
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
|
||||||
|
|
||||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
|
||||||
|
|
||||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||||
|
|
||||||
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
|
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
"@tabler/icons-react": "^3.35.0",
|
"@tabler/icons-react": "^3.35.0",
|
||||||
"@vitejs/plugin-react": "^5.0.2",
|
"@vitejs/plugin-react": "^5.0.2",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-animated-numbers": "^1.1.1",
|
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
"vike": "^0.4.240",
|
"vike": "^0.4.240",
|
||||||
"vike-react": "^0.6.5"
|
"vike-react": "^0.6.5"
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { IconTrophy, IconCalendar } from "@tabler/icons-react";
|
import { IconTrophy, IconCalendar } from "@tabler/icons-react";
|
||||||
import { clientOnly } from "vike-react/clientOnly";
|
|
||||||
|
|
||||||
const AnimatedNumbers = clientOnly(() => import("react-animated-numbers"));
|
|
||||||
|
|
||||||
interface LeaderboardEntry {
|
interface LeaderboardEntry {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -238,15 +235,7 @@ function LeaderboardTable({ data }: { data: LeaderboardEntry[] }) {
|
|||||||
</td>
|
</td>
|
||||||
<td className="py-2">
|
<td className="py-2">
|
||||||
<span className="text-yellow-300 font-[600] text-lg">
|
<span className="text-yellow-300 font-[600] text-lg">
|
||||||
<AnimatedNumbers
|
{entry.score.toLocaleString()}
|
||||||
fallback={<span className="text-transparent">{entry.score.toLocaleString()}</span>}
|
|
||||||
useThousandsSeparator
|
|
||||||
transitions={(digitIndex) => ({
|
|
||||||
type: "easeIn",
|
|
||||||
duration: 0.75 + digitIndex * 0.25 + entryIndex * 0.2,
|
|
||||||
})}
|
|
||||||
animateToNumber={entry.score}
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="py-2">
|
<td className="py-2">
|
||||||
|
|||||||
6
web/pages/leaderboard/+config.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import type { Config } from "vike/types";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
prerender: true, // Generate static HTML for deployment
|
||||||
|
ssr: false, // Force client-side only rendering
|
||||||
|
} satisfies Config;
|
||||||