Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@heroicons/react": "^2.2.0",
"axios": "^1.10.0",
"date-fns": "^4.1.0",
"framer-motion": "^12.23.24",
"framer-motion": "^12.23.26",
"jspdf": "^3.0.1",
"lucide-react": "^0.525.0",
"react": "^19.1.0",
Expand Down
86 changes: 86 additions & 0 deletions client/src/components/quicklab/DesktopFooter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
export default function DesktopFooter() {
return (
<footer className="bg-lab-black-900 dark:bg-black text-lab-black-100 py-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid md:grid-cols-4 gap-8 mb-8">
<div>
<h3 className="text-2xl font-bold mb-4">
<span className="text-white">Quick</span>
<span className="text-lab-yellow-400">Lab</span>
</h3>
<p className="text-lab-black-400">Your trusted healthcare companion</p>
</div>

<div>
<h4 className="font-semibold mb-4 text-white">Quick Ecosystem</h4>
<ul className="space-y-2 text-lab-black-400">
<li>
<a href="#" className="hover:text-lab-yellow-400 transition-colors">
QuickClinic
</a>
</li>
<li>
<a href="#" className="hover:text-lab-yellow-400 transition-colors">
QuickMed
</a>
</li>
<li>
<a href="#" className="hover:text-lab-yellow-400 transition-colors">
QuickLab
</a>
</li>
<li>
<a href="#" className="hover:text-lab-yellow-400 transition-colors">
QuickInsure
</a>
</li>
</ul>
</div>

<div>
<h4 className="font-semibold mb-4 text-white">Resources</h4>
<ul className="space-y-2 text-lab-black-400">
<li>
<a href="#" className="hover:text-lab-yellow-400 transition-colors">
About Us
</a>
</li>
<li>
<a href="#" className="hover:text-lab-yellow-400 transition-colors">
Privacy Policy
</a>
</li>
<li>
<a href="#" className="hover:text-lab-yellow-400 transition-colors">
Terms of Service
</a>
</li>
<li>
<a href="#" className="hover:text-lab-yellow-400 transition-colors">
Contact
</a>
</li>
</ul>
</div>

<div>
<h4 className="font-semibold mb-4 text-white">Stay Connected</h4>
<p className="text-lab-black-400 mb-4">Subscribe for health tips and updates</p>
<div className="flex gap-2">
<input
type="email"
placeholder="Your email"
className="flex-1 px-4 py-2 rounded bg-lab-black-800 text-white border border-lab-black-700 focus:border-lab-yellow-400 focus:outline-none"
/>
<button className="btn-quicklab-primary">Join</button>
</div>
</div>
</div>

<div className="border-t border-lab-black-800 pt-8 text-center text-lab-black-400">
<p>&copy; 2025 Quick Healthcare Ecosystem. All rights reserved.</p>
</div>
</div>
</footer>
);
}
2 changes: 1 addition & 1 deletion client/src/components/quicklab/DesktopNavbar.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// DesktopNavbar.jsx
import { Search } from 'lucide-react';
import DarkModeToggle from '../ui/DarkModeToggle';

import DesktopFooter from './DesktopFooter';
export default function DesktopNavbar({ searchQuery, setSearchQuery }) {
return (
<nav className="hidden lg:block fixed top-0 left-0 right-0 z-50 bg-white dark:bg-black border-b border-slate-200 dark:border-slate-800 shadow-sm">
Expand Down
21 changes: 21 additions & 0 deletions client/src/components/quicklab/HomePage/AnimatedSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { motion, useInView } from 'framer-motion';

const AnimatedSection = ({ children, className = '' }) => {
const ref = React.useRef(null);
const isInView = useInView(ref, { once: true, margin: '-100px' });

return (
<motion.div
ref={ref}
initial={{ opacity: 0, y: 50 }}
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
transition={{ duration: 0.6, ease: 'easeOut' }}
className={className}
>
{children}
</motion.div>
);
};

export default AnimatedSection;
102 changes: 102 additions & 0 deletions client/src/components/quicklab/HomePage/EcosystemSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React from 'react';
import { motion } from 'framer-motion';
import AnimatedSection from './AnimatedSection';

const EcosystemSection = () => {
const products = [
{
name: 'QuickClinic',
color: 'blue',
colorClass: 'from-blue-500 to-blue-600',
darkColorClass: 'from-blue-600 to-blue-700',
description: 'Online doctor booking and video consultations',
available: true,
},
{
name: 'QuickMed',
color: 'green',
colorClass: 'from-green-500 to-green-600',
darkColorClass: 'from-green-600 to-green-700',
description: 'Free access to complete medicine information',
available: true,
},
{
name: 'QuickLab',
color: 'yellow',
colorClass: 'from-yellow-500 to-yellow-600',
darkColorClass: 'from-yellow-500 to-yellow-600',
description: 'Book and compare labs across your city',
available: true,
current: true,
},
{
name: 'QuickInsure',
color: 'purple',
colorClass: 'from-purple-500 to-purple-600',
darkColorClass: 'from-purple-600 to-purple-700',
description: 'Buy and claim health insurance seamlessly',
available: false,
},
];

return (
<section id="ecosystem" className="py-20 bg-lab-black-50 dark:bg-lab-black-800">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<AnimatedSection>
<div className="text-center mb-16">
<h2 className="text-3xl sm:text-4xl font-bold mb-6">
Building a Complete{' '}
<span className="text-lab-yellow-600 dark:text-lab-yellow-400">
Healthcare Ecosystem
</span>
</h2>
<p className="text-lg text-lab-black-700 dark:text-lab-black-300 max-w-3xl mx-auto leading-relaxed">
From appointment booking, we are moving toward building a complete digital healthcare
ecosystem for your convenience—so you only need one platform for all health-related
queries and services. Your health, simplified.
</p>
</div>
</AnimatedSection>

<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
{products.map((product, index) => (
<AnimatedSection key={index}>
<motion.div
whileHover={{ y: -8 }}
className="card-quicklab relative overflow-hidden group"
>
{product.current && (
<div className="absolute top-4 right-4">
<span className="badge-quicklab text-xs">You are here</span>
</div>
)}
{!product.available && (
<div className="absolute top-4 right-4">
<span className="bg-lab-black-200 dark:bg-lab-black-700 text-lab-black-700 dark:text-lab-black-300 px-3 py-1 rounded-full text-xs font-semibold">
Coming Soon
</span>
</div>
)}

<div
className={`w-full h-2 bg-gradient-to-r ${product.colorClass} dark:${product.darkColorClass} rounded-t-lg mb-4 -mx-6 -mt-6`}
></div>

<h3 className="text-2xl font-bold mb-2">
<span className="text-lab-black-900 dark:text-lab-black-50">Quick</span>
<span className={`text-${product.color}-600 dark:text-${product.color}-400`}>
{product.name.replace('Quick', '')}
</span>
</h3>

<p className="text-lab-black-600 dark:text-lab-black-400">{product.description}</p>
</motion.div>
</AnimatedSection>
))}
</div>
</div>
</section>
);
};

export default EcosystemSection;
88 changes: 88 additions & 0 deletions client/src/components/quicklab/HomePage/FeaturesSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React from 'react';
import { motion } from 'framer-motion';
import AnimatedSection from './AnimatedSection';
import Icons from './Icons';

const FeaturesSection = () => {
const features = [
{
icon: <Icons.Calendar />,
title: 'Online Lab Test Booking',
description:
'Book lab appointments online with ease. Choose home sample collection or visit the lab at your convenience.',
},
{
icon: <Icons.Doctor />,
title: 'Doctor-Linked Reports',
description:
'Reports from labs suggested by your QuickClinic doctor are sent directly to them with personalized remarks—no extra fees for normal results.',
badge: 'Key Feature',
},
{
icon: <Icons.Home />,
title: 'Home Sample Collection',
description:
'Get samples collected from the comfort of your home. Professional staff, timely service, safe handling.',
},
{
icon: <Icons.Star />,
title: 'Honest Lab Reviews',
description:
'Compare labs based on genuine user reviews, ratings, and test availability to make informed decisions.',
},
{
icon: <Icons.Flask />,
title: 'Search by Test Name',
description:
'Find labs offering specific tests across your city. Filter by distance, ratings, and availability.',
},
{
icon: <Icons.Shield />,
title: 'No Hidden Costs',
description:
'Transparent pricing, no consultation fee when results are normal—saving you time and money.',
},
];

return (
<section id="features" className="py-20 bg-white dark:bg-lab-black-900">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<AnimatedSection>
<div className="text-center mb-16">
<h2 className="text-3xl sm:text-4xl font-bold mb-4">
Why Choose{' '}
<span className="text-lab-yellow-600 dark:text-lab-yellow-400">QuickLab</span>?
</h2>
<p className="text-lg text-lab-black-600 dark:text-lab-black-300 max-w-2xl mx-auto">
Experience seamless lab test booking with features designed for your convenience
</p>
</div>
</AnimatedSection>

<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{features.map((feature, index) => (
<AnimatedSection key={index}>
<motion.div
whileHover={{ y: -8, boxShadow: '0 20px 25px -5px rgba(234, 179, 8, 0.1)' }}
className="card-quicklab h-full relative"
>
{feature.badge && (
<div className="absolute -top-3 -right-3">
<span className="badge-quicklab text-xs">{feature.badge}</span>
</div>
)}
<div className="text-lab-yellow-600 dark:text-lab-yellow-400 mb-4">
{feature.icon}
</div>
<h3 className="text-xl font-semibold mb-3">{feature.title}</h3>
<p className="text-lab-black-600 dark:text-lab-black-400">{feature.description}</p>
</motion.div>
</AnimatedSection>
))}
</div>
</div>
</section>
);
};

export default FeaturesSection;
57 changes: 57 additions & 0 deletions client/src/components/quicklab/HomePage/HeroSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import { motion } from 'framer-motion';

const HeroSection = () => {
return (
<section className="relative overflow-hidden bg-gradient-to-br from-lab-yellow-50 via-white to-lab-blue-50 dark:from-lab-black-900 dark:via-lab-black-800 dark:to-lab-black-900">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 lg:py-28">
<div className="text-center">
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
>
<div className="inline-block mb-4">
<span className="badge-quicklab">Smart Healthcare Booking</span>
</div>

<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold mb-6 leading-tight">
Book Lab Tests Online,
<br />
<span className="text-lab-yellow-600 dark:text-lab-yellow-400">
Get Doctor Remarks Instantly
</span>
</h1>

<p className="text-xl text-lab-black-600 dark:text-lab-black-300 mb-10 max-w-3xl mx-auto">
Save time and money with doctor-linked lab reports. No consultation fees for normal
results. Book tests, compare labs, and get home sample collection—all in one platform.
</p>

<div className="flex flex-col sm:flex-row gap-4 justify-center">
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
className="btn-quicklab-primary text-lg px-8 py-4"
>
Book Lab Test Now
</motion.button>
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
className="btn-quicklab-secondary text-lg px-8 py-4"
>
Find Labs Near You
</motion.button>
</div>
</motion.div>
</div>
</div>

<div className="absolute top-20 right-10 w-72 h-72 bg-lab-yellow-200 dark:bg-lab-yellow-900 rounded-full mix-blend-multiply dark:mix-blend-soft-light filter blur-3xl opacity-20 animate-blob"></div>
<div className="absolute bottom-20 left-10 w-72 h-72 bg-lab-blue-200 dark:bg-lab-blue-900 rounded-full mix-blend-multiply dark:mix-blend-soft-light filter blur-3xl opacity-20 animate-blob animation-delay-2000"></div>
</section>
);
};

export default HeroSection;
Loading