diff --git a/client/src/App.jsx b/client/src/App.jsx
index 20b4ea6..c96cd82 100644
--- a/client/src/App.jsx
+++ b/client/src/App.jsx
@@ -12,6 +12,7 @@ import PatientRoutes from './routes/PatientRoutes';
import PublicRoutes from './routes/PublicRoutes';
import getDashboardPath from './utility/getDashboardPath';
import QuickmedRoutes from './routes/QuickmedRoutes';
+import QuickLabRoutes from './routes/QuickLabRoutes';
// App.jsx - Updated AppInner component
function AppInner() {
@@ -43,9 +44,13 @@ function AppInner() {
const renderRoutes = () => {
console.log('Auth state:', { isAuthenticated, isLoading, user, pathname: location.pathname });
const quickMedPath = location.pathname.startsWith('/quick-med');
+ const quickLabPath = location.pathname.startsWith('/quick-lab');
if (quickMedPath) {
return ;
}
+ if (quickLabPath) {
+ return ;
+ }
// For authenticated users
if (isAuthenticated && user) {
switch (user.role) {
diff --git a/client/src/components/quicklab/DesktopNavbar.jsx b/client/src/components/quicklab/DesktopNavbar.jsx
new file mode 100644
index 0000000..09907e7
--- /dev/null
+++ b/client/src/components/quicklab/DesktopNavbar.jsx
@@ -0,0 +1,51 @@
+// DesktopNavbar.jsx
+import { Search } from 'lucide-react';
+import DarkModeToggle from '../ui/DarkModeToggle';
+
+export default function DesktopNavbar({ searchQuery, setSearchQuery }) {
+ return (
+
+ );
+}
diff --git a/client/src/components/quicklab/MobileNavbar.jsx b/client/src/components/quicklab/MobileNavbar.jsx
new file mode 100644
index 0000000..f5768d9
--- /dev/null
+++ b/client/src/components/quicklab/MobileNavbar.jsx
@@ -0,0 +1,69 @@
+// MobileNavbar.jsx
+import { Search, Home, BookOpen, User } from 'lucide-react';
+import DarkModeToggle from '../ui/DarkModeToggle';
+
+export default function MobileNavbar({ searchQuery, setSearchQuery }) {
+ return (
+ <>
+ {/* Top Bar - Search Only */}
+
+
+ {/* Logo */}
+
+
+
+
+
+
+
setSearchQuery(e.target.value)}
+ placeholder="Search labs..."
+ className="block w-full pl-10 pr-3 py-2 border border-slate-300 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-slate-50 placeholder-slate-500 dark:placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-yellow-500 dark:focus:ring-yellow-400 focus:border-transparent transition-all"
+ />
+
+
+
+
+ {/* Bottom Navigation Bar */}
+
+
+ {/* Home/Labs */}
+
+
+ {/* Labs */}
+
+
+ {/* Dark Mode Toggle */}
+
+
+
+ Theme
+
+
+
+ {/* Login/Account */}
+
+
+
+
+ {/* Spacer for fixed navbars */}
+
+ >
+ );
+}
diff --git a/client/src/components/quicklab/Navbar.jsx b/client/src/components/quicklab/Navbar.jsx
new file mode 100644
index 0000000..c31687e
--- /dev/null
+++ b/client/src/components/quicklab/Navbar.jsx
@@ -0,0 +1,18 @@
+// Navbar.jsx
+import { useState } from 'react';
+import DesktopNavbar from './DesktopNavbar';
+import MobileNavbar from './MobileNavbar';
+
+export default function Navbar() {
+ const [searchQuery, setSearchQuery] = useState('');
+
+ return (
+ <>
+ {/* Desktop Navbar - Hidden on mobile */}
+
+
+ {/* Mobile Navbar - Hidden on desktop */}
+
+ >
+ );
+}
diff --git a/client/src/quicklab-theme.js b/client/src/quicklab-theme.js
new file mode 100644
index 0000000..3bcbb03
--- /dev/null
+++ b/client/src/quicklab-theme.js
@@ -0,0 +1,79 @@
+// quicklab-theme.js
+
+export const colors = {
+ primary: '#eab308', // yellow-500
+ primaryDark: '#ca8a04', // yellow-600
+ primaryLight: '#facc15', // yellow-400
+ secondary: '#1e293b', // black-800
+ accent: '#3b82f6', // blue-500
+ accentDark: '#2563eb', // blue-600
+ light: '#f8fafc', // slate-50
+ dark: '#000000', // pure black
+ darkSurface: '#0f172a', // slate-900
+ success: '#22c55e', // green (from QuickMed)
+ warning: '#f59e0b', // amber
+ danger: '#ef4444', // red
+ info: '#3b82f6', // blue
+ text: {
+ light: '#0f172a',
+ dark: '#f8fafc',
+ muted: {
+ light: '#64748b',
+ dark: '#94a3b8',
+ },
+ },
+ border: {
+ light: '#e2e8f0',
+ dark: '#1e293b',
+ },
+};
+
+export const spacing = {
+ xs: '0.25rem',
+ sm: '0.5rem',
+ md: '1rem',
+ lg: '1.5rem',
+ xl: '2rem',
+ '2xl': '3rem',
+};
+
+export const breakpoints = {
+ sm: '640px',
+ md: '768px',
+ lg: '1024px',
+ xl: '1280px',
+ '2xl': '1536px',
+};
+
+export const shadows = {
+ sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
+ md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
+ lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
+ xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
+ yellow: '0 4px 14px 0 rgba(234, 179, 8, 0.39)', // yellow glow
+ blue: '0 4px 14px 0 rgba(59, 130, 246, 0.39)', // blue glow
+};
+
+export const transitions = {
+ fast: '150ms ease-in-out',
+ normal: '200ms ease-in-out',
+ slow: '300ms ease-in-out',
+};
+
+// Theme toggle functionality
+export const initTheme = () => {
+ const theme = localStorage.getItem('quicklab-theme') || 'light';
+ document.documentElement.classList.toggle('dark', theme === 'dark');
+ return theme;
+};
+
+export const toggleTheme = () => {
+ const isDark = document.documentElement.classList.toggle('dark');
+ localStorage.setItem('quicklab-theme', isDark ? 'dark' : 'light');
+ return isDark ? 'dark' : 'light';
+};
+
+export const setTheme = (theme) => {
+ document.documentElement.classList.toggle('dark', theme === 'dark');
+ localStorage.setItem('quicklab-theme', theme);
+};
diff --git a/client/src/quicklab.css b/client/src/quicklab.css
new file mode 100644
index 0000000..447f199
--- /dev/null
+++ b/client/src/quicklab.css
@@ -0,0 +1,135 @@
+@import 'tailwindcss';
+
+/* Enable dark mode with class selector */
+@custom-variant dark (&:where(.dark, .dark *));
+
+@theme {
+ /* QuickLab Light Mode Colors - Yellow/Gold Spectrum */
+ --color-lab-yellow-50: #fefce8;
+ --color-lab-yellow-100: #fef9c3;
+ --color-lab-yellow-200: #fef08a;
+ --color-lab-yellow-300: #fde047;
+ --color-lab-yellow-400: #facc15;
+ --color-lab-yellow-500: #eab308;
+ --color-lab-yellow-600: #ca8a04;
+ --color-lab-yellow-700: #a16207;
+ --color-lab-yellow-800: #854d0e;
+ --color-lab-yellow-900: #713f12;
+
+ /* QuickLab Black/Gray Spectrum */
+ --color-lab-black-50: #f8fafc;
+ --color-lab-black-100: #f1f5f9;
+ --color-lab-black-200: #e2e8f0;
+ --color-lab-black-300: #cbd5e1;
+ --color-lab-black-400: #94a3b8;
+ --color-lab-black-500: #64748b;
+ --color-lab-black-600: #475569;
+ --color-lab-black-700: #334155;
+ --color-lab-black-800: #1e293b;
+ --color-lab-black-900: #0f172a;
+
+ /* QuickLab Blue Accent */
+ --color-lab-blue-400: #60a5fa;
+ --color-lab-blue-500: #3b82f6;
+ --color-lab-blue-600: #2563eb;
+ --color-lab-blue-700: #1d4ed8;
+}
+
+/* Dark Mode Overrides */
+@layer base {
+ .dark {
+ --color-lab-yellow-400: #facc15;
+ --color-lab-yellow-500: #facc15;
+ --color-lab-yellow-600: #eab308;
+ --color-lab-yellow-700: #ca8a04;
+ --color-lab-blue-500: #60a5fa;
+ --color-lab-blue-600: #3b82f6;
+ }
+}
+
+/* Custom Component Classes */
+@layer components {
+ /* Primary Button */
+ .btn-quicklab-primary {
+ background-color: rgb(234 179 8); /* yellow-500 */
+ color: rgb(15 23 42); /* black-900 */
+ padding: 0.75rem 1.5rem;
+ border-radius: 0.5rem;
+ transition: background-color 0.2s;
+ font-weight: 600;
+ }
+
+ .dark .btn-quicklab-primary {
+ background-color: rgb(250 204 21); /* yellow-400 */
+ color: rgb(15 23 42); /* black-900 - stays dark */
+ }
+
+ .btn-quicklab-primary:hover {
+ background-color: rgb(202 138 4); /* yellow-600 */
+ }
+
+ .dark .btn-quicklab-primary:hover {
+ background-color: rgb(234 179 8); /* yellow-500 */
+ }
+
+ /* Secondary Button (Black) */
+ .btn-quicklab-secondary {
+ background-color: rgb(30 41 59); /* black-800 */
+ color: rgb(250 204 21); /* yellow-400 */
+ padding: 0.75rem 1.5rem;
+ border-radius: 0.5rem;
+ transition: all 0.2s;
+ font-weight: 600;
+ border: 2px solid rgb(234 179 8); /* yellow-500 */
+ }
+
+ .dark .btn-quicklab-secondary {
+ background-color: rgb(248 250 252); /* light in dark mode */
+ color: rgb(30 41 59); /* dark text */
+ border-color: rgb(250 204 21); /* yellow-400 */
+ }
+
+ .btn-quicklab-secondary:hover {
+ background-color: rgb(15 23 42); /* black-900 */
+ border-color: rgb(234 179 8); /* yellow-500 */
+ }
+
+ /* Card Component */
+ .card-quicklab {
+ background-color: rgb(248 250 252); /* surface light */
+ border: 1px solid rgb(226 232 240); /* border light */
+ border-radius: 0.75rem;
+ padding: 1.5rem;
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
+ transition: all 0.2s;
+ }
+
+ .dark .card-quicklab {
+ background-color: rgb(15 23 42); /* surface dark */
+ border-color: rgb(30 41 59); /* border dark */
+ }
+
+ .card-quicklab:hover {
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+ border-color: rgb(234 179 8); /* yellow-500 */
+ }
+
+ .dark .card-quicklab:hover {
+ border-color: rgb(250 204 21); /* yellow-400 */
+ }
+
+ /* Badge Component */
+ .badge-quicklab {
+ background-color: rgb(254 249 195); /* yellow-100 */
+ color: rgb(133 77 14); /* yellow-800 */
+ padding: 0.25rem 0.75rem;
+ border-radius: 9999px;
+ font-size: 0.875rem;
+ font-weight: 600;
+ }
+
+ .dark .badge-quicklab {
+ background-color: rgb(113 63 18); /* yellow-900 */
+ color: rgb(253 224 71); /* yellow-300 */
+ }
+}
diff --git a/client/src/routes/QuickLabRoutes.jsx b/client/src/routes/QuickLabRoutes.jsx
new file mode 100644
index 0000000..8a53883
--- /dev/null
+++ b/client/src/routes/QuickLabRoutes.jsx
@@ -0,0 +1,13 @@
+import { Routes, Route } from 'react-router-dom';
+import NotFoundPage from '../components/ui/NotFoundPage';
+import Navbar from '../components/quicklab/Navbar';
+export default function QuickLabRoutes() {
+ return (
+ <>
+
+
+ } />
+
+ >
+ );
+}
diff --git a/client/src/shared-base.css b/client/src/shared-base.css
new file mode 100644
index 0000000..40ec3b6
--- /dev/null
+++ b/client/src/shared-base.css
@@ -0,0 +1,21 @@
+/* shared-base.css */
+:root {
+ --transition-speed: 0.2s;
+ --border-radius-sm: 0.5rem;
+ --border-radius-md: 0.75rem;
+ --border-radius-lg: 1rem;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family:
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+ transition:
+ background-color var(--transition-speed),
+ color var(--transition-speed);
+}
diff --git a/server/Controllers/QuickLab/labReportController.js b/server/Controllers/QuickLab/labReportController.js
index 3eb9415..b84db20 100644
--- a/server/Controllers/QuickLab/labReportController.js
+++ b/server/Controllers/QuickLab/labReportController.js
@@ -1,5 +1,3 @@
-// controllers/labReportController.js
-import mongoose from 'mongoose';
import LabReport from '../../models/Lab/LabReport.js';
import LabAppointment from '../../models/Lab/LabAppointment.js';
import { uploadToCloudinary } from '../../services/uploadService.js';