Initial commit

This commit is contained in:
dk
2026-06-20 21:20:19 +00:00
commit b29df5c1dc
313 changed files with 37562 additions and 0 deletions

227
src/pages/HomePage.tsx Normal file
View File

@@ -0,0 +1,227 @@
import AboutText from '@/components/sections/about/AboutText';
import ContactCta from '@/components/sections/contact/ContactCta';
import FaqTwoColumn from '@/components/sections/faq/FaqTwoColumn';
import FeaturesTaggedCards from '@/components/sections/features/FeaturesTaggedCards';
import HeroCenteredLogos from '@/components/sections/hero/HeroCenteredLogos';
import MetricsFeatureCards from '@/components/sections/metrics/MetricsFeatureCards';
import TestimonialMarqueeCards from '@/components/sections/testimonial/TestimonialMarqueeCards';
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
export default function HomePage() {
return (
<>
<div id="hero" data-section="hero">
<SectionErrorBoundary name="hero">
<HeroCenteredLogos
avatarsSrc={[
"http://img.b2bpic.net/free-photo/elderly-couple-talking_23-2148116315.jpg",
"http://img.b2bpic.net/free-photo/woman-doing-gymnastics-with-help-his-young-physical-therapist_169016-43495.jpg",
"http://img.b2bpic.net/free-photo/retired-woman-browsing-internet-digital-tablet-home-elder-person-with-crutches-sofa-using-modern-gadget-with-touch-screen-learn-technology-living-room-pensioner-with-device_482257-40616.jpg",
"http://img.b2bpic.net/free-photo/medical-assistant-helping-patient-with-physiotherapy-exercises_23-2149071465.jpg",
"http://img.b2bpic.net/free-photo/people-watching-news-tv_23-2149718956.jpg",
]}
avatarText="Trusted by 60+ patients"
title="Professional Home Physiotherapy & Cupping"
description="Expert physiotherapy, hijama, and therapeutic massage delivered in the comfort of your home. Professional care with a personal touch."
primaryButton={{
text: "Book Now",
href: "#contact",
}}
secondaryButton={{
text: "View Reviews",
href: "#reviews",
}}
names={[
"Ahmed",
"Sara",
"Khalid",
"Mona",
"Omar",
]}
imageSrc="http://img.b2bpic.net/free-photo/female-therapist-rehabilitation-center-giving-back-massage_23-2150356750.jpg"
/>
</SectionErrorBoundary>
</div>
<div id="about" data-section="about">
<SectionErrorBoundary name="about">
<AboutText
title="Providing Golden Hand Healing at Your Home"
primaryButton={{
text: "Learn More",
href: "#services",
}}
/>
</SectionErrorBoundary>
</div>
<div id="services" data-section="services">
<SectionErrorBoundary name="services">
<FeaturesTaggedCards
tag="Our Services"
title="Comprehensive Recovery Care"
description="We specialize in bringing clinical quality treatments to your door."
items={[
{
tag: "Physical Therapy",
title: "Physiotherapy",
description: "Tailored exercises and rehabilitation plans for your specific recovery journey.",
primaryButton: {
text: "Learn more",
href: "#",
},
imageSrc: "http://img.b2bpic.net/free-photo/close-up-rehab-doctor-hands-massaging-patient-shoulder-shoulder-therapy_169016-71210.jpg",
},
{
tag: "Cupping",
title: "Hijama & Cupping",
description: "Professional hijama and dry cupping services for pain relief and improved circulation.",
primaryButton: {
text: "Learn more",
href: "#",
},
imageSrc: "http://img.b2bpic.net/free-photo/hand-putting-suction-cups-woman-s-back_23-2149406810.jpg",
},
{
tag: "Massage",
title: "Therapeutic Massage",
description: "Professional deep tissue and recovery massage to soothe muscles and reduce stress.",
primaryButton: {
text: "Learn more",
href: "#",
},
imageSrc: "http://img.b2bpic.net/free-photo/leg-massage-with-oil-long-gliding-strokes-daylight-spa-ease_169016-69622.jpg",
},
]}
/>
</SectionErrorBoundary>
</div>
<div id="stats" data-section="stats">
<SectionErrorBoundary name="stats">
<MetricsFeatureCards
tag="Our Experience"
title="Proven Results"
description="Consistently providing 5-star rated care for every patient."
metrics={[
{
value: "4.9/5",
title: "Average Rating",
features: [
"63+ Reviews",
"Top-rated service",
"Reliable",
],
},
{
value: "100+",
title: "Cases Handled",
features: [
"Rehabilitation",
"Pain Relief",
"Post-op",
],
},
{
value: "24/7",
title: "Support",
features: [
"Flexible Timing",
"Home Visit",
"Available",
],
},
]}
/>
</SectionErrorBoundary>
</div>
<div id="reviews" data-section="reviews">
<SectionErrorBoundary name="reviews">
<TestimonialMarqueeCards
tag="Testimonials"
title="What Our Patients Say"
description="Trusted by hundreds across the country."
testimonials={[
{
name: "Abdulrahman",
role: "Patient",
quote: "Dr. Gamal is excellent. His hands are magic in massage and cupping.",
imageSrc: "http://img.b2bpic.net/free-photo/patient-consulting-doctor_1170-2096.jpg",
},
{
name: "Safa",
role: "Patient",
quote: "Professional in every way. Dr. Gamal has a golden hand.",
imageSrc: "http://img.b2bpic.net/free-photo/unrecognizable-male-doctor-writing-medical-report-while-visiting-senior-couple-their-home_637285-1354.jpg",
},
{
name: "Ahmed Ali",
role: "Hotel Guest",
quote: "Very professional, came to my hotel and then my apartment.",
imageSrc: "http://img.b2bpic.net/free-photo/vertical-shot-female-doctor-listening-elderly-heartbeat_181624-46401.jpg",
},
{
name: "Khalid",
role: "Patient",
quote: "Best recovery massage I have ever had at home.",
imageSrc: "http://img.b2bpic.net/free-photo/doctor-s-supportin-their-patient_23-2152020805.jpg",
},
{
name: "Mona",
role: "Patient",
quote: "Responsive and skilled, highly recommend for physiotherapy.",
imageSrc: "http://img.b2bpic.net/free-photo/front-view-female-doctor-medical-shirt-rejoicing-yellow-background_179666-31447.jpg",
},
]}
/>
</SectionErrorBoundary>
</div>
<div id="faq" data-section="faq">
<SectionErrorBoundary name="faq">
<FaqTwoColumn
tag="Support"
title="Frequently Asked Questions"
description="Everything you need to know about our home visit services."
items={[
{
question: "Do you offer services on weekends?",
answer: "Yes, we operate 24/7 and provide services on weekends and public holidays.",
},
{
question: "What equipment do you bring?",
answer: "We bring all necessary clinical equipment for physiotherapy, cupping, and massage.",
},
{
question: "Where do you provide service?",
answer: "We cover Cairo, Sheikh Zayed, 6th of October, and surrounding areas.",
},
{
question: "How to book an appointment?",
answer: "Simply contact us via phone or WhatsApp at the provided number to schedule your visit.",
},
]}
/>
</SectionErrorBoundary>
</div>
<div id="contact" data-section="contact">
<SectionErrorBoundary name="contact">
<ContactCta
tag="Book Now"
text="Ready to start your recovery? Contact Dr. Gamal for a professional home visit today."
primaryButton={{
text: "Call 015 52557597",
href: "tel:01552557597",
}}
secondaryButton={{
text: "WhatsApp Us",
href: "https://wa.me/201552557597",
}}
/>
</SectionErrorBoundary>
</div>
</>
);
}

View File

@@ -0,0 +1,13 @@
import BlogSimpleCards from "@/components/sections/blog/BlogSimpleCards";
const BlogPage = () => {
return (
<BlogSimpleCards
tag="Blog"
title="Latest Articles"
description="Stay updated with our latest insights and news"
/>
);
};
export default BlogPage;

View File

@@ -0,0 +1,50 @@
import { useParams, useNavigate } from "react-router-dom";
import { Loader2 } from "lucide-react";
import BlogArticle from "@/components/sections/blog/BlogArticle";
import useBlogPost from "@/hooks/useBlogPost";
const BlogPostPage = () => {
const { slug } = useParams<{ slug: string }>();
const navigate = useNavigate();
const { post, isLoading } = useBlogPost(slug || "");
if (isLoading) {
return (
<section className="w-content-width mx-auto py-20">
<div className="flex justify-center">
<Loader2 className="size-8 animate-spin text-foreground" strokeWidth={1.5} />
</div>
</section>
);
}
if (!post || !post.content) {
return (
<section className="w-content-width mx-auto py-20 text-center">
<p className="text-foreground mb-4">Post not found</p>
<button onClick={() => navigate("/blog")} className="primary-button px-6 py-2 rounded-theme text-primary-cta-text">
Back to Blog
</button>
</section>
);
}
const wordCount = post.content.replace(/<[^>]*>/g, " ").trim().split(/\s+/).length;
const readingTime = `${Math.max(1, Math.round(wordCount / 200))} min read`;
return (
<BlogArticle
category={post.category}
title={post.title}
excerpt={post.excerpt}
content={post.content}
imageSrc={post.imageSrc}
authorName={post.authorName}
authorImageSrc={post.authorAvatar}
date={post.date}
readingTime={readingTime}
/>
);
};
export default BlogPostPage;

View File

@@ -0,0 +1,79 @@
import { ReactLenis } from "lenis/react";
import { useParams, useNavigate } from "react-router-dom";
import { Loader2 } from "lucide-react";
import ProductDetailCard from "@/components/ecommerce/ProductDetailCard";
import ProductCart from "@/components/ecommerce/ProductCart";
import useProductDetail from "@/hooks/useProductDetail";
import useCart from "@/hooks/useCart";
import useCheckout from "@/hooks/useCheckout";
const ProductPage = () => {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const { product, isLoading, images, createCartItem, selectedQuantity } = useProductDetail(id || "");
const { items: cartItems, isOpen: cartOpen, setIsOpen: setCartOpen, addItem, updateQuantity, removeItem, total: cartTotal, getCheckoutItems } = useCart();
const { buyNow, checkout } = useCheckout();
if (isLoading) {
return (
<section className="w-content-width mx-auto py-20">
<div className="flex justify-center">
<Loader2 className="size-8 animate-spin text-foreground" strokeWidth={1.5} />
</div>
</section>
);
}
if (!product) {
return (
<section className="w-content-width mx-auto py-20 text-center">
<p className="text-foreground mb-4">Product not found</p>
<button onClick={() => navigate("/shop")} className="primary-button px-6 py-2 rounded-theme text-primary-cta-text">
Back to Shop
</button>
</section>
);
}
const handleAddToCart = () => {
const item = createCartItem();
if (item) addItem(item);
};
const handleBuyNow = () => {
buyNow(product, selectedQuantity);
};
const handleCheckout = async () => {
if (cartItems.length === 0) return;
const url = new URL(window.location.href);
url.searchParams.set("success", "true");
await checkout(getCheckoutItems(), { successUrl: url.toString() });
};
return (
<ReactLenis root>
<ProductDetailCard
name={product.name}
price={product.price}
description={product.description}
images={images.map((img) => img.src)}
rating={product.rating}
onAddToCart={handleAddToCart}
onBuyNow={handleBuyNow}
/>
<ProductCart
isOpen={cartOpen}
onClose={() => setCartOpen(false)}
items={cartItems}
total={`$${cartTotal}`}
onQuantityChange={updateQuantity}
onRemove={removeItem}
onCheckout={handleCheckout}
/>
</ReactLenis>
);
};
export default ProductPage;

View File

@@ -0,0 +1,31 @@
import { useNavigate } from "react-router-dom";
import { Loader2 } from "lucide-react";
import ProductCatalog from "@/components/ecommerce/ProductCatalog";
import useProductCatalog from "@/hooks/useProductCatalog";
const ShopPage = () => {
const navigate = useNavigate();
const { products, isLoading, search, setSearch } = useProductCatalog({
onProductClick: (productId) => navigate(`/shop/${productId}`),
});
if (isLoading) {
return (
<section className="w-content-width mx-auto py-20">
<div className="flex justify-center">
<Loader2 className="size-8 animate-spin text-foreground" strokeWidth={1.5} />
</div>
</section>
);
}
return (
<ProductCatalog
products={products}
searchValue={search}
onSearchChange={setSearch}
/>
);
};
export default ShopPage;