diff --git a/endpoint.go b/endpoint.go index 4b167e98..8d02f424 100644 --- a/endpoint.go +++ b/endpoint.go @@ -107,6 +107,14 @@ func getReportEvidence(w http.ResponseWriter, r *http.Request) { } } +func getReportSchedule(w http.ResponseWriter, r *http.Request) { + code := chi.URLParam(r, "code") + err := htmlReportSchedule(w, code) + if err != nil { + respondError(w, "Failed to generate report page", err, http.StatusInternalServerError) + } +} + func getRoot(w http.ResponseWriter, r *http.Request) { user, err := getAuthenticatedUser(r) if err != nil && !errors.Is(err, &NoCredentialsError{}) { diff --git a/html.go b/html.go index c3173f2e..dc8f4e59 100644 --- a/html.go +++ b/html.go @@ -19,6 +19,7 @@ var ( reportContribute = newBuiltTemplate("report-contribute", "base") reportDetail = newBuiltTemplate("report-detail", "base") reportEvidence = newBuiltTemplate("report-evidence", "base") + reportSchedule = newBuiltTemplate("report-schedule", "base") signin = newBuiltTemplate("signin", "base") signup = newBuiltTemplate("signup", "base") ) @@ -127,6 +128,14 @@ func htmlReportEvidence(w io.Writer, code string) error { return reportEvidence.ExecuteTemplate(w, data) } +func htmlReportSchedule(w io.Writer, code string) error { + nextURL := BaseURL + "/report/" + code + "/confirm" + data := ContentReportDetail{ + NextURL: nextURL, + } + return reportSchedule.ExecuteTemplate(w, data) +} + func htmlSignin(w io.Writer, errorCode string) error { data := ContentSignin{ InvalidCredentials: errorCode == "invalid-credentials", diff --git a/main.go b/main.go index 2f032556..6608c971 100644 --- a/main.go +++ b/main.go @@ -63,6 +63,7 @@ func main() { r.Get("/report/{code}", getReportDetail) r.Get("/report/{code}/contribute", getReportContribute) r.Get("/report/{code}/evidence", getReportEvidence) + r.Get("/report/{code}/schedule", getReportSchedule) r.Post("/signin", postSignin) r.Get("/signup", getSignup) r.Post("/signup", postSignup) diff --git a/templates/report-schedule.html b/templates/report-schedule.html new file mode 100644 index 00000000..e83dfca3 --- /dev/null +++ b/templates/report-schedule.html @@ -0,0 +1,317 @@ +{{template "base.html" .}} + +{{define "title"}}Login{{end}} +{{define "style"}} + body { + background-color: #f8f9fa; + } + .page-container { + max-width: 800px; + margin: 0 auto; + padding: 20px; + } + .content-card { + background-color: white; + border-radius: 15px; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); + padding: 25px; + margin-bottom: 20px; + } + .logo-area { + text-align: center; + margin-bottom: 20px; + } + .logo-placeholder { + height: 50px; + max-width: 200px; + margin: 0 auto; + } + .progress-container { + margin: 30px 0 20px; + } + .progress { + height: 8px; + } + .calendar-section { + margin-bottom: 30px; + } + .dates-container { + display: flex; + overflow-x: auto; + gap: 10px; + padding-bottom: 10px; + margin-bottom: 20px; + } + .date-card { + min-width: 110px; + border: 1px solid #dee2e6; + border-radius: 8px; + padding: 10px; + text-align: center; + cursor: pointer; + transition: all 0.2s; + } + .date-card:hover { + border-color: #0d6efd; + background-color: #f8f9fa; + } + .date-card.selected { + border-color: #0d6efd; + background-color: #e6f2ff; + box-shadow: 0 0 0 1px #0d6efd; + } + .date-card .month { + font-size: 0.8rem; + text-transform: uppercase; + color: #6c757d; + font-weight: 600; + } + .date-card .day { + font-size: 1.5rem; + font-weight: 700; + line-height: 1.2; + } + .date-card .weekday { + font-size: 0.8rem; + color: #6c757d; + } + .time-slots { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + gap: 10px; + margin-bottom: 20px; + } + .time-slot { + border: 1px solid #dee2e6; + border-radius: 6px; + padding: 10px; + text-align: center; + cursor: pointer; + transition: all 0.2s; + } + .time-slot:hover { + border-color: #0d6efd; + background-color: #f8f9fa; + } + .time-slot.selected { + border-color: #0d6efd; + background-color: #e6f2ff; + box-shadow: 0 0 0 1px #0d6efd; + } + .time-slot.unavailable { + background-color: #f8f9fa; + color: #adb5bd; + cursor: not-allowed; + text-decoration: line-through; + } + .form-section { + margin-top: 30px; + padding-top: 20px; + border-top: 1px solid #dee2e6; + } + .section-title { + margin-bottom: 20px; + display: flex; + align-items: center; + } + .section-title i { + margin-right: 10px; + color: #0d6efd; + } + .selected-date-time { + background-color: #e8f4f8; + border-left: 4px solid #0d6efd; + padding: 15px; + border-radius: 5px; + margin-bottom: 20px; + } +{{end}} +{{define "content"}} +
+ +
+ County Vector Control +
+ + +
+
+ Schedule Follow-up + 4 of 4 +
+
+
+
+
+ + +
+

Schedule a Follow-up Inspection

+

Please select a convenient date and time for our inspector to visit your property.

+ + +
+
+ +
Select Date
+
+ + +
+
+
Jun
+
20
+
Tue
+
+
+
Jun
+
21
+
Wed
+
+
+
Jun
+
22
+
Thu
+
+
+
Jun
+
23
+
Fri
+
+
+
Jun
+
26
+
Mon
+
+
+
Jun
+
27
+
Tue
+
+
+
Jun
+
28
+
Wed
+
+
+
Jun
+
29
+
Thu
+
+
+
Jun
+
30
+
Fri
+
+
+
Jul
+
03
+
Mon
+
+
+ + +
+ +
Select Time
+
+ +
+
+ 8:00 AM +
+
+ 9:00 AM +
+
+ 10:00 AM +
+
+ 11:00 AM +
+
+ 1:00 PM +
+
+ 2:00 PM +
+
+ 3:00 PM +
+
+ 4:00 PM +
+
+ + +
+
+ Selected Appointment: + Thursday, June 22, 2023 at 10:00 AM +
+
+
+ + +
+
+ +
Contact Information
+
+ +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+
+ + +
+
+
+ + +
+ Our inspector will need access to view your pool area. If you won't be home during the appointment, please provide access instructions in the notes. +
+ + + +
+
+
+ + +
+

If you need assistance, please contact Vector Control at (555) 123-4567

+
+
+{{end}}