Seed: healthcare template (18 files)
This commit is contained in:
@@ -0,0 +1,185 @@
|
|||||||
|
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 { useSaasMutation } from "@/hooks/use-tygarun";
|
||||||
|
import {
|
||||||
|
MapPin, Phone, Mail, Clock, AlertTriangle, Send
|
||||||
|
} from "lucide-react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{ q: "What insurance plans do you accept?", a: "We accept most major insurance plans including BlueCross BlueShield, Aetna, UnitedHealthcare, Cigna, Kaiser Permanente, and Humana. Please contact our billing department for specific coverage questions." },
|
||||||
|
{ q: "How long is the average wait time?", a: "We respect your time. Most appointments begin within 15 minutes of your scheduled time. For walk-in visits, wait times average 30–45 minutes depending on patient volume." },
|
||||||
|
{ q: "What should new patients bring?", a: "New patients should bring a valid photo ID, insurance card, list of current medications, and any relevant medical records or imaging. Please arrive 15 minutes early to complete paperwork." },
|
||||||
|
{ q: "Do you handle medical emergencies?", a: "For life-threatening emergencies, always call 911. Our clinic provides urgent care for non-life-threatening conditions. Our 24/7 emergency line is available for guidance on whether to visit the ER or schedule an urgent appointment." },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function ContactPage() {
|
||||||
|
const [sending, setSending] = useState(false);
|
||||||
|
const { mutate: bookAppointment } = useSaasMutation("scheduling", "/bookings");
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const form = e.currentTarget as HTMLFormElement;
|
||||||
|
const body = Object.fromEntries(new FormData(form).entries());
|
||||||
|
setSending(true);
|
||||||
|
try {
|
||||||
|
await bookAppointment(body);
|
||||||
|
toast.success("Appointment request submitted!", {
|
||||||
|
description: "Our team will call you within 24 hours to confirm your appointment.",
|
||||||
|
});
|
||||||
|
form.reset();
|
||||||
|
} catch {
|
||||||
|
toast.error("Could not submit request. Please call us or try again.");
|
||||||
|
} finally {
|
||||||
|
setSending(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background text-foreground antialiased">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
{/* ── HERO ── */}
|
||||||
|
<section className="pt-32 pb-16 bg-gradient-to-b from-sky-950 via-slate-900 to-background">
|
||||||
|
<div className="mx-auto max-w-4xl px-6 text-center animate-fade-up">
|
||||||
|
<Badge variant="secondary" className="mb-4 bg-sky-900/40 text-sky-300 border-sky-700/30 backdrop-blur">Get in Touch</Badge>
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-bold text-white tracking-tight">Contact Us</h1>
|
||||||
|
<p className="mt-4 text-slate-300 max-w-2xl mx-auto">We are here to help. Reach out to schedule an appointment or ask any questions about our services.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── MAIN CONTENT ── */}
|
||||||
|
<section className="py-20">
|
||||||
|
<div className="mx-auto max-w-6xl px-6">
|
||||||
|
<div className="grid lg:grid-cols-2 gap-12">
|
||||||
|
|
||||||
|
{/* LEFT: LOCATIONS */}
|
||||||
|
<div className="space-y-6 animate-fade-up">
|
||||||
|
<Card className="bg-white/60 dark:bg-slate-900/60 backdrop-blur-sm border-slate-200/60 dark:border-slate-800/60">
|
||||||
|
<CardContent className="p-6">
|
||||||
|
<h3 className="font-semibold text-lg mb-4">Main Campus</h3>
|
||||||
|
<div className="space-y-3 text-sm">
|
||||||
|
<div className="flex items-start gap-3"><MapPin className="h-4 w-4 mt-0.5 text-sky-500 flex-shrink-0" /><span>1200 Wellness Boulevard, Suite 100, San Francisco, CA 94102</span></div>
|
||||||
|
<div className="flex items-center gap-3"><Phone className="h-4 w-4 text-sky-500" /><span>(415) 555-0180</span></div>
|
||||||
|
<div className="flex items-center gap-3"><Mail className="h-4 w-4 text-sky-500" /><span>care@vitalitymedical.com</span></div>
|
||||||
|
<div className="flex items-center gap-3"><Clock className="h-4 w-4 text-sky-500" /><span>Mon–Fri 8:00 AM – 6:00 PM, Sat 9:00 AM – 1:00 PM</span></div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="bg-white/60 dark:bg-slate-900/60 backdrop-blur-sm border-slate-200/60 dark:border-slate-800/60">
|
||||||
|
<CardContent className="p-6">
|
||||||
|
<h3 className="font-semibold text-lg mb-4">Satellite Clinic – Marina District</h3>
|
||||||
|
<div className="space-y-3 text-sm">
|
||||||
|
<div className="flex items-start gap-3"><MapPin className="h-4 w-4 mt-0.5 text-sky-500 flex-shrink-0" /><span>3456 Chestnut Street, San Francisco, CA 94123</span></div>
|
||||||
|
<div className="flex items-center gap-3"><Phone className="h-4 w-4 text-sky-500" /><span>(415) 555-0195</span></div>
|
||||||
|
<div className="flex items-center gap-3"><Clock className="h-4 w-4 text-sky-500" /><span>Mon–Fri 9:00 AM – 5:00 PM</span></div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="bg-red-50 dark:bg-red-950/30 border-red-200 dark:border-red-900/50">
|
||||||
|
<CardContent className="p-6">
|
||||||
|
<div className="flex items-center gap-2 text-red-600 dark:text-red-400 font-semibold mb-2">
|
||||||
|
<AlertTriangle className="h-5 w-5" /> Emergency Line
|
||||||
|
</div>
|
||||||
|
<p className="text-2xl font-bold text-red-700 dark:text-red-300">(415) 555-0911</p>
|
||||||
|
<p className="text-sm text-red-500 dark:text-red-400 mt-1">Available 24 hours, 7 days a week</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* MAP PLACEHOLDER */}
|
||||||
|
<div className="aspect-video rounded-xl bg-slate-100 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 flex items-center justify-center">
|
||||||
|
<div className="text-center text-muted-foreground">
|
||||||
|
<MapPin className="h-8 w-8 mx-auto mb-2 opacity-50" />
|
||||||
|
<p className="text-sm">Interactive Map</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* RIGHT: FORM */}
|
||||||
|
<div className="animate-fade-up">
|
||||||
|
<Card className="bg-white/60 dark:bg-slate-900/60 backdrop-blur-sm border-slate-200/60 dark:border-slate-800/60">
|
||||||
|
<CardContent className="p-8">
|
||||||
|
<h3 className="text-xl font-semibold mb-6">Request an Appointment</h3>
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
|
<div className="grid sm:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Full Name</label>
|
||||||
|
<Input name="name" placeholder="John Doe" required className="rounded-lg" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Email</label>
|
||||||
|
<Input name="email" type="email" placeholder="john@example.com" required className="rounded-lg" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid sm:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Phone</label>
|
||||||
|
<Input name="phone" type="tel" placeholder="(415) 555-0000" required className="rounded-lg" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Department</label>
|
||||||
|
<Select>
|
||||||
|
<SelectTrigger className="rounded-lg">
|
||||||
|
<SelectValue placeholder="Select department" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="primary">Primary Care</SelectItem>
|
||||||
|
<SelectItem value="cardiology">Cardiology</SelectItem>
|
||||||
|
<SelectItem value="neurology">Neurology</SelectItem>
|
||||||
|
<SelectItem value="orthopedics">Orthopedics</SelectItem>
|
||||||
|
<SelectItem value="ophthalmology">Ophthalmology</SelectItem>
|
||||||
|
<SelectItem value="pediatrics">Pediatrics</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Preferred Date</label>
|
||||||
|
<Input name="date" type="date" required className="rounded-lg" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium mb-1.5 block">Message</label>
|
||||||
|
<Textarea name="message" placeholder="Tell us about your symptoms or concerns..." rows={4} className="rounded-lg resize-none" />
|
||||||
|
</div>
|
||||||
|
<Button type="submit" disabled={sending} className="w-full bg-sky-500 hover:bg-sky-600 text-white rounded-full shadow-lg shadow-sky-500/20 active:scale-[0.97] transition-all">
|
||||||
|
{sending ? "Submitting..." : (<><Send className="mr-2 h-4 w-4" /> Submit Request</>)}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── FAQ ── */}
|
||||||
|
<section className="py-20 bg-slate-50 dark:bg-slate-950">
|
||||||
|
<div className="mx-auto max-w-3xl px-6">
|
||||||
|
<div className="text-center mb-12 animate-fade-up">
|
||||||
|
<h2 className="text-2xl sm:text-3xl font-bold">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-slate-900 rounded-xl border border-slate-200/60 dark:border-slate-800/60 px-6">
|
||||||
|
<AccordionTrigger className="text-left font-medium hover:no-underline">{f.q}</AccordionTrigger>
|
||||||
|
<AccordionContent className="text-muted-foreground">{f.a}</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user