feat: v2 tasarımını ana sayfa yap, brutalist sürümü yedekle

Ekip kararıyla kırmızı/zinc "v2" tasarımı artık ana sayfa (/[locale]).
Eski brutalist page.tsx ve contact-form.tsx, önceki "classical" geçişte
kurulan aynı yedekleme deseniyle *.brutalist-backup.tsx.txt olarak
saklandı — kod olarak derlenmiyor, sadece referans. Ayrı /v2 route'u
kaldırıldı (içerik ana sayfaya taşındığı için artık yinelenen kopya).
İletişim formu (contact-form.tsx) v2 geçişinde unutulmuş turuncu
renklerden kırmızıya (#E61919) güncellendi — sayfanın geri kalanıyla
tutarlı hale geldi.
This commit is contained in:
mstfyldz
2026-08-13 23:16:15 +03:00
parent e391eeb832
commit 5ac5988a3a
6 changed files with 1339 additions and 1382 deletions
-146
View File
@@ -1,146 +0,0 @@
'use client'
import { useState } from 'react'
type FormState = 'idle' | 'loading' | 'success' | 'error'
const T = {
ink: '#0B1220',
inkSoft: 'rgba(11,18,32,0.6)',
border: 'rgba(11,18,32,0.12)',
orange: '#F2600C',
orangeSoft: '#FFF1E6',
fontHead: '"Archivo", sans-serif',
}
export default function ContactFormV2() {
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')
}
}
if (state === 'success') {
return (
<div style={{ borderRadius: '24px', padding: '40px', textAlign: 'center', background: T.orangeSoft, border: `1px solid ${T.border}` }}>
<div style={{ width: '48px', height: '48px', borderRadius: '50%', background: T.orange, display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 16px', color: '#fff', fontSize: '22px' }}></div>
<h3 style={{ fontFamily: T.fontHead, fontWeight: 800, fontSize: '20px', margin: '0 0 8px', color: T.ink }}>Talebiniz alındı!</h3>
<p style={{ fontSize: '14px', margin: 0, color: T.inkSoft }}>
Kurucu ekipten kısa süre içinde size dönüş yapılacak.
</p>
</div>
)
}
const inputStyle: React.CSSProperties = {
width: '100%', minHeight: '46px', padding: '10px 16px',
fontFamily: 'inherit', fontSize: '14px', color: T.ink,
background: '#fff',
border: `1.5px solid ${T.border}`,
borderRadius: '12px',
transition: 'border-color .15s, box-shadow .15s',
boxSizing: 'border-box',
outline: 'none',
}
const labelStyle: React.CSSProperties = {
display: 'block', fontSize: '13px', fontWeight: 600,
marginBottom: '6px', color: T.ink,
}
const focusOn = (e: React.FocusEvent<HTMLInputElement>) => {
e.target.style.borderColor = T.orange
e.target.style.boxShadow = `0 0 0 4px ${T.orangeSoft}`
}
const focusOff = (e: React.FocusEvent<HTMLInputElement>) => {
e.target.style.borderColor = T.border
e.target.style.boxShadow = 'none'
}
return (
<form
onSubmit={handleSubmit}
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit,minmax(200px,1fr))',
gap: '18px',
borderRadius: '24px',
border: `1px solid ${T.border}`,
padding: '32px',
background: '#fff',
boxShadow: '0 12px 40px rgba(11,18,32,0.06)',
}}
noValidate
>
<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="af2_name">Ad Soyad <span style={{ color: T.orange }}>*</span></label>
<input id="af2_name" type="text" required placeholder="Av. Ayşe Yılmaz" value={form.name} onChange={set('name')} style={inputStyle} onFocus={focusOn} onBlur={focusOff} />
</div>
<div>
<label style={labelStyle} htmlFor="af2_org">Büro / Kurum</label>
<input id="af2_org" type="text" placeholder="Yılmaz Hukuk Bürosu" value={form.org} onChange={set('org')} style={inputStyle} onFocus={focusOn} onBlur={focusOff} />
</div>
<div>
<label style={labelStyle} htmlFor="af2_email">E-posta <span style={{ color: T.orange }}>*</span></label>
<input id="af2_email" type="email" required placeholder="ayse@buro.com" value={form.email} onChange={set('email')} style={inputStyle} onFocus={focusOn} onBlur={focusOff} />
</div>
<div>
<label style={labelStyle} htmlFor="af2_phone">Telefon</label>
<input id="af2_phone" type="tel" placeholder="0532 000 00 00" value={form.phone} onChange={set('phone')} style={inputStyle} onFocus={focusOn} onBlur={focusOff} />
</div>
{state === 'error' && (
<div style={{ gridColumn: '1 / -1', fontSize: '13px', color: '#DC2626' }}>
Bir hata oluştu. Lütfen tekrar deneyin veya{' '}
<a href="mailto:info@ayris.tech" style={{ color: '#DC2626' }}>info@ayris.tech</a> adresine yazın.
</div>
)}
<button
type="submit"
disabled={state === 'loading'}
style={{
gridColumn: '1 / -1',
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px',
cursor: state === 'loading' ? 'not-allowed' : 'pointer',
fontFamily: 'inherit', fontWeight: 700, fontSize: '15px',
color: '#fff',
background: T.orange,
border: 'none',
borderRadius: '999px',
padding: '15px',
transition: 'background .15s, transform .1s',
opacity: state === 'loading' ? 0.7 : 1,
marginTop: '4px',
}}
onMouseEnter={e => { if (state !== 'loading') (e.currentTarget as HTMLElement).style.background = '#D94E00' }}
onMouseLeave={e => { if (state !== 'loading') (e.currentTarget as HTMLElement).style.background = T.orange }}
>
{state === 'loading' ? 'Gönderiliyor…' : 'Demo Talep Et →'}
</button>
</form>
)
}
@@ -0,0 +1,165 @@
'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>
)
}
+34 -96
View File
@@ -1,18 +1,13 @@
'use client'
import { useState } from 'react'
import { CheckCircle2 } from 'lucide-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',
}
const ACCENT = '#E61919'
const ACCENT_DARK = '#B8140F'
const ACCENT_SOFT = '#FDEEEC'
export default function ContactForm() {
const [state, setState] = useState<FormState>('idle')
@@ -37,128 +32,71 @@ export default function ContactForm() {
}
}
/* 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 className="rounded-3xl border border-zinc-200/70 p-10 text-center" style={{ background: ACCENT_SOFT }}>
<div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full text-white" style={{ background: ACCENT }}>
<CheckCircle2 size={22} strokeWidth={2.5} />
</div>
<h3 className="text-xl font-extrabold tracking-tight text-zinc-950">Talebiniz alındı!</h3>
<p className="mt-2 text-sm text-zinc-500">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,
}
const inputClass = 'w-full min-h-[46px] rounded-xl border-[1.5px] border-zinc-200 bg-white px-4 py-2.5 text-sm text-zinc-900 outline-none transition-colors focus:border-[var(--accent)]'
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',
}}
className="grid grid-cols-1 gap-4 rounded-3xl border border-zinc-200/70 bg-white p-8 shadow-[0_20px_60px_-30px_rgba(24,24,27,0.2)] sm:grid-cols-2"
style={{ ['--accent' as string]: ACCENT }}
noValidate
>
{/* Honeypot */}
<div aria-hidden="true" style={{ display: 'none' }} tabIndex={-1}>
<div aria-hidden="true" className="hidden">
<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 className="sm:col-span-1">
<label className="mb-1.5 block text-[13px] font-semibold text-zinc-900" htmlFor="af_name">
Ad Soyad <span style={{ color: ACCENT }}>*</span>
</label>
<input id="af_name" type="text" required placeholder="Av. Ayşe Yılmaz" value={form.name} onChange={set('name')} className={inputClass} />
</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)}
/>
<label className="mb-1.5 block text-[13px] font-semibold text-zinc-900" 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')} className={inputClass} />
</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)}
/>
<label className="mb-1.5 block text-[13px] font-semibold text-zinc-900" htmlFor="af_email">
E-posta <span style={{ color: ACCENT }}>*</span>
</label>
<input id="af_email" type="email" required placeholder="ayse@buro.com" value={form.email} onChange={set('email')} className={inputClass} />
</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)}
/>
<label className="mb-1.5 block text-[13px] font-semibold text-zinc-900" htmlFor="af_phone">Telefon</label>
<input id="af_phone" type="tel" placeholder="0532 000 00 00" value={form.phone} onChange={set('phone')} className={inputClass} />
</div>
{state === 'error' && (
<div style={{ gridColumn: '1 / -1', fontSize: '12.5px', color: T.red, fontFamily: T.fontMono }}>
<div className="text-[13px] text-red-600 sm:col-span-2">
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.
<a href="mailto:info@ayris.tech" className="underline">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 } }}
className="mt-1 flex items-center justify-center gap-2 rounded-full py-3.5 text-[15px] font-bold text-white transition-colors disabled:cursor-not-allowed disabled:opacity-70 sm:col-span-2"
style={{ background: ACCENT }}
onMouseEnter={e => { if (state !== 'loading') (e.currentTarget as HTMLElement).style.background = ACCENT_DARK }}
onMouseLeave={e => { if (state !== 'loading') (e.currentTarget as HTMLElement).style.background = ACCENT }}
>
{state === 'loading' ? 'GÖNDERİLİYOR…' : 'DEMO TALEP ET'}
{state === 'loading' ? 'Gönderiliyor…' : 'Demo Talep Et →'}
</button>
</form>
)