From 4284e923a6dab0253b035352939d084b2b4db8e0 Mon Sep 17 00:00:00 2001 From: sneak Date: Wed, 31 Dec 2025 14:56:02 -0800 Subject: [PATCH] Add navbar and home page with search functionality - Create new home page (/) with overview stats, ASN lookup, AS name search, and IP address lookup with JSON display - Add responsive navbar to all pages with app branding - Navbar shows "routewatch by @sneak" with link to author - Status page accessible via navbar link - Remove redirect from / to /status, serve home page instead --- internal/server/handlers.go | 14 +- internal/server/routes.go | 2 +- internal/templates/as_detail.html | 78 ++++- internal/templates/index.html | 466 ++++++++++++++++++++++++++ internal/templates/prefix_detail.html | 79 ++++- internal/templates/prefix_length.html | 79 ++++- internal/templates/status.html | 78 ++++- internal/templates/templates.go | 16 + 8 files changed, 799 insertions(+), 13 deletions(-) create mode 100644 internal/templates/index.html diff --git a/internal/server/handlers.go b/internal/server/handlers.go index b69f192..4464153 100644 --- a/internal/server/handlers.go +++ b/internal/server/handlers.go @@ -87,10 +87,16 @@ func (s *Server) handleHealthCheck() http.HandlerFunc { } } -// handleRoot returns a handler that redirects to /status. -func (s *Server) handleRoot() http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "/status", http.StatusSeeOther) +// handleIndex returns a handler that serves the home page. +func (s *Server) handleIndex() http.HandlerFunc { + return func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + + tmpl := templates.IndexTemplate() + if err := tmpl.Execute(w, nil); err != nil { + s.logger.Error("Failed to render index template", "error", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + } } } diff --git a/internal/server/routes.go b/internal/server/routes.go index a5e37a7..fceab5c 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -21,7 +21,7 @@ func (s *Server) setupRoutes() { r.Use(JSONResponseMiddleware) // Routes - r.Get("/", s.handleRoot()) + r.Get("/", s.handleIndex()) r.Get("/status", s.handleStatusHTML()) r.Get("/status.json", JSONValidationMiddleware(s.handleStatusJSON()).ServeHTTP) r.Get("/.well-known/healthcheck.json", JSONValidationMiddleware(s.handleHealthCheck()).ServeHTTP) diff --git a/internal/templates/as_detail.html b/internal/templates/as_detail.html index 15ade24..acc9099 100644 --- a/internal/templates/as_detail.html +++ b/internal/templates/as_detail.html @@ -5,13 +5,74 @@ AS{{.ASN.ASN}} - {{.ASN.Handle}} - RouteWatch + + +
- ← Back to Status

AS{{.ASN.ASN}}{{if .ASN.Handle}} - {{.ASN.Handle}}{{end}}

{{if .ASN.Description}} @@ -266,5 +339,6 @@
{{end}} +
\ No newline at end of file diff --git a/internal/templates/index.html b/internal/templates/index.html new file mode 100644 index 0000000..9d2c872 --- /dev/null +++ b/internal/templates/index.html @@ -0,0 +1,466 @@ + + + + + + RouteWatch - BGP Route Monitor + + + + + +
+
+

RouteWatch

+

Real-time BGP route monitoring powered by RIPE RIS Live

+
+ +
+
+
-
+
Status
+
+
+
-
+
Live Routes
+
+
+
-
+
Autonomous Systems
+
+
+
-
+
Prefixes
+
+
+
-
+
BGP Peers
+
+
+
-
+
Updates/sec
+
+
+ +
+
+

AS Number Lookup

+
+ + +
+

Enter an AS number to view its announced prefixes and peers

+
+ +
+

AS Name Search

+
+ + +
+

Search for autonomous systems by organization name

+
+
+ +
+

IP Address Lookup

+
+ + +
+

Get routing information for any IP address

+
+
+

Result

+ +
+

+                
+
+
+
+ + + + + + diff --git a/internal/templates/prefix_detail.html b/internal/templates/prefix_detail.html index a228aca..e93247a 100644 --- a/internal/templates/prefix_detail.html +++ b/internal/templates/prefix_detail.html @@ -5,13 +5,74 @@ {{.Prefix}} - RouteWatch + + +
- ← Back to Status -

{{.Prefix}}

IPv{{.IPVersion}} Prefix{{if .MaskLength}} • /{{.MaskLength}}{{end}}

@@ -255,5 +327,6 @@
{{end}} +
\ No newline at end of file diff --git a/internal/templates/prefix_length.html b/internal/templates/prefix_length.html index ca5f8f2..2c44914 100644 --- a/internal/templates/prefix_length.html +++ b/internal/templates/prefix_length.html @@ -5,12 +5,74 @@ Prefixes with /{{ .MaskLength }} - RouteWatch - ← Back to Status + + +

IPv{{ .IPVersion }} Prefixes with /{{ .MaskLength }}

Showing {{ .Count }} randomly selected prefixes

@@ -104,5 +178,6 @@ {{ end }} +
\ No newline at end of file diff --git a/internal/templates/status.html b/internal/templates/status.html index 41b7f9c..7f45c5c 100644 --- a/internal/templates/status.html +++ b/internal/templates/status.html @@ -5,12 +5,74 @@ RouteWatch Status + + +

RouteWatch Status

@@ -542,6 +617,7 @@ updateStatus(); setInterval(updateStatus, 2000); +