task/1.8
1package main
2
3import (
4 "html/template"
5 "log"
6 "net/http"
7 "regexp"
8)
9
10// PageData holds common data passed to templates
11type PageData struct {
12 Title string
13 ServiceName string
14 Content interface{}
15}
16
17// home displays the buylater.email landing page
18func home(w http.ResponseWriter, r *http.Request) {
19 w.Header().Add("Server", "buylater.email")
20
21 // Parse templates with inheritance
22 ts, err := template.ParseFiles(
23 "./ui/html/layouts/base.tmpl",
24 "./ui/html/pages/home.tmpl",
25 )
26 if err != nil {
27 log.Println(err.Error())
28 http.Error(w, "Internal Server Error", 500)
29 return
30 }
31
32 // Prepare template data
33 data := PageData{
34 Title: "Home",
35 ServiceName: "buylater.email",
36 Content: nil,
37 }
38
39 // Execute template - specify the base template name
40 err = ts.ExecuteTemplate(w, "base", data)
41 if err != nil {
42 log.Println(err.Error())
43 http.Error(w, "Internal Server Error", 500)
44 }
45}
46
47// submitForm displays the email submission form for scheduling purchase reminders
48func submitForm(w http.ResponseWriter, r *http.Request) {
49 w.Header().Add("Server", "buylater.email")
50
51 // Parse templates with inheritance
52 ts, err := template.ParseFiles(
53 "./ui/html/layouts/base.tmpl",
54 "./ui/html/pages/submit.tmpl",
55 )
56 if err != nil {
57 log.Println(err.Error())
58 http.Error(w, "Internal Server Error", 500)
59 return
60 }
61
62 // Prepare template data
63 data := PageData{
64 Title: "Submit",
65 ServiceName: "buylater.email",
66 Content: nil,
67 }
68
69 // Execute template - specify the base template name
70 err = ts.ExecuteTemplate(w, "base", data)
71 if err != nil {
72 log.Println(err.Error())
73 http.Error(w, "Internal Server Error", 500)
74 }
75}
76
77// processSubmit handles the form submission and schedules the email reminder
78func processSubmit(w http.ResponseWriter, r *http.Request) {
79 w.Header().Add("Server", "buylater.email")
80 w.WriteHeader(http.StatusCreated)
81 w.Write([]byte("Form submitted! Check your email for a confirmation link to activate your reminder."))
82}
83
84// confirmWithToken handles magic link confirmation with token validation
85func confirmWithToken(w http.ResponseWriter, r *http.Request) {
86 token := r.PathValue("token")
87
88 if !isValidToken(token) {
89 w.Header().Add("Server", "buylater.email")
90 http.NotFound(w, r)
91 return
92 }
93
94 w.Header().Add("Server", "buylater.email")
95 w.WriteHeader(http.StatusOK)
96 w.Write([]byte("Email Confirmed! Your purchase reminder has been activated via magic link."))
97}
98
99// isValidToken validates that the token is alphanumeric and at least 32 characters
100func isValidToken(token string) bool {
101 if len(token) < 32 {
102 return false
103 }
104
105 // Check if token contains only alphanumeric characters
106 matched, _ := regexp.MatchString("^[a-zA-Z0-9]+$", token)
107 return matched
108}
109
110// about displays information about the buylater.email service
111func about(w http.ResponseWriter, r *http.Request) {
112 w.Header().Add("Server", "buylater.email")
113 w.Write([]byte("About - buylater.email helps you delay purchases and buy more intentionally"))
114}