import { useSendTelemetryEvent } from '~/lib/telemetry' import { CircleAlert } from 'lucide-react' import Link from 'next/link' import { FC, useEffect, useState } from 'react' import { Alert, Button, cn, Input, Label, Separator, TextArea } from 'ui' interface FormData { firstName: string secondName: string companyEmail: string message: string } interface FormItem { type: 'text' | 'textarea' label: string placeholder: string required: boolean className?: string component: typeof TextArea | typeof Input } type FormConfig = { [K in keyof FormData]: FormItem } interface Props { className?: string } const formConfig: FormConfig = { firstName: { type: 'text', label: 'First Name', placeholder: 'First Name', required: true, className: 'md:col-span-1', component: Input, }, secondName: { type: 'text', label: 'Last Name', placeholder: 'Last Name', required: true, className: 'md:col-span-1', component: Input, }, companyEmail: { type: 'text', label: 'Company Email', placeholder: 'Company Email', required: true, className: '', component: Input, }, message: { type: 'textarea', label: 'What are you interested in?', placeholder: 'Share more about what you want to accomplish', required: true, className: '[&_textarea]:min-h-[100px] [&_textarea]:bg-foreground/[.026]', component: TextArea, }, } const isValidEmail = (email: string): boolean => { const emailPattern = /^[\w-\.+]+@([\w-]+\.)+[\w-]{2,8}$/ return emailPattern.test(email) } const personalEmailDomains = [ '@gmail.com', '@yahoo.com', '@hotmail.', '@outlook.com', '@aol.com', '@icloud.com', '@live.com', '@protonmail.com', '@mail.com', '@example.com', ] const isCompanyEmail = (email: string): boolean => { for (const domain of personalEmailDomains) { if (email.includes(domain)) { return false } } return true } const defaultFormValue: FormData = { firstName: '', secondName: '', companyEmail: '', message: '', } const RequestADemoForm: FC = ({ className }) => { const [formData, setFormData] = useState(defaultFormValue) const [honeypot, setHoneypot] = useState('') // field to prevent spam const [errors, setErrors] = useState<{ [key: string]: string }>({}) const [isSubmitting, setIsSubmitting] = useState(false) const [success, setSuccess] = useState(null) const [startTime, setStartTime] = useState(0) const sendTelemetryEvent = useSendTelemetryEvent() const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target setErrors({}) setFormData((prev) => ({ ...prev, [name]: value })) } const handleReset = (e: React.MouseEvent) => { e.preventDefault() setFormData(defaultFormValue) setSuccess(null) setErrors({}) } const validate = (): boolean => { const newErrors: { [key in keyof FormData]?: string } = {} // Check required fields for (const key in formConfig) { if (formConfig[key as keyof FormData].required && !formData[key as keyof FormData]) { newErrors[key as keyof FormData] = `This field is required` } } // Validate email if (formData.companyEmail && !isValidEmail(formData.companyEmail)) { newErrors.companyEmail = 'Invalid email address' } // Validate company email if (formData.companyEmail && !isCompanyEmail(formData.companyEmail)) { newErrors.companyEmail = 'Please use a company email address' } setErrors(newErrors) // Return validation status, also check if honeypot is filled (indicating a bot) return Object.keys(newErrors).length === 0 && honeypot === '' } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() const currentTime = Date.now() const timeElapsed = (currentTime - startTime) / 1000 // Spam prevention: Reject form if submitted too quickly (less than 3 seconds) if (timeElapsed < 3) { setErrors({ general: 'Submission too fast. Please fill the form correctly.' }) return } if (!validate()) { return } setIsSubmitting(true) setSuccess(null) try { const response = await fetch('/api-v2/submit-form-contact-sales', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formData), }) if (response.ok) { setSuccess('Thank you for your submission!') setFormData({ firstName: '', secondName: '', companyEmail: '', message: '' }) } else { const errorData = await response.json() setErrors({ general: `Submission failed: ${errorData.message}` }) } } catch (error) { setErrors({ general: 'An unexpected error occurred. Please try again.' }) } finally { setIsSubmitting(false) } } useEffect(() => { setStartTime(Date.now()) }, []) return (
{success ? (

{success}

) : (
{Object.entries(formConfig).map(([key, { component: Component, ...fieldValue }]) => { const fieldKey = key as keyof FormData return (
) })} {/* Spam prevention */} ) => setHoneypot(e.target.value)} style={{ display: 'none' }} aria-hidden="true" />

By submitting this form, I confirm that I have read and understood the{' '} Privacy Policy .

{errors.general && ( {errors.general} )} )}

Contact support {' '} if you need technical help

) } export default RequestADemoForm