Seed: photography template (19 files)

This commit is contained in:
2026-07-23 22:13:18 +00:00
parent 6f17248cd3
commit 9c87b91de6
+177
View File
@@ -0,0 +1,177 @@
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Card, CardContent } from "@/components/ui/card";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
import { MapPin, Mail, Phone, Send } from "lucide-react";
import { toast } from "sonner";
import { useSaasMutation } from "@/hooks/use-tygarun";
import Header from "@/components/Header";
import Footer from "@/components/Footer";
export default function ContactPage() {
const [sending, setSending] = useState(false);
const [sessionType, setSessionType] = useState("");
const [budget, setBudget] = useState("");
// Session booking is LIVE via tyga.run scheduling
const { mutate: bookSession } = useSaasMutation("scheduling", "/bookings");
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const fd = new FormData(e.currentTarget);
setSending(true);
try {
await bookSession({
name: fd.get("name"),
email: fd.get("email"),
sessionType,
date: fd.get("date"),
location: fd.get("location"),
budget,
message: fd.get("message"),
});
toast.success("Your session request is in, I will confirm within 24 hours.");
e.currentTarget.reset();
setSessionType("");
setBudget("");
} catch (err) {
toast.error("Something went wrong. Please try again or email me directly.");
} finally {
setSending(false);
}
};
return (
<div className="min-h-screen bg-zinc-950 text-white antialiased">
<Header />
<section className="pt-32 pb-24 px-6">
<div className="mx-auto max-w-7xl">
<h1 className="text-4xl md:text-6xl font-serif font-light tracking-tight mb-4 animate-fade-up">Get in Touch</h1>
<p className="text-zinc-500 max-w-xl mb-16">Have a project in mind? I would love to hear your story. Fill out the form and I will get back to you within 24 hours.</p>
<div className="grid lg:grid-cols-5 gap-16">
{/* ── FORM ── */}
<form onSubmit={handleSubmit} className="lg:col-span-3 space-y-6">
<div className="grid sm:grid-cols-2 gap-6">
<div className="space-y-2">
<Label htmlFor="name" className="text-zinc-400 text-sm">Name</Label>
<Input id="name" name="name" required placeholder="Your full name" className="bg-zinc-900 border-zinc-800 text-white placeholder:text-zinc-600 focus:border-zinc-500" />
</div>
<div className="space-y-2">
<Label htmlFor="email" className="text-zinc-400 text-sm">Email</Label>
<Input id="email" name="email" type="email" required placeholder="you@example.com" className="bg-zinc-900 border-zinc-800 text-white placeholder:text-zinc-600 focus:border-zinc-500" />
</div>
</div>
<div className="grid sm:grid-cols-2 gap-6">
<div className="space-y-2">
<Label className="text-zinc-400 text-sm">Event Type</Label>
<Select value={sessionType} onValueChange={setSessionType}>
<SelectTrigger className="bg-zinc-900 border-zinc-800 text-white">
<SelectValue placeholder="Select type" />
</SelectTrigger>
<SelectContent>
<SelectItem value="wedding">Wedding</SelectItem>
<SelectItem value="portrait">Portrait</SelectItem>
<SelectItem value="commercial">Commercial</SelectItem>
<SelectItem value="event">Event</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="date" className="text-zinc-400 text-sm">Preferred Date</Label>
<Input id="date" name="date" type="date" className="bg-zinc-900 border-zinc-800 text-white focus:border-zinc-500" />
</div>
</div>
<div className="grid sm:grid-cols-2 gap-6">
<div className="space-y-2">
<Label htmlFor="location" className="text-zinc-400 text-sm">Location</Label>
<Input id="location" name="location" placeholder="City or venue" className="bg-zinc-900 border-zinc-800 text-white placeholder:text-zinc-600 focus:border-zinc-500" />
</div>
<div className="space-y-2">
<Label className="text-zinc-400 text-sm">Budget Range</Label>
<Select value={budget} onValueChange={setBudget}>
<SelectTrigger className="bg-zinc-900 border-zinc-800 text-white">
<SelectValue placeholder="Select range" />
</SelectTrigger>
<SelectContent>
<SelectItem value="under1k">Under $1,000</SelectItem>
<SelectItem value="1k-3k">$1,000 - $3,000</SelectItem>
<SelectItem value="3k-5k">$3,000 - $5,000</SelectItem>
<SelectItem value="5k-10k">$5,000 - $10,000</SelectItem>
<SelectItem value="10kplus">$10,000+</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="message" className="text-zinc-400 text-sm">Message</Label>
<Textarea id="message" name="message" required rows={5} placeholder="Tell me about your vision..." className="bg-zinc-900 border-zinc-800 text-white placeholder:text-zinc-600 focus:border-zinc-500 resize-none" />
</div>
<Button type="submit" disabled={sending} size="lg" className="rounded-none bg-white text-zinc-900 hover:bg-zinc-200 px-10 tracking-wider w-full sm:w-auto">
{sending ? "Sending..." : "Book My Session"} <Send className="ml-2 h-4 w-4" />
</Button>
</form>
{/* ── STUDIO INFO ── */}
<div className="lg:col-span-2 space-y-8">
<Card className="backdrop-blur-sm bg-card/80 border-zinc-800">
<CardContent className="pt-6 space-y-5">
<div className="flex items-start gap-3">
<MapPin className="h-5 w-5 text-zinc-500 mt-0.5 shrink-0" />
<div>
<p className="text-white text-sm font-medium">Studio</p>
<p className="text-zinc-400 text-sm">412 Mission Street, Studio 7, San Francisco, CA 94105</p>
</div>
</div>
<div className="flex items-start gap-3">
<Mail className="h-5 w-5 text-zinc-500 mt-0.5 shrink-0" />
<div>
<p className="text-white text-sm font-medium">Email</p>
<p className="text-zinc-400 text-sm">hello@elenatorres.com</p>
</div>
</div>
<div className="flex items-start gap-3">
<Phone className="h-5 w-5 text-zinc-500 mt-0.5 shrink-0" />
<div>
<p className="text-white text-sm font-medium">Phone</p>
<p className="text-zinc-400 text-sm">+1 (415) 555-0142</p>
</div>
</div>
</CardContent>
</Card>
{/* ── FAQ ── */}
<div>
<h3 className="text-lg font-light tracking-tight mb-4 animate-fade-up">Frequently Asked</h3>
<Accordion type="single" collapsible className="space-y-2">
<AccordionItem value="faq-1" className="border-zinc-800">
<AccordionTrigger className="text-sm text-zinc-300 hover:text-white">How does pricing work?</AccordionTrigger>
<AccordionContent className="text-zinc-500 text-sm">Pricing depends on the type of session, duration, and deliverables. After our initial consultation, I provide a detailed custom quote. No surprises.</AccordionContent>
</AccordionItem>
<AccordionItem value="faq-2" className="border-zinc-800">
<AccordionTrigger className="text-sm text-zinc-300 hover:text-white">What is the typical turnaround time?</AccordionTrigger>
<AccordionContent className="text-zinc-500 text-sm">Portrait and commercial galleries are delivered within two weeks. Wedding collections take three to four weeks for the full edited gallery.</AccordionContent>
</AccordionItem>
<AccordionItem value="faq-3" className="border-zinc-800">
<AccordionTrigger className="text-sm text-zinc-300 hover:text-white">Do you travel for shoots?</AccordionTrigger>
<AccordionContent className="text-zinc-500 text-sm">Absolutely. I am based in San Francisco but regularly travel for destination weddings and on-location shoots. Travel fees apply for sessions beyond 50 miles.</AccordionContent>
</AccordionItem>
</Accordion>
</div>
</div>
</div>
</div>
</section>
<Footer />
</div>
);
}