Özellikler bölümü rapordaki gerçek modüllere göre yeniden yapılandırıldı (dosya analizi, otomasyon, interaktif AI, içtihat arama, UYAP entegrasyonu). Güven bölümüne mesleki sorumluluk maddesi, itiraz giderme için yeni bir SSS bölümü ve iletişim formuna sonraki adım açıklaması eklendi. Contact form ve favicon, sitenin brutalist tema sistemiyle tutarlı hale getirildi.
166 lines
6.0 KiB
TypeScript
166 lines
6.0 KiB
TypeScript
'use client'
|
||
|
||
import { useState } from 'react'
|
||
|
||
type FormState = 'idle' | 'loading' | 'success' | 'error'
|
||
|
||
const T = {
|
||
bg: '#F4F4F0',
|
||
ink: '#0A0A0A',
|
||
inkSoft: 'rgba(10,10,10,0.6)',
|
||
divider: 'rgba(10,10,10,0.16)',
|
||
red: '#E61919',
|
||
fontHead: '"Archivo", sans-serif',
|
||
fontMono: '"JetBrains Mono", monospace',
|
||
}
|
||
|
||
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: `2px solid ${T.ink}`, padding: '36px', textAlign: 'center', background: '#fff' }}>
|
||
<span style={{ display: 'inline-block', fontSize: '10.5px', letterSpacing: '0.12em', color: T.red, fontFamily: T.fontMono, fontWeight: 700, marginBottom: '10px' }}>STATUS: RECEIVED</span>
|
||
<h3 style={{ fontFamily: T.fontHead, fontWeight: 900, fontSize: '20px', margin: '0 0 8px', textTransform: 'uppercase', letterSpacing: '-0.01em' }}>Talebiniz alındı.</h3>
|
||
<p style={{ fontSize: '13px', margin: 0, color: T.inkSoft, fontFamily: T.fontMono }}>
|
||
Kurucu ekipten kısa süre içinde size dönüş yapılacak.
|
||
</p>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
const inputStyle: React.CSSProperties = {
|
||
width: '100%', minHeight: '40px', padding: '8px 12px',
|
||
fontFamily: T.fontMono, fontSize: '13.5px', color: T.ink,
|
||
background: '#fff',
|
||
border: `2px solid ${T.divider}`,
|
||
transition: 'border-color .12s',
|
||
boxSizing: 'border-box',
|
||
}
|
||
|
||
const labelStyle: React.CSSProperties = {
|
||
display: 'block', fontSize: '10.5px', letterSpacing: '0.1em', textTransform: 'uppercase',
|
||
marginBottom: '6px', color: T.inkSoft, fontFamily: T.fontMono, fontWeight: 600,
|
||
}
|
||
|
||
return (
|
||
<form
|
||
onSubmit={handleSubmit}
|
||
style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(auto-fit,minmax(200px,1fr))',
|
||
gap: '16px',
|
||
border: `2px solid ${T.ink}`,
|
||
padding: '28px',
|
||
background: '#fff',
|
||
}}
|
||
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.red }}>*</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.red)}
|
||
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.red)}
|
||
onBlur={e => (e.target.style.borderColor = T.divider)}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label style={labelStyle} htmlFor="af_email">E-posta <span style={{ color: T.red }}>*</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.red)}
|
||
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.red)}
|
||
onBlur={e => (e.target.style.borderColor = T.divider)}
|
||
/>
|
||
</div>
|
||
|
||
{state === 'error' && (
|
||
<div style={{ gridColumn: '1 / -1', fontSize: '12.5px', color: T.red, fontFamily: T.fontMono }}>
|
||
Bir hata oluştu. Lütfen tekrar deneyin veya{' '}
|
||
<a href="mailto:info@ayris.tech" style={{ color: T.red }}>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.fontMono, fontWeight: 700, fontSize: '13px', letterSpacing: '0.06em', textTransform: 'uppercase',
|
||
color: '#fff',
|
||
background: T.ink,
|
||
border: `2px solid ${T.ink}`,
|
||
padding: '14px',
|
||
transition: 'background .12s',
|
||
opacity: state === 'loading' ? 0.6 : 1,
|
||
marginTop: '4px',
|
||
}}
|
||
onMouseEnter={e => { if (state !== 'loading') { (e.currentTarget as HTMLElement).style.background = T.red; (e.currentTarget as HTMLElement).style.borderColor = T.red } }}
|
||
onMouseLeave={e => { if (state !== 'loading') { (e.currentTarget as HTMLElement).style.background = T.ink; (e.currentTarget as HTMLElement).style.borderColor = T.ink } }}
|
||
>
|
||
{state === 'loading' ? 'GÖNDERİLİYOR…' : 'DEMO TALEP ET'}
|
||
</button>
|
||
</form>
|
||
)
|
||
}
|