Seed: saas template (34 files)
This commit is contained in:
@@ -0,0 +1,156 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Mail, Phone, MapPin, Send, CheckCircle2 } from "lucide-react";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
import { useSaasMutation } from "@/hooks/use-tygarun";
|
||||||
|
|
||||||
|
export default function ContactPage() {
|
||||||
|
const { mutate: createLead, loading: sending } = useSaasMutation("crm", "/leads");
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [company, setCompany] = useState("");
|
||||||
|
const [subject, setSubject] = useState("");
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [success, setSuccess] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-white text-slate-900 antialiased">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
{/* ── HERO ── */}
|
||||||
|
<section className="pt-32 pb-16 bg-gradient-to-b from-slate-50 to-white">
|
||||||
|
<div className="mx-auto max-w-7xl px-6 text-center">
|
||||||
|
<Badge className="mb-4 bg-indigo-50 text-indigo-600 border-0">Contact</Badge>
|
||||||
|
<h1 className="animate-fade-up text-4xl font-bold tracking-tight sm:text-5xl">Get in touch</h1>
|
||||||
|
<p className="mt-4 text-lg text-slate-500 max-w-2xl mx-auto">
|
||||||
|
Have questions? We would love to hear from you. Our team typically responds within 24 hours.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── CONTACT SPLIT ── */}
|
||||||
|
<section className="py-24">
|
||||||
|
<div className="mx-auto max-w-7xl px-6">
|
||||||
|
<div className="grid lg:grid-cols-5 gap-12">
|
||||||
|
{/* Left:Info */}
|
||||||
|
<div className="lg:col-span-2 space-y-8">
|
||||||
|
<div>
|
||||||
|
<h2 className="animate-fade-up text-3xl font-bold mb-4 tracking-tight">Contact Information</h2>
|
||||||
|
<p className="text-slate-500">Reach out through any of these channels and we will get back to you as soon as possible.</p>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div className="flex items-start gap-4">
|
||||||
|
<div className="h-10 w-10 rounded-xl bg-indigo-50 flex items-center justify-center flex-shrink-0">
|
||||||
|
<Mail className="h-5 w-5 text-indigo-600" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-semibold text-sm">Email</h3>
|
||||||
|
<p className="text-slate-500 text-sm mt-0.5">hello@nexus.dev</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-start gap-4">
|
||||||
|
<div className="h-10 w-10 rounded-xl bg-indigo-50 flex items-center justify-center flex-shrink-0">
|
||||||
|
<Phone className="h-5 w-5 text-indigo-600" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-semibold text-sm">Phone</h3>
|
||||||
|
<p className="text-slate-500 text-sm mt-0.5">+1 (415) 555-0132</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-start gap-4">
|
||||||
|
<div className="h-10 w-10 rounded-xl bg-indigo-50 flex items-center justify-center flex-shrink-0">
|
||||||
|
<MapPin className="h-5 w-5 text-indigo-600" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-semibold text-sm">Office</h3>
|
||||||
|
<p className="text-slate-500 text-sm mt-0.5">100 Market St, Suite 400, San Francisco, CA 94105</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right:Form */}
|
||||||
|
<div className="lg:col-span-3">
|
||||||
|
<Card className="border-slate-200 shadow-lg">
|
||||||
|
<CardContent className="p-8">
|
||||||
|
{success && (
|
||||||
|
<div className="mb-6 flex items-center gap-2 rounded-lg bg-green-50 border border-green-200 px-4 py-3 text-sm text-green-700">
|
||||||
|
<CheckCircle2 className="h-4 w-4 flex-shrink-0" /> Message sent successfully! We will get back to you within 24 hours.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<form onSubmit={async (e) => { e.preventDefault(); try { await createLead({ name, email, company, subject, message }); setSuccess(true); toast.success("Message sent! Our team will reach out shortly."); } catch (err) { toast.error("Something went wrong. Please try again."); } }}>
|
||||||
|
<div className="grid sm:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<Label htmlFor="contact-name" className="text-sm">Name</Label>
|
||||||
|
<Input id="contact-name" required placeholder="Your name" value={name} onChange={(e) => setName(e.target.value)} className="mt-1.5" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label htmlFor="contact-email" className="text-sm">Email</Label>
|
||||||
|
<Input id="contact-email" type="email" required placeholder="you@company.com" value={email} onChange={(e) => setEmail(e.target.value)} className="mt-1.5" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<Label htmlFor="contact-company" className="text-sm">Company</Label>
|
||||||
|
<Input id="contact-company" placeholder="Your company" value={company} onChange={(e) => setCompany(e.target.value)} className="mt-1.5" />
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<Label htmlFor="contact-subject" className="text-sm">Subject</Label>
|
||||||
|
<Select value={subject} onValueChange={setSubject}>
|
||||||
|
<SelectTrigger className="mt-1.5">
|
||||||
|
<SelectValue placeholder="Select a subject" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="general">General Inquiry</SelectItem>
|
||||||
|
<SelectItem value="sales">Sales</SelectItem>
|
||||||
|
<SelectItem value="support">Technical Support</SelectItem>
|
||||||
|
<SelectItem value="partnership">Partnership</SelectItem>
|
||||||
|
<SelectItem value="press">Press & Media</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<Label htmlFor="contact-message" className="text-sm">Message</Label>
|
||||||
|
<Textarea
|
||||||
|
id="contact-message"
|
||||||
|
required
|
||||||
|
placeholder="Tell us how we can help..."
|
||||||
|
value={message}
|
||||||
|
onChange={(e) => setMessage(e.target.value)}
|
||||||
|
className="mt-1.5 min-h-[120px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Button type="submit" disabled={sending} className="active:scale-[0.98] mt-6 w-full bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg font-semibold">
|
||||||
|
<Send className="mr-2 h-4 w-4" /> {sending ? "Sending..." : "Send Message"}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── MAP PLACEHOLDER ── */}
|
||||||
|
<section className="pb-24">
|
||||||
|
<div className="mx-auto max-w-7xl px-6">
|
||||||
|
<div className="animate-scale-in h-64 rounded-2xl bg-gradient-to-br from-slate-100 to-slate-200 flex items-center justify-center relative overflow-hidden">
|
||||||
|
<div className="absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxnIGZpbGw9IiNmZmYiIGZpbGwtb3BhY2l0eT0iMC4wMyI+PGNpcmNsZSBjeD0iMSIgY3k9IjEiIHI9IjEiLz48L2c+PC9nPjwvc3ZnPg==')] opacity-60" />
|
||||||
|
<div className="absolute -top-10 -right-10 w-40 h-40 rounded-full bg-indigo-200/30 blur-3xl" />
|
||||||
|
<div className="absolute -bottom-10 -left-10 w-32 h-32 rounded-full bg-cyan-200/30 blur-3xl" />
|
||||||
|
<span className="relative text-slate-400 text-sm">Map Placeholder</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user