diff --git a/src/meshcore_hub/api/routes/dashboard.py b/src/meshcore_hub/api/routes/dashboard.py index 621d576..c725fab 100644 --- a/src/meshcore_hub/api/routes/dashboard.py +++ b/src/meshcore_hub/api/routes/dashboard.py @@ -31,6 +31,7 @@ async def get_stats( now = datetime.now(timezone.utc) today_start = now.replace(hour=0, minute=0, second=0, microsecond=0) yesterday = now - timedelta(days=1) + seven_days_ago = now - timedelta(days=7) # Total nodes total_nodes = session.execute(select(func.count()).select_from(Node)).scalar() or 0 @@ -73,6 +74,26 @@ async def get_stats( or 0 ) + # Advertisements in last 7 days + advertisements_7d = ( + session.execute( + select(func.count()) + .select_from(Advertisement) + .where(Advertisement.received_at >= seven_days_ago) + ).scalar() + or 0 + ) + + # Messages in last 7 days + messages_7d = ( + session.execute( + select(func.count()) + .select_from(Message) + .where(Message.received_at >= seven_days_ago) + ).scalar() + or 0 + ) + # Recent advertisements (last 10) recent_ads = ( session.execute( @@ -185,8 +206,10 @@ async def get_stats( active_nodes=active_nodes, total_messages=total_messages, messages_today=messages_today, + messages_7d=messages_7d, total_advertisements=total_advertisements, advertisements_24h=advertisements_24h, + advertisements_7d=advertisements_7d, recent_advertisements=recent_advertisements, channel_message_counts=channel_message_counts, channel_messages=channel_messages, diff --git a/src/meshcore_hub/common/schemas/messages.py b/src/meshcore_hub/common/schemas/messages.py index 72ef361..7a26900 100644 --- a/src/meshcore_hub/common/schemas/messages.py +++ b/src/meshcore_hub/common/schemas/messages.py @@ -239,10 +239,14 @@ class DashboardStats(BaseModel): active_nodes: int = Field(..., description="Nodes active in last 24h") total_messages: int = Field(..., description="Total number of messages") messages_today: int = Field(..., description="Messages received today") + messages_7d: int = Field(default=0, description="Messages received in last 7 days") total_advertisements: int = Field(..., description="Total advertisements") advertisements_24h: int = Field( default=0, description="Advertisements received in last 24h" ) + advertisements_7d: int = Field( + default=0, description="Advertisements received in last 7 days" + ) recent_advertisements: list[RecentAdvertisement] = Field( default_factory=list, description="Last 10 advertisements" ) diff --git a/src/meshcore_hub/web/templates/home.html b/src/meshcore_hub/web/templates/home.html index a13d111..36ee5cb 100644 --- a/src/meshcore_hub/web/templates/home.html +++ b/src/meshcore_hub/web/templates/home.html @@ -19,25 +19,25 @@

{% endif %}
- + Dashboard - + Nodes - + Advertisements - + @@ -49,7 +49,7 @@
-
+
@@ -62,7 +62,7 @@
All discovered nodes
- +
@@ -70,32 +70,20 @@
Advertisements
-
{{ stats.advertisements_24h }}
-
Received in last 24 hours
+
{{ stats.advertisements_7d }}
+
Last 7 days
- +
-
Total Messages
-
{{ stats.total_messages }}
-
All time
-
- - -
-
- - - -
-
Messages Today
-
{{ stats.messages_today }}
-
Last 24 hours
+
Messages
+
{{ stats.messages_7d }}
+
Last 7 days
@@ -239,8 +227,8 @@ datasets: [{ label: 'Advertisements', data: counts, - borderColor: 'oklch(0.7 0.15 250)', - backgroundColor: 'oklch(0.7 0.15 250 / 0.1)', + borderColor: 'oklch(0.7 0.17 330)', + backgroundColor: 'oklch(0.7 0.17 330 / 0.1)', fill: true, tension: 0.3, pointRadius: 2, diff --git a/src/meshcore_hub/web/templates/network.html b/src/meshcore_hub/web/templates/network.html index 48724ed..65dc7a6 100644 --- a/src/meshcore_hub/web/templates/network.html +++ b/src/meshcore_hub/web/templates/network.html @@ -22,8 +22,63 @@
{% endif %} + +
+ +
+
+ + + +
+
Total Nodes
+
{{ stats.total_nodes }}
+
All discovered nodes
+
+ + +
+
+ + + +
+
Advertisements
+
{{ stats.advertisements_7d }}
+
Last 7 days
+
+ + +
+
+ + + +
+
Messages
+
{{ stats.messages_7d }}
+
Last 7 days
+
+
+
+ +
+
+

+ + + + Total Nodes +

+

Over time (last 7 days)

+
+ +
+
+
+
@@ -55,22 +110,6 @@
- - -
-
-

- - - - Total Nodes -

-

Over time (last 7 days)

-
- -
-
-
@@ -163,27 +202,6 @@ {% endif %} - -
- - - - - Browse Nodes - - - - - - View Messages - - - - - - View Map - -
{% endblock %} {% block extra_scripts %} @@ -232,7 +250,7 @@ }); } - // Advertisements chart + // Advertisements chart (secondary color - pink/magenta) const advertCtx = document.getElementById('advertChart'); if (advertCtx && advertData.data && advertData.data.length > 0) { new Chart(advertCtx, { @@ -242,8 +260,8 @@ datasets: [{ label: 'Advertisements', data: advertData.data.map(d => d.count), - borderColor: 'oklch(0.7 0.15 250)', - backgroundColor: 'oklch(0.7 0.15 250 / 0.1)', + borderColor: 'oklch(0.7 0.17 330)', + backgroundColor: 'oklch(0.7 0.17 330 / 0.1)', fill: true, tension: 0.3, pointRadius: 2, @@ -254,7 +272,7 @@ }); } - // Messages chart + // Messages chart (accent color - teal/cyan) const messageCtx = document.getElementById('messageChart'); if (messageCtx && messageData.data && messageData.data.length > 0) { new Chart(messageCtx, { @@ -264,8 +282,8 @@ datasets: [{ label: 'Messages', data: messageData.data.map(d => d.count), - borderColor: 'oklch(0.7 0.15 160)', - backgroundColor: 'oklch(0.7 0.15 160 / 0.1)', + borderColor: 'oklch(0.75 0.18 180)', + backgroundColor: 'oklch(0.75 0.18 180 / 0.1)', fill: true, tension: 0.3, pointRadius: 2, @@ -276,7 +294,7 @@ }); } - // Node count chart + // Node count chart (primary color - purple/blue) const nodeCtx = document.getElementById('nodeChart'); if (nodeCtx && nodeData.data && nodeData.data.length > 0) { new Chart(nodeCtx, { @@ -286,8 +304,8 @@ datasets: [{ label: 'Total Nodes', data: nodeData.data.map(d => d.count), - borderColor: 'oklch(0.7 0.15 30)', - backgroundColor: 'oklch(0.7 0.15 30 / 0.1)', + borderColor: 'oklch(0.65 0.24 265)', + backgroundColor: 'oklch(0.65 0.24 265 / 0.1)', fill: true, tension: 0.3, pointRadius: 2,