'use client'; import { useEffect, useRef, useState } from 'react'; import { SITE, GITEA_URL, GITEA_USERNAME } from '@/lib/config'; const TURNSTILE_SITE_KEY = process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY; declare global { interface Window { turnstile?: { render: ( container: string | HTMLElement, options: { sitekey: string; theme?: 'light' | 'dark' | 'auto'; callback?: (token: string) => void; 'expired-callback'?: () => void; 'error-callback'?: () => void; } ) => string; reset: (widgetId?: string) => void; }; } } type Status = 'idle' | 'loading' | 'sent' | 'error'; export default function Contact() { const [status, setStatus] = useState('idle'); const [errorMessage, setErrorMessage] = useState(''); const [turnstileToken, setTurnstileToken] = useState(''); const widgetIdRef = useRef(null); const turnstileRef = useRef(null); const startedAtRef = useRef(Date.now()); useEffect(() => { if (!TURNSTILE_SITE_KEY) { setErrorMessage('Captcha is not configured correctly.'); return; } const scriptId = 'cf-turnstile-script'; const renderWidget = () => { if (!window.turnstile || !turnstileRef.current || widgetIdRef.current) return; widgetIdRef.current = window.turnstile.render(turnstileRef.current, { sitekey: TURNSTILE_SITE_KEY, theme: 'dark', callback: token => { setTurnstileToken(token); setErrorMessage(''); }, 'expired-callback': () => { setTurnstileToken(''); }, 'error-callback': () => { setTurnstileToken(''); setErrorMessage('Captcha failed to load. Please try again.'); }, }); }; if (document.getElementById(scriptId)) { renderWidget(); return; } const script = document.createElement('script'); script.id = scriptId; script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit'; script.async = true; script.defer = true; script.onload = renderWidget; document.body.appendChild(script); }, []); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setStatus('loading'); setErrorMessage(''); const form = e.currentTarget; const fd = new FormData(form); const payload = { name: String(fd.get('name') || '').trim(), email: String(fd.get('email') || '').trim(), message: String(fd.get('message') || '').trim(), company: String(fd.get('company') || '').trim(), turnstileToken, formStartedAt: String(fd.get('formStartedAt') || ''), }; if (!payload.name || !payload.email || !payload.message) { setStatus('error'); setErrorMessage('Please complete all fields.'); return; } if (!payload.turnstileToken) { setStatus('error'); setErrorMessage('Please complete the captcha.'); return; } try { const res = await fetch('/api/contact', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); const data = await res.json(); if (!res.ok) { throw new Error(data?.error || 'Failed to send message.'); } setStatus('sent'); form.reset(); startedAtRef.current = Date.now(); setTurnstileToken(''); if (window.turnstile && widgetIdRef.current) { window.turnstile.reset(widgetIdRef.current); } } catch (err) { setStatus('error'); setErrorMessage( err instanceof Error ? err.message : 'Something went wrong.', ); if (window.turnstile && widgetIdRef.current) { window.turnstile.reset(widgetIdRef.current); } setTurnstileToken(''); } } return (
Get in touch

Let’s work together.

Open to interesting roles, collaborations, and serious product ideas.

{/* Left side contact cards */} {/* Form */}
{/* Honeypot */}