Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
617f65f
first iteration with download, upload and ping data
alexjustesen Dec 18, 2025
eec7fcb
add full benchmark data tracking to metrics dashboard
alexjustesen Dec 18, 2025
7321a12
implement theme switching functionality in the layout component to sy…
alexjustesen Dec 18, 2025
d282445
add theme change listener to re-draw charts on metrics dashboard
alexjustesen Dec 18, 2025
f713722
refactor: consolidate CSS imports and add dashboard styles
alexjustesen Dec 18, 2025
6f74a9e
updated filter ranges and added flux amber theme
alexjustesen Dec 18, 2025
d1ee0fe
feat: add latest benchmark failure tracking to metrics dashboard
alexjustesen Dec 18, 2025
b7b4488
revert change to next speedtest banner
alexjustesen Dec 18, 2025
ce19c1f
feat: add jitter data tracking and visualization to metrics dashboard
alexjustesen Dec 18, 2025
639ab6c
feat: enhance benchmark failure visualization with dynamic point radi…
alexjustesen Dec 18, 2025
de95c37
feat: add download latency tracking and dual-axis chart visualization…
alexjustesen Dec 18, 2025
be46af9
toying with a combined download and upload chart
alexjustesen Dec 18, 2025
a422607
feat: implement date range persistence for metrics dashboard using lo…
alexjustesen Dec 18, 2025
3a4607e
feat: increase tension for line charts to improve visual smoothness
alexjustesen Dec 18, 2025
241d2e4
feat: add subtle vertical separator to improve layout spacing in app …
alexjustesen Dec 18, 2025
f6d3819
added some icons
alexjustesen Dec 19, 2025
dd35b50
feat: add latest benchmark data to metrics dashboard for download, up…
alexjustesen Dec 19, 2025
56c6779
feat: increase border width for chart lines to enhance visibility
alexjustesen Dec 19, 2025
a627ef8
feat: add download and upload icons to metrics dashboard headings
alexjustesen Dec 19, 2025
819702a
feat: rename speed comparison chart and stats for clarity
alexjustesen Dec 19, 2025
63902c6
feat: remove download latency data from metrics dashboard
alexjustesen Dec 19, 2025
1a6181d
feat: add download and upload latency data to metrics dashboard with …
alexjustesen Dec 19, 2025
cea47e3
feat: add packet loss data and chart to metrics dashboard
alexjustesen Dec 19, 2025
4a22899
feat: enhance metrics dashboard with result IDs and tooltip improvements
alexjustesen Dec 19, 2025
c75419e
feat: implement date range filtering and scheduled status in metrics …
alexjustesen Dec 19, 2025
c7cea15
update filter modal width
alexjustesen Dec 19, 2025
72ddb96
removed packet loss chart, wasn't a fan
alexjustesen Dec 19, 2025
eab77ff
feat: implement section management and sorting in metrics dashboard
alexjustesen Dec 19, 2025
d282147
add show/hide sections
alexjustesen Dec 19, 2025
82d7e9e
feat: adjust button size and sidebar separator visibility in layout
alexjustesen Dec 20, 2025
7503000
feat: update default start date to one week ago in metrics dashboard
alexjustesen Dec 20, 2025
a15fde2
feat: enhance date input fields and add quick filter buttons in metri…
alexjustesen Dec 20, 2025
eb2fd26
feat: add date range selection methods for last day, week, and month …
alexjustesen Dec 20, 2025
ca3afcd
feat: implement stats cards for download, upload, ping, and jitter se…
alexjustesen Dec 20, 2025
2255548
feat: implement dynamic default start date based on DEFAULT_CHART_RAN…
alexjustesen Dec 20, 2025
87074e4
feat: add real-time result checking and chart refreshing in metrics d…
alexjustesen Dec 20, 2025
fbdbcc0
bump deps
alexjustesen Dec 20, 2025
483632c
feat: enhance metrics dashboard to track failed results in benchmarks
alexjustesen Dec 20, 2025
55db0cd
added failed results to the charts
alexjustesen Dec 20, 2025
5d73734
fix default chart range
alexjustesen Dec 22, 2025
ec4e587
fixed ping missing from jitter chart
alexjustesen Dec 22, 2025
fdf71d3
feat: simplify theme toggle logic and update default theme to light
alexjustesen Dec 22, 2025
60b8fd3
feat: add daysDifference to chart data for improved visualization
alexjustesen Dec 22, 2025
36cce2d
add vertical bands to show when a result failed
alexjustesen Dec 22, 2025
eb057d5
reorder sections
alexjustesen Dec 22, 2025
9aed5da
added packet loss chart
alexjustesen Dec 22, 2025
c4f2139
Merge branch 'main' into feat/metrics-dashboard
alexjustesen Dec 27, 2025
5a456b2
Add theme selection options and implement responsive header layout
alexjustesen Dec 27, 2025
c6c72dc
brought back the theme dropdown with system as the default
alexjustesen Dec 27, 2025
9bad382
removed p95 from packet loss stats
alexjustesen Dec 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
370 changes: 370 additions & 0 deletions app/Livewire/MetricsDashboard.php

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions app/Models/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ public function prunable(): Builder
return static::where('created_at', '<=', now()->subDays(config('speedtest.prune_results_older_than')));
}

/**
* Scope a query to only include completed results.
*/
public function scopeCompleted(Builder $query): Builder
{
return $query->where('status', ResultStatus::Completed);
}

/**
* Get the user who dispatched this speedtest.
*/
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"laravel/framework": "^12.41.1",
"laravel/prompts": "^0.3.8",
"laravel/sanctum": "^4.2.1",
"livewire/flux": "^2.10.1",
"livewire/livewire": "^3.7.1",
"lorisleiva/laravel-actions": "^2.9.1",
"maennchen/zipstream-php": "^2.4",
Expand Down
68 changes: 67 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions lang/en/general.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
'links' => 'Links',
'donate' => 'Donate',
'donations' => 'Donations',
'light' => 'Light',
'dark' => 'Dark',
'system' => 'System',

// Roles
'admin' => 'Admin',
Expand Down
30 changes: 29 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@
"laravel-vite-plugin": "^1.0.0",
"tailwindcss": "^4.1.17",
"vite": "^6.4.1"
},
"dependencies": {
"@alpinejs/sort": "^3.15.3",
"chart.js": "^4.5.1"
}
}
62 changes: 32 additions & 30 deletions resources/css/app.css
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
@import 'tailwindcss';
@import './custom.css';

/* Safelist max-width utilities to always generate them */
@source inline("max-w-{xs,sm,md,lg,xl,2xl,3xl,4xl,5xl,6xl,7xl,full,min,max,fit,prose,screen-sm,screen-md,screen-lg,screen-xl,screen-2xl}");

/* Required by all components */
@import '../../vendor/filament/support/resources/css/index.css';

/* Required by actions and tables */
@import '../../vendor/filament/actions/resources/css/index.css';

/* Required by actions, forms and tables */
@import '../../vendor/filament/forms/resources/css/index.css';

/* Required by actions and infolists */
@import '../../vendor/filament/infolists/resources/css/index.css';

/* Required by notifications */
/* @import '../../vendor/filament/notifications/resources/css/index.css'; */

/* Required by actions, infolists, forms, schemas and tables */
@import '../../vendor/filament/schemas/resources/css/index.css';

/* Required by tables */
/* @import '../../vendor/filament/tables/resources/css/index.css'; */

/* Required by widgets */
@import '../../vendor/filament/widgets/resources/css/index.css';

@variant dark (&:where(.dark, .dark *));
@import '../../vendor/livewire/flux/dist/flux.css';

@custom-variant dark (&:where(.dark, .dark *));

/* Re-assign Flux's gray of choice... */
@theme {
--color-zinc-50: var(--color-neutral-50);
--color-zinc-100: var(--color-neutral-100);
--color-zinc-200: var(--color-neutral-200);
--color-zinc-300: var(--color-neutral-300);
--color-zinc-400: var(--color-neutral-400);
--color-zinc-500: var(--color-neutral-500);
--color-zinc-600: var(--color-neutral-600);
--color-zinc-700: var(--color-neutral-700);
--color-zinc-800: var(--color-neutral-800);
--color-zinc-900: var(--color-neutral-900);
--color-zinc-950: var(--color-neutral-950);
}

@theme {
--color-accent: var(--color-amber-400);
--color-accent-content: var(--color-amber-600);
--color-accent-foreground: var(--color-amber-950);
}

@layer theme {
.dark {
--color-accent: var(--color-amber-400);
--color-accent-content: var(--color-amber-400);
--color-accent-foreground: var(--color-amber-950);
}
}
31 changes: 31 additions & 0 deletions resources/css/dashboard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@import 'tailwindcss';
@import './custom.css';

/* Safelist max-width utilities to always generate them */
@source inline("max-w-{xs,sm,md,lg,xl,2xl,3xl,4xl,5xl,6xl,7xl,full,min,max,fit,prose,screen-sm,screen-md,screen-lg,screen-xl,screen-2xl}");

/* Required by all components */
@import '../../vendor/filament/support/resources/css/index.css';

/* Required by actions and tables */
@import '../../vendor/filament/actions/resources/css/index.css';

/* Required by actions, forms and tables */
@import '../../vendor/filament/forms/resources/css/index.css';

/* Required by actions and infolists */
@import '../../vendor/filament/infolists/resources/css/index.css';

/* Required by notifications */
/* @import '../../vendor/filament/notifications/resources/css/index.css'; */

/* Required by actions, infolists, forms, schemas and tables */
@import '../../vendor/filament/schemas/resources/css/index.css';

/* Required by tables */
/* @import '../../vendor/filament/tables/resources/css/index.css'; */

/* Required by widgets */
@import '../../vendor/filament/widgets/resources/css/index.css';

@variant dark (&:where(.dark, .dark *));
39 changes: 39 additions & 0 deletions resources/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';
import sort from '@alpinejs/sort';

import {
Chart,
LineController,
LineElement,
PointElement,
LinearScale,
CategoryScale,
BarController,
BarElement,
ScatterController,
Tooltip,
Legend,
Filler
} from 'chart.js';

Chart.register(
LineController,
LineElement,
PointElement,
LinearScale,
CategoryScale,
BarController,
BarElement,
ScatterController,
Tooltip,
Legend,
Filler
);

window.Chart = Chart;

document.addEventListener('livewire:init', () => {
window.Alpine.plugin(sort);
});

Livewire.start();
7 changes: 7 additions & 0 deletions resources/views/components/dashboard/stats-card.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div {{ $attributes->merge(['class' => 'px-6 py-3']) }}>
@isset($heading)
<flux:heading class="flex items-center">{{ $heading }}</flux:heading>
@endisset

{{ $slot }}
</div>
32 changes: 32 additions & 0 deletions resources/views/components/layouts/app.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>{{ $title ?? 'Page Title' }} - {{ config('app.name') }}</title>

@vite(['resources/css/app.css', 'resources/js/app.js'])

<script>
const theme = localStorage.getItem('theme') ?? 'system'
const effectiveTheme = theme === 'system'
? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
: theme

if (effectiveTheme === 'dark') {
document.documentElement.classList.add('dark')
}
</script>
</head>
<body class="min-h-screen bg-white dark:bg-neutral-950 antialiased">
@include('partials.header')

<flux:main container>
{{ $slot }}
</flux:main>

@fluxScripts
@livewireScriptConfig
</body>
</html>
Loading
Loading