Improved header
This commit is contained in:
parent
6237a806e4
commit
be9ecf4224
@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { usePathname ,useRouter } from "next/navigation";
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
import { FileText, Moon, Sun } from "lucide-react";
|
import { FileText, Moon, Sun } from "lucide-react";
|
||||||
import { FaLock, FaChevronDown, FaChevronUp } from "react-icons/fa";
|
import { FaLock, FaChevronDown, FaChevronUp } from "react-icons/fa";
|
||||||
import { useTheme } from "../context/ThemeContext";
|
import { useTheme } from "../context/ThemeContext";
|
||||||
@ -27,7 +27,7 @@ const Sidebar = ({ sidebarOpen, setSidebarOpen, isCollapsed }) => {
|
|||||||
};
|
};
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
localStorage.removeItem("token"); // or account.deleteSession("current") if using Appwrite
|
localStorage.removeItem("token"); // or account.deleteSession("current") if using Appwrite
|
||||||
router.push("/signup"); // ✅ This will now work
|
router.push("/signup");
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
@ -84,121 +84,6 @@ const Sidebar = ({ sidebarOpen, setSidebarOpen, isCollapsed }) => {
|
|||||||
/>
|
/>
|
||||||
{!isCollapsed && "Dashboard"}
|
{!isCollapsed && "Dashboard"}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* User Profile Link */}
|
|
||||||
<Link
|
|
||||||
href="/pages/UserProfile"
|
|
||||||
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/UserProfile")
|
|
||||||
? darkMode
|
|
||||||
? "bg-blue-900 text-blue-200"
|
|
||||||
: "bg-blue-100 text-blue-800"
|
|
||||||
: darkMode
|
|
||||||
? "hover:bg-gray-700"
|
|
||||||
: "hover:bg-gray-200"
|
|
||||||
} ${isCollapsed ? 'justify-center' : ''}`}
|
|
||||||
onClick={closeSidebarOnMobile}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={darkMode ? "/images/icons/user-circle-white.svg" : "/images/icons/user-circle.svg"}
|
|
||||||
alt="Profile"
|
|
||||||
width={18}
|
|
||||||
className="w-5"
|
|
||||||
/>
|
|
||||||
{!isCollapsed && "User Profile"}
|
|
||||||
</Link>
|
|
||||||
{/* -----------------------Entries-------------------------------------------- */}
|
|
||||||
|
|
||||||
{/* User Profile Link */}
|
|
||||||
<Link
|
|
||||||
href="/pages/entries"
|
|
||||||
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/UserProfile")
|
|
||||||
? darkMode
|
|
||||||
? "bg-blue-900 text-blue-200"
|
|
||||||
: "bg-blue-100 text-blue-800"
|
|
||||||
: darkMode
|
|
||||||
? "hover:bg-gray-700"
|
|
||||||
: "hover:bg-gray-200"
|
|
||||||
} ${isCollapsed ? 'justify-center' : ''}`}
|
|
||||||
onClick={closeSidebarOnMobile}
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
|
||||||
</svg>
|
|
||||||
{!isCollapsed && "Entries"}
|
|
||||||
</Link>
|
|
||||||
{/* ------------------Bulk Entries------------------------------ */}
|
|
||||||
<Link
|
|
||||||
href="/pages/BulkEntries"
|
|
||||||
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/UserProfile")
|
|
||||||
? darkMode
|
|
||||||
? "bg-blue-900 text-blue-200"
|
|
||||||
: "bg-blue-100 text-blue-800"
|
|
||||||
: darkMode
|
|
||||||
? "hover:bg-gray-700"
|
|
||||||
: "hover:bg-gray-200"
|
|
||||||
} ${isCollapsed ? 'justify-center' : ''}`}
|
|
||||||
onClick={closeSidebarOnMobile}
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
|
||||||
</svg>
|
|
||||||
{!isCollapsed && "Bulk Entries"}
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
{/* -------------multibooking--------- */}
|
|
||||||
<Link
|
|
||||||
href="/pages/MultiBooking"
|
|
||||||
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/UserProfile")
|
|
||||||
? darkMode
|
|
||||||
? "bg-blue-900 text-blue-200"
|
|
||||||
: "bg-blue-100 text-blue-800"
|
|
||||||
: darkMode
|
|
||||||
? "hover:bg-gray-700"
|
|
||||||
: "hover:bg-gray-200"
|
|
||||||
} ${isCollapsed ? 'justify-center' : ''}`}
|
|
||||||
onClick={closeSidebarOnMobile}
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
|
||||||
</svg>
|
|
||||||
{!isCollapsed && "MultiBooking"}
|
|
||||||
</Link>
|
|
||||||
{/*--------------Multibooked------------ */}
|
|
||||||
<Link
|
|
||||||
href="/pages/MultiBooked"
|
|
||||||
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/UserProfile")
|
|
||||||
? darkMode
|
|
||||||
? "bg-blue-900 text-blue-200"
|
|
||||||
: "bg-blue-100 text-blue-800"
|
|
||||||
: darkMode
|
|
||||||
? "hover:bg-gray-700"
|
|
||||||
: "hover:bg-gray-200"
|
|
||||||
} ${isCollapsed ? 'justify-center' : ''}`}
|
|
||||||
onClick={closeSidebarOnMobile}
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
|
||||||
</svg>
|
|
||||||
{!isCollapsed && "MultiBooked"}
|
|
||||||
</Link>
|
|
||||||
{/* ------------------SingleBooked----------------- */}
|
|
||||||
<Link
|
|
||||||
href="/pages/SingleBooked"
|
|
||||||
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/UserProfile")
|
|
||||||
? darkMode
|
|
||||||
? "bg-blue-900 text-blue-200"
|
|
||||||
: "bg-blue-100 text-blue-800"
|
|
||||||
: darkMode
|
|
||||||
? "hover:bg-gray-700"
|
|
||||||
: "hover:bg-gray-200"
|
|
||||||
} ${isCollapsed ? 'justify-center' : ''}`}
|
|
||||||
onClick={closeSidebarOnMobile}
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
|
||||||
</svg>
|
|
||||||
{!isCollapsed && "SingleBooked"}
|
|
||||||
</Link>
|
|
||||||
{/* -----------singleBooking-------------- */}
|
{/* -----------singleBooking-------------- */}
|
||||||
<Link
|
<Link
|
||||||
href="/pages/SingleBooking"
|
href="/pages/SingleBooking"
|
||||||
@ -215,8 +100,50 @@ const Sidebar = ({ sidebarOpen, setSidebarOpen, isCollapsed }) => {
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
||||||
</svg>
|
</svg>
|
||||||
{!isCollapsed && "SingleBooking"}
|
{!isCollapsed && "Add Token"}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
||||||
|
{/* -------------multibooking--------- */}
|
||||||
|
<Link
|
||||||
|
href="/pages/MultiBooking"
|
||||||
|
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/UserProfile")
|
||||||
|
? darkMode
|
||||||
|
? "bg-blue-900 text-blue-200"
|
||||||
|
: "bg-blue-100 text-blue-800"
|
||||||
|
: darkMode
|
||||||
|
? "hover:bg-gray-700"
|
||||||
|
: "hover:bg-gray-200"
|
||||||
|
} ${isCollapsed ? 'justify-center' : ''}`}
|
||||||
|
onClick={closeSidebarOnMobile}
|
||||||
|
>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
||||||
|
</svg>
|
||||||
|
{!isCollapsed && "Add Multiple Tokens"}
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{/* -----------------------Entries-------------------------------------------- */}
|
||||||
|
|
||||||
|
{/* User Profile Link */}
|
||||||
|
{/* <Link
|
||||||
|
href="/pages/entries"
|
||||||
|
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/UserProfile")
|
||||||
|
? darkMode
|
||||||
|
? "bg-blue-900 text-blue-200"
|
||||||
|
: "bg-blue-100 text-blue-800"
|
||||||
|
: darkMode
|
||||||
|
? "hover:bg-gray-700"
|
||||||
|
: "hover:bg-gray-200"
|
||||||
|
} ${isCollapsed ? 'justify-center' : ''}`}
|
||||||
|
onClick={closeSidebarOnMobile}
|
||||||
|
>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"></path>
|
||||||
|
</svg>
|
||||||
|
{!isCollapsed && "Entries"}
|
||||||
|
</Link> */}
|
||||||
|
|
||||||
{/* ------------staffBooking---------------- */}
|
{/* ------------staffBooking---------------- */}
|
||||||
<Link
|
<Link
|
||||||
href="/pages/StaffBooking"
|
href="/pages/StaffBooking"
|
||||||
@ -256,22 +183,6 @@ const Sidebar = ({ sidebarOpen, setSidebarOpen, isCollapsed }) => {
|
|||||||
</Link>
|
</Link>
|
||||||
{/* ---------------------------------------------------------------------- */}
|
{/* ---------------------------------------------------------------------- */}
|
||||||
|
|
||||||
{/* Visits Link */}
|
|
||||||
<Link
|
|
||||||
href="/pages/visits"
|
|
||||||
className={`flex items-center gap-2 p-3 rounded-md text-sm font-semibold transition-colors ${isActive("/pages/visits")
|
|
||||||
? darkMode
|
|
||||||
? "bg-blue-900 text-blue-200"
|
|
||||||
: "bg-blue-100 text-blue-800"
|
|
||||||
: darkMode
|
|
||||||
? "hover:bg-gray-700"
|
|
||||||
: "hover:bg-gray-200"
|
|
||||||
} ${isCollapsed ? 'justify-center' : ''}`}
|
|
||||||
onClick={closeSidebarOnMobile}
|
|
||||||
>
|
|
||||||
<FileText size={18} className="w-5" />
|
|
||||||
{!isCollapsed && "Visits"}
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
{/* Custom Report Link */}
|
{/* Custom Report Link */}
|
||||||
{/* <Link
|
{/* <Link
|
||||||
|
@ -19,8 +19,8 @@ export default function Header({
|
|||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="grid grid-cols-4 gap-4">
|
<div className="grid grid-cols-4 gap-4">
|
||||||
{/* ----------Total Tokens Card---------------- */}
|
{/* ----------Total Tokens Card---------------- */}
|
||||||
<div className="border-2 rounded-[10px] px-2 py-2 flex flex-col gap-3 w-[10rem]">
|
<div className="border-3 border-gray-300 rounded-[10px] px-2 py-2 flex flex-col gap-3 w-[10rem]">
|
||||||
<h2 className="text-[14px] text-[#667085]">Total Tokens</h2>
|
<h2 className="font-semibold text-[14px] text-[#667085]">Total Tokens</h2>
|
||||||
<div className="flex gap-5 -mt-1">
|
<div className="flex gap-5 -mt-1">
|
||||||
<p className="text-[25px]">{totalTokens}</p>
|
<p className="text-[25px]">{totalTokens}</p>
|
||||||
<p className="text-[8px] text-[#667085] mt-[18px]">
|
<p className="text-[8px] text-[#667085] mt-[18px]">
|
||||||
@ -33,8 +33,8 @@ export default function Header({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ----------Done Tokens Card---------------- */}
|
{/* ----------Done Tokens Card---------------- */}
|
||||||
<div className="border-2 rounded-[10px] px-2 py-2 flex flex-col gap-3 w-[10rem]">
|
<div className="border-3 border-gray-300 rounded-[10px] px-2 py-2 flex flex-col gap-3 w-[10rem]">
|
||||||
<h2 className="text-[14px] text-[#667085]">Completed</h2>
|
<h2 className="font-semibold text-[14px] text-[#667085]">Done</h2>
|
||||||
<div className="flex gap-5 -mt-1">
|
<div className="flex gap-5 -mt-1">
|
||||||
<p className="text-[25px]">{doneTokens}</p>
|
<p className="text-[25px]">{doneTokens}</p>
|
||||||
<p className="text-[8px] text-[#667085] mt-[18px]">
|
<p className="text-[8px] text-[#667085] mt-[18px]">
|
||||||
@ -49,8 +49,8 @@ export default function Header({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ----------Missed Tokens Card---------------- */}
|
{/* ----------Missed Tokens Card---------------- */}
|
||||||
<div className="border-2 rounded-[10px] px-2 py-2 flex flex-col gap-3 w-[10rem]">
|
<div className="border-3 border-gray-300 rounded-[10px] px-2 py-2 flex flex-col gap-3 w-[10rem]">
|
||||||
<h2 className="text-[14px] text-[#667085]">Missed Tokens</h2>
|
<h2 className="font-semibold text-[14px] text-[#667085]">Missed Tokens</h2>
|
||||||
<div className="flex gap-5 -mt-1">
|
<div className="flex gap-5 -mt-1">
|
||||||
<p className="text-[25px]">{missedTokensCount}</p>
|
<p className="text-[25px]">{missedTokensCount}</p>
|
||||||
<p className="text-[8px] text-[#667085] mt-[18px]">
|
<p className="text-[8px] text-[#667085] mt-[18px]">
|
||||||
@ -67,8 +67,8 @@ export default function Header({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ----------Current Token Card---------------- */}
|
{/* ----------Current Token Card---------------- */}
|
||||||
<div className="border-2 rounded-[10px] px-2 py-2 flex flex-col gap-3 w-[10rem]">
|
<div className="border-3 border-gray-300 rounded-[10px] px-2 py-2 flex flex-col gap-3 w-[10rem]">
|
||||||
<h2 className="text-[14px] text-[#667085]">Current Token</h2>
|
<h2 className="font-semibold text-[14px] text-[#667085]">Current Token</h2>
|
||||||
<div className="flex flex-col gap-1 -mt-1">
|
<div className="flex flex-col gap-1 -mt-1">
|
||||||
<p className="text-[25px] text-center">
|
<p className="text-[25px] text-center">
|
||||||
{currentToken || "---"}
|
{currentToken || "---"}
|
||||||
|
@ -4,8 +4,6 @@ import { useState, useEffect } from 'react';
|
|||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import Preloader from '../../components/partials/preloaders';
|
import Preloader from '../../components/partials/preloaders';
|
||||||
import Overlay from '../../components/partials/overlay';
|
|
||||||
import Header from '../../components/partials/header';
|
|
||||||
|
|
||||||
export default function SingleBooking() {
|
export default function SingleBooking() {
|
||||||
const [darkMode, setDarkMode] = useState(false);
|
const [darkMode, setDarkMode] = useState(false);
|
||||||
@ -47,28 +45,14 @@ export default function SingleBooking() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`flex flex-col min-h-screen ${darkMode ? 'dark bg-gray-900' : ''}`}>
|
<div className={`flex flex-col min-h-screen ${darkMode ? 'dark bg-gray-900' : ''}`}>
|
||||||
<Head>
|
|
||||||
<title>Book Appointment</title>
|
|
||||||
<meta charSet="UTF-8" />
|
|
||||||
<meta
|
|
||||||
name="viewport"
|
|
||||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
|
|
||||||
/>
|
|
||||||
<meta httpEquiv="X-UA-Compatible" content="ie=edge" />
|
|
||||||
</Head>
|
|
||||||
|
|
||||||
<div className="flex h-screen overflow-hidden">
|
<div className="flex h-screen overflow-hidden">
|
||||||
<div className="relative flex flex-col flex-1 overflow-x-hidden overflow-y-auto">
|
<div className="relative flex flex-col flex-1 overflow-x-hidden overflow-y-auto">
|
||||||
<Overlay />
|
|
||||||
|
|
||||||
<div className="flex bg-white dark:bg-gray-800 shadow-sm sticky top-0 z-50 w-full">
|
|
||||||
<Header />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div className="p-4 mx-auto max-w-4xl md:p-6">
|
<div className="p-4 mx-auto max-w-4xl md:p-6">
|
||||||
<h2 className="text-2xl font-semibold mb-6 text-gray-800 dark:text-white">Book Appointment</h2>
|
<h2 className="text-2xl font-semibold text-gray-800 dark:text-white">Book Appointment</h2>
|
||||||
|
<p className='mb-6'>Date: {new Date().toLocaleDateString('en-GB')}</p>
|
||||||
<form onSubmit={handleSubmit} className="space-y-6">
|
<form onSubmit={handleSubmit} className="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-400 mb-1.5">
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-400 mb-1.5">
|
||||||
|
@ -181,7 +181,7 @@ export default function EntriesTable() {
|
|||||||
<tr>
|
<tr>
|
||||||
<th className="p-3 text-left">Token</th>
|
<th className="p-3 text-left">Token</th>
|
||||||
<th className="p-3 text-left">Name</th>
|
<th className="p-3 text-left">Name</th>
|
||||||
<th className="p-3 text-left">Booked By</th>
|
{/* <th className="p-3 text-left">Booked By</th> */}
|
||||||
<th className="p-3 text-left">Status</th>
|
<th className="p-3 text-left">Status</th>
|
||||||
{/* <th className="p-3 text-left">Wait Time</th> */}
|
{/* <th className="p-3 text-left">Wait Time</th> */}
|
||||||
<th className="p-3 text-left">Actions</th>
|
<th className="p-3 text-left">Actions</th>
|
||||||
@ -195,14 +195,14 @@ export default function EntriesTable() {
|
|||||||
>
|
>
|
||||||
<td className="p-3 font-mono">{entry.tokenNumber}</td>
|
<td className="p-3 font-mono">{entry.tokenNumber}</td>
|
||||||
<td className="p-3">{entry.patientName}</td>
|
<td className="p-3">{entry.patientName}</td>
|
||||||
<td className="p-3">
|
{/* <td className="p-3">
|
||||||
<span className={`text-xs px-2 py-1 rounded ${entry.bookedBy === 'staff' ?
|
<span className={`text-xs px-2 py-1 rounded ${entry.bookedBy === 'staff' ?
|
||||||
'bg-purple-100 text-purple-800' :
|
'bg-purple-100 text-purple-800' :
|
||||||
'bg-blue-100 text-blue-800'
|
'bg-blue-100 text-blue-800'
|
||||||
}`}>
|
}`}>
|
||||||
{entry.bookedBy}
|
{entry.bookedBy}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td> */}
|
||||||
<td className="p-3">
|
<td className="p-3">
|
||||||
<span
|
<span
|
||||||
className={`px-2 py-1 rounded-full text-xs ${entry.status === "done"
|
className={`px-2 py-1 rounded-full text-xs ${entry.status === "done"
|
||||||
|
@ -182,7 +182,7 @@ export default function EntriesTable() {
|
|||||||
<tr>
|
<tr>
|
||||||
<th className="p-3 text-left">Token</th>
|
<th className="p-3 text-left">Token</th>
|
||||||
<th className="p-3 text-left">Name</th>
|
<th className="p-3 text-left">Name</th>
|
||||||
<th className="p-3 text-left">Booked By</th>
|
{/* <th className="p-3 text-left">Booked By</th> */}
|
||||||
<th className="p-3 text-left">Status</th>
|
<th className="p-3 text-left">Status</th>
|
||||||
{/* <th className="p-3 text-left">Wait Time</th> */}
|
{/* <th className="p-3 text-left">Wait Time</th> */}
|
||||||
<th className="p-3 text-left">Actions</th>
|
<th className="p-3 text-left">Actions</th>
|
||||||
@ -196,14 +196,14 @@ export default function EntriesTable() {
|
|||||||
>
|
>
|
||||||
<td className="p-3 font-mono">{entry.tokenNumber}</td>
|
<td className="p-3 font-mono">{entry.tokenNumber}</td>
|
||||||
<td className="p-3">{entry.patientName}</td>
|
<td className="p-3">{entry.patientName}</td>
|
||||||
<td className="p-3">
|
{/* <td className="p-3">
|
||||||
<span className={`text-xs px-2 py-1 rounded ${entry.bookedBy === 'staff' ?
|
<span className={`text-xs px-2 py-1 rounded ${entry.bookedBy === 'staff' ?
|
||||||
'bg-purple-100 text-purple-800' :
|
'bg-purple-100 text-purple-800' :
|
||||||
'bg-blue-100 text-blue-800'
|
'bg-blue-100 text-blue-800'
|
||||||
}`}>
|
}`}>
|
||||||
{entry.bookedBy}
|
{entry.bookedBy}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td> */}
|
||||||
<td className="p-3">
|
<td className="p-3">
|
||||||
<span
|
<span
|
||||||
className={`px-2 py-1 rounded-full text-xs ${entry.status === "done"
|
className={`px-2 py-1 rounded-full text-xs ${entry.status === "done"
|
||||||
|
@ -1,151 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import { useTheme } from "../../context/ThemeContext"; // Import the theme context
|
|
||||||
|
|
||||||
const Visits = () => {
|
|
||||||
const { darkMode } = useTheme(); // Get dark mode state
|
|
||||||
const [data, setData] = useState(null);
|
|
||||||
const [deviceData, setDeviceData] = useState(null);
|
|
||||||
const [browserData, setBrowserData] = useState(null);
|
|
||||||
const [osData, setOsData] = useState(null);
|
|
||||||
const [lastMonthData, setLastMonthData] = useState(null);
|
|
||||||
const [lastTwoMonthsData, setLastTwoMonthsData] = useState(null);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [error, setError] = useState(null);
|
|
||||||
|
|
||||||
// Fetch data from the API
|
|
||||||
const fetchData = async (endpoint, setDataFunction) => {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`/api/proxy?domain=meerafirms.in&endpoint=${endpoint}`);
|
|
||||||
if (!response.ok) {
|
|
||||||
const errorData = await response.json();
|
|
||||||
throw new Error(errorData.error || `HTTP Error: ${response.status}`);
|
|
||||||
}
|
|
||||||
const result = await response.json();
|
|
||||||
setDataFunction(result);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error fetching ${endpoint}:`, err);
|
|
||||||
setError(err.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchAllData = async () => {
|
|
||||||
setLoading(true);
|
|
||||||
await Promise.all([
|
|
||||||
fetchData("visits/total-visits", setData),
|
|
||||||
fetchData("visits/total-visits?fields=device", setDeviceData),
|
|
||||||
fetchData("visits/total-visits?fields=device,browser,os", setBrowserData),
|
|
||||||
fetchData("visits/last-month", setLastMonthData),
|
|
||||||
fetchData("visits/last-2-months", setLastTwoMonthsData),
|
|
||||||
]);
|
|
||||||
setLoading(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchAllData();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Card component for consistent styling
|
|
||||||
const DataCard = ({ title, children }) => (
|
|
||||||
<div className={`m-2 p-6 rounded-2xl border transition-colors duration-300
|
|
||||||
${darkMode ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200'}`}>
|
|
||||||
<h2 className={`text-lg font-bold mb-4 ${darkMode ? 'text-white' : 'text-gray-800'}`}>
|
|
||||||
{title}
|
|
||||||
</h2>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
// Data row component
|
|
||||||
const DataRow = ({ label, value }) => (
|
|
||||||
<div className="flex justify-between py-2 border-b border-gray-200 dark:border-gray-700 last:border-0">
|
|
||||||
<span className={`font-medium ${darkMode ? 'text-gray-300' : 'text-gray-600'}`}>
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
<span className={`font-semibold ${darkMode ? 'text-white' : 'text-gray-800'}`}>
|
|
||||||
{value}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={`min-h-screen p-4 transition-colors duration-300 ${darkMode ? 'bg-gray-900' : 'bg-gray-50'}`}>
|
|
||||||
<h1 className={`text-2xl font-bold mb-6 ${darkMode ? 'text-white' : 'text-gray-800'}`}>
|
|
||||||
Website Analytics
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
{loading && (
|
|
||||||
<div className="flex justify-center items-center h-64">
|
|
||||||
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{error && (
|
|
||||||
<DataCard title="Error">
|
|
||||||
<p className="text-red-500">{error}</p>
|
|
||||||
</DataCard>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{data && (
|
|
||||||
<DataCard title="Website Visits">
|
|
||||||
<div className="space-y-3">
|
|
||||||
<DataRow label="Total Visits" value={data["Total Visits"]} />
|
|
||||||
<DataRow label="Total Views" value={data["Total Views"]} />
|
|
||||||
</div>
|
|
||||||
</DataCard>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{deviceData && (
|
|
||||||
<DataCard title="Device Distribution">
|
|
||||||
<div className="space-y-3">
|
|
||||||
{Object.entries(deviceData.Devices || {}).map(([key, value]) => (
|
|
||||||
<DataRow key={key} label={key} value={value} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</DataCard>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{browserData && (
|
|
||||||
<>
|
|
||||||
<DataCard title="Browser Distribution">
|
|
||||||
<div className="space-y-3">
|
|
||||||
{Object.entries(browserData.Browsers || {}).map(([key, value]) => (
|
|
||||||
<DataRow key={key} label={key} value={value} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</DataCard>
|
|
||||||
|
|
||||||
<DataCard title="Operating System Distribution">
|
|
||||||
<div className="space-y-3">
|
|
||||||
{Object.entries(browserData.OS || {}).map(([key, value]) => (
|
|
||||||
<DataRow key={key} label={key} value={value} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</DataCard>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{lastMonthData && (
|
|
||||||
<DataCard title="Last Month Visits">
|
|
||||||
<div className="space-y-3">
|
|
||||||
{Object.entries(lastMonthData || {}).map(([key, value]) => (
|
|
||||||
<DataRow key={key} label={key} value={value} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</DataCard>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{lastTwoMonthsData && (
|
|
||||||
<DataCard title="Last 2 Months Visits">
|
|
||||||
<div className="space-y-3">
|
|
||||||
{Object.entries(lastTwoMonthsData || {}).map(([key, value]) => (
|
|
||||||
<DataRow key={key} label={key} value={value} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</DataCard>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Visits;
|
|
Loading…
Reference in New Issue
Block a user