Seed: real-estate template (18 files)
This commit is contained in:
@@ -0,0 +1,150 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
||||||
|
import { MapPin, Phone, Mail, Clock, Send } from "lucide-react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
import { useSaasMutation } from "@/hooks/use-tygarun";
|
||||||
|
|
||||||
|
const offices = [
|
||||||
|
{ city: "New York Office", addr: "500 Prestige Tower, 5th Avenue, New York, NY 10001", phone: "+1 (212) 555-0199", hours: "Mon-Fri 9:00 AM - 6:00 PM" },
|
||||||
|
{ city: "Los Angeles Office", addr: "8800 Sunset Blvd, Suite 300, West Hollywood, CA 90069", phone: "+1 (310) 555-0188", hours: "Mon-Fri 9:00 AM - 6:00 PM" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{ q: "How do I start the home buying process?", a: "Start by getting pre-approved for a mortgage, then connect with one of our agents who will help you identify properties that match your criteria, schedule viewings, and guide you through every step to closing." },
|
||||||
|
{ q: "What fees are involved in buying a property?", a: "Typical costs include the down payment (3-20% of purchase price), closing costs (2-5%), home inspection fees, appraisal fees, and title insurance. Our agents will provide a detailed breakdown specific to your situation." },
|
||||||
|
{ q: "How long does it take to sell a property?", a: "On average, our listings sell within 30-45 days, though this varies by market and price point. Our marketing strategy, professional photography, and extensive network often lead to faster sales at premium prices." },
|
||||||
|
{ q: "Do you help with property investment analysis?", a: "Absolutely. Our investment specialists provide detailed market analysis, ROI projections, rental income estimates, and neighborhood growth data to help you make informed investment decisions." },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function ContactPage() {
|
||||||
|
// toast from sonner (imported above)
|
||||||
|
const [interest, setInterest] = useState("");
|
||||||
|
const { mutate: createLead, loading: sending } = useSaasMutation("crm", "/leads");
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const form = e.currentTarget;
|
||||||
|
const fd = new FormData(form);
|
||||||
|
try {
|
||||||
|
await createLead({
|
||||||
|
name: fd.get("name"),
|
||||||
|
email: fd.get("email"),
|
||||||
|
phone: fd.get("phone"),
|
||||||
|
interest,
|
||||||
|
message: fd.get("message"),
|
||||||
|
});
|
||||||
|
toast.success("Message sent! An agent will get back to you within 24 hours.");
|
||||||
|
form.reset();
|
||||||
|
setInterest("");
|
||||||
|
} catch {
|
||||||
|
toast.error("Could not send message. Please try again.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground antialiased">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
{/* ── HERO ── */}
|
||||||
|
<section className="pt-32 pb-16 bg-gradient-to-b from-stone-950 via-emerald-950/20 to-background">
|
||||||
|
<div className="mx-auto max-w-7xl px-6 text-center animate-fade-up">
|
||||||
|
<Badge className="bg-emerald-600/20 text-emerald-400 border-emerald-600/30 mb-4">Get in Touch</Badge>
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-bold text-white mb-4">Contact Us</h1>
|
||||||
|
<p className="text-stone-400 max-w-lg mx-auto">Have a question or ready to start your property search? We would love to hear from you.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── CONTACT SPLIT ── */}
|
||||||
|
<section className="py-20 bg-background">
|
||||||
|
<div className="mx-auto max-w-7xl px-6">
|
||||||
|
<div className="grid lg:grid-cols-2 gap-16">
|
||||||
|
|
||||||
|
{/* LEFT:Offices */}
|
||||||
|
<div className="animate-fade-up">
|
||||||
|
<h2 className="text-2xl font-bold text-stone-900 dark:text-white mb-8">Our Offices</h2>
|
||||||
|
<div className="space-y-6 mb-10">
|
||||||
|
{offices.map((o, i) => (
|
||||||
|
<Card key={i} className="bg-white/70 dark:bg-white/5 backdrop-blur-xl border-stone-200 dark:border-white/10 rounded-2xl hover:-translate-y-1 transition-transform duration-300">
|
||||||
|
<CardContent className="p-6">
|
||||||
|
<h3 className="text-lg font-bold text-stone-900 dark:text-white mb-3">{o.city}</h3>
|
||||||
|
<div className="space-y-2 text-sm text-stone-600 dark:text-stone-400">
|
||||||
|
<div className="flex items-start gap-3"><MapPin className="h-4 w-4 mt-0.5 text-emerald-500 shrink-0" />{o.addr}</div>
|
||||||
|
<div className="flex items-center gap-3"><Phone className="h-4 w-4 text-emerald-500 shrink-0" />{o.phone}</div>
|
||||||
|
<div className="flex items-center gap-3"><Clock className="h-4 w-4 text-emerald-500 shrink-0" />{o.hours}</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="flex items-center gap-3 text-stone-600 dark:text-stone-400">
|
||||||
|
<Mail className="h-5 w-5 text-emerald-500" />
|
||||||
|
<span>hello@prestigerealty.com</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3 text-stone-600 dark:text-stone-400">
|
||||||
|
<Phone className="h-5 w-5 text-emerald-500" />
|
||||||
|
<span>+1 (800) 555-REAL</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* RIGHT:Form */}
|
||||||
|
<div className="animate-fade-up" style={{ animationDelay: "150ms" }}>
|
||||||
|
<Card className="bg-white/70 dark:bg-white/5 backdrop-blur-xl border-stone-200 dark:border-white/10 rounded-2xl shadow-lg">
|
||||||
|
<CardContent className="p-8">
|
||||||
|
<h2 className="text-2xl font-bold text-stone-900 dark:text-white mb-6">Send Us a Message</h2>
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
|
<div className="grid sm:grid-cols-2 gap-4">
|
||||||
|
<Input name="name" placeholder="Full Name" required className="rounded-xl" />
|
||||||
|
<Input name="email" type="email" placeholder="Email Address" required className="rounded-xl" />
|
||||||
|
</div>
|
||||||
|
<Input name="phone" type="tel" placeholder="Phone Number" className="rounded-xl" />
|
||||||
|
<Select value={interest} onValueChange={setInterest}>
|
||||||
|
<SelectTrigger className="rounded-xl"><SelectValue placeholder="Property Interest" /></SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{["Buying a Home", "Selling a Property", "Renting", "Investment", "Commercial", "Other"].map((t) => <SelectItem key={t} value={t.toLowerCase()}>{t}</SelectItem>)}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<Textarea name="message" placeholder="Your message..." rows={5} className="rounded-xl resize-none" />
|
||||||
|
<Button type="submit" disabled={sending} className="w-full bg-emerald-600 hover:bg-emerald-700 text-white rounded-full shadow-lg shadow-emerald-600/20 active:scale-[0.97] transition-all">
|
||||||
|
<Send className="h-4 w-4 mr-2" />{sending ? "Sending..." : "Send Message"}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── FAQ ── */}
|
||||||
|
<section className="py-20 bg-stone-50 dark:bg-stone-900/50">
|
||||||
|
<div className="mx-auto max-w-3xl px-6">
|
||||||
|
<div className="text-center mb-12 animate-fade-up">
|
||||||
|
<Badge className="bg-amber-100 text-amber-700 dark:bg-amber-600/20 dark:text-amber-400 mb-4">FAQ</Badge>
|
||||||
|
<h2 className="text-3xl font-bold text-stone-900 dark:text-white">Frequently Asked Questions</h2>
|
||||||
|
</div>
|
||||||
|
<Accordion type="single" collapsible className="space-y-3 animate-fade-up">
|
||||||
|
{faqs.map((f, i) => (
|
||||||
|
<AccordionItem key={i} value={`faq-\${i}`} className="bg-white dark:bg-stone-900/50 border border-stone-200 dark:border-stone-800 rounded-xl px-6 overflow-hidden">
|
||||||
|
<AccordionTrigger className="text-left font-semibold text-stone-900 dark:text-white hover:no-underline">{f.q}</AccordionTrigger>
|
||||||
|
<AccordionContent className="text-stone-600 dark:text-stone-400">{f.a}</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user