diff --git a/handlers/collector.go b/handlers/collector.go index f00f3f7..edabac8 100644 --- a/handlers/collector.go +++ b/handlers/collector.go @@ -112,11 +112,6 @@ func Collect(w http.ResponseWriter, r *http.Request) { if errs.Any() { slog.Info("[collector] failed validation", "errors", errs) w.WriteHeader(http.StatusBadRequest) - } else { - // TODO Redirect to a thank-you page - w.Header().Add("hx-redirect", frm.CollectorPathForm(ctx, *formID)) - - w.WriteHeader(http.StatusOK) } sc := submission.Get("short_code") submission.Del("short_code") @@ -176,6 +171,11 @@ func Collect(w http.ResponseWriter, r *http.Request) { return } + err = ui.ThankYou().Render(ctx, w) + if err != nil { + slog.Error("[collector] unable to render thank you page", "error", err) + w.WriteHeader(http.StatusInternalServerError) + } } // validate validates forms diff --git a/static/css/styles.css b/static/css/styles.css index 080a045..4219b4c 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -958,6 +958,59 @@ html { } } +.form-input,.form-textarea,.form-select,.form-multiselect { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: #fff; + border-color: #6d6d6d; + border-width: 1px; + border-radius: 0px; + padding-top: 0.5rem; + padding-right: 0.75rem; + padding-bottom: 0.5rem; + padding-left: 0.75rem; + font-size: 1rem; + line-height: 1.5rem; + --tw-shadow: 0 0 #0000; +} + +.form-input:focus, .form-textarea:focus, .form-select:focus, .form-multiselect:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + border-color: #2563eb; +} + +.form-input::-moz-placeholder, .form-textarea::-moz-placeholder { + color: #6d6d6d; + opacity: 1; +} + +.form-input::placeholder,.form-textarea::placeholder { + color: #6d6d6d; + opacity: 1; +} + +.form-input::-webkit-datetime-edit-fields-wrapper { + padding: 0; +} + +.form-input::-webkit-date-and-time-value { + min-height: 1.5em; +} + +.form-input::-webkit-datetime-edit,.form-input::-webkit-datetime-edit-year-field,.form-input::-webkit-datetime-edit-month-field,.form-input::-webkit-datetime-edit-day-field,.form-input::-webkit-datetime-edit-hour-field,.form-input::-webkit-datetime-edit-minute-field,.form-input::-webkit-datetime-edit-second-field,.form-input::-webkit-datetime-edit-millisecond-field,.form-input::-webkit-datetime-edit-meridiem-field { + padding-top: 0; + padding-bottom: 0; +} + .avatar.placeholder > div { display: flex; align-items: center; @@ -2793,6 +2846,10 @@ input.tab:checked + .tab-content, padding-top: 0.75rem; } +.pt-9 { + padding-top: 2.25rem; +} + .text-center { text-align: center; } @@ -2802,6 +2859,11 @@ input.tab:checked + .tab-content, line-height: 2rem; } +.text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; +} + .text-5xl { font-size: 3rem; line-height: 1; diff --git a/ui/common.templ b/ui/common.templ index 417232a..12ae4fe 100644 --- a/ui/common.templ +++ b/ui/common.templ @@ -133,7 +133,7 @@ func SafePath(ctx context.Context, path string) templ.SafeURL { // head simply provides the element templ head(pageTitle string) { - { ApplicationName } :: { pageTitle } + { pageTitle } @loadDependenciesOnce.Once() { @@ -269,7 +269,7 @@ templ Builder(form frm.Form) { // Builder is the primary form builder UI, surrounded by the app chrome templ Viewer(form frm.Form) { - @App("Form viewer") { + @App(form.Name) {
@FormView(form, false) @@ -846,84 +846,96 @@ templ FormView(form frm.Form, isPreview bool) {

{ form.Name }

-
- - if sc := shortCode(ctx); sc != nil { - - } - for _, field := range sortFields(form.Fields) { -
+ } +
+ @button(buttonArgs{ + Label: "submit", + Type: "submit", + Classes: []string{"flex-grow", "justify-center", "uppercase"}, + }, templ.Attributes{ + "type": "submit", + "data-hx-post": formCollectorUrl[string](ctx, form), + "data-hx-trigger": "click", + "data-hx-target": "#form-input", + "data-hx-target-400": "form", + "disabled": isPreview, + }, + ) + +
} +templ ThankYou() { + @App("Form viewer") { +
+
+

Thank you!

+
+
+ } +} + func toSelectorOpts(opts []types.Option, selectAll bool) (sopts []selector.Option) { // TODO: Fix -- adding an empty option because the first select