From 0098a69d7ed03a159ab3641723dbd2022562e70a Mon Sep 17 00:00:00 2001 From: Nath Date: Wed, 23 Sep 2026 11:47:12 +0100 Subject: [PATCH] feat: update contact-us form to use the same format as feedback forms --- app/assets/styles/blocks/_form.scss | 41 +++- .../styles/tokens/semantic/_colors.scss | 4 + app/components/public/MessageTypeSelect.vue | 99 +++++++++ app/components/public/ToggleSwitch.vue | 72 +++++++ app/pages/contact-us.vue | 201 +++++++++++++----- app/types/contact.ts | 4 + bun.lock | 1 + i18n/locales/ar/common.json | 25 +++ i18n/locales/de/common.json | 14 ++ i18n/locales/en/common.json | 14 ++ i18n/locales/es/common.json | 14 ++ i18n/locales/fr/common.json | 14 ++ i18n/locales/hi/common.json | 39 ++++ i18n/locales/pt/common.json | 14 ++ i18n/locales/ru/common.json | 25 +++ package.json | 1 + server/api/contact.post.ts | 23 +- server/plugins/migrations.ts | 27 ++- 18 files changed, 576 insertions(+), 56 deletions(-) create mode 100644 app/components/public/MessageTypeSelect.vue create mode 100644 app/components/public/ToggleSwitch.vue create mode 100644 app/types/contact.ts diff --git a/app/assets/styles/blocks/_form.scss b/app/assets/styles/blocks/_form.scss index eefc345f..dd52cd69 100644 --- a/app/assets/styles/blocks/_form.scss +++ b/app/assets/styles/blocks/_form.scss @@ -2,7 +2,7 @@ textarea, select, input, .input { - border: 1px solid var(--input-border-color); + border: 1px solid gray; border-radius: 8px; background-color: var(--color-surface-white); width: 100%; @@ -127,6 +127,43 @@ input[type=radio] { fill: var(--color-brand-secondary-light); } +/* Required-field marker: the red asterisk that follows a label's text. */ +.required-marker { + color: var(--color-status-error); + margin-inline-start: 0.15em; +} + +/* Per-field validation message, rendered directly under the field it belongs to. */ +.field-error { + color: var(--color-status-error); + font-size: var(--font-size-xs); +} + +/* Quieter form chrome: field outlines drop to the weight of placeholder text so + the labels lead instead of the boxes. Opt in per form, not site-wide. */ +.form--quiet { + textarea, + select, + input, + .input { + border-color: var(--input-border-color-muted); + } +} + +/* Opt-in row: a switch beside small print, rather than a checkbox beside a label. */ +.form-consent { + display: flex; + align-items: center; + gap: var(--spacing-sm); + + & .form-consent__label { + font-size: var(--font-size-sm); + color: var(--color-text-muted); + max-width: 60ch; + cursor: pointer; + } +} + .contact-message { &.error { color: var(--color-error, #c00); @@ -139,4 +176,4 @@ input[type=radio] { .iti { width: 100%; display: block; -} \ No newline at end of file +} diff --git a/app/assets/styles/tokens/semantic/_colors.scss b/app/assets/styles/tokens/semantic/_colors.scss index 29852c03..0c8d45a9 100644 --- a/app/assets/styles/tokens/semantic/_colors.scss +++ b/app/assets/styles/tokens/semantic/_colors.scss @@ -75,6 +75,7 @@ $color-red-600: #bd1218; --color-text-on-brand-lightest: #{$color-beige-50}; --color-text-on-secondary-light: #{$color-green-600}; --color-text-on-white: #{$color-green-600}; + --color-text-muted: #{$color-gray-500}; --color-white: #{$color-white}; // Status @@ -87,5 +88,8 @@ $color-red-600: #bd1218; // forms --input-border-color: #{$color-gray-500}; + // Quieter field outline, the same weight as placeholder text — for forms that + // should let their labels lead rather than their boxes (see `.form--quiet`). + --input-border-color-muted: #{$color-gray-400}; --table-border-color: #{$color-gray-500}; } \ No newline at end of file diff --git a/app/components/public/MessageTypeSelect.vue b/app/components/public/MessageTypeSelect.vue new file mode 100644 index 00000000..eae263be --- /dev/null +++ b/app/components/public/MessageTypeSelect.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/app/components/public/ToggleSwitch.vue b/app/components/public/ToggleSwitch.vue new file mode 100644 index 00000000..8da458b1 --- /dev/null +++ b/app/components/public/ToggleSwitch.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/app/pages/contact-us.vue b/app/pages/contact-us.vue index 9684b961..6e7f89c9 100644 --- a/app/pages/contact-us.vue +++ b/app/pages/contact-us.vue @@ -1,51 +1,87 @@