feat(contact): implement Formspree contact form submission
Some checks failed
CI / lint-and-test (push) Has been cancelled
Some checks failed
CI / lint-and-test (push) Has been cancelled
- Enable contact form fields with component IDs - Add callback for Formspree POST with JSON/AJAX - Include honeypot spam protection (_gotcha field) - Handle validation, loading, success/error states - Clear form on successful submission - Add lessons learned documentation Closes #92, #93, #94 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import dash
|
||||
import dash_mantine_components as dmc
|
||||
from dash import html
|
||||
from dash_iconify import DashIconify
|
||||
|
||||
dash.register_page(__name__, path="/contact", name="Contact")
|
||||
@@ -51,51 +52,57 @@ def create_intro_section() -> dmc.Stack:
|
||||
|
||||
|
||||
def create_contact_form() -> dmc.Paper:
|
||||
"""Create the contact form (disabled in Phase 1)."""
|
||||
"""Create the contact form with Formspree integration."""
|
||||
return dmc.Paper(
|
||||
dmc.Stack(
|
||||
[
|
||||
dmc.Title("Send a Message", order=2, size="h4"),
|
||||
dmc.Alert(
|
||||
"Contact form submission is coming soon. Please use the direct contact "
|
||||
"methods below for now.",
|
||||
title="Form Coming Soon",
|
||||
color="blue",
|
||||
variant="light",
|
||||
),
|
||||
# Feedback container for success/error messages
|
||||
html.Div(id="contact-feedback"),
|
||||
dmc.TextInput(
|
||||
id="contact-name",
|
||||
label="Name",
|
||||
placeholder="Your name",
|
||||
leftSection=DashIconify(icon="tabler:user", width=18),
|
||||
disabled=True,
|
||||
required=True,
|
||||
),
|
||||
dmc.TextInput(
|
||||
id="contact-email",
|
||||
label="Email",
|
||||
placeholder="your.email@example.com",
|
||||
leftSection=DashIconify(icon="tabler:mail", width=18),
|
||||
disabled=True,
|
||||
required=True,
|
||||
),
|
||||
dmc.Select(
|
||||
id="contact-subject",
|
||||
label="Subject",
|
||||
placeholder="Select a subject",
|
||||
data=SUBJECT_OPTIONS,
|
||||
leftSection=DashIconify(icon="tabler:tag", width=18),
|
||||
disabled=True,
|
||||
),
|
||||
dmc.Textarea(
|
||||
id="contact-message",
|
||||
label="Message",
|
||||
placeholder="Your message...",
|
||||
minRows=4,
|
||||
disabled=True,
|
||||
required=True,
|
||||
),
|
||||
# Honeypot field for spam protection (hidden from users)
|
||||
dmc.TextInput(
|
||||
id="contact-gotcha",
|
||||
style={"position": "absolute", "left": "-9999px"},
|
||||
tabIndex=-1,
|
||||
autoComplete="off",
|
||||
),
|
||||
dmc.Button(
|
||||
"Send Message",
|
||||
id="contact-submit",
|
||||
fullWidth=True,
|
||||
leftSection=DashIconify(icon="tabler:send", width=18),
|
||||
disabled=True,
|
||||
),
|
||||
],
|
||||
gap="md",
|
||||
style={"position": "relative"},
|
||||
),
|
||||
p="xl",
|
||||
radius="md",
|
||||
|
||||
Reference in New Issue
Block a user