From efece7733fc801411b0fcbcab6ae12fa2a9d85d7 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Sat, 21 Mar 2026 20:47:46 +0000 Subject: [PATCH] Migrate root of application to use a basic Vue app We'll build from here. --- html/template/sync/authenticated.html | 20 +++++ sync/dash.go | 117 +++++++++----------------- sync/routes.go | 3 +- ts/main.ts | 4 +- 4 files changed, 64 insertions(+), 80 deletions(-) create mode 100644 html/template/sync/authenticated.html diff --git a/html/template/sync/authenticated.html b/html/template/sync/authenticated.html new file mode 100644 index 00000000..0e5045c3 --- /dev/null +++ b/html/template/sync/authenticated.html @@ -0,0 +1,20 @@ + + + + + + Nidus Sync + + + {{ if not .Config.IsProductionEnvironment }} + + {{ end }} + + +
+ {{ if not .Config.IsProductionEnvironment }} + + {{ end }} + + + diff --git a/sync/dash.go b/sync/dash.go index fd56234b..829a6d7a 100644 --- a/sync/dash.go +++ b/sync/dash.go @@ -2,12 +2,10 @@ package sync import ( "context" - "errors" "html/template" "net/http" "time" - "github.com/Gleipnir-Technology/nidus-sync/auth" "github.com/Gleipnir-Technology/nidus-sync/html" nhttp "github.com/Gleipnir-Technology/nidus-sync/http" "github.com/Gleipnir-Technology/nidus-sync/platform" @@ -56,27 +54,50 @@ func getLayoutTest(ctx context.Context, r *http.Request, user platform.User) (*h return html.NewResponse("sync/layout-test.html", contentLayoutTest{}), nil } -func getRoot(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - user, err := auth.GetAuthenticatedUser(r) +func getRoot(ctx context.Context, r *http.Request, user platform.User) (*html.Response[contentDashboard], *nhttp.ErrorWithStatus) { + var lastSync *time.Time + sync, err := user.Organization.FieldseekerSyncLatest(ctx) if err != nil { - // No credentials or user not found: go to login - if errors.Is(err, &auth.NoCredentialsError{}) || errors.Is(err, &platform.NoUserError{}) { - http.Redirect(w, r, "/signin", http.StatusFound) - return - } else { - respondError(w, "Failed to get root", err, http.StatusInternalServerError) - return - } + return nil, nhttp.NewError("Failed to get syncs: %w", err) + } else if sync != nil { + lastSync = &sync.Created } - if user == nil { - errorCode := r.URL.Query().Get("error") - signin(w, errorCode, "/") - return - } else { - dashboard(ctx, w, *user) - return + is_syncing := user.Organization.IsSyncOngoing() + count_trap, err := user.Organization.CountTrap(ctx) + if err != nil { + return nil, nhttp.NewError("Failed to get trap count: %w", err) } + count_source, err := user.Organization.CountTrap(ctx) + if err != nil { + return nil, nhttp.NewError("Failed to get source count: %w", err) + } + count_service, err := user.Organization.CountServiceRequest(ctx) + if err != nil { + return nil, nhttp.NewError("Failed to get service count: %w", err) + } + service_request_recent, err := user.Organization.ServiceRequestRecent(ctx) + if err != nil { + return nil, nhttp.NewError("Failed to get recent service: %w", err) + } + + requests := make([]ServiceRequestSummary, 0) + for _, r := range service_request_recent { + requests = append(requests, ServiceRequestSummary{ + Date: r.Creationdate.MustGet(), + Location: r.Reqaddr1.MustGet(), + Status: "Completed", + }) + } + content := contentDashboard{ + CountTraps: int(count_trap), + CountMosquitoSources: int(count_source), + CountServiceRequests: int(count_service), + IsSyncOngoing: is_syncing, + LastSync: lastSync, + MapData: ComponentMap{}, + RecentRequests: requests, + } + return html.NewResponse("sync/authenticated.html", content), nil } func getSource(ctx context.Context, r *http.Request, user platform.User) (*html.Response[contentSource], *nhttp.ErrorWithStatus) { @@ -175,62 +196,6 @@ func getTrap(ctx context.Context, r *http.Request, user platform.User) (*html.Re return html.NewResponse("sync/trap.html", data), nil } -func dashboard(ctx context.Context, w http.ResponseWriter, user platform.User) { - var lastSync *time.Time - sync, err := user.Organization.FieldseekerSyncLatest(ctx) - if err != nil { - respondError(w, "Failed to get syncs", err, http.StatusInternalServerError) - } else if sync != nil { - lastSync = &sync.Created - } - is_syncing := user.Organization.IsSyncOngoing() - count_trap, err := user.Organization.CountTrap(ctx) - if err != nil { - respondError(w, "Failed to get trap count", err, http.StatusInternalServerError) - return - } - count_source, err := user.Organization.CountTrap(ctx) - if err != nil { - respondError(w, "Failed to get source count", err, http.StatusInternalServerError) - return - } - count_service, err := user.Organization.CountServiceRequest(ctx) - if err != nil { - respondError(w, "Failed to get service count", err, http.StatusInternalServerError) - return - } - service_request_recent, err := user.Organization.ServiceRequestRecent(ctx) - if err != nil { - respondError(w, "Failed to get recent service", err, http.StatusInternalServerError) - return - } - - requests := make([]ServiceRequestSummary, 0) - for _, r := range service_request_recent { - requests = append(requests, ServiceRequestSummary{ - Date: r.Creationdate.MustGet(), - Location: r.Reqaddr1.MustGet(), - Status: "Completed", - }) - } - content := contentDashboard{ - CountTraps: int(count_trap), - CountMosquitoSources: int(count_source), - CountServiceRequests: int(count_service), - IsSyncOngoing: is_syncing, - LastSync: lastSync, - MapData: ComponentMap{}, - RecentRequests: requests, - } - html.RenderOrError(w, "sync/dashboard.html", contentAuthenticated[contentDashboard]{ - C: content, - Config: html.NewContentConfig(), - Organization: user.Organization, - URL: html.NewContentURL(), - User: user, - }) -} - func source(w http.ResponseWriter, r *http.Request, user platform.User, id uuid.UUID) { } diff --git a/sync/routes.go b/sync/routes.go index 1225f906..9c56ed64 100644 --- a/sync/routes.go +++ b/sync/routes.go @@ -9,8 +9,6 @@ import ( func Router() chi.Router { r := chi.NewRouter() - // Root is a special endpoint that is neither authenticated nor unauthenticated - r.Get("/", getRoot) // Unauthenticated endpoints r.Get("/arcgis/oauth/begin", getArcgisOauthBegin) @@ -42,6 +40,7 @@ func Router() chi.Router { // Authenticated endpoints r.Route("/api", api.AddRoutes) + r.Method("GET", "/", authenticatedHandler(getRoot)) r.Method("GET", "/admin", authenticatedHandler(getAdminDash)) r.Method("GET", "/cell/{cell}", authenticatedHandler(getCellDetails)) r.Method("GET", "/communication", authenticatedHandler(getCommunicationRoot)) diff --git a/ts/main.ts b/ts/main.ts index 26552281..0f013d35 100644 --- a/ts/main.ts +++ b/ts/main.ts @@ -2,7 +2,7 @@ import Alpine from "./vendor/alpinejs-3.15.8.js"; import { createApp } from "vue"; import App from "./app.vue"; import { SSEManager } from "./sse-manager"; -import { SetupSidebar } from "./sidebar"; +//import { SetupSidebar } from "./sidebar"; import "maplibre-gl/dist/maplibre-gl.css"; // Import Bootstrap Icons CSS @@ -37,7 +37,7 @@ window.createAppPlanning = createAppPlanning; document.addEventListener("DOMContentLoaded", () => { Alpine.start(); SSEManager.connect("/api/events"); - SetupSidebar(); + //SetupSidebar(); }); document.addEventListener("alpine:init", () => { const user = {