add GH release points to timeline & fix padding of nav and logo

This commit is contained in:
Starystars67
2025-12-29 18:52:34 +00:00
parent 6ed1bf7352
commit df371568c7
3 changed files with 74 additions and 24 deletions

View File

@@ -1,7 +1,7 @@
{ {
"name": "beammp-website", "name": "beammp-website",
"private": true, "private": true,
"version": "2.4.8", "version": "2.4.9",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -33,30 +33,31 @@ function localRoute(path) {
<template> <template>
<header <header
class="border-b border-neutral-200 dark:border-neutral-800 bg-white/80 dark:bg-neutral-900/70 backdrop-blur sticky top-0 z-20 overflow-hidden" class="border-b border-neutral-200 dark:border-neutral-800 bg-white/80 dark:bg-neutral-900/70 backdrop-blur sticky top-0 z-20"
> >
<nav class="max-w-7xl mx-auto px-3 sm:px-4 h-16 flex items-center justify-between gap-2 sm:gap-4"> <nav class="max-w-6xl mx-auto px-4 h-16 flex items-center justify-between">
<RouterLink <RouterLink
:to="localRoute('')" :to="localRoute('')"
class="flex items-center gap-2 flex-shrink-0" class="flex items-center gap-2 shrink-0 mr-4"
@click="closeMobileMenu" @click="closeMobileMenu"
> >
<!-- Light mode logo (black) --> <!-- Light mode logo (black) -->
<img <img
src="/src/assets/BeamMP_blk.png" src="/src/assets/BeamMP_blk.png"
alt="BeamMP Logo" alt="BeamMP Logo"
class="h-12 sm:h-14 w-auto flex-shrink-0 dark:hidden" class="h-16 w-auto shrink-0 dark:hidden"
/> />
<!-- Dark mode logo (white) --> <!-- Dark mode logo (white) -->
<img <img
src="/src/assets/BeamMP_wht.png" src="/src/assets/BeamMP_wht.png"
alt="BeamMP Logo" alt="BeamMP Logo"
class="h-12 sm:h-14 w-auto flex-shrink-0 hidden dark:block" class="h-16 w-auto shrink-0 hidden dark:block"
/> />
</RouterLink> </RouterLink>
<!-- Desktop Navigation --> <!-- Desktop Navigation -->
<div class="hidden xl:flex items-center gap-1 flex-1 justify-end overflow-x-auto"> <!-- Switch to mobile earlier (avoid logo crowding) -->
<div class="hidden xl:flex items-center gap-4">
<NavigationMenu> <NavigationMenu>
<NavigationMenuList> <NavigationMenuList>
<NavigationMenuItem> <NavigationMenuItem>
@@ -155,6 +156,24 @@ function localRoute(path) {
</a> </a>
</NavigationMenuLink> </NavigationMenuLink>
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink as-child>
<a
href="https://store.beammp.com"
target="_blank"
rel="noopener noreferrer"
aria-label="External link"
:class="
cn(
navigationMenuTriggerStyle(),
'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white'
)
"
>
{{ $t('message.nav.store') }}
</a>
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuItem>
<NavigationMenuLink as-child> <NavigationMenuLink as-child>
<a <a
@@ -200,7 +219,7 @@ function localRoute(path) {
</div> </div>
<!-- Mobile Menu Button and Theme Toggle --> <!-- Mobile Menu Button and Theme Toggle -->
<div class="flex xl:hidden items-center gap-1 sm:gap-2 flex-shrink-0"> <div class="flex xl:hidden items-center gap-2">
<LanguageSelector /> <LanguageSelector />
<ThemeToggle /> <ThemeToggle />
<button <button
@@ -225,7 +244,7 @@ function localRoute(path) {
> >
<div <div
v-if="mobileMenuOpen" v-if="mobileMenuOpen"
class="xl:hidden border-t border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900" class="md:hidden border-t border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900"
> >
<div class="px-4 py-3 space-y-1"> <div class="px-4 py-3 space-y-1">
<RouterLink <RouterLink
@@ -274,15 +293,6 @@ function localRoute(path) {
> >
{{ $t('message.nav.docs') }} {{ $t('message.nav.docs') }}
</a> </a>
<a
href="https://store.beammp.com"
target="_blank"
rel="noopener noreferrer"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
{{ $t('message.nav.store') }}
</a>
<a <a
href="https://github.com/BeamMP/BeamMP" href="https://github.com/BeamMP/BeamMP"
target="_blank" target="_blank"

View File

@@ -7,6 +7,8 @@ const servers = ref([])
// Backend endpoints (use null to fall back to synthetic data) // Backend endpoints (use null to fall back to synthetic data)
const STATS_ENDPOINT = null // e.g., 'https://backend.beammp.com/stats-timeseries' const STATS_ENDPOINT = null // e.g., 'https://backend.beammp.com/stats-timeseries'
const MOD_RELEASES_ENDPOINT = 'https://api.github.com/repos/BeamMP/BeamMP/releases' // e.g., 'https://backend.beammp.com/releases'
const SERVER_RELEASES_ENDPOINT = 'https://api.github.com/repos/BeamMP/BeamMP-Server/releases' // e.g., 'https://backend.beammp.com/server-releases'
// All-time high tracking // All-time high tracking
const peakPlayers = ref(0) const peakPlayers = ref(0)
@@ -33,14 +35,52 @@ const selectedRangeKey = ref('7d')
const selectedRange = computed(() => ranges.find((r) => r.key === selectedRangeKey.value)) const selectedRange = computed(() => ranges.find((r) => r.key === selectedRangeKey.value))
// Release markers (fill with real dates/labels as desired) // Release markers (fill with real dates/labels as desired)
const releases = ref([ const mod_releases = ref([
{ date: '2025-11-24', label: 'v4.0.0' }, //{ date: '2025-11-24', label: 'v4.0.0' },
{ date: '2025-11-27', label: 'v4.1.0' }, //{ date: '2025-11-27', label: 'v4.1.0' },
{ date: '2025-11-29', label: 'v4.2.0' }, //{ date: '2025-11-29', label: 'v4.2.0' },
])
const server_releases = ref([
//{ date: '2025-11-25', label: 'v4.0.0' },
//{ date: '2025-11-28', label: 'v4.1.0' },
//{ date: '2025-11-30', label: 'v4.2.0' },
]) ])
// Load time-series from backend or generate synthetic // Load time-series from backend or generate synthetic
async function loadTimeSeries(points, stepHours) { async function loadTimeSeries(points, stepHours) {
if (MOD_RELEASES_ENDPOINT) {
try {
const res = await fetch(MOD_RELEASES_ENDPOINT)
if (res.ok) {
const r = await res.json()
r.forEach((rel) => {
const existing = mod_releases.value.find((e) => e.label === rel.tag_name)
if (!existing) {
mod_releases.value.push({ date: rel.published_at, label: rel.tag_name })
}
})
}
} catch (e) {
console.error('Failed to load releases:', e)
}
}
if (SERVER_RELEASES_ENDPOINT) {
try {
const res = await fetch(SERVER_RELEASES_ENDPOINT)
if (res.ok) {
const r = await res.json()
r.forEach((rel) => {
const existing = server_releases.value.find((e) => e.label === rel.tag_name)
if (!existing) {
server_releases.value.push({ date: rel.published_at, label: rel.tag_name })
}
})
}
} catch (e) {
console.error('Failed to load releases:', e)
}
}
if (STATS_ENDPOINT) { if (STATS_ENDPOINT) {
try { try {
const res = await fetch(STATS_ENDPOINT) const res = await fetch(STATS_ENDPOINT)
@@ -256,7 +296,7 @@ function drawPlayers() {
ctx.strokeStyle = 'rgba(255,106,0,0.8)' ctx.strokeStyle = 'rgba(255,106,0,0.8)'
ctx.fillStyle = 'rgba(255,106,0,0.9)' ctx.fillStyle = 'rgba(255,106,0,0.9)'
ctx.lineWidth = 1 ctx.lineWidth = 1
const rels = (releases.value || []) const rels = (mod_releases.value || [])
.map((r) => ({ ...r, time: new Date(r.date).getTime() })) .map((r) => ({ ...r, time: new Date(r.date).getTime() }))
.filter((r) => !isNaN(r.time) && r.time >= minT && r.time <= maxT) .filter((r) => !isNaN(r.time) && r.time >= minT && r.time <= maxT)
releaseMarkersPlayers = [] releaseMarkersPlayers = []
@@ -380,7 +420,7 @@ function drawServers() {
ctx.strokeStyle = 'rgba(255,106,0,0.8)' ctx.strokeStyle = 'rgba(255,106,0,0.8)'
ctx.fillStyle = 'rgba(255,106,0,0.9)' ctx.fillStyle = 'rgba(255,106,0,0.9)'
ctx.lineWidth = 1 ctx.lineWidth = 1
const rels = (releases.value || []) const rels = (server_releases.value || [])
.map((r) => ({ ...r, time: new Date(r.date).getTime() })) .map((r) => ({ ...r, time: new Date(r.date).getTime() }))
.filter((r) => !isNaN(r.time) && r.time >= minT && r.time <= maxT) .filter((r) => !isNaN(r.time) && r.time >= minT && r.time <= maxT)
releaseMarkersServers = [] releaseMarkersServers = []