From 4c23eba5d77427478e3d0405b3b447d593239473 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Wed, 7 Jan 2026 15:34:09 +0000 Subject: [PATCH] Move html pages to a package That way I can separate out HTML for the public-facing report system and Nidus sync. --- default.nix | 4 ++-- endpoint.go | 21 ++++++++++--------- fieldseeker.go | 15 ------------- h3.go => htmlpage/h3.go | 2 +- html.go => htmlpage/html.go | 20 ++++++++++-------- .../model_conversion.go | 2 +- notification.go => htmlpage/notification.go | 2 +- htmlpage/response.go | 13 ++++++++++++ {templates => htmlpage/templates}/admin.html | 0 .../templates}/authenticated.html | 0 {templates => htmlpage/templates}/base.html | 0 {templates => htmlpage/templates}/cell.html | 0 .../templates}/components/header.html | 0 .../templates}/components/map.html | 0 .../templates}/dashboard.html | 0 .../templates}/data-entry-bad.html | 0 .../templates}/data-entry-good.html | 0 .../templates}/data-entry.html | 0 .../templates}/dispatch-results.html | 0 .../templates}/dispatch.html | 0 .../templates}/empty-auth.html | 0 {templates => htmlpage/templates}/empty.html | 0 .../templates}/mock-root.html | 0 .../templates}/oauth-prompt.html | 0 .../templates}/report-confirmation.html | 0 .../templates}/report-contribute.html | 0 .../templates}/report-detail.html | 0 .../templates}/report-evidence.html | 0 .../templates}/report-schedule.html | 0 .../templates}/report-update.html | 0 {templates => htmlpage/templates}/report.html | 0 .../templates}/service-request-detail.html | 0 .../templates}/service-request-location.html | 0 .../templates}/service-request-mosquito.html | 0 .../templates}/service-request-pool.html | 0 .../service-request-quick-confirmation.html | 0 .../templates}/service-request-quick.html | 0 .../templates}/service-request-updates.html | 0 .../templates}/service-request.html | 0 .../templates}/setting-integration.html | 0 .../templates}/setting-mock.html | 0 .../templates}/setting-pesticide-add.html | 0 .../templates}/setting-pesticide.html | 0 .../templates}/setting-user-add.html | 0 .../templates}/setting-user.html | 0 .../templates}/settings.html | 0 {templates => htmlpage/templates}/signin.html | 0 {templates => htmlpage/templates}/signup.html | 0 {templates => htmlpage/templates}/source.html | 0 time.go => htmlpage/time.go | 2 +- main.go | 7 ++++--- 51 files changed, 45 insertions(+), 43 deletions(-) delete mode 100644 fieldseeker.go rename h3.go => htmlpage/h3.go (99%) rename html.go => htmlpage/html.go (97%) rename model_conversion.go => htmlpage/model_conversion.go (99%) rename notification.go => htmlpage/notification.go (99%) create mode 100644 htmlpage/response.go rename {templates => htmlpage/templates}/admin.html (100%) rename {templates => htmlpage/templates}/authenticated.html (100%) rename {templates => htmlpage/templates}/base.html (100%) rename {templates => htmlpage/templates}/cell.html (100%) rename {templates => htmlpage/templates}/components/header.html (100%) rename {templates => htmlpage/templates}/components/map.html (100%) rename {templates => htmlpage/templates}/dashboard.html (100%) rename {templates => htmlpage/templates}/data-entry-bad.html (100%) rename {templates => htmlpage/templates}/data-entry-good.html (100%) rename {templates => htmlpage/templates}/data-entry.html (100%) rename {templates => htmlpage/templates}/dispatch-results.html (100%) rename {templates => htmlpage/templates}/dispatch.html (100%) rename {templates => htmlpage/templates}/empty-auth.html (100%) rename {templates => htmlpage/templates}/empty.html (100%) rename {templates => htmlpage/templates}/mock-root.html (100%) rename {templates => htmlpage/templates}/oauth-prompt.html (100%) rename {templates => htmlpage/templates}/report-confirmation.html (100%) rename {templates => htmlpage/templates}/report-contribute.html (100%) rename {templates => htmlpage/templates}/report-detail.html (100%) rename {templates => htmlpage/templates}/report-evidence.html (100%) rename {templates => htmlpage/templates}/report-schedule.html (100%) rename {templates => htmlpage/templates}/report-update.html (100%) rename {templates => htmlpage/templates}/report.html (100%) rename {templates => htmlpage/templates}/service-request-detail.html (100%) rename {templates => htmlpage/templates}/service-request-location.html (100%) rename {templates => htmlpage/templates}/service-request-mosquito.html (100%) rename {templates => htmlpage/templates}/service-request-pool.html (100%) rename {templates => htmlpage/templates}/service-request-quick-confirmation.html (100%) rename {templates => htmlpage/templates}/service-request-quick.html (100%) rename {templates => htmlpage/templates}/service-request-updates.html (100%) rename {templates => htmlpage/templates}/service-request.html (100%) rename {templates => htmlpage/templates}/setting-integration.html (100%) rename {templates => htmlpage/templates}/setting-mock.html (100%) rename {templates => htmlpage/templates}/setting-pesticide-add.html (100%) rename {templates => htmlpage/templates}/setting-pesticide.html (100%) rename {templates => htmlpage/templates}/setting-user-add.html (100%) rename {templates => htmlpage/templates}/setting-user.html (100%) rename {templates => htmlpage/templates}/settings.html (100%) rename {templates => htmlpage/templates}/signin.html (100%) rename {templates => htmlpage/templates}/signup.html (100%) rename {templates => htmlpage/templates}/source.html (100%) rename time.go => htmlpage/time.go (99%) diff --git a/default.nix b/default.nix index 297af692..df6517b5 100644 --- a/default.nix +++ b/default.nix @@ -7,7 +7,7 @@ pkgs.buildGoModule rec { pname = "nidus-sync"; src = ./.; subPackages = []; - version = "0.0.7"; + version = "0.0.8"; # Needs to be updated after every modification of go.mod/go.sum - vendorHash = "sha256-JuRB/2pNidonwQm6iCyUXiFxkAwizEXdwieRRjgSBwI="; + vendorHash = "sha256-5E5gQJh2cr/XwDg+XRQEdXW7mkObZMoyqQnfToVuZ10="; } diff --git a/endpoint.go b/endpoint.go index cf3c3116..80ed7bf7 100644 --- a/endpoint.go +++ b/endpoint.go @@ -11,6 +11,7 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/auth" "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/Gleipnir-Technology/nidus-sync/htmlpage" "github.com/go-chi/chi/v5" "github.com/google/uuid" "github.com/rs/zerolog/log" @@ -53,7 +54,7 @@ func getCellDetails(w http.ResponseWriter, r *http.Request, user *models.User) { respondError(w, "Cannot convert provided cell to uint64", err, http.StatusBadRequest) return } - htmlCell(r.Context(), w, user, cell) + htmlpage.Cell(r.Context(), w, user, cell) } func getFavicon(w http.ResponseWriter, r *http.Request) { @@ -68,7 +69,7 @@ func getOAuthRefresh(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/?next=/oauth/refresh", http.StatusFound) return } - htmlOauthPrompt(w, user) + htmlpage.OauthPrompt(w, user) } func getQRCodeReport(w http.ResponseWriter, r *http.Request) { @@ -145,7 +146,7 @@ func getRoot(w http.ResponseWriter, r *http.Request) { } if user == nil { errorCode := r.URL.Query().Get("error") - htmlSignin(w, errorCode) + htmlpage.Signin(w, errorCode) return } else { has, err := hasFieldseekerConnection(r.Context(), user) @@ -154,10 +155,10 @@ func getRoot(w http.ResponseWriter, r *http.Request) { return } if has { - htmlDashboard(r.Context(), w, user) + htmlpage.Dashboard(r.Context(), w, user) return } else { - htmlOauthPrompt(w, user) + htmlpage.OauthPrompt(w, user) return } } @@ -167,16 +168,16 @@ func getRoot(w http.ResponseWriter, r *http.Request) { } func getSettings(w http.ResponseWriter, r *http.Request, u *models.User) { - htmlSettings(w, r, u) + htmlpage.Settings(w, r, u) } func getSignin(w http.ResponseWriter, r *http.Request) { errorCode := r.URL.Query().Get("error") - htmlSignin(w, errorCode) + htmlpage.Signin(w, errorCode) } func getSignup(w http.ResponseWriter, r *http.Request) { - htmlSignup(w, r.URL.Path) + htmlpage.Signup(w, r.URL.Path) } func getSource(w http.ResponseWriter, r *http.Request, u *models.User) { @@ -190,7 +191,7 @@ func getSource(w http.ResponseWriter, r *http.Request, u *models.User) { respondError(w, "globalid is not a UUID", nil, http.StatusBadRequest) return } - htmlSource(w, r, u, globalid) + htmlpage.Source(w, r, u, globalid) } func postSMS(w http.ResponseWriter, r *http.Request) { @@ -324,6 +325,6 @@ func renderMock(templateName string) http.HandlerFunc { if code == "" { code = "abc-123" } - htmlMock(templateName, w, code) + htmlpage.Mock(templateName, w, code) } } diff --git a/fieldseeker.go b/fieldseeker.go deleted file mode 100644 index 459ad588..00000000 --- a/fieldseeker.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "time" - - "github.com/aarondl/opt/null" -) - -func fsTimestampToTime(t null.Val[int64]) *time.Time { - if t.IsNull() { - return nil - } - result := time.UnixMilli(t.MustGet()) - return &result -} diff --git a/h3.go b/htmlpage/h3.go similarity index 99% rename from h3.go rename to htmlpage/h3.go index ef1feec4..b994ca2a 100644 --- a/h3.go +++ b/htmlpage/h3.go @@ -1,4 +1,4 @@ -package main +package htmlpage import ( "fmt" diff --git a/html.go b/htmlpage/html.go similarity index 97% rename from html.go rename to htmlpage/html.go index 355271a6..8cad39cc 100644 --- a/html.go +++ b/htmlpage/html.go @@ -1,4 +1,4 @@ -package main +package htmlpage import ( "bytes" @@ -30,6 +30,8 @@ import ( //go:embed templates/* var embeddedFiles embed.FS +var MapboxToken string + // Authenticated pages var ( cell = newBuiltTemplate("cell", "authenticated") @@ -251,7 +253,7 @@ func extractInitials(name string) string { return initials.String() } -func htmlCell(ctx context.Context, w http.ResponseWriter, user *models.User, c int64) { +func Cell(ctx context.Context, w http.ResponseWriter, user *models.User, c int64) { org, err := user.Organization().One(ctx, db.PGInstance.BobDB) if err != nil { respondError(w, "Failed to get org", err, http.StatusInternalServerError) @@ -312,7 +314,7 @@ func htmlCell(ctx context.Context, w http.ResponseWriter, user *models.User, c i renderOrError(w, cell, &data) } -func htmlDashboard(ctx context.Context, w http.ResponseWriter, user *models.User) { +func Dashboard(ctx context.Context, w http.ResponseWriter, user *models.User) { org, err := user.Organization().One(ctx, db.PGInstance.BobDB) if err != nil { respondError(w, "Failed to get org", err, http.StatusInternalServerError) @@ -379,7 +381,7 @@ func htmlDashboard(ctx context.Context, w http.ResponseWriter, user *models.User renderOrError(w, dashboard, data) } -func htmlMock(t string, w http.ResponseWriter, code string) { +func Mock(t string, w http.ResponseWriter, code string) { data := ContentMock{ DistrictName: "Delta MVCD", URLs: ContentMockURLs{ @@ -409,7 +411,7 @@ func htmlMock(t string, w http.ResponseWriter, code string) { renderOrError(w, &template, data) } -func htmlOauthPrompt(w http.ResponseWriter, user *models.User) { +func OauthPrompt(w http.ResponseWriter, user *models.User) { dp := user.DisplayName data := ContentDashboard{ User: User{ @@ -421,7 +423,7 @@ func htmlOauthPrompt(w http.ResponseWriter, user *models.User) { renderOrError(w, oauthPrompt, data) } -func htmlSettings(w http.ResponseWriter, r *http.Request, user *models.User) { +func Settings(w http.ResponseWriter, r *http.Request, user *models.User) { userContent, err := contentForUser(r.Context(), user) if err != nil { respondError(w, "Failed to get user content", err, http.StatusInternalServerError) @@ -433,19 +435,19 @@ func htmlSettings(w http.ResponseWriter, r *http.Request, user *models.User) { renderOrError(w, settings, data) } -func htmlSignin(w http.ResponseWriter, errorCode string) { +func Signin(w http.ResponseWriter, errorCode string) { data := ContentSignin{ InvalidCredentials: errorCode == "invalid-credentials", } renderOrError(w, signin, data) } -func htmlSignup(w http.ResponseWriter, path string) { +func Signup(w http.ResponseWriter, path string) { data := ContentSignup{} renderOrError(w, signup, data) } -func htmlSource(w http.ResponseWriter, r *http.Request, user *models.User, id uuid.UUID) { +func Source(w http.ResponseWriter, r *http.Request, user *models.User, id uuid.UUID) { org, err := user.Organization().One(r.Context(), db.PGInstance.BobDB) if err != nil { respondError(w, "Failed to get org", err, http.StatusInternalServerError) diff --git a/model_conversion.go b/htmlpage/model_conversion.go similarity index 99% rename from model_conversion.go rename to htmlpage/model_conversion.go index 59b7d108..39a01917 100644 --- a/model_conversion.go +++ b/htmlpage/model_conversion.go @@ -1,4 +1,4 @@ -package main +package htmlpage import ( "errors" diff --git a/notification.go b/htmlpage/notification.go similarity index 99% rename from notification.go rename to htmlpage/notification.go index 9e7db8dc..ec2180a9 100644 --- a/notification.go +++ b/htmlpage/notification.go @@ -1,4 +1,4 @@ -package main +package htmlpage import ( "context" diff --git a/htmlpage/response.go b/htmlpage/response.go new file mode 100644 index 00000000..88874871 --- /dev/null +++ b/htmlpage/response.go @@ -0,0 +1,13 @@ +package htmlpage + +import ( + "net/http" + + "github.com/rs/zerolog/log" +) + +// Respond with an error that is visible to the user +func respondError(w http.ResponseWriter, m string, e error, s int) { + log.Warn().Int("status", s).Err(e).Str("user message", m).Msg("Responding with an error") + http.Error(w, m, s) +} diff --git a/templates/admin.html b/htmlpage/templates/admin.html similarity index 100% rename from templates/admin.html rename to htmlpage/templates/admin.html diff --git a/templates/authenticated.html b/htmlpage/templates/authenticated.html similarity index 100% rename from templates/authenticated.html rename to htmlpage/templates/authenticated.html diff --git a/templates/base.html b/htmlpage/templates/base.html similarity index 100% rename from templates/base.html rename to htmlpage/templates/base.html diff --git a/templates/cell.html b/htmlpage/templates/cell.html similarity index 100% rename from templates/cell.html rename to htmlpage/templates/cell.html diff --git a/templates/components/header.html b/htmlpage/templates/components/header.html similarity index 100% rename from templates/components/header.html rename to htmlpage/templates/components/header.html diff --git a/templates/components/map.html b/htmlpage/templates/components/map.html similarity index 100% rename from templates/components/map.html rename to htmlpage/templates/components/map.html diff --git a/templates/dashboard.html b/htmlpage/templates/dashboard.html similarity index 100% rename from templates/dashboard.html rename to htmlpage/templates/dashboard.html diff --git a/templates/data-entry-bad.html b/htmlpage/templates/data-entry-bad.html similarity index 100% rename from templates/data-entry-bad.html rename to htmlpage/templates/data-entry-bad.html diff --git a/templates/data-entry-good.html b/htmlpage/templates/data-entry-good.html similarity index 100% rename from templates/data-entry-good.html rename to htmlpage/templates/data-entry-good.html diff --git a/templates/data-entry.html b/htmlpage/templates/data-entry.html similarity index 100% rename from templates/data-entry.html rename to htmlpage/templates/data-entry.html diff --git a/templates/dispatch-results.html b/htmlpage/templates/dispatch-results.html similarity index 100% rename from templates/dispatch-results.html rename to htmlpage/templates/dispatch-results.html diff --git a/templates/dispatch.html b/htmlpage/templates/dispatch.html similarity index 100% rename from templates/dispatch.html rename to htmlpage/templates/dispatch.html diff --git a/templates/empty-auth.html b/htmlpage/templates/empty-auth.html similarity index 100% rename from templates/empty-auth.html rename to htmlpage/templates/empty-auth.html diff --git a/templates/empty.html b/htmlpage/templates/empty.html similarity index 100% rename from templates/empty.html rename to htmlpage/templates/empty.html diff --git a/templates/mock-root.html b/htmlpage/templates/mock-root.html similarity index 100% rename from templates/mock-root.html rename to htmlpage/templates/mock-root.html diff --git a/templates/oauth-prompt.html b/htmlpage/templates/oauth-prompt.html similarity index 100% rename from templates/oauth-prompt.html rename to htmlpage/templates/oauth-prompt.html diff --git a/templates/report-confirmation.html b/htmlpage/templates/report-confirmation.html similarity index 100% rename from templates/report-confirmation.html rename to htmlpage/templates/report-confirmation.html diff --git a/templates/report-contribute.html b/htmlpage/templates/report-contribute.html similarity index 100% rename from templates/report-contribute.html rename to htmlpage/templates/report-contribute.html diff --git a/templates/report-detail.html b/htmlpage/templates/report-detail.html similarity index 100% rename from templates/report-detail.html rename to htmlpage/templates/report-detail.html diff --git a/templates/report-evidence.html b/htmlpage/templates/report-evidence.html similarity index 100% rename from templates/report-evidence.html rename to htmlpage/templates/report-evidence.html diff --git a/templates/report-schedule.html b/htmlpage/templates/report-schedule.html similarity index 100% rename from templates/report-schedule.html rename to htmlpage/templates/report-schedule.html diff --git a/templates/report-update.html b/htmlpage/templates/report-update.html similarity index 100% rename from templates/report-update.html rename to htmlpage/templates/report-update.html diff --git a/templates/report.html b/htmlpage/templates/report.html similarity index 100% rename from templates/report.html rename to htmlpage/templates/report.html diff --git a/templates/service-request-detail.html b/htmlpage/templates/service-request-detail.html similarity index 100% rename from templates/service-request-detail.html rename to htmlpage/templates/service-request-detail.html diff --git a/templates/service-request-location.html b/htmlpage/templates/service-request-location.html similarity index 100% rename from templates/service-request-location.html rename to htmlpage/templates/service-request-location.html diff --git a/templates/service-request-mosquito.html b/htmlpage/templates/service-request-mosquito.html similarity index 100% rename from templates/service-request-mosquito.html rename to htmlpage/templates/service-request-mosquito.html diff --git a/templates/service-request-pool.html b/htmlpage/templates/service-request-pool.html similarity index 100% rename from templates/service-request-pool.html rename to htmlpage/templates/service-request-pool.html diff --git a/templates/service-request-quick-confirmation.html b/htmlpage/templates/service-request-quick-confirmation.html similarity index 100% rename from templates/service-request-quick-confirmation.html rename to htmlpage/templates/service-request-quick-confirmation.html diff --git a/templates/service-request-quick.html b/htmlpage/templates/service-request-quick.html similarity index 100% rename from templates/service-request-quick.html rename to htmlpage/templates/service-request-quick.html diff --git a/templates/service-request-updates.html b/htmlpage/templates/service-request-updates.html similarity index 100% rename from templates/service-request-updates.html rename to htmlpage/templates/service-request-updates.html diff --git a/templates/service-request.html b/htmlpage/templates/service-request.html similarity index 100% rename from templates/service-request.html rename to htmlpage/templates/service-request.html diff --git a/templates/setting-integration.html b/htmlpage/templates/setting-integration.html similarity index 100% rename from templates/setting-integration.html rename to htmlpage/templates/setting-integration.html diff --git a/templates/setting-mock.html b/htmlpage/templates/setting-mock.html similarity index 100% rename from templates/setting-mock.html rename to htmlpage/templates/setting-mock.html diff --git a/templates/setting-pesticide-add.html b/htmlpage/templates/setting-pesticide-add.html similarity index 100% rename from templates/setting-pesticide-add.html rename to htmlpage/templates/setting-pesticide-add.html diff --git a/templates/setting-pesticide.html b/htmlpage/templates/setting-pesticide.html similarity index 100% rename from templates/setting-pesticide.html rename to htmlpage/templates/setting-pesticide.html diff --git a/templates/setting-user-add.html b/htmlpage/templates/setting-user-add.html similarity index 100% rename from templates/setting-user-add.html rename to htmlpage/templates/setting-user-add.html diff --git a/templates/setting-user.html b/htmlpage/templates/setting-user.html similarity index 100% rename from templates/setting-user.html rename to htmlpage/templates/setting-user.html diff --git a/templates/settings.html b/htmlpage/templates/settings.html similarity index 100% rename from templates/settings.html rename to htmlpage/templates/settings.html diff --git a/templates/signin.html b/htmlpage/templates/signin.html similarity index 100% rename from templates/signin.html rename to htmlpage/templates/signin.html diff --git a/templates/signup.html b/htmlpage/templates/signup.html similarity index 100% rename from templates/signup.html rename to htmlpage/templates/signup.html diff --git a/templates/source.html b/htmlpage/templates/source.html similarity index 100% rename from templates/source.html rename to htmlpage/templates/source.html diff --git a/time.go b/htmlpage/time.go similarity index 99% rename from time.go rename to htmlpage/time.go index d7b611b1..24427292 100644 --- a/time.go +++ b/htmlpage/time.go @@ -1,4 +1,4 @@ -package main +package htmlpage import ( "sort" diff --git a/main.go b/main.go index e394c3f9..b78b9e2d 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,7 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/api" "github.com/Gleipnir-Technology/nidus-sync/auth" "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/htmlpage" "github.com/Gleipnir-Technology/nidus-sync/queue" "github.com/Gleipnir-Technology/nidus-sync/report" "github.com/Gleipnir-Technology/nidus-sync/userfile" @@ -24,7 +25,7 @@ import ( "github.com/rs/zerolog/log" ) -var ClientID, ClientSecret, Environment, FieldseekerSchemaDirectory, MapboxToken, URLReport, URLSync string +var ClientID, ClientSecret, Environment, FieldseekerSchemaDirectory, URLReport, URLSync string func main() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix @@ -63,8 +64,8 @@ func main() { log.Error().Str("ENVIRONMENT", Environment).Msg("ENVIRONMENT should be either DEVELOPMENT or PRODUCTION") os.Exit(2) } - MapboxToken = os.Getenv("MAPBOX_TOKEN") - if MapboxToken == "" { + htmlpage.MapboxToken = os.Getenv("MAPBOX_TOKEN") + if htmlpage.MapboxToken == "" { log.Error().Msg("You must specify a non-empty MAPBOX_TOKEN") os.Exit(1) }