From 6efd04942457bbf15b5059de497f0a054b3e4642 Mon Sep 17 00:00:00 2001 From: Chris Sherwood Date: Wed, 21 Jan 2026 16:55:11 -0800 Subject: [PATCH] fix(benchmark): Add settings nav link, fix submission bug, improve UX - Add Benchmark to Settings sidebar navigation - Fix Luxon DateTime bug when saving submission timestamp - Add privacy explanation text before Share button - Add error handling and display for failed submissions - Show "Submitting..." state and success confirmation - Add link to view leaderboard after successful submission Co-Authored-By: Claude Opus 4.5 --- admin/app/services/benchmark_service.ts | 3 +- admin/inertia/layouts/SettingsLayout.tsx | 2 + admin/inertia/pages/settings/benchmark.tsx | 53 ++++++++++++++++++---- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/admin/app/services/benchmark_service.ts b/admin/app/services/benchmark_service.ts index 2e9d149..80cb9e8 100644 --- a/admin/app/services/benchmark_service.ts +++ b/admin/app/services/benchmark_service.ts @@ -5,6 +5,7 @@ import Docker from 'dockerode' import si from 'systeminformation' import { v4 as uuidv4 } from 'uuid' import axios from 'axios' +import { DateTime } from 'luxon' import BenchmarkResult from '#models/benchmark_result' import BenchmarkSetting from '#models/benchmark_setting' import { SystemService } from '#services/system_service' @@ -154,7 +155,7 @@ export class BenchmarkService { if (response.data.success) { result.submitted_to_repository = true - result.submitted_at = new Date() as any + result.submitted_at = DateTime.now() result.repository_id = response.data.repository_id await result.save() diff --git a/admin/inertia/layouts/SettingsLayout.tsx b/admin/inertia/layouts/SettingsLayout.tsx index dd08a4c..996ee5e 100644 --- a/admin/inertia/layouts/SettingsLayout.tsx +++ b/admin/inertia/layouts/SettingsLayout.tsx @@ -1,4 +1,5 @@ import { + ChartBarIcon, Cog6ToothIcon, CommandLineIcon, FolderIcon, @@ -16,6 +17,7 @@ import { getServiceLink } from '~/lib/navigation' const navigation = [ { name: 'Apps', href: '/settings/apps', icon: CommandLineIcon, current: false }, + { name: 'Benchmark', href: '/settings/benchmark', icon: ChartBarIcon, current: false }, { name: 'Legal Notices', href: '/settings/legal', icon: IconGavel, current: false }, { name: 'Maps Manager', href: '/settings/maps', icon: IconMapRoute, current: false }, { name: 'Models Manager', href: '/settings/models', icon: IconDatabaseStar, current: false }, diff --git a/admin/inertia/pages/settings/benchmark.tsx b/admin/inertia/pages/settings/benchmark.tsx index 57a5072..015e7d9 100644 --- a/admin/inertia/pages/settings/benchmark.tsx +++ b/admin/inertia/pages/settings/benchmark.tsx @@ -128,18 +128,27 @@ export default function BenchmarkPage(props: { }) // Submit to repository mutation + const [submitError, setSubmitError] = useState(null) const submitResult = useMutation({ mutationFn: async (benchmarkId?: string) => { + setSubmitError(null) const res = await fetch('/api/benchmark/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ benchmark_id: benchmarkId }), }) - return res.json() + const data = await res.json() + if (!data.success) { + throw new Error(data.error || 'Failed to submit benchmark') + } + return data }, onSuccess: () => { refetchLatest() }, + onError: (error: Error) => { + setSubmitError(error.message) + }, }) // Simulate progress during sync benchmark (since we don't get SSE updates) @@ -336,21 +345,45 @@ export default function BenchmarkPage(props: { Your NOMAD Score is a weighted composite of all benchmark results.

{!latestResult.submitted_to_repository && ( - submitResult.mutate(latestResult.benchmark_id)} - disabled={submitResult.isPending} - leftIcon={} - > - Share with Community - +
+

+ Share your benchmark score anonymously with the NOMAD community. Only your hardware specs and scores are sent — no identifying information. +

+ submitResult.mutate(latestResult.benchmark_id)} + disabled={submitResult.isPending} + leftIcon={} + > + {submitResult.isPending ? 'Submitting...' : 'Share with Community'} + + {submitError && ( + setSubmitError(null)} + /> + )} +
)} {latestResult.submitted_to_repository && ( + > + + View the leaderboard → + + )}