From: early Date: Sun, 25 Aug 2024 06:50:28 +0000 (-0600) Subject: start working on some standard components X-Git-Url: https://git.earlybird.gay/?a=commitdiff_plain;h=5d169091d8923390da3053c2f6e509a0210f0d0b;p=today start working on some standard components --- diff --git a/standard/part/contact_form.go b/standard/part/contact_form.go new file mode 100644 index 0000000..45515fc --- /dev/null +++ b/standard/part/contact_form.go @@ -0,0 +1,104 @@ +package stdpart + +import ( + "errors" + "fmt" + "net/http" + "net/url" + + "git.earlybird.gay/today-engine/part" + "git.earlybird.gay/today-engine/render" +) + +var ( + ErrFormValidation = errors.New("form input is invalid") +) + +func Err(base error, reason string) error { + return errors.Join(base, errors.New(reason)) +} + +type ContactFormResponse struct { + ID string + Name string + Contact string + Category string + Content string +} + +func parseContactFormResponse(r *http.Request) (ContactFormResponse, error) { + resp := ContactFormResponse{} + err := r.ParseForm() + if err != nil { + return resp, err + } + f := r.Form + + resp.ID = f.Get("id") + resp.Name = f.Get("name") + resp.Contact = f.Get("contact") + resp.Category = f.Get("category") + resp.Content = f.Get("content") + + return resp, nil +} + +func ContactForm(categories []string) *part.Part { + return part.New("stdp-contact-form", "contact_form.html", + part.OnLoad(func(data render.Data) error { + data.Set("categories", categories) + + // Set message if one is given for this part + r := data.Request() + q := r.URL.Query() + id := data.ID() + + if q.Get("resp_to") == id { + message, err := url.QueryUnescape(q.Get("message")) + if err != nil { + message = "invalid response message from server" + } + data.Set("message", map[string]any{ + "success": q.Get("success") == "true", + "message": message, + }) + } + return nil + }), + ) +} + +func HandleContactForm(validate, handle func(ContactFormResponse) error) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + resp, err := parseContactFormResponse(r) + callback := r.FormValue("callback") + respond := func(ok bool, msg string) { + msg = url.QueryEscape(msg) + w.Header().Set("Location", fmt.Sprintf("%s?resp_to=%s&success=%t&message=%s", callback, resp.ID, ok, msg)) + w.WriteHeader(http.StatusSeeOther) + } + if err != nil { + respond(false, "unexpected error, please try again later") + return + } + + if validate != nil { + err = validate(resp) + if err != nil { + respond(false, err.Error()) + } + } + + err = handle(resp) + if err != nil { + respond(false, "unexpected error, please try again later") + } + + respond(true, "message sent") + }) +} + +func PrintContact(resp ContactFormResponse) error { + fmt.Printf("%+v\n", resp) + return nil +} diff --git a/standard/part/contact_form.html b/standard/part/contact_form.html new file mode 100644 index 0000000..273ed38 --- /dev/null +++ b/standard/part/contact_form.html @@ -0,0 +1,27 @@ + \ No newline at end of file