diff --git a/htmlpage/public-reports/page.go b/htmlpage/public-reports/page.go index 4ce4e388..8a37af49 100644 --- a/htmlpage/public-reports/page.go +++ b/htmlpage/public-reports/page.go @@ -16,15 +16,19 @@ var EmbeddedStaticFS embed.FS type ContextNuisance struct{} type ContextPool struct{} type ContextQuick struct{} +type ContextQuickSubmitComplete struct { + ReportID string +} type ContextRoot struct{} type ContextStatus struct{} var ( - Nuisance = buildTemplate("nuisance", "base") - Pool = buildTemplate("pool", "base") - Quick = buildTemplate("quick", "base") - Root = buildTemplate("root", "base") - Status = buildTemplate("status", "base") + Nuisance = buildTemplate("nuisance", "base") + Pool = buildTemplate("pool", "base") + Quick = buildTemplate("quick", "base") + QuickSubmitComplete = buildTemplate("quick-submit-complete", "base") + Root = buildTemplate("root", "base") + Status = buildTemplate("status", "base") ) var components = [...]string{"footer"} diff --git a/htmlpage/public-reports/template/quick-submit-complete.html b/htmlpage/public-reports/template/quick-submit-complete.html new file mode 100644 index 00000000..be20cfb5 --- /dev/null +++ b/htmlpage/public-reports/template/quick-submit-complete.html @@ -0,0 +1,125 @@ +{{template "base.html" .}} + +{{define "title"}}Dash{{end}} +{{define "extraheader"}} + + +{{end}} +{{define "content"}} +
+
+
+ +
+
+

+ + + + Report Successfully Submitted +

+
+
+
+

Thank you for helping us control mosquito populations in your area!

+
+ Your Report ID: + {{.ReportID}} +
+

Please save this ID for your reference.

+
+ +
+ + +
+

+ + + + Check Your Report Status +

+

You can check the status of your report at any time using your Report ID.

+ + Check Status + +
+ +
+ + +
+

+ + + + Get Updates +

+

Provide your contact information to receive updates about your report.

+ +
+ + +
+ +
+ + + + + + +
+
+ +
+ +
+ + + + + + + +
+
+ +
+ + +
+ You must consent to receive notifications. +
+
+ + +
+
+
+
+ + + +
+
+
+{{end}} diff --git a/htmlpage/public-reports/template/quick.html b/htmlpage/public-reports/template/quick.html index bbd5711c..ffb86d61 100644 --- a/htmlpage/public-reports/template/quick.html +++ b/htmlpage/public-reports/template/quick.html @@ -51,6 +51,184 @@ } } + {{end}} {{define "content"}} @@ -60,18 +238,22 @@

Quick Mosquito Report

- + -
+
- Your location and current time will be automatically collected with your report. + Requesting your location... + + + +
- +
@@ -81,27 +263,26 @@
- +
Take pictures of the mosquito problem area - - -
- - Preview + + +
+
- +
- +
- + -
- - -
- - - - - Back to home - -
+ +
+
+
+

Submitting your report...

+
+
{{end}} diff --git a/main.go b/main.go index ad0e09fe..8e3b5dcb 100644 --- a/main.go +++ b/main.go @@ -15,8 +15,8 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/background" "github.com/Gleipnir-Technology/nidus-sync/config" "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/public-report" "github.com/Gleipnir-Technology/nidus-sync/queue" - "github.com/Gleipnir-Technology/nidus-sync/report" nidussync "github.com/Gleipnir-Technology/nidus-sync/sync" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" @@ -52,9 +52,9 @@ func main() { // Set up routing by hostname sr := nidussync.Router() - hr.Map("", sr) // default - hr.Map("*", sr) // default - hr.Map(config.URLReport, report.Router()) // report.mosquitoes.online + hr.Map("", sr) // default + hr.Map("*", sr) // default + hr.Map(config.URLReport, publicreport.Router()) // report.mosquitoes.online hr.Map(config.URLSync, sr) r.Mount("/", hr) diff --git a/public-report/endpoint.go b/public-report/endpoint.go new file mode 100644 index 00000000..2d278605 --- /dev/null +++ b/public-report/endpoint.go @@ -0,0 +1,125 @@ +package publicreport + +import ( + "bytes" + "io" + "net/http" + + "github.com/Gleipnir-Technology/nidus-sync/htmlpage" + "github.com/Gleipnir-Technology/nidus-sync/htmlpage/public-reports" + "github.com/go-chi/chi/v5" + "github.com/rs/zerolog/log" +) + +func Router() chi.Router { + r := chi.NewRouter() + r.Get("/", getRoot) + r.Get("/nuisance", getNuisance) + r.Get("/pool", getPool) + r.Get("/quick", getQuick) + r.Post("/quick-submit", postQuick) + r.Get("/quick-submit-complete", getQuickSubmitComplete) + r.Get("/status", getStatus) + localFS := http.Dir("./static") + htmlpage.FileServer(r, "/static", localFS, publicreports.EmbeddedStaticFS, "static") + return r +} + +func getRoot(w http.ResponseWriter, r *http.Request) { + htmlpage.RenderOrError( + w, + publicreports.Root, + publicreports.ContextRoot{}, + ) +} + +func getNuisance(w http.ResponseWriter, r *http.Request) { + htmlpage.RenderOrError( + w, + publicreports.Nuisance, + publicreports.ContextNuisance{}, + ) +} +func getPool(w http.ResponseWriter, r *http.Request) { + htmlpage.RenderOrError( + w, + publicreports.Pool, + publicreports.ContextPool{}, + ) +} +func getQuick(w http.ResponseWriter, r *http.Request) { + htmlpage.RenderOrError( + w, + publicreports.Quick, + publicreports.ContextQuick{}, + ) +} +func getQuickSubmitComplete(w http.ResponseWriter, r *http.Request) { + report := r.URL.Query().Get("report") + htmlpage.RenderOrError( + w, + publicreports.QuickSubmitComplete, + publicreports.ContextQuickSubmitComplete{ + ReportID: report, + }, + ) +} +func getStatus(w http.ResponseWriter, r *http.Request) { + htmlpage.RenderOrError( + w, + publicreports.Status, + publicreports.ContextStatus{}, + ) +} +func postQuick(w http.ResponseWriter, r *http.Request) { + err := r.ParseMultipartForm(32 << 10) // 32 MB buffer + if err != nil { + log.Error().Err(err).Msg("Failed to parse form") + respondError(w, "Failed to parse form", err, http.StatusBadRequest) + return + } + latitude := r.FormValue("latitude") + longitude := r.FormValue("longitude") + created := r.FormValue("created") + //photos := r.FormValue("photos") + + log.Info().Str("latitude", latitude).Str("longitude", longitude).Str("created", created).Msg("Got upload") + for _, fheaders := range r.MultipartForm.File { + for _, headers := range fheaders { + file, err := headers.Open() + + if err != nil { + respondError(w, "Failed to open header", err, http.StatusInternalServerError) + return + } + + defer file.Close() + + buff := make([]byte, 512) + file.Read(buff) + + file.Seek(0, 0) + contentType := http.DetectContentType(buff) + var sizeBuff bytes.Buffer + fileSize, err := sizeBuff.ReadFrom(file) + if err != nil { + respondError(w, "Failed to read file", err, http.StatusInternalServerError) + return + } + file.Seek(0, 0) + contentBuf := bytes.NewBuffer(nil) + if _, err := io.Copy(contentBuf, file); err != nil { + respondError(w, "Failed to save file", err, http.StatusInternalServerError) + return + } + log.Info().Int64("size", fileSize).Str("filename", headers.Filename).Str("content-type", contentType).Msg("Got an uploaded file") + } + } + http.Redirect(w, r, "/quick-submit-complete?report=123", http.StatusFound) +} + +// 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/report/endpoint.go b/report/endpoint.go deleted file mode 100644 index be2d6683..00000000 --- a/report/endpoint.go +++ /dev/null @@ -1,58 +0,0 @@ -package report - -import ( - "net/http" - - "github.com/Gleipnir-Technology/nidus-sync/htmlpage" - "github.com/Gleipnir-Technology/nidus-sync/htmlpage/public-reports" - "github.com/go-chi/chi/v5" -) - -func Router() chi.Router { - r := chi.NewRouter() - r.Get("/", getRoot) - r.Get("/nuisance", getNuisance) - r.Get("/pool", getPool) - r.Get("/quick", getQuick) - r.Get("/status", getStatus) - localFS := http.Dir("./static") - htmlpage.FileServer(r, "/static", localFS, publicreports.EmbeddedStaticFS, "static") - return r -} - -func getRoot(w http.ResponseWriter, r *http.Request) { - htmlpage.RenderOrError( - w, - publicreports.Root, - publicreports.ContextRoot{}, - ) -} - -func getNuisance(w http.ResponseWriter, r *http.Request) { - htmlpage.RenderOrError( - w, - publicreports.Nuisance, - publicreports.ContextNuisance{}, - ) -} -func getPool(w http.ResponseWriter, r *http.Request) { - htmlpage.RenderOrError( - w, - publicreports.Pool, - publicreports.ContextPool{}, - ) -} -func getQuick(w http.ResponseWriter, r *http.Request) { - htmlpage.RenderOrError( - w, - publicreports.Quick, - publicreports.ContextQuick{}, - ) -} -func getStatus(w http.ResponseWriter, r *http.Request) { - htmlpage.RenderOrError( - w, - publicreports.Status, - publicreports.ContextStatus{}, - ) -}