Dental Care

This commit is contained in:
Iliyan Angelov
2025-11-16 14:29:51 +02:00
commit 39077550ef
194 changed files with 43197 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
import { Button } from "@/components/ui/button";
import Image from "next/image";
interface About3Props {
title?: string;
description?: string;
mainImage?: {
src: string;
alt: string;
};
secondaryImage?: {
src: string;
alt: string;
};
breakout?: {
src: string;
alt: string;
title?: string;
description?: string;
buttonText?: string;
buttonUrl?: string;
};
companiesTitle?: string;
companies?: Array<{
src: string;
alt: string;
}>;
achievementsTitle?: string;
achievementsDescription?: string;
achievements?: Array<{
label: string;
value: string;
}>;
}
const defaultCompanies = [
{
src: "/tooth.svg",
alt: "tooth",
},
];
const defaultAchievements = [
{ label: "Happy Patients", value: "500+" },
{ label: "Appointments Booked", value: "1000+" },
{ label: "Satisfaction Rate", value: "98%" },
{ label: "Expert Dentists", value: "4" },
];
const About = ({
title = "About Dental U Care",
description = "We're a modern dental care provider committed to making quality dental services accessible through our innovative online appointment system. Experience hassle-free booking and world-class dental care.",
mainImage = {
src: "/clinic.jpg",
alt: "Modern dental clinic interior",
},
secondaryImage = {
src: "/team.jpg",
alt: "Professional dental team",
},
breakout = {
src: "/tooth.svg",
alt: "Dental U Care Logo",
title: "Book Your Appointment in Minutes",
description:
"Our easy-to-use online booking system lets you schedule appointments 24/7, choose your preferred dentist, and manage your dental health journey.",
buttonText: "Book Now",
buttonUrl: "patient/book-appointment",
},
companiesTitle = "Trusted Insurance Partners",
companies = defaultCompanies,
achievementsTitle = "Our Impact in Numbers",
achievementsDescription = "Providing quality dental care and making appointments easier for thousands of patients across the Philippines.",
achievements = defaultAchievements,
}: About3Props = {}) => {
return (
<section className="py-32">
<div className="container">
<div className="mb-14 grid gap-5 text-center md:grid-cols-2 md:text-left">
<h1 className="text-5xl font-semibold">{title}</h1>
<p className="text-muted-foreground">{description}</p>
</div>
<div className="grid gap-7 lg:grid-cols-3">
<Image
src={mainImage.src}
alt={mainImage.alt}
className="size-full max-h-[620px] rounded-xl object-cover lg:col-span-2"
width={600}
height={400}
priority
/>
<div className="flex flex-col gap-7 md:flex-row lg:flex-col">
<div className="bg-muted flex flex-col justify-between gap-6 rounded-xl p-7 md:w-1/2 lg:w-auto">
<Image
src={breakout.src}
alt={breakout.alt}
className="mr-auto h-12"
width={48}
height={48}
/>
<div>
<p className="mb-2 text-lg font-semibold">{breakout.title}</p>
<p className="text-muted-foreground">{breakout.description}</p>
</div>
<Button variant="outline" className="mr-auto" asChild>
<a href={breakout.buttonUrl} target="_blank">
{breakout.buttonText}
</a>
</Button>
</div>
<Image
src={secondaryImage.src}
alt={secondaryImage.alt}
className="grow basis-0 rounded-xl object-cover md:w-1/2 lg:min-h-0 lg:w-auto"
width={600}
height={400}
priority
/>
</div>
</div>
<div className="py-32">
<p className="text-center">{companiesTitle} </p>
<div className="mt-8 flex flex-wrap justify-center gap-8">
{companies.map((company, idx) => (
<div className="flex items-center gap-3" key={company.src + idx}>
<Image
src={company.src}
alt={company.alt}
className="h-6 w-auto md:h-8"
width={32}
height={32}
/>
</div>
))}
</div>
</div>
<div className="relative overflow-hidden rounded-xl bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 dark:from-blue-950/30 dark:via-purple-950/30 dark:to-pink-950/30 p-10 md:p-16 shadow-xl">
<div className="flex flex-col gap-4 text-center md:text-left relative z-10">
<h2 className="text-4xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">{achievementsTitle}</h2>
<p className="text-muted-foreground max-w-xl">
{achievementsDescription}
</p>
</div>
<div className="mt-10 flex flex-wrap justify-between gap-10 text-center relative z-10">
{achievements.map((item, idx) => {
const gradients = [
"from-blue-500 to-cyan-500",
"from-purple-500 to-pink-500",
"from-green-500 to-emerald-500",
"from-orange-500 to-red-500",
];
return (
<div className="flex flex-col gap-4 group" key={item.label + idx}>
<p className="font-semibold text-muted-foreground group-hover:text-foreground transition-colors">{item.label}</p>
<span className={`text-4xl font-bold md:text-5xl bg-gradient-to-r ${gradients[idx % gradients.length]} bg-clip-text text-transparent`}>
{item.value}
</span>
</div>
);
})}
</div>
<div className="pointer-events-none absolute -top-1 right-1 z-0 hidden h-full w-full bg-[linear-gradient(to_right,hsl(var(--primary))_1px,transparent_1px),linear-gradient(to_bottom,hsl(var(--primary))_1px,transparent_1px)] bg-[size:80px_80px] opacity-5 [mask-image:linear-gradient(to_bottom_right,#000,transparent,transparent)] md:block"></div>
</div>
</div>
</section>
);
};
export { About };

View File

@@ -0,0 +1,89 @@
import React from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
interface Contact2Props {
title?: string;
description?: string;
phone?: string;
email?: string;
web?: { label: string; url: string };
}
const Contact = ({
title = "Get In Touch",
description = "Have questions about our services or need help with booking? We're here to help! Reach out to us and we'll get back to you as soon as possible.",
phone = "(+63) 917-123-4567",
email = "info@dentalucare.com",
web = { label: "dentalucare.com", url: "https://dentalucare.com" },
}: Contact2Props) => {
return (
<section className="py-32">
<div className="container">
<div className="mx-auto flex max-w-7xl flex-col justify-between gap-10 lg:flex-row lg:gap-20">
<div className="mx-auto flex max-w-sm flex-col justify-between gap-10">
<div className="text-center lg:text-left">
<h1 className="mb-2 text-5xl font-semibold lg:mb-1 lg:text-6xl">
{title}
</h1>
<p className="text-muted-foreground">{description}</p>
</div>
<div className="mx-auto w-fit lg:mx-0">
<h3 className="mb-6 text-center text-2xl font-semibold lg:text-left">
Contact Details
</h3>
<ul className="ml-4 list-disc">
<li>
<span className="font-bold">Phone: </span>
{phone}
</li>
<li>
<span className="font-bold">Email: </span>
<a href={`mailto:${email}`} className="underline">
{email}
</a>
</li>
<li>
<span className="font-bold">Web: </span>
<a href={web.url} target="_blank" className="underline">
{web.label}
</a>
</li>
</ul>
</div>
</div>
<div className="mx-auto flex max-w-3xl flex-col gap-6 rounded-lg border p-10">
<div className="flex gap-4">
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="firstname">First Name</Label>
<Input type="text" id="firstname" placeholder="First Name" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="lastname">Last Name</Label>
<Input type="text" id="lastname" placeholder="Last Name" />
</div>
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input type="email" id="email" placeholder="Email" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="subject">Subject</Label>
<Input type="text" id="subject" placeholder="Subject" />
</div>
<div className="grid w-full gap-1.5">
<Label htmlFor="message">Message</Label>
<Textarea placeholder="Type your message here." id="message" />
</div>
<Button className="w-full">Send Message</Button>
</div>
</div>
</div>
</section>
);
};
export { Contact };

View File

@@ -0,0 +1,133 @@
"use client";
import {
Calendar,
Clock,
CreditCard,
Bell,
UserCheck,
Search,
} from "lucide-react";
import { ShimmeringText } from "@/components/ui/shimmering-text";
const Features = () => {
const services = [
{
icon: <Calendar className="h-6 w-6" />,
title: "Easy Online Booking",
description:
"Book your dental appointment online anytime, anywhere. Choose your preferred date, time slot, and specific dental service with real-time availability.",
items: [
"Real-time Availability",
"Choose Date & Time",
"Service Selection",
],
gradient: "from-indigo-500 to-blue-500",
bgColor: "bg-gradient-to-br from-indigo-50 to-blue-50 dark:from-indigo-950/30 dark:to-blue-950/30",
iconBg: "bg-gradient-to-br from-indigo-500 to-blue-500",
},
{
icon: <UserCheck className="h-6 w-6" />,
title: "Secure Patient Portal",
description:
"Create your secure account with email verification. Manage your profile, medical history, and view all your appointments in one dashboard.",
items: ["Profile Management", "Medical History", "Appointment Overview"],
gradient: "from-teal-500 to-cyan-500",
bgColor: "bg-gradient-to-br from-teal-50 to-cyan-50 dark:from-teal-950/30 dark:to-cyan-950/30",
iconBg: "bg-gradient-to-br from-teal-500 to-cyan-500",
},
{
icon: <Bell className="h-6 w-6" />,
title: "Smart Reminders",
description:
"Never miss an appointment with automatic email and SMS reminders. Stay informed about upcoming visits and important updates.",
items: ["Email Notifications", "SMS Reminders", "Real-time Updates"],
gradient: "from-violet-500 to-purple-500",
bgColor: "bg-gradient-to-br from-violet-50 to-purple-50 dark:from-violet-950/30 dark:to-purple-950/30",
iconBg: "bg-gradient-to-br from-violet-500 to-purple-500",
},
{
icon: <CreditCard className="h-6 w-6" />,
title: "Flexible Payments",
description:
"Pay consultation and booking fees conveniently online via credit card, e-wallet, or bank transfer. Secure and hassle-free transactions.",
items: ["Multiple Payment Methods", "Secure Checkout", "Payment History"],
gradient: "from-emerald-500 to-green-500",
bgColor: "bg-gradient-to-br from-emerald-50 to-green-50 dark:from-emerald-950/30 dark:to-green-950/30",
iconBg: "bg-gradient-to-br from-emerald-500 to-green-500",
},
{
icon: <Clock className="h-6 w-6" />,
title: "Appointment Management",
description:
"Full control over your appointments. View, reschedule, or cancel upcoming visits easily through your patient dashboard.",
items: ["View Appointments", "Reschedule Anytime", "Easy Cancellation"],
gradient: "from-amber-500 to-orange-500",
bgColor: "bg-gradient-to-br from-amber-50 to-orange-50 dark:from-amber-950/30 dark:to-orange-950/30",
iconBg: "bg-gradient-to-br from-amber-500 to-orange-500",
},
{
icon: <Search className="h-6 w-6" />,
title: "Find Your Dentist",
description:
"Search for dentists by specialty or service. View detailed profiles with qualifications, experience, and patient reviews to make informed decisions.",
items: ["Dentist Profiles", "Read Reviews", "Compare Specialists"],
gradient: "from-pink-500 to-rose-500",
bgColor: "bg-gradient-to-br from-pink-50 to-rose-50 dark:from-pink-950/30 dark:to-rose-950/30",
iconBg: "bg-gradient-to-br from-pink-500 to-rose-500",
},
];
return (
<section className="py-32">
<div className="container">
<div className="mx-auto max-w-6xl space-y-12">
<div className="space-y-4 text-center">
<h2 className="text-3xl font-bold tracking-tight md:text-4xl">
<ShimmeringText
text="Features"
className="bg-gradient-to-r from-indigo-600 via-purple-600 to-pink-600 bg-clip-text text-transparent"
shimmeringColor="rgb(147 51 234)"
color="rgb(79 70 229)"
duration={2}
/>
</h2>
<p className="text-muted-foreground mx-auto max-w-2xl text-lg tracking-tight md:text-xl">
Everything you need to manage your dental health journey. Book
appointments, track your history, and connect with top dentists.
</p>
</div>
<div className="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3">
{services.map((service, index) => (
<div
key={index}
className={`${service.bgColor} space-y-6 rounded-xl border p-8 shadow-lg dark:shadow-xl dark:shadow-gray-900/50 transition-shadow duration-300 hover:shadow-2xl dark:hover:shadow-2xl dark:hover:shadow-gray-900/70`}
>
<div className="flex items-center gap-4">
<div className={`${service.iconBg} text-white rounded-full p-3 shadow-lg`}>
{service.icon}
</div>
<h3 className="text-xl font-bold">{service.title}</h3>
</div>
<p className="text-muted-foreground leading-relaxed">
{service.description}
</p>
<div className="space-y-2">
{service.items.map((item, itemIndex) => (
<div key={itemIndex} className="flex items-center gap-2">
<div className={`h-2 w-2 rounded-full bg-gradient-to-r ${service.gradient}`} />
<span className="text-sm font-medium">{item}</span>
</div>
))}
</div>
</div>
))}
</div>
</div>
</div>
</section>
);
};
export { Features };

View File

@@ -0,0 +1,148 @@
import React from "react";
import { FaFacebook, FaInstagram } from "react-icons/fa";
import Image from "next/image";
interface Footer7Props {
logo?: {
url: string;
src: string;
alt: string;
title: string;
};
sections?: Array<{
title: string;
links: Array<{ name: string; href: string }>;
}>;
description?: string;
socialLinks?: Array<{
icon: React.ReactElement;
href: string;
label: string;
}>;
copyright?: string;
legalLinks?: Array<{
name: string;
href: string;
}>;
}
const defaultSections = [
{
title: "Services",
links: [
{ name: "Preventive Care", href: "/services/preventive-care" },
{ name: "Cosmetic Dentistry", href: "/services/cosmetic-dentistry" },
{ name: "Orthodontics", href: "/services/orthodontics" },
{ name: "Pediatric Dentistry", href: "/services/pediatric-dentistry" },
{ name: "Emergency Care", href: "/services/emergency-care" },
],
},
{
title: "Patient Resources",
links: [
{ name: "Book Appointment", href: "/book" },
{ name: "Patient Portal", href: "/dashboard" },
{ name: "Insurance Info", href: "/insurance" },
{ name: "Financing Options", href: "/financing" },
{ name: "New Patient Forms", href: "/forms" },
],
},
{
title: "About Us",
links: [
{ name: "Our Team", href: "/team" },
{ name: "Our Clinic", href: "/clinic" },
{ name: "Contact Us", href: "/contact" },
{ name: "Careers", href: "/careers" },
],
},
];
const defaultSocialLinks = [
{ icon: <FaInstagram className="size-5" />, href: "#", label: "Instagram" },
{ icon: <FaFacebook className="size-5" />, href: "#", label: "Facebook" },
];
const defaultLegalLinks = [
{ name: "Terms and Conditions", href: "/docs/terms-and-conditions" },
{ name: "Privacy Policy", href: "/docs/privacy-policy" },
];
const Footer = ({
logo = {
url: "/",
src: "/tooth.svg",
alt: "Dental U Care Logo",
title: "Dental U Care",
},
sections = defaultSections,
description = "Your trusted online dental appointment system. Book appointments, manage your dental health, and connect with expert dentists - all in one place.",
socialLinks = defaultSocialLinks,
copyright = "© 2025 Dental U Care. All rights reserved.",
legalLinks = defaultLegalLinks,
}: Footer7Props) => {
return (
<section className="py-32">
<div className="container">
<div className="flex w-full flex-col justify-between gap-10 lg:flex-row lg:items-start lg:text-left">
<div className="flex w-full flex-col justify-between gap-6 lg:items-start">
{/* Logo */}
<div className="flex items-center gap-2 lg:justify-start">
<a href={logo.url}>
<Image
src={logo.src}
alt={logo.alt}
title={logo.title}
className="h-8"
width={32}
height={32}
/>
</a>
<h2 className="text-xl font-semibold">{logo.title}</h2>
</div>
<p className="text-muted-foreground max-w-[70%] text-sm">
{description}
</p>
<ul className="text-muted-foreground flex items-center space-x-6">
{socialLinks.map((social, idx) => (
<li key={idx} className="hover:text-primary font-medium">
<a href={social.href} aria-label={social.label}>
{social.icon}
</a>
</li>
))}
</ul>
</div>
<div className="grid w-full gap-6 md:grid-cols-3 lg:gap-20">
{sections.map((section, sectionIdx) => (
<div key={sectionIdx}>
<h3 className="mb-4 font-bold">{section.title}</h3>
<ul className="text-muted-foreground space-y-3 text-sm">
{section.links.map((link, linkIdx) => (
<li
key={linkIdx}
className="hover:text-primary font-medium"
>
<a href={link.href}>{link.name}</a>
</li>
))}
</ul>
</div>
))}
</div>
</div>
<div className="text-muted-foreground mt-8 flex flex-col justify-between gap-4 border-t py-8 text-xs font-medium md:flex-row md:items-center md:text-left">
<p className="order-2 lg:order-1">{copyright}</p>
<ul className="order-1 flex flex-col gap-2 md:order-2 md:flex-row">
{legalLinks.map((link, idx) => (
<li key={idx} className="hover:text-primary font-medium">
<a href={link.href}>{link.name}</a>
</li>
))}
</ul>
</div>
</div>
</section>
);
};
export { Footer };

View File

@@ -0,0 +1,101 @@
import React from "react"
export default function GetStartedGuide() {
return (
<section className="max-w-3xl mx-auto py-10 px-4">
<h1 className="text-3xl font-bold mb-4 text-center">Dental U Care Get Started Guide</h1>
<p className="mb-6 text-center">Welcome to Dental U Care!<br />Were excited to help you on your journey toward better oral health. Heres how to get started as a new patient or team member.</p>
<div className="mb-8">
<h2 className="text-2xl font-semibold mb-2">For Patients</h2>
<ol className="list-decimal list-inside space-y-4">
<li>
<strong>Register or Book Online</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>Visit our website/app and click on Book Appointment or Register as New Patient.</li>
<li>Fill in your details: Name, email, contact number, and medical history.</li>
<li>Choose your preferred date, time, and service (e.g., cleaning, checkup, whitening).</li>
</ul>
</li>
<li>
<strong>Confirmation & Reminders</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>After booking, youll receive a confirmation via email or SMS with your appointment details.</li>
<li>You can reschedule or cancel anytime via the link in your confirmation message.</li>
<li>Well send you reminders 24 hours before your appointment.</li>
</ul>
</li>
<li>
<strong>Before Your Visit</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>Bring a valid ID and your insurance card (if applicable).</li>
<li>Arrive 10 minutes early for check-in and medical history review.</li>
</ul>
</li>
<li>
<strong>On Your Appointment Day</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>Our friendly staff will guide you through your visit.</li>
<li>Feel free to ask about treatment plans or payment options.</li>
</ul>
</li>
<li>
<strong>Aftercare and Follow-Up</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>You may receive aftercare instructions by email or SMS.</li>
<li>Book your next visit directly from our website or app whenever youre ready.</li>
</ul>
</li>
</ol>
</div>
<div className="mb-8">
<h2 className="text-2xl font-semibold mb-2">For Staff</h2>
<ol className="list-decimal list-inside space-y-4">
<li>
<strong>Secure Login</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>Use your assigned credentials to log in to the Dental U Care admin portal.</li>
<li>Update your profile and verify your contact information.</li>
</ul>
</li>
<li>
<strong>Dashboard Overview</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>Access the appointments dashboard to see upcoming bookings.</li>
<li>Use the patient records section to review medical histories or notes.</li>
</ul>
</li>
<li>
<strong>Managing Appointments</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>Confirm, reschedule, or cancel bookings as needed.</li>
<li>Send reminders and follow-up messages to patients with a single click.</li>
</ul>
</li>
<li>
<strong>Treatment Documentation</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>Log treatments, prescribe medicines, and upload documents directly to each patient record.</li>
</ul>
</li>
<li>
<strong>Communication</strong>
<ul className="list-disc list-inside ml-5 mt-1">
<li>Use the messaging tools to answer patient queries or coordinate internally.</li>
</ul>
</li>
</ol>
</div>
<div className="border-t pt-6 mt-8">
<h2 className="text-xl font-semibold mb-2">Need Help?</h2>
<ul className="list-disc list-inside ml-5">
<li>Call our help desk at <span className="font-medium">6-1234-5678</span>, or email <span className="font-medium">support@dentalucare.com</span>.</li>
<li>Visit our FAQ on the website for common questions about appointments, insurance, or care tips.</li>
</ul>
</div>
</section>
)
}

View File

@@ -0,0 +1,97 @@
import { ArrowRight, Calendar} from "lucide-react";
import Image from "next/image";
import { Button } from "@/components/ui/button";
import { ShimmeringText } from "@/components/ui/shimmering-text";
import TypingText from "@/components/ui/typing-text";
import Link from "next/link";
const Hero = () => {
return (
<section>
<div className="container mt-5 ">
<div className="bg-muted/25 grid items-center gap-8 lg:grid-cols-2 border rounded-lg shadow-lg">
<div className="flex flex-col items-center p-16 text-center lg:items-start lg:text-left">
<div className="mb-6 flex items-center gap-3">
<Image
src="/tooth.svg"
alt="Dental U Care Logo"
width={40}
height={40}
className="h-10 w-10"
/>
<ShimmeringText
text="Dental U-Care"
className="text-2xl font-bold"
shimmeringColor="rgb(147 51 234)"
color="rgb(37 99 235)"
duration={2}
/>
</div>
<h1 className="my-6 text-pretty text-4xl font-bold lg:text-6xl min-h-[120px] lg:min-h-[160px] flex items-start">
<TypingText
text={[
"Your Smile, Our Priority",
"Book Appointments Online",
"Smile with Confidence",
"Expert Dental Care for you"
]}
typingSpeed={80}
deletingSpeed={50}
pauseDuration={2000}
loop={true}
showCursor={true}
cursorClassName="bg-primary"
cursorCharacter="|"
className="inline-block"
/>
</h1>
<p className="text-muted-foreground mb-8 max-w-xl lg:text-xl">
Book your dental appointment online in minutes. Choose your
preferred date, time, and service. Real-time availability with
instant confirmation.
</p>
<div className="flex w-full flex-col justify-center gap-2 sm:flex-row lg:justify-start">
<Button size="lg">
<Calendar className="mr-2 h-4 w-4" />
Book Appointment Now
<ArrowRight className="ml-2 h-4 w-4" />
</Button>
<Button variant="outline" size="lg">
<Link href="/get-started" className="flex items-center">
Get Started
</Link>
</Button>
</div>
<div className="mt-8 grid grid-cols-3 gap-6 text-center lg:text-left">
<div>
<p className="text-2xl font-bold">500+</p>
<p className="text-muted-foreground text-xs">Happy Patients</p>
</div>
<div>
<p className="text-2xl font-bold">4</p>
<p className="text-muted-foreground text-xs">Expert Dentists</p>
</div>
<div>
<p className="text-2xl font-bold">98%</p>
<p className="text-muted-foreground text-xs">
Satisfaction Rate
</p>
</div>
</div>
</div>
<div className="relative h-full w-full overflow-hidden rounded-r-lg sm:rounded-lg md:rounded-lg">
<Image
src="/smile.jpg"
alt="Professional dental care at Dental U Care"
width={600}
height={500}
priority
className="h-full w-full object-cover dark:brightness-75"
/>
</div>
</div>
</div>
</section>
);
};
export { Hero };

View File

@@ -0,0 +1,31 @@
"use client";
import { Navbar } from "./navbar";
import { useEffect, useState } from "react";
export function NavbarWrapper() {
const [user, setUser] = useState(null);
const [isUserAdmin, setIsUserAdmin] = useState(false);
useEffect(() => {
async function fetchUser() {
try {
const res = await fetch("/api/auth/session");
if (res.ok) {
const session = await res.json();
setUser(session.user);
setIsUserAdmin(session.user?.role === "admin");
} else {
setUser(null);
setIsUserAdmin(false);
}
} catch (error) {
console.error("NavbarWrapper: Error fetching session", error);
setUser(null);
setIsUserAdmin(false);
}
}
fetchUser();
}, []);
return <Navbar user={user} isAdmin={isUserAdmin} />;
}

View File

@@ -0,0 +1,651 @@
"use client";
import { MenuIcon, SearchIcon, LogOut, User, Shield } from "lucide-react";
import Link from "next/link";
import { useState, useEffect, useRef } from "react";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
DialogClose,
} from "@/components/ui/dialog";
import Image from "next/image";
import { authClient } from "@/lib/auth-session/auth-client";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
import { Button } from "@/components/ui/button";
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
} from "@/components/ui/navigation-menu";
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
} from "@/components/ui/input-group";
import { ModeToggle } from "../ui/mode-toggle";
import { cn } from "@/lib/utils";
type User = {
id: string;
name: string;
email: string;
image?: string | null;
role?: string;
} | null;
type NavbarProps = {
user?: User;
isAdmin?: boolean;
};
const Navbar = ({ user, isAdmin: userIsAdmin }: NavbarProps) => {
const [isScrolled, setIsScrolled] = useState(false);
const router = useRouter();
useEffect(() => {
let ticking = false;
const handleScroll = () => {
if (!ticking) {
window.requestAnimationFrame(() => {
setIsScrolled(window.scrollY > 50);
ticking = false;
});
ticking = true;
}
};
window.addEventListener("scroll", handleScroll, { passive: true });
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const [showLogoutDialog, setShowLogoutDialog] = useState(false);
const [showRequiredDialog, setShowRequiredDialog] = useState(false);
const [searchValue, setSearchValue] = useState("");
const [showSuggestions, setShowSuggestions] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const handleSignOut = async () => {
setShowLogoutDialog(false);
try {
await authClient.signOut();
toast.success("Signed out successfully");
router.push("/sign-in");
router.refresh();
} catch {
toast.error("Failed to sign out");
}
};
// Handle search submit
const handleSearch = (e?: React.FormEvent) => {
if (e) e.preventDefault();
if (searchValue.trim()) {
router.push(`/search?query=${encodeURIComponent(searchValue.trim())}`);
}
};
const getInitials = (name: string) => {
return name
.split(" ")
.map((n) => n[0])
.join("")
.toUpperCase()
.slice(0, 2);
};
const Services = [
{
title: "Preventive Care",
description:
"Cleanings, exams, and routine check-ups to keep smiles healthy",
href: "/services/preventive-care",
},
{
title: "Cosmetic Dentistry",
description: "Teeth whitening, veneers, and smile makeovers",
href: "/services/cosmetic-dentistry",
},
{
title: "Orthodontics",
description: "Braces and clear aligners for children and adults",
href: "/services/orthodontics",
},
{
title: "Pediatric Dentistry",
description: "Gentle, kid-friendly dental care for your little ones",
href: "/services/pediatric-dentistry",
},
{
title: "Emergency Care",
description:
"Same-day treatment for tooth pain, injuries, and urgent issues",
href: "/services/emergency-care",
},
{
title: "Patient Resources",
description: "New patient forms, insurance info, and financing options",
href: "/patient-resources",
},
];
// Filtered suggestions based on searchValue
const suggestions =
searchValue.trim().length > 0
? Services.filter(
(s) =>
s.title.toLowerCase().includes(searchValue.toLowerCase()) ||
s.description.toLowerCase().includes(searchValue.toLowerCase())
)
: [];
const aboutItems = [
{
title: "Our Story",
description: "Learn about Dental U Care's mission and values",
href: "/#about",
},
{
title: "Our Team",
description: "Meet our expert dental professionals",
href: "/#team",
},
{
title: "Features",
description: "Discover our online booking system features",
href: "/#features",
},
{
title: "Pricing",
description: "Transparent pricing for all dental services",
href: "/#pricing",
},
];
return (
<section className="sticky top-0 z-50 py-2">
<div
className={cn(
"container transition-all duration-300",
isScrolled && "px-6 lg:px-12"
)}
>
<nav
className={cn(
"flex items-center justify-between rounded-full px-6 py-6 transition-all duration-300 ",
isScrolled
? "border-2 border-accent dark:border-gray-900 bg-background/80 shadow-lg"
: "border-2 border-accent dark:border-gray-800 bg-background/80 shadow-lg"
)}
>
<Link href="/" className="flex items-center gap-2">
<Image
src="/tooth.svg"
alt="Dental U Care"
width={32}
height={32}
className="h-8 w-8"
/>
<span className="text-2xl font-semibold bg-gradient-to-r from-blue-600 to-blue-800 text-transparent bg-clip-text tracking-tighter">
Dental U Care
</span>
</Link>
<NavigationMenu className="hidden lg:block">
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger className="bg-transparent hover:bg-transparent focus:bg-transparent data-[active]:bg-transparent data-[state=open]:bg-transparent">
About
</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid w-[500px] grid-cols-2 p-3">
{aboutItems.map((item, index) => (
<NavigationMenuLink
href={item.href}
key={index}
className="rounded-md p-3 transition-colors"
>
<div key={item.title}>
<p className="text-foreground mb-1 font-semibold">
{item.title}
</p>
<p className="text-muted-foreground text-sm">
{item.description}
</p>
</div>
</NavigationMenuLink>
))}
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger className="bg-transparent hover:bg-transparent focus:bg-transparent data-[active]:bg-transparent data-[state=open]:bg-transparent">
Services
</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid w-[600px] grid-cols-2 p-3">
{Services.map((service, index) => (
<NavigationMenuLink
href={service.href}
key={index}
className="rounded-md p-3 transition-colors"
>
<div key={service.title}>
<p className="text-foreground mb-1 font-semibold">
{service.title}
</p>
<p className="text-muted-foreground text-sm">
{service.description}
</p>
</div>
</NavigationMenuLink>
))}
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink
href="/#pricing"
className="group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-all hover:text-accent-foreground hover:border-b-2 hover:border-primary focus:outline-none disabled:pointer-events-none disabled:opacity-50"
>
Pricing
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink
href="/#contact"
className="group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-all hover:text-accent-foreground hover:border-b-2 hover:border-primary focus:outline-none disabled:pointer-events-none disabled:opacity-50"
>
Contact
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
<div className="hidden items-center gap-4 lg:flex">
<div className="relative">
<form onSubmit={handleSearch} className="contents">
<InputGroup
className={cn(
"w-64 transition-all duration-300 border border-gray-300 hover:border-primary hover:shadow-sm dark:border-gray-700 dark:hover:border-primary rounded-md",
isScrolled && "w-58"
)}
>
<InputGroupInput
ref={inputRef}
placeholder="Search services..."
className="border-0 focus-visible:ring-0"
value={searchValue}
onChange={(e) => {
setSearchValue(e.target.value);
setShowSuggestions(true);
}}
onFocus={() => setShowSuggestions(true)}
onBlur={() =>
setTimeout(() => setShowSuggestions(false), 100)
}
onKeyDown={(e) => {
if (e.key === "Enter") handleSearch();
}}
aria-label="Search services"
autoComplete="off"
/>
<InputGroupAddon>
<SearchIcon className="h-4 w-4" />
</InputGroupAddon>
<InputGroupAddon align="inline-end">
<InputGroupButton size="sm" type="submit">
Search
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
{showSuggestions && suggestions.length > 0 && (
<ul className="absolute left-0 z-50 mt-1 w-full bg-background border border-gray-200 dark:border-gray-700 rounded-md shadow-lg max-h-56 overflow-auto">
{suggestions.map((s) => (
<li
key={s.title}
className="px-4 py-2 cursor-pointer hover:bg-accent"
onMouseDown={() => {
setShowSuggestions(false);
setSearchValue("");
router.push(s.href);
}}
>
<span className="font-semibold">{s.title}</span>
<span className="block text-xs text-muted-foreground">
{s.description}
</span>
</li>
))}
</ul>
)}
</form>
</div>
<ModeToggle />
{user ? (
<>
<Button
className={cn(isScrolled ? "hidden" : "lg:inline-flex")}
asChild
>
<Link href="/patient/book-appointment">Book Now</Link>
</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="outline"
size="icon"
className="rounded-full"
>
<Avatar className="h-8 w-8">
<AvatarImage
src={user.image || undefined}
alt={user.name}
/>
<AvatarFallback>
{getInitials(user.name)}
</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56">
<DropdownMenuLabel>
<div className="flex flex-col space-y-1">
<p className="text-sm font-medium leading-none">
{user.name}
</p>
<p className="text-xs leading-none text-muted-foreground">
{user.email}
</p>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
{userIsAdmin && (
<>
<DropdownMenuItem asChild>
<Link href="/admin" className="cursor-pointer">
<Shield className="mr-2 h-4 w-4" />
<span>Dashboard</span>
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
{user?.role === "dentist" && (
<>
<DropdownMenuItem asChild>
<Link href="/dentist" className="cursor-pointer">
<User className="mr-2 h-4 w-4" />
<span>Dashboard</span>
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
{user?.role === "patient" && (
<>
<DropdownMenuItem asChild>
<Link href="/patient" className="cursor-pointer">
<User className="mr-2 h-4 w-4" />
<span>Dashboard</span>
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
<DropdownMenuItem
onClick={() => setShowLogoutDialog(true)}
className="cursor-pointer text-red-600"
>
<LogOut className="mr-2 h-4 w-4" />
<span>Sign Out</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</>
) : (
<>
<Button
variant="outline"
className={cn(isScrolled ? "hidden" : "lg:inline-flex")}
>
<Link href="/sign-in">Sign In</Link>
</Button>
<Button
className={cn(isScrolled ? "hidden" : "lg:inline-flex")}
onClick={() => setShowRequiredDialog(true)}
>
Book Now
</Button>
</>
)}
</div>
<Sheet>
<SheetTrigger asChild className="lg:hidden">
<Button variant="outline" size="icon">
<MenuIcon className="h-4 w-4" />
</Button>
</SheetTrigger>
<SheetContent side="top" className="max-h-screen overflow-auto">
<SheetHeader>
<SheetTitle>
<a href="#" className="flex items-center gap-2">
<Image
src="/tooth.svg"
alt="Dental U Care"
width={32}
height={32}
className="h-8 w-8"
/>
<span className="text-lg font-semibold tracking-tighter">
Dental U Care
</span>
</a>
</SheetTitle>
</SheetHeader>
<div className="flex flex-col p-4">
<Accordion type="single" collapsible className="mb-2 mt-4">
<AccordionItem value="about" className="border-none">
<AccordionTrigger className="text-base hover:no-underline">
About
</AccordionTrigger>
<AccordionContent>
<div className="grid gap-2">
{aboutItems.map((item, index) => (
<a
href={item.href}
key={index}
className="rounded-md p-3 transition-colors"
>
<div key={item.title}>
<p className="text-foreground mb-1 font-semibold">
{item.title}
</p>
<p className="text-muted-foreground text-sm">
{item.description}
</p>
</div>
</a>
))}
</div>
</AccordionContent>
</AccordionItem>
<AccordionItem value="solutions" className="border-none">
<AccordionTrigger className="text-base hover:no-underline">
Services
</AccordionTrigger>
<AccordionContent>
<div className="grid md:grid-cols-2">
{Services.map((service, index) => (
<a
href={service.href}
key={index}
className="rounded-md p-3 transition-colors"
>
<div key={service.title}>
<p className="text-foreground mb-1 font-semibold">
{service.title}
</p>
<p className="text-muted-foreground text-sm">
{service.description}
</p>
</div>
</a>
))}
</div>
</AccordionContent>
</AccordionItem>
</Accordion>
<div className="flex flex-col gap-6">
<Link href="/#contact" className="font-medium">
Contact
</Link>
</div>
<div className="mt-6 flex flex-col gap-4">
{user ? (
<>
<div className="flex items-center gap-3 rounded-lg border p-4">
<Avatar className="h-10 w-10">
<AvatarImage
src={user.image || undefined}
alt={user.name}
/>
<AvatarFallback>
{getInitials(user.name)}
</AvatarFallback>
</Avatar>
<div className="flex flex-col">
<p className="text-sm font-medium leading-none">
{user.name}
</p>
<p className="text-xs leading-none text-muted-foreground mt-1">
{user.email}
</p>
</div>
</div>
<Button asChild>
<Link href="/patient/book-appointment">Book Now</Link>
</Button>
{userIsAdmin && (
<Button variant="outline" asChild>
<Link href="/admin">
<Shield className="mr-2 h-4 w-4" />
Admin Dashboard
</Link>
</Button>
)}
{user?.role === "dentist" && (
<Button variant="outline" asChild>
<Link href="/dentist">
<User className="mr-2 h-4 w-4" />
Dentist Dashboard
</Link>
</Button>
)}
{user?.role === "patient" && (
<Button variant="outline" asChild>
<Link href="/patient">
<User className="mr-2 h-4 w-4" />
Dashboard
</Link>
</Button>
)}
<Button
variant="destructive"
onClick={() => setShowLogoutDialog(true)}
>
<LogOut className="mr-2 h-4 w-4" />
Sign Out
</Button>
</>
) : (
<>
<Button variant="outline">
<Link href="/sign-in">Sign in</Link>
</Button>
<Button onClick={() => setShowRequiredDialog(true)}>
Book Now
</Button>
</>
)}
</div>
</div>
</SheetContent>
</Sheet>
</nav>
</div>
<Dialog open={showLogoutDialog} onOpenChange={setShowLogoutDialog}>
<DialogContent>
<DialogHeader>
<DialogTitle>Log out</DialogTitle>
<DialogDescription>
Are you sure you want to log out?
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button variant="destructive" onClick={handleSignOut}>
Log out
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<Dialog open={showRequiredDialog} onOpenChange={setShowRequiredDialog}>
<DialogContent>
<DialogHeader>
<DialogTitle>Sign in required</DialogTitle>
<DialogDescription>
You need to sign in to book an appointment. Would you like to sign
in now?
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button
onClick={() => {
setShowRequiredDialog(false);
router.push("/sign-in");
}}
>
Sign in
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</section>
);
};
export { Navbar };

View File

@@ -0,0 +1,286 @@
"use client";
import { Check } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import Link from "next/link";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
interface Service {
name: string;
price: string;
description?: string;
}
interface ServiceCategory {
id: string;
title: string;
badge: string;
services: Service[];
}
import React, { useState } from "react";
const Pricing = () => {
const [showRequiredDialog, setShowRequiredDialog] = useState(false);
const serviceCategories: ServiceCategory[] = [
{
id: "basic",
title: "Basic Services",
badge: "Essential",
services: [
{
name: "Dental Consultation / Checkup",
price: "₱500 ₱1,500",
description: "Basic dental examination to check overall condition of teeth and gums",
},
{
name: "Oral Prophylaxis (Cleaning)",
price: "₱1,200 ₱3,000",
description: "Regular teeth cleaning, recommended every 6 months",
},
{
name: "Tooth X-Ray",
price: "₱700 ₱2,500+",
description: "Depends on type (periapical, panoramic, etc.)",
},
{
name: "Simple Tooth Extraction",
price: "₱1,500 ₱5,000",
description: "Basic tooth extraction procedure",
},
{
name: "Deep Cleaning / Scaling and Root Planing",
price: "₱3,000 ₱10,000+",
description: "For early signs of gum disease, deeper cleaning procedure",
},
],
},
{
id: "fillings",
title: "Dental Fillings",
badge: "Restorative",
services: [
{
name: "Amalgam Filling (Silver)",
price: "₱800 ₱2,500",
description: "Traditional silver-colored filling material",
},
{
name: "Composite Filling (Tooth-colored)",
price: "₱1,500 ₱4,500+",
description: "Natural-looking tooth-colored filling",
},
{
name: "Ceramic/Gold Filling",
price: "₱5,000 ₱15,000+",
description: "Premium filling materials for durability",
},
],
},
{
id: "advanced",
title: "Advanced Treatments",
badge: "Popular",
services: [
{
name: "Surgical/Impacted Tooth Extraction",
price: "₱10,000 ₱30,000+",
description: "Complex extraction for impacted teeth",
},
{
name: "Root Canal Treatment",
price: "₱5,000 ₱20,000+",
description: "Treatment for infected tooth pulp, cleaned and sealed",
},
{
name: "Dental Crowns (Basic - Metal or PFM)",
price: "₱8,000 ₱20,000+",
description: "Cap for damaged tooth, metal or porcelain-fused-to-metal",
},
{
name: "Dental Crowns (Premium - Zirconia, Emax)",
price: "₱30,000 ₱45,000+",
description: "High-quality aesthetic crowns",
},
{
name: "Teeth Whitening (Bleaching)",
price: "₱9,000 ₱30,000+",
description: "Laser or in-clinic whitening procedure",
},
],
},
{
id: "replacement",
title: "Tooth Replacement",
badge: "Restoration",
services: [
{
name: "Partial Denture",
price: "₱10,000 ₱30,000+",
description: "Removable denture for missing teeth",
},
{
name: "Full Denture",
price: "Contact for pricing",
description: "Complete denture set, depends on number of teeth",
},
{
name: "Dental Bridges",
price: "₱20,000 ₱60,000+",
description: "Replacement of missing teeth using adjacent teeth",
},
{
name: "Dental Implants",
price: "₱80,000 ₱150,000+",
description: "Permanent tooth replacement using titanium post + crown",
},
],
},
{
id: "cosmetic",
title: "Cosmetic & Orthodontics",
badge: "Premium",
services: [
{
name: "Dental Veneers",
price: "₱12,000 ₱35,000+ per tooth",
description: "For aesthetic purposes - straight, white, beautiful teeth",
},
{
name: "Traditional Metal Braces",
price: "₱35,000 ₱80,000+",
description: "Classic metal braces for teeth alignment",
},
{
name: "Ceramic / Clear Braces",
price: "₱100,000 ₱200,000+",
description: "Aesthetic clear or tooth-colored braces",
},
],
},
];
return (
<section className="py-32 ml-10">
<div className="container">
<div className="mx-auto flex max-w-7xl flex-col gap-8">
<div className="text-center space-y-4">
<h2 className="text-pretty text-4xl font-bold lg:text-6xl">
Dental Services & Pricing
</h2>
<p className="text-muted-foreground max-w-3xl mx-auto lg:text-xl">
Transparent pricing for all your dental needs. Quality dental care at competitive rates.
</p>
</div>
<Tabs defaultValue="basic" className="w-full">
<TabsList className="grid w-full grid-cols-2 lg:grid-cols-5 h-auto gap-2">
{serviceCategories.map((category) => (
<TabsTrigger
key={category.id}
value={category.id}
className="text-sm sm:text-base"
>
{category.title}
</TabsTrigger>
))}
</TabsList>
{serviceCategories.map((category) => (
<TabsContent
key={category.id}
value={category.id}
className="mt-8 animate-in fade-in-50 slide-in-from-bottom-4 duration-500"
>
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<CardTitle className="text-2xl lg:text-3xl">{category.title}</CardTitle>
<Badge className="uppercase">{category.badge}</Badge>
</div>
<CardDescription>
Professional dental services with transparent pricing
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
{category.services.map((service, index) => (
<div
key={index}
className="flex flex-col sm:flex-row sm:items-center justify-between p-4 rounded-lg border hover:border-primary transition-all duration-300 hover:shadow-md gap-2 animate-in fade-in-50 slide-in-from-left-4"
style={{ animationDelay: `${index * 100}ms` }}
>
<div className="flex-1">
<div className="flex items-start gap-2">
<Check className="size-5 text-primary mt-1 shrink-0" />
<div>
<h3 className="font-semibold text-lg">{service.name}</h3>
{service.description && (
<p className="text-muted-foreground text-sm mt-1">
{service.description}
</p>
)}
</div>
</div>
</div>
<div className="text-right sm:text-left sm:ml-4">
<span className="text-xl font-bold text-primary whitespace-nowrap">
{service.price}
</span>
</div>
</div>
))}
</div>
<div className="mt-6 flex justify-center animate-in fade-in-50 zoom-in-95 duration-500 delay-300">
<Button
size="lg"
className="w-full sm:w-auto"
onClick={() => setShowRequiredDialog(true)}
>
<Link href="patient/book-appointment" className="flex items-center">
Book Appointment
</Link>
</Button>
</div>
</CardContent>
</Card>
</TabsContent>
))}
</Tabs>
</div>
</div>
<Dialog open={showRequiredDialog} onOpenChange={setShowRequiredDialog}>
<DialogContent>
<DialogHeader>
<DialogTitle>Required To Sign In & Sign Up</DialogTitle>
<DialogDescription>
Please sign in or sign up to access this content.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline"><Link href="/sign-in">Sign In</Link></Button>
</DialogClose>
<Button variant="default">
<Link href="/sign-up">Sign Up</Link>
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</section>
);
};
export { Pricing };

View File

@@ -0,0 +1,83 @@
import React from "react";
export default function PrivacyPolicy() {
return (
<section className="max-w-3xl mx-auto py-10 px-4 text-gray-800">
<h1 className="text-3xl font-bold mb-4 text-center">Privacy Policy</h1>
<h2 className="text-xl font-semibold mb-2 text-center">Dental U Care</h2>
<p className="mb-6 text-center">
Dental U Care values your privacy and is committed to protecting your personal information. This Privacy Policy explains how we collect, use, store, and protect your data when you visit our clinic, website, or contact us through any communication channel.
</p>
<ol className="list-decimal pl-6 space-y-4">
<li>
<strong>Information We Collect</strong><br />
We collect the following types of information to deliver quality dental care and manage our services effectively:<br />
<ul className="list-disc pl-6">
<li>Personal Information: Name, address, contact number, email, and date of birth.</li>
<li>Medical and Dental Information: Health history, dental records, X-rays, treatment notes, and insurance details.</li>
<li>Payment Information: Billing addresses, payment records, and insurance claim details.</li>
<li>Digital Information: Information from your visits to our website, including cookies, browser type, and access time (if applicable).</li>
</ul>
</li>
<li>
<strong>How We Use Your Information</strong><br />
Your information is used solely for legitimate purposes related to your treatment and clinic operations:<br />
<ul className="list-disc pl-6">
<li>To provide dental diagnosis, care, and follow-up services.</li>
<li>To maintain accurate internal records and manage appointments.</li>
<li>To process billing, payments, and insurance claims.</li>
<li>To communicate important updates, reminders, and follow-up instructions.</li>
<li>To improve the quality and safety of our services.</li>
<li>To comply with local laws, regulations, or legal obligations.</li>
</ul>
</li>
<li>
<strong>Data Protection and Security</strong><br />
We implement security measures to protect your personal and health information from unauthorized access, misuse, or disclosure.<br />
Patient records are stored securely in electronic or physical form and accessed only by authorized personnel.<br />
Access to data is strictly limited to staff members who require it for care delivery or administrative purposes.
</li>
<li>
<strong>Information Sharing</strong><br />
Dental U Care respects the confidentiality of your information. We do not sell or rent patient data. Information may be shared only:<br />
<ul className="list-disc pl-6">
<li>With authorized healthcare professionals involved in your care.</li>
<li>With insurance providers for claim processing.</li>
<li>With laboratories or specialists when necessary for your treatment.</li>
<li>As required by law, such as health or regulatory reporting.</li>
</ul>
</li>
<li>
<strong>Retention of Records</strong><br />
Patient records are retained for as long as required by Philippine law or professional standards. Once retention periods expire, records are securely disposed of.
</li>
<li>
<strong>Your Rights</strong><br />
You have the right to:
<ul className="list-disc pl-6">
<li>Access and review your dental records.</li>
<li>Request correction of inaccurate or incomplete data.</li>
<li>Withdraw consent for certain uses, subject to legal and contractual limitations.</li>
<li>File a privacy-related complaint with the clinic management.</li>
</ul>
</li>
<li>
<strong>Cookies and Website Data (if applicable)</strong><br />
If you use our website, cookies may be used to enhance your browsing experience. You can disable cookies through your browser settings, but some features may not function properly.
</li>
<li>
<strong>Policy Updates</strong><br />
Dental U Care may update this Privacy Policy from time to time to comply with updated legal requirements or improve data management. Revisions will take effect immediately upon posting.
</li>
<li>
<strong>Contact Information</strong><br />
For questions, requests, or concerns regarding this Privacy Policy, please contact:<br />
Dental U Care<br />
Address: <span className="italic">[Baltan Street, Puerto Princesa City, Palawan]</span><br />
Phone: <span className="italic">[63+ 1234 5678]</span><br />
Email: <span className="italic">[info@dentalucare.com]</span>
</li>
</ol>
</section>
);
}

View File

@@ -0,0 +1,132 @@
"use client";
import {
Stethoscope,
Sparkles,
Brackets,
Drill,
Baby,
ShieldAlert,
} from "lucide-react";
import { ShimmeringText } from "@/components/ui/shimmering-text";
const Services = () => {
const services = [
{
icon: <Stethoscope className="h-6 w-6" />,
title: "General Dentistry",
description:
"Comprehensive oral health care including routine checkups, professional cleanings, and preventive treatments to maintain your dental health.",
items: [
"Routine Checkups",
"Professional Cleaning",
"Cavity Fillings",
],
gradient: "from-blue-500 to-cyan-500",
bgColor: "bg-gradient-to-br from-blue-50 to-cyan-50 dark:from-blue-950/30 dark:to-cyan-950/30",
iconBg: "bg-gradient-to-br from-blue-500 to-cyan-500",
},
{
icon: <Sparkles className="h-6 w-6" />,
title: "Cosmetic Dentistry",
description:
"Transform your smile with our advanced cosmetic procedures. From teeth whitening to complete smile makeovers, we help you achieve the perfect smile.",
items: ["Teeth Whitening", "Veneers", "Smile Makeover"],
gradient: "from-purple-500 to-pink-500",
bgColor: "bg-gradient-to-br from-purple-50 to-pink-50 dark:from-purple-950/30 dark:to-pink-950/30",
iconBg: "bg-gradient-to-br from-purple-500 to-pink-500",
},
{
icon: <Brackets className="h-6 w-6" />,
title: "Orthodontics",
description:
"Straighten your teeth and correct bite issues with traditional braces or modern clear aligners for both children and adults.",
items: ["Traditional Braces", "Clear Aligners", "Retainers"],
gradient: "from-green-500 to-emerald-500",
bgColor: "bg-gradient-to-br from-green-50 to-emerald-50 dark:from-green-950/30 dark:to-emerald-950/30",
iconBg: "bg-gradient-to-br from-green-500 to-emerald-500",
},
{
icon: <Drill className="h-6 w-6" />,
title: "Restorative Care",
description:
"Restore damaged or missing teeth with dental implants, crowns, bridges, and root canal therapy using advanced techniques.",
items: ["Dental Implants", "Crowns & Bridges", "Root Canal Therapy"],
gradient: "from-orange-500 to-red-500",
bgColor: "bg-gradient-to-br from-orange-50 to-red-50 dark:from-orange-950/30 dark:to-red-950/30",
iconBg: "bg-gradient-to-br from-orange-500 to-red-500",
},
{
icon: <Baby className="h-6 w-6" />,
title: "Pediatric Dentistry",
description:
"Gentle, kid-friendly dental care designed to make children feel comfortable and establish healthy oral hygiene habits from an early age.",
items: ["Children's Checkups", "Fluoride Treatment", "Sealants"],
gradient: "from-yellow-500 to-amber-500",
bgColor: "bg-gradient-to-br from-yellow-50 to-amber-50 dark:from-yellow-950/30 dark:to-amber-950/30",
iconBg: "bg-gradient-to-br from-yellow-500 to-amber-500",
},
{
icon: <ShieldAlert className="h-6 w-6" />,
title: "Emergency Dental Care",
description:
"Same-day emergency services for dental injuries, severe toothaches, broken teeth, and other urgent dental issues.",
items: ["Tooth Pain Relief", "Broken Tooth Repair", "Same-Day Treatment"],
gradient: "from-rose-500 to-red-600",
bgColor: "bg-gradient-to-br from-rose-50 to-red-50 dark:from-rose-950/30 dark:to-red-950/30",
iconBg: "bg-gradient-to-br from-rose-500 to-red-600",
},
];
return (
<section className="py-32">
<div className="container">
<div className="mx-auto max-w-6xl space-y-12">
<div className="space-y-4 text-center">
<h2 className="text-3xl font-bold tracking-tight md:text-4xl">
<ShimmeringText
text="Our Dental Services"
className="bg-gradient-to-r from-blue-600 via-purple-600 to-pink-600 bg-clip-text text-transparent"
shimmeringColor="rgb(236 72 153)"
color="rgb(37 99 235)"
duration={2}
/>
</h2>
<p className="text-muted-foreground mx-auto max-w-2xl text-lg tracking-tight md:text-xl">
Comprehensive dental care tailored to your needs. From preventive treatments to advanced procedures, we provide exceptional care for the whole family.
</p>
</div>
<div className="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3">
{services.map((service, index) => (
<div
key={index}
className={`${service.bgColor} space-y-6 rounded-xl border p-8 shadow-lg dark:shadow-xl dark:shadow-gray-900/50 transition-shadow duration-300 hover:shadow-2xl dark:hover:shadow-2xl dark:hover:shadow-gray-900/70`}
>
<div className="flex items-center gap-4">
<div className={`${service.iconBg} text-white rounded-full p-3 shadow-lg`}>
{service.icon}
</div>
<h3 className="text-xl font-bold">{service.title}</h3>
</div>
<p className="text-muted-foreground leading-relaxed">
{service.description}
</p>
<div className="space-y-2">
{service.items.map((item, itemIndex) => (
<div key={itemIndex} className="flex items-center gap-2">
<div className={`h-2 w-2 rounded-full bg-gradient-to-r ${service.gradient}`} />
<span className="text-sm font-medium">{item}</span>
</div>
))}
</div>
</div>
))}
</div>
</div>
</div>
</section>
);
};
export { Services };

129
components/landing/team.tsx Normal file
View File

@@ -0,0 +1,129 @@
import { Github, Linkedin, Twitter } from "lucide-react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
interface TeamMember {
id: string;
name: string;
role: string;
avatar: string;
github?: string;
twitter?: string;
linkedin?: string;
}
interface Team1Props {
heading?: string;
subheading?: string;
description?: string;
members?: TeamMember[];
}
const Team = ({
heading = "Meet Our Expert Dental Team",
description = "Our team of highly qualified dentists and specialists are dedicated to providing you with exceptional dental care. Each brings years of experience and a passion for creating healthy, beautiful smiles.",
members = [
{
id: "member-1",
name: "Kath Estrada",
role: "Chief Dentist & Orthodontist",
avatar:
"/kath.jpg",
},
{
id: "member-2",
name: "Clyrelle Jade Cervantes",
role: "Cosmetic Dentistry Specialist",
avatar:
" /cervs.jpg",
},
{
id: "member-3",
name: "Von Vryan Arguelles",
role: "Oral Surgeon",
avatar:
"/von.jpg",
},
{
id: "member-4",
name: "Dexter Cabanag",
role: "Periodontist",
avatar:
"/dexter.jpg",
},
],
}: Team1Props) => {
return (
<section className="py-24 lg:py-32">
<div className="container mx-auto px-4">
<div className="mb-16 text-center">
<h2 className="mb-6 text-3xl font-bold tracking-tight lg:text-5xl">
{heading}
</h2>
<p className="text-muted-foreground mx-auto max-w-2xl text-lg leading-relaxed">
{description}
</p>
</div>
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3 [&>*:last-child:nth-child(3n-2)]:col-start-2">
{members.map((member) => (
<div
key={member.id}
className="border rounded-lg p-6 hover:shadow-lg transition-shadow"
>
<div className="flex flex-col items-center text-center">
<div className="mb-4">
<Avatar className="size-20 lg:size-24">
<AvatarImage src={member.avatar} />
<AvatarFallback className="text-lg font-semibold">
{member.name}
</AvatarFallback>
</Avatar>
</div>
<div className="mb-6">
<h3 className="mb-1 text-lg font-semibold">{member.name}</h3>
<p className="text-primary text-sm font-medium">
{member.role}
</p>
</div>
<div className="flex gap-3">
{member.github && (
<a
href={member.github}
className="bg-muted/50 rounded-lg p-2"
>
<Github className="text-muted-foreground size-4" />
</a>
)}
{member.twitter && (
<a
href={member.twitter}
className="bg-muted/50 rounded-lg p-2"
>
<Twitter className="text-muted-foreground size-4" />
</a>
)}
{member.linkedin && (
<a
href={member.linkedin}
className="bg-muted/50 rounded-lg p-2"
>
<Linkedin className="text-muted-foreground size-4" />
</a>
)}
</div>
</div>
</div>
))}
</div>
</div>
</section>
);
};
export { Team };

View File

@@ -0,0 +1,78 @@
import React from "react";
export default function TermsAndConditions() {
return (
<section className="max-w-3xl mx-auto py-10 px-4 text-gray-800">
<h1 className="text-3xl font-bold mb-4 text-center">Terms and Conditions</h1>
<h2 className="text-xl font-semibold mb-2 text-center">Dental U Care</h2>
<p className="mb-6 text-center">
Welcome to Dental U Care. By accessing our website, booking an appointment, or receiving services at our clinic, you agree to the following Terms and Conditions. Please read them carefully before engaging with our services.
</p>
<ol className="list-decimal pl-6 space-y-4">
<li>
<strong>General Terms</strong><br />
Dental U Care provides dental healthcare services in accordance with professional and ethical standards.<br />
These Terms apply to all patients, clients, and users who interact with our clinic, whether in person, by phone, or online.<br />
We reserve the right to update these Terms at any time. Any changes will be posted on our premises or website.
</li>
<li>
<strong>Appointments and Cancellations</strong><br />
Appointments can be booked via phone, online, or in person.<br />
Please arrive at least 10 minutes before your scheduled time.<br />
Appointment cancellations must be made at least 24 hours in advance. Late cancellations or missed appointments may result in a cancellation fee.
</li>
<li>
<strong>Payments and Billing</strong><br />
Fees for dental services are determined based on the procedure and disclosed prior to treatment whenever possible.<br />
Payment is required at the time of service unless otherwise arranged.<br />
We accept cash, major credit/debit cards, and approved insurance.<br />
Any additional laboratory or specialist fees will be discussed before proceeding.
</li>
<li>
<strong>Insurance and Claims</strong><br />
Dental U Care assists patients in processing insurance claims but is not responsible for approval or denial of coverage.<br />
Patients remain fully responsible for any amount not covered by insurance.
</li>
<li>
<strong>Patient Responsibilities</strong><br />
Patients must provide accurate and complete medical and dental history information.<br />
Any changes to health status, medications, or allergies must be reported promptly.<br />
Patients are expected to follow the dentists recommended care and post-treatment instructions.
</li>
<li>
<strong>Treatment Consent</strong><br />
Before any procedure, your dentist will explain the diagnosis, treatment options, and estimated costs.<br />
By agreeing to proceed, you acknowledge that you understand the risks and benefits of the treatment.<br />
Written consent may be required for certain procedures.
</li>
<li>
<strong>Privacy and Confidentiality</strong><br />
Dental U Care complies with applicable privacy laws regarding the protection of personal and medical information.<br />
Your records will not be shared without your consent, except as required by law or for insurance processing.
</li>
<li>
<strong>Disclaimer of Liability</strong><br />
While our professionals strive to provide high-quality care, results may vary depending on individual conditions.<br />
Dental U Care is not liable for post-treatment complications that arise from failure to follow prescribed care or external factors beyond our control.
</li>
<li>
<strong>Intellectual Property</strong><br />
All content on our website and marketing materialsincluding text, logos, and imagesis owned by Dental U Care and may not be copied or reproduced without permission.
</li>
<li>
<strong>Governing Law</strong><br />
These Terms are governed by and construed in accordance with the laws of the Republic of the Philippines.<br />
Any disputes shall be handled within the proper courts of Puerto Princesa City, Palawan.
</li>
<li>
<strong>Contact Information</strong><br />
For questions regarding these Terms, please contact:<br />
Dental U Care<br />
Address: <span className="italic">[Baltan Street, Puerto Princesa City, Palawan]</span><br />
Phone: <span className="italic">[63+ 1234 5678]</span><br />
Email: <span className="italic">[info@dentalucare.com]</span>
</li>
</ol>
</section>
);
}