Add support for generating the QR code in the page.
This commit is contained in:
parent
24aa1b88ef
commit
c99a5a3f62
6 changed files with 77 additions and 47 deletions
63
endpoint.go
63
endpoint.go
|
|
@ -4,7 +4,11 @@ import (
|
|||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/skip2/go-qrcode"
|
||||
)
|
||||
func getFavicon(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-type", "image/x-icon")
|
||||
|
|
@ -12,6 +16,65 @@ func getFavicon(w http.ResponseWriter, r *http.Request) {
|
|||
http.ServeFile(w, r, "static/favicon.ico")
|
||||
}
|
||||
|
||||
func getQRCodeReport(w http.ResponseWriter, r *http.Request) {
|
||||
code := chi.URLParam(r, "code")
|
||||
if code == "" {
|
||||
respondError(w, "There should always be a code", nil, http.StatusBadRequest)
|
||||
}
|
||||
content := BaseURL + "/report/" + code
|
||||
// Get optional size parameter (default to 256)
|
||||
size := 256
|
||||
if sizeStr := r.URL.Query().Get("size"); sizeStr != "" {
|
||||
var err error
|
||||
size, err = strconv.Atoi(sizeStr)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid 'size' parameter, must be an integer", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Get optional error correction level (default to Medium)
|
||||
level := qrcode.Medium
|
||||
if levelStr := r.URL.Query().Get("level"); levelStr != "" {
|
||||
switch levelStr {
|
||||
case "L", "l":
|
||||
level = qrcode.Low
|
||||
case "M", "m":
|
||||
level = qrcode.Medium
|
||||
case "Q", "q":
|
||||
level = qrcode.High
|
||||
case "H", "h":
|
||||
level = qrcode.Highest
|
||||
default:
|
||||
respondError(w, "Invalid 'level' parameter, must be L, M, Q, or H", nil, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the QR code
|
||||
var qr *qrcode.QRCode
|
||||
var err error
|
||||
qr, err = qrcode.New(content, level)
|
||||
if err != nil {
|
||||
respondError(w, "Error generating QR code", err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Set the appropriate content type
|
||||
w.Header().Set("Content-Type", "image/png")
|
||||
|
||||
// Generate PNG and write directly to the response writer
|
||||
png, err := qr.PNG(size)
|
||||
if err != nil {
|
||||
respondError(w, "Error encoding QR code to PNG", err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = w.Write(png)
|
||||
if err != nil {
|
||||
respondError(w, "Error writing response", err, http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
func getReport(w http.ResponseWriter, r *http.Request) {
|
||||
//org := r.URL.Query().Get("org")
|
||||
err := htmlReport(w)
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -15,6 +15,7 @@ require (
|
|||
github.com/lib/pq v1.10.9
|
||||
github.com/pressly/goose/v3 v3.26.0
|
||||
github.com/riverqueue/river/rivershared v0.26.0
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stephenafamo/bob v0.41.1
|
||||
github.com/stephenafamo/scan v0.7.0
|
||||
github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -144,6 +144,8 @@ github.com/shirou/gopsutil/v4 v4.25.5 h1:rtd9piuSMGeU8g1RMXjZs9y9luK5BwtnG7dZaQU
|
|||
github.com/shirou/gopsutil/v4 v4.25.5/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/stephenafamo/bob v0.41.1 h1:xcRPuRMCwtZZ9tS4JIVbZ5Erdm5Dy5dIvbS5kivwPpA=
|
||||
github.com/stephenafamo/bob v0.41.1/go.mod h1:8l55917DM36gF518Iz1MHjLds7KGAfkitJfxISYlth8=
|
||||
github.com/stephenafamo/fakedb v0.0.0-20221230081958-0b86f816ed97 h1:XItoZNmhOih06TC02jK7l3wlpZ0XT/sPQYutDcGOQjg=
|
||||
|
|
|
|||
8
html.go
8
html.go
|
|
@ -30,6 +30,9 @@ type Link struct {
|
|||
Href string
|
||||
Title string
|
||||
}
|
||||
type ContentReportDiagnostic struct {
|
||||
URL string
|
||||
}
|
||||
type ContentDashboard struct {
|
||||
User User
|
||||
}
|
||||
|
|
@ -87,7 +90,10 @@ func htmlDashboard(w io.Writer, user *models.User) error {
|
|||
}
|
||||
|
||||
func htmlReport(w io.Writer) error {
|
||||
data := ContentPlaceholder{}
|
||||
url := BaseURL + "/report/t78fd3"
|
||||
data := ContentReportDiagnostic{
|
||||
URL: url,
|
||||
}
|
||||
return report.ExecuteTemplate(w, data)
|
||||
}
|
||||
|
||||
|
|
|
|||
1
main.go
1
main.go
|
|
@ -58,6 +58,7 @@ func main() {
|
|||
r.Use(sessionManager.LoadAndSave)
|
||||
|
||||
r.Get("/", getRoot)
|
||||
r.Get("/qr-code/report/{code}", getQRCodeReport)
|
||||
r.Get("/report", getReport)
|
||||
r.Post("/signin", postSignin)
|
||||
r.Get("/signup", getSignup)
|
||||
|
|
|
|||
|
|
@ -102,49 +102,6 @@
|
|||
}
|
||||
{{end}}
|
||||
{{define "content"}}
|
||||
<header class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
|
||||
<div class="container">
|
||||
<!-- Logo -->
|
||||
<a class="navbar-brand" href="#">
|
||||
<div class="logo-placeholder" style="width: 100px; height: 40px; background-color: #e9ecef; display: flex; align-items: center; justify-content: center; border-radius: 4px;">
|
||||
<span class="text-muted small">Your Logo</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Toggle Button for Mobile -->
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<!-- Nav Items -->
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#">Diagnostics</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- User Info & Logout -->
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="dropdown">
|
||||
<a class="text-decoration-none dropdown-toggle d-flex align-items-center" href="#" role="button" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<div class="avatar me-2 bg-primary rounded-circle d-flex align-items-center justify-content-center" style="width: 36px; height: 36px;">
|
||||
<span class="text-white">JD</span>
|
||||
</div>
|
||||
<span class="me-2">John Doe</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="userDropdown">
|
||||
<li><a class="dropdown-item" href="#">Profile</a></li>
|
||||
<li><a class="dropdown-item" href="#">Settings</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item text-danger" href="#">Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container py-5">
|
||||
<div class="entry-container">
|
||||
<div class="entry-box">
|
||||
|
|
@ -168,7 +125,7 @@
|
|||
<p>Customers will receive the following text message with a link to begin the reporting process:</p>
|
||||
|
||||
<div class="sms-mockup">
|
||||
<strong>Vector Control:</strong> We noticed a potential green pool at your property. Please tap the link to report status or schedule inspection: <a href="#">https://sync.nidus.cloud/report/t78fd3</a>
|
||||
<strong>Vector Control:</strong> We noticed a potential green pool at your property. Please tap the link to report status or schedule inspection: <a href="{{ .URL }}">{{ .URL }}</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
|
|
@ -197,7 +154,7 @@
|
|||
<img src="/qr-code/report/t78fd3" width="256" height="256"/>
|
||||
|
||||
<p><strong>Scan this code</strong> with your phone camera to report your pool status or schedule an inspection.</p>
|
||||
<p class="small text-muted">Or visit: https://sync.nidus.cloud/report/t78fd3</p>
|
||||
<p class="small text-muted">Or visit: {{ .URL }}</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
|
|
@ -235,7 +192,7 @@
|
|||
<a href="/report/t78fd3" class="btn btn-primary">Report Pool Status or Schedule Inspection</a>
|
||||
</div>
|
||||
|
||||
<p>Please click the button above or visit <a href="#">https://sync.nidus.cloud/report/t78fd3</a> to complete a brief questionnaire about your pool status. This will help us determine if an inspection is needed or if you've already addressed the issue.</p>
|
||||
<p>Please click the button above or visit <a href="{{ .URL }}">{{ .URL }}</a> to complete a brief questionnaire about your pool status. This will help us determine if an inspection is needed or if you've already addressed the issue.</p>
|
||||
|
||||
<p>Thank you for helping keep our community safe and healthy.</p>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue