170 lines
5.9 KiB
TypeScript
170 lines
5.9 KiB
TypeScript
'use client'
|
||
|
||
import { useState } from 'react'
|
||
|
||
type FormState = 'idle' | 'loading' | 'success' | 'error'
|
||
|
||
const T = {
|
||
bg: '#f3f2f2',
|
||
surface: '#eae9e9',
|
||
text: '#201f1d',
|
||
divider: 'rgba(32,31,29,0.16)',
|
||
accent: '#b68235',
|
||
accentDark: '#7d5411',
|
||
fontHead: '"Sora", sans-serif',
|
||
fontBody: '"Inter", sans-serif',
|
||
radiusMd: '4px',
|
||
radiusLg: '7px',
|
||
}
|
||
|
||
export default function ContactForm() {
|
||
const [state, setState] = useState<FormState>('idle')
|
||
const [form, setForm] = useState({ name: '', org: '', email: '', phone: '', _hp: '' })
|
||
|
||
const set = (k: keyof typeof form) => (e: React.ChangeEvent<HTMLInputElement>) =>
|
||
setForm(p => ({ ...p, [k]: e.target.value }))
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault()
|
||
if (form._hp) return
|
||
setState('loading')
|
||
try {
|
||
const res = await fetch('/api/contact', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ name: form.name, email: form.email, barNo: form.org, message: form.phone }),
|
||
})
|
||
setState(res.ok ? 'success' : 'error')
|
||
} catch {
|
||
setState('error')
|
||
}
|
||
}
|
||
|
||
/* Success */
|
||
if (state === 'success') {
|
||
return (
|
||
<div style={{ border: `1px solid ${T.divider}`, borderRadius: T.radiusLg, padding: '40px', textAlign: 'center', background: T.surface }}>
|
||
<h3 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: '22px', margin: '0 0 8px' }}>Talebiniz alındı.</h3>
|
||
<p style={{ fontSize: '14.5px', margin: 0, color: 'rgba(32,31,29,0.78)', fontFamily: T.fontBody }}>
|
||
Kurucu ekipten kısa süre içinde size dönüş yapılacak.
|
||
</p>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
const inputStyle: React.CSSProperties = {
|
||
width: '100%', minHeight: '36px', padding: '6px 10px',
|
||
fontFamily: T.fontBody, fontSize: '14px', color: T.text,
|
||
background: 'transparent',
|
||
border: `1px solid ${T.divider}`, borderRadius: T.radiusMd,
|
||
transition: 'border-color .15s',
|
||
boxSizing: 'border-box',
|
||
}
|
||
|
||
const labelStyle: React.CSSProperties = {
|
||
display: 'block', fontSize: '12px', marginBottom: '5px',
|
||
color: 'rgba(32,31,29,0.7)', fontFamily: T.fontBody,
|
||
}
|
||
|
||
return (
|
||
<form
|
||
onSubmit={handleSubmit}
|
||
style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(auto-fit,minmax(200px,1fr))',
|
||
gap: '16px',
|
||
border: `1px solid ${T.divider}`,
|
||
borderRadius: T.radiusLg,
|
||
padding: '28px',
|
||
background: T.bg,
|
||
}}
|
||
noValidate
|
||
>
|
||
{/* Honeypot */}
|
||
<div aria-hidden="true" style={{ display: 'none' }} tabIndex={-1}>
|
||
<input type="text" name="_hp" value={form._hp} onChange={set('_hp')} autoComplete="off" tabIndex={-1} />
|
||
</div>
|
||
|
||
<div style={{ gridColumn: 'span 1' }}>
|
||
<label style={labelStyle} htmlFor="af_name">Ad Soyad <span style={{ color: T.accent }}>*</span></label>
|
||
<input
|
||
id="af_name" type="text" required
|
||
placeholder="Av. Ayşe Yılmaz"
|
||
value={form.name} onChange={set('name')}
|
||
style={inputStyle}
|
||
onFocus={e => (e.target.style.borderColor = T.accent)}
|
||
onBlur={e => (e.target.style.borderColor = T.divider)}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label style={labelStyle} htmlFor="af_org">Büro / Kurum</label>
|
||
<input
|
||
id="af_org" type="text"
|
||
placeholder="Yılmaz Hukuk Bürosu"
|
||
value={form.org} onChange={set('org')}
|
||
style={inputStyle}
|
||
onFocus={e => (e.target.style.borderColor = T.accent)}
|
||
onBlur={e => (e.target.style.borderColor = T.divider)}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label style={labelStyle} htmlFor="af_email">E-posta <span style={{ color: T.accent }}>*</span></label>
|
||
<input
|
||
id="af_email" type="email" required
|
||
placeholder="ayse@buro.com"
|
||
value={form.email} onChange={set('email')}
|
||
style={inputStyle}
|
||
onFocus={e => (e.target.style.borderColor = T.accent)}
|
||
onBlur={e => (e.target.style.borderColor = T.divider)}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label style={labelStyle} htmlFor="af_phone">Telefon</label>
|
||
<input
|
||
id="af_phone" type="tel"
|
||
placeholder="0532 000 00 00"
|
||
value={form.phone} onChange={set('phone')}
|
||
style={inputStyle}
|
||
onFocus={e => (e.target.style.borderColor = T.accent)}
|
||
onBlur={e => (e.target.style.borderColor = T.divider)}
|
||
/>
|
||
</div>
|
||
|
||
{state === 'error' && (
|
||
<div style={{ gridColumn: '1 / -1', fontSize: '13px', color: '#c0392b', fontFamily: T.fontBody }}>
|
||
Bir hata oluştu. Lütfen tekrar deneyin veya{' '}
|
||
<a href="mailto:info@ayris.tech" style={{ color: T.accent }}>info@ayris.tech</a> adresine yazın.
|
||
</div>
|
||
)}
|
||
|
||
<button
|
||
id="contact_submit"
|
||
type="submit"
|
||
disabled={state === 'loading'}
|
||
style={{
|
||
gridColumn: '1 / -1',
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '6px',
|
||
cursor: state === 'loading' ? 'not-allowed' : 'pointer',
|
||
textDecoration: 'none',
|
||
fontFamily: T.fontHead, fontWeight: 600, fontSize: '15px', lineHeight: 1.2,
|
||
color: T.accent,
|
||
background: 'transparent',
|
||
border: `1px solid ${T.accent}`,
|
||
padding: '12px',
|
||
borderRadius: T.radiusMd,
|
||
transition: 'background .15s',
|
||
opacity: state === 'loading' ? 0.6 : 1,
|
||
marginTop: '4px',
|
||
}}
|
||
onMouseEnter={e => { if (state !== 'loading') (e.currentTarget as HTMLElement).style.background = 'rgba(182,130,53,0.10)' }}
|
||
onMouseLeave={e => { if (state !== 'loading') (e.currentTarget as HTMLElement).style.background = 'transparent' }}
|
||
>
|
||
{state === 'loading' ? 'Gönderiliyor…' : 'Demo Talep Et'}
|
||
</button>
|
||
</form>
|
||
)
|
||
}
|