Files
williammarch.xyz/components/Contact.tsx
2026-04-02 19:13:46 +01:00

104 lines
5.9 KiB
TypeScript

'use client';
import { useState } from 'react';
import { SITE, GITEA_URL, GITEA_USERNAME } from '@/lib/config';
export default function Contact() {
const [status, setStatus] = useState<'idle'|'sent'>('idle');
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const fd = new FormData(e.currentTarget);
const name = fd.get('name') as string;
const email = fd.get('email') as string;
const message = fd.get('message') as string;
if (!name || !email || !message) return;
const sub = encodeURIComponent(`Message from ${name} via williammarch.xyz`);
const body = encodeURIComponent(`From: ${name} <${email}>\n\n${message}`);
window.location.href = `mailto:${SITE.email}?subject=${sub}&body=${body}`;
setStatus('sent');
}
return (
<section id="contact" className="py-24 px-6 bg-[#0a0a0a]" aria-labelledby="contact-heading">
<div className="max-w-5xl mx-auto">
<span className="label">Get in touch</span>
<h2 id="contact-heading"
className="text-[clamp(1.8rem,4vw,2.5rem)] font-black tracking-tight text-white mb-10">
Let&rsquo;s work together.
</h2>
<div className="grid md:grid-cols-[280px_1fr] gap-6">
{/* Links */}
<div className="flex flex-col gap-3">
<a href={`mailto:${SITE.email}`}
className="glass rounded-xl p-4 flex items-center gap-3 group hover:border-white/[0.14]
hover:-translate-x-[-4px] transition-all duration-150">
<div className="w-8 h-8 rounded-lg bg-white/[0.05] flex items-center justify-center flex-shrink-0" aria-hidden="true">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,0.5)" strokeWidth="1.8">
<rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>
</svg>
</div>
<div className="min-w-0">
<p className="text-[10px] text-white/25 uppercase tracking-wider">Email</p>
<p className="text-xs font-medium text-white/55 truncate group-hover:text-white/80 transition-colors">{SITE.email}</p>
</div>
</a>
<a href={`${GITEA_URL}/${GITEA_USERNAME}`}
target="_blank" rel="noopener noreferrer"
className="glass rounded-xl p-4 flex items-center gap-3 group hover:border-white/[0.14]
hover:translate-x-1 transition-all duration-150">
<div className="w-8 h-8 rounded-lg bg-white/[0.05] flex items-center justify-center flex-shrink-0" aria-hidden="true">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,0.5)" strokeWidth="1.8">
<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.2c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/>
<path d="M9 18c-4.51 2-5-2-7-2"/>
</svg>
</div>
<div className="min-w-0">
<p className="text-[10px] text-white/25 uppercase tracking-wider">Gitea</p>
<p className="text-xs font-medium text-white/55 truncate group-hover:text-white/80 transition-colors font-mono">
{GITEA_URL.replace(/^https?:\/\//, '')}/{GITEA_USERNAME}
</p>
</div>
</a>
</div>
{/* Form */}
<form onSubmit={handleSubmit} className="glass rounded-xl p-6 flex flex-col gap-4" noValidate>
<div className="grid sm:grid-cols-2 gap-4">
<label className="flex flex-col gap-1.5">
<span className="text-[10px] font-semibold uppercase tracking-wider text-white/30">Name</span>
<input name="name" type="text" required placeholder="Your name" autoComplete="name"
className="bg-white/[0.03] border border-white/[0.08] rounded-lg px-3 py-2.5 text-sm
text-white placeholder-white/20 outline-none transition-colors
focus:border-white/[0.2] focus:ring-1 focus:ring-white/[0.1]" />
</label>
<label className="flex flex-col gap-1.5">
<span className="text-[10px] font-semibold uppercase tracking-wider text-white/30">Email</span>
<input name="email" type="email" required placeholder="you@example.com" autoComplete="email"
className="bg-white/[0.03] border border-white/[0.08] rounded-lg px-3 py-2.5 text-sm
text-white placeholder-white/20 outline-none transition-colors
focus:border-white/[0.2] focus:ring-1 focus:ring-white/[0.1]" />
</label>
</div>
<label className="flex flex-col gap-1.5">
<span className="text-[10px] font-semibold uppercase tracking-wider text-white/30">Message</span>
<textarea name="message" required placeholder="What's on your mind?" rows={4}
className="bg-white/[0.03] border border-white/[0.08] rounded-lg px-3 py-2.5 text-sm
text-white placeholder-white/20 outline-none resize-none transition-colors
focus:border-white/[0.2] focus:ring-1 focus:ring-white/[0.1]" />
</label>
<div className="flex items-center gap-4">
<button type="submit" className="btn btn-primary">
{status === 'sent' ? 'Opening email…' : 'Send message'}
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" aria-hidden="true">
<line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/>
</svg>
</button>
</div>
</form>
</div>
</div>
</section>
);
}