'use client' import React, { useState } from 'react' import type { FDContactFormBlock as FDContactFormBlockProps } from '@/payload-types' import type { Media } from '@/payload-types' import { FDImage } from '@/components/FDImage' import { FDButton } from '@/components/FDButton' /* ------------------------------------------------------------------ */ /* Theme maps */ /* ------------------------------------------------------------------ */ const sectionBgMap: Record = { white: 'bg-white dark:bg-fd-navy', gray: 'bg-fd-gray-light dark:bg-fd-navy', navy: 'bg-fd-navy', navyGradient: 'bg-gradient-to-br from-fd-navy via-[#153350] to-fd-navy', } const isExplicitDark = (bg: string) => bg === 'navy' || bg === 'navyGradient' const cardRadius = 'rounded-[32px] md:rounded-[50px] lg:rounded-[70px]' /* ------------------------------------------------------------------ */ /* Component */ /* ------------------------------------------------------------------ */ export const FDContactFormBlockComponent: React.FC = ({ heading, description, form: formRelation, submitText = 'Skicka förfrågan', privacyText, privacyLinkText, privacyLinkUrl, sideImage, sectionBackground = 'white', layout = 'standard', externalApi, anchorId, }) => { const [formData, setFormData] = useState>({}) const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle') const media = sideImage as Media | undefined const hasSideImage = layout === 'withImage' && Boolean(media?.url) const dark = isExplicitDark(sectionBackground || 'white') const sectionBg = sectionBgMap[sectionBackground || 'white'] const isCard = layout === 'card' const form = formRelation && typeof formRelation === 'object' ? formRelation : null const formId = form ? form.id : (formRelation ?? null) /* ---- Handlers ---- */ const handleChange = (name: string, value: string) => { setFormData((prev) => ({ ...prev, [name]: value })) } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!formId) return setStatus('sending') try { const res = await fetch('/api/form-submissions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ form: formId, submissionData: Object.entries(formData).map(([field, value]) => ({ field, value })), }), }) if (externalApi?.enabled && externalApi?.endpoint) { const headers: Record = { 'Content-Type': 'application/json' } if (externalApi.authToken) headers['Authorization'] = `Bearer ${externalApi.authToken}` fetch(externalApi.endpoint, { method: 'POST', headers, body: JSON.stringify({ formId, formName: form?.title || '', data: formData, submittedAt: new Date().toISOString(), }), }).catch(() => {}) } setStatus(res.ok ? 'sent' : 'error') } catch { setStatus('error') } } /* ---- Input styles ---- */ const inputBase = 'w-full rounded-xl px-4 py-3 font-joey text-base outline-none transition-all' const inputClass = dark ? `${inputBase} bg-white/10 text-white placeholder:text-white/40 border border-white/20 focus:ring-2 focus:ring-fd-yellow/30 focus:bg-white/15 focus:border-fd-yellow/50` : `${inputBase} bg-gray-100 text-fd-navy placeholder:text-fd-navy/40 focus:ring-2 focus:ring-fd-navy/20 focus:bg-white dark:bg-white/10 dark:text-white dark:placeholder:text-white/40 dark:border dark:border-white/20 dark:focus:ring-fd-yellow/30 dark:focus:bg-white/15` const checkboxClass = dark ? 'w-5 h-5 rounded border-white/30 text-fd-yellow focus:ring-fd-yellow/30' : 'w-5 h-5 rounded border-gray-300 text-fd-navy focus:ring-fd-navy/20 dark:border-white/30 dark:text-fd-yellow dark:focus:ring-fd-yellow/30' /* ---- Text color helpers ---- */ const headingColor = dark ? 'text-fd-yellow' : 'text-fd-navy dark:text-fd-yellow' const bodyColor = dark ? 'text-white/80' : 'text-fd-navy/80 dark:text-white/80' const labelColor = dark ? 'text-white' : 'text-fd-navy dark:text-white' const mutedColor = dark ? 'text-white/50' : 'text-fd-navy/60 dark:text-white/50' const errorColor = dark ? 'text-red-300' : 'text-red-600 dark:text-red-300' const requiredColor = dark ? 'text-fd-yellow' : 'text-fd-navy dark:text-fd-yellow' const linkColor = dark ? 'underline underline-offset-2 hover:text-fd-yellow transition-colors' : 'underline underline-offset-2 hover:text-fd-navy dark:hover:text-fd-yellow transition-colors' /* ---- Field renderer ---- */ const renderFormField = (field: any) => { const blockType = field.blockType const name = field.name || field.label?.toLowerCase().replace(/\s+/g, '-') || '' const label = field.label || '' const required = field.required || false const width = field.width ? Number(field.width) : 100 const input = (() => { switch (blockType) { case 'textarea': return (