Seed: services template (18 files)
This commit is contained in:
@@ -0,0 +1,200 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
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, ArrowRight } from "lucide-react";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
import { useSaasMutation } from "@/hooks/use-tygarun";
|
||||||
|
|
||||||
|
const offices = [
|
||||||
|
{ city: "San Francisco", address: "123 Design Street, Suite 400, SF, CA 94105", phone: "+1 (555) 123-4567" },
|
||||||
|
{ city: "New York", address: "456 Creative Ave, Floor 12, NY, NY 10001", phone: "+1 (555) 987-6543" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{ q: "How long does a typical project take?", a: "Most projects take 8-12 weeks from kickoff to launch, depending on scope and complexity. We will provide a detailed timeline during our discovery phase." },
|
||||||
|
{ q: "What is your design process?", a: "We follow a four-phase process: Discovery, Design, Development, and Delivery. Each phase includes client checkpoints to ensure alignment." },
|
||||||
|
{ q: "Do you work with startups?", a: "Absolutely! We love working with startups. Our Starter plan is specifically designed for early-stage companies looking to establish their digital presence." },
|
||||||
|
{ q: "Can you help with ongoing maintenance?", a: "Yes, we offer ongoing support and maintenance packages. Most clients stay with us well beyond the initial launch for continuous improvement." },
|
||||||
|
{ q: "What technologies do you use?", a: "We work with modern frameworks like React, Next.js, and TypeScript on the frontend, with Node.js, Python, and cloud services on the backend." },
|
||||||
|
{ q: "How do you handle project communication?", a: "Each project gets a dedicated Slack channel, weekly video check-ins, and access to our project management board for full transparency." },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function ContactPage() {
|
||||||
|
const { mutate: bookConsult, loading: sending } = useSaasMutation("scheduling", "/bookings");
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [company, setCompany] = useState("");
|
||||||
|
const [budget, setBudget] = useState("");
|
||||||
|
const [projectType, setProjectType] = useState("");
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [submitted, setSubmitted] = useState(false);
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
await bookConsult({ name, email, company, budget, projectType, message });
|
||||||
|
setSubmitted(true);
|
||||||
|
toast.success("Message sent! We'll get back to you within 24 hours.");
|
||||||
|
} catch (err) {
|
||||||
|
toast.error("Something went wrong. Please try again.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground antialiased">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
{/* ── CONTACT SECTION ── */}
|
||||||
|
<section className="pt-32 pb-24">
|
||||||
|
<div className="mx-auto max-w-7xl px-6">
|
||||||
|
<div className="grid lg:grid-cols-2 gap-16">
|
||||||
|
{/* LEFT: Info */}
|
||||||
|
<div>
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-extrabold tracking-tight animate-fade-up">
|
||||||
|
Let’s Build Something Great
|
||||||
|
</h1>
|
||||||
|
<p className="mt-6 text-lg text-muted-foreground leading-relaxed">
|
||||||
|
Have a project in mind? We’d love to hear about it. Reach out and let’s start a conversation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-12 space-y-6">
|
||||||
|
{offices.map((office, i) => (
|
||||||
|
<Card key={i} className="border">
|
||||||
|
<CardContent className="p-6">
|
||||||
|
<div className="flex items-start gap-4">
|
||||||
|
<div className="w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center shrink-0">
|
||||||
|
<MapPin className={`h-5 w-5 text-primary \${i === 0 ? "animate-bounce" : ""}`} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-bold">{office.city}</h3>
|
||||||
|
<p className="text-sm text-muted-foreground mt-1">{office.address}</p>
|
||||||
|
<p className="text-sm text-muted-foreground flex items-center gap-2 mt-1">
|
||||||
|
<Phone className="h-3.5 w-3.5" /> {office.phone}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Map Placeholder */}
|
||||||
|
<div className="relative mt-8 aspect-[2/1] rounded-xl bg-muted border flex items-center justify-center text-sm text-muted-foreground overflow-hidden animate-scale-in">
|
||||||
|
<div className="absolute inset-0 opacity-[0.06]" style={{ backgroundImage: "radial-gradient(circle, currentColor 1px, transparent 1px)", backgroundSize: "16px 16px" }} />
|
||||||
|
<div className="absolute -top-8 -right-8 w-32 h-32 rounded-full bg-primary/10 blur-2xl" />
|
||||||
|
Map Placeholder
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* RIGHT: Form */}
|
||||||
|
<div>
|
||||||
|
<Card className="border shadow-sm backdrop-blur-sm bg-card/80">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="text-2xl">Send us a message</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
{submitted ? (
|
||||||
|
<div className="py-12 text-center space-y-3 animate-fade-in">
|
||||||
|
<div className="mx-auto w-14 h-14 rounded-full bg-primary/10 flex items-center justify-center mb-4">
|
||||||
|
<ArrowRight className="h-6 w-6 text-primary" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-xl font-bold">Message Sent!</h3>
|
||||||
|
<p className="text-sm text-muted-foreground">Thanks for reaching out. We will get back to you within 24 hours.</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-5">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">Name</label>
|
||||||
|
<Input placeholder="Your name" value={name} onChange={(e) => setName(e.target.value)} required />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">Email</label>
|
||||||
|
<Input type="email" placeholder="you@company.com" value={email} onChange={(e) => setEmail(e.target.value)} required />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">Company</label>
|
||||||
|
<Input placeholder="Company name" value={company} onChange={(e) => setCompany(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">Budget</label>
|
||||||
|
<Select value={budget} onValueChange={setBudget}>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select budget range" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="5k-10k">$5K - $10K</SelectItem>
|
||||||
|
<SelectItem value="10k-25k">$10K - $25K</SelectItem>
|
||||||
|
<SelectItem value="25k-50k">$25K - $50K</SelectItem>
|
||||||
|
<SelectItem value="50k+">$50K+</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">Project Type</label>
|
||||||
|
<Select value={projectType} onValueChange={setProjectType}>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select project type" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="brand">Brand & Design</SelectItem>
|
||||||
|
<SelectItem value="web">Web Development</SelectItem>
|
||||||
|
<SelectItem value="marketing">Digital Marketing</SelectItem>
|
||||||
|
<SelectItem value="mobile">Mobile App</SelectItem>
|
||||||
|
<SelectItem value="other">Other</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">Message</label>
|
||||||
|
<Textarea
|
||||||
|
placeholder="Tell us about your project..."
|
||||||
|
rows={5}
|
||||||
|
value={message}
|
||||||
|
onChange={(e) => setMessage(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Button type="submit" disabled={sending} className="w-full active:scale-[0.98]" size="lg">
|
||||||
|
{sending ? "Sending..." : "Send Message"} <ArrowRight className="ml-2 h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
<p className="text-center text-xs text-muted-foreground mt-3">Average response time: <span className="font-semibold text-primary">4 hours</span></p>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── FAQ ── */}
|
||||||
|
<section className="py-24 bg-muted/30">
|
||||||
|
<div className="mx-auto max-w-3xl px-6">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight animate-fade-up">Frequently Asked Questions</h2>
|
||||||
|
</div>
|
||||||
|
<div className="backdrop-blur-sm bg-card/80 border border-border/50 rounded-2xl p-6">
|
||||||
|
<Accordion type="single" collapsible className="space-y-4">
|
||||||
|
{faqs.map((faq, i) => (
|
||||||
|
<AccordionItem key={i} value={`faq-\${i}`} className="bg-background border rounded-lg px-6">
|
||||||
|
<AccordionTrigger className="text-sm font-medium hover:no-underline">{faq.q}</AccordionTrigger>
|
||||||
|
<AccordionContent className="text-sm text-muted-foreground leading-relaxed">
|
||||||
|
{faq.a}
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user