Skip to content

Commit

Permalink
user context
Browse files Browse the repository at this point in the history
  • Loading branch information
AmanRahees committed Feb 14, 2024
1 parent 96fda3e commit e4b1e96
Show file tree
Hide file tree
Showing 15 changed files with 319 additions and 68 deletions.
19 changes: 11 additions & 8 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
PublicRoute,
DoctorRoute,
CredentialRoute,
DocRestrictedRoute,
} from "@/routes/PublicRoute";

// Patient
Expand Down Expand Up @@ -55,14 +56,16 @@ function App() {
<Route path="/doctors/:id/:name/booking" element={<Booking />} />

<Route element={<PublicRoute />}>
<Route path="/profile" element={<Profile />} />
<Route path="/profile/appointments" element={<MyBookings />} />
<Route path="/profile/favourites" element={<Favourites />} />
<Route path="/profile/wallet" element={<Wallet />} />
<Route
path="/profile/change-password"
element={<PasswordChange />}
/>
<Route element={<DocRestrictedRoute />}>
<Route path="/profile" element={<Profile />} />
<Route path="/profile/appointments" element={<MyBookings />} />
<Route path="/profile/favourites" element={<Favourites />} />
<Route path="/profile/wallet" element={<Wallet />} />
<Route
path="/profile/change-password"
element={<PasswordChange />}
/>
</Route>
</Route>

<Route element={<DoctorRoute />}>
Expand Down
12 changes: 12 additions & 0 deletions src/components/Icons.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCircleCheck } from "@fortawesome/free-solid-svg-icons";

export const ApprovedIcon = () => {
return (
<FontAwesomeIcon
icon={faCircleCheck}
className="mx-1 text-green-400"
size="sm"
/>
);
};
36 changes: 20 additions & 16 deletions src/components/backend/Header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable no-unused-vars */
import React from "react";
import { useContext } from "react";
import { Link } from "react-router-dom";
import { Button } from "@/widgets/ui/button";
import {
DropdownMenu,
DropdownMenuTrigger,
Expand All @@ -12,10 +11,12 @@ import {
} from "@/widgets/ui/dropdown-menu";
import { ScrollArea } from "@/widgets/ui/scroll-area";
import { User, Settings, Power, Bell, Mail } from "lucide-react";
import AuthContext from "@/contexts/AuthContext";
import { Notification } from "@/data/notification";
import "./header.css";

function Header() {
const { userData, Logout } = useContext(AuthContext);
return (
<header className="adm-header_">
<DropdownMenu>
Expand Down Expand Up @@ -77,31 +78,34 @@ function Header() {
className="w-10 rounded-full"
/>
<div>
<p className="font-bold text-main">Aman Rahees</p>
<p className="font-bold text-main capitalize">
{userData?.username}
</p>
<small className="text-gray-500">Administrator</small>
</div>
</div>
</DropdownMenuLabel>
<hr className="my-1 border-gray-300" />
<DropdownMenuGroup className="px-1">
<DropdownMenuItem>
<Link className="flex items-center gap-2">
<Link>
<DropdownMenuItem className="flex items-center gap-2 cursor-pointer">
<User className="inline-block text-zinc-700" size={20} />
Profile
</Link>
</DropdownMenuItem>
<DropdownMenuItem>
<Link className="flex items-center gap-2">
</DropdownMenuItem>
</Link>
<Link>
<DropdownMenuItem className="flex items-center gap-2 cursor-pointer">
<Settings className="inline-block text-zinc-700" size={20} />
Settings
</Link>
</DropdownMenuItem>
</DropdownMenuItem>
</Link>
<hr className="my-1 border-gray-300" />
<DropdownMenuItem>
<Link className="flex items-center gap-2 text-red-600 hover:text-red-600">
<Power />
Logout
</Link>
<DropdownMenuItem
onClick={Logout}
className="flex items-center gap-2 text-red-600 focus:text-red-600 cursor-pointer"
>
<Power />
Logout
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
Expand Down
4 changes: 3 additions & 1 deletion src/components/backend/Layout/Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/* eslint-disable react/prop-types */
/* eslint-disable no-unused-vars */
import React, { useState } from "react";
import React, { useState, useContext } from "react";
import AuthContext from "@/contexts/AuthContext";
import Sidebar from "../Sidebar/Sidebar";
import Header from "../Header/Header";
import ExpiredAlert from "../Elements/ExpiredAlert";
import "./layout.css";

function Layout({ children }) {
const [isToken, setIsToken] = useState(true);
const { authTokens } = useContext(AuthContext);
return (
<div className="layout_">
<Sidebar />
Expand Down
83 changes: 61 additions & 22 deletions src/components/frontend/Aside/Aside.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,65 @@ import {
faLocationDot,
faPowerOff,
} from "@fortawesome/free-solid-svg-icons";
import { Stethoscope } from "lucide-react";
import { apiUrl } from "@/services/constants";
import { Skeleton } from "@/widgets/ui/skeleton";
import { ApprovedIcon } from "@/components/Icons";
import { stringDOB, getAge } from "@/func/DOB";

Aside.propTypes = {
items: PropTypes.array,
};

function Aside({ items }) {
function Aside({ items, userInfo, loading, role }) {
const location = useLocation();
return (
<aside className="pfl_n1 border">
<div className="flex flex-col justify-center items-center gap-1 p-5">
<img
src="https://icon-library.com/images/avatar-icon-images/avatar-icon-images-4.jpg"
alt=""
className="w-[80px] border rounded-full"
/>
<div className="text-center">
<p className="font-bold text-gray-700">Aman Rahees</p>
<small className="flex justify-center items-center gap-1 text-gray-600">
<FontAwesomeIcon icon={faCake} className="mb-1" /> 04 June 2004, 19
years
</small>
<small className="flex justify-center items-center gap-1 text-gray-600">
<FontAwesomeIcon icon={faLocationDot} className="mb-1" />{" "}
Mananthavady, Kerala
</small>
{!loading ? (
<div className="flex flex-col justify-center items-center gap-1 p-5">
<img
src={
userInfo?.picture
? `${apiUrl + userInfo.picture}`
: "https://icon-library.com/images/avatar-icon-images/avatar-icon-images-4.jpg"
}
alt=""
className="w-[80px] border rounded-full"
/>
{role === "doctor" ? (
<div className="text-center">
<p className="font-bold text-gray-800">
Dr. {userInfo?.name}
{userInfo?.is_approved ? <ApprovedIcon /> : ""}
</p>
<small className="font-bold text-secondary">
<Stethoscope size={15} className="inline-block" />{" "}
{userInfo?.speciality ? userInfo.speciality : "-"}
</small>
</div>
) : (
<div className="text-center">
<p className="font-bold text-gray-700">
{userInfo?.first_name}
{userInfo?.last_name}
</p>
<small className="flex justify-center items-center gap-1 text-gray-600">
<FontAwesomeIcon icon={faCake} className="mb-1" />{" "}
{stringDOB(userInfo?.DOB)}, {getAge("2024-01-15")}
</small>
<small className="flex justify-center items-center gap-1 text-gray-600">
<FontAwesomeIcon icon={faLocationDot} className="mb-1" />{" "}
{userInfo?.city}, {userInfo?.state}
</small>
</div>
)}
</div>
</div>
) : (
<div className="flex flex-col justify-center items-center gap-1 p-5">
<Skeleton className="w-[80px] h-[80px] bg-zinc-200 border rounded-full" />
<div className="text-center">
<Skeleton className="bg-zinc-200 h-4 w-[160px] rounded-none my-1" />
<Skeleton className="bg-zinc-200 h-4 w-[160px] rounded-none my-1" />
<Skeleton className="bg-zinc-200 h-4 w-[160px] rounded-none my-1" />
</div>
</div>
)}
<hr />
<div className="">
{items.map((item, index) => (
Expand All @@ -56,4 +88,11 @@ function Aside({ items }) {
);
}

Aside.propTypes = {
items: PropTypes.array,
userInfo: PropTypes.object,
loading: PropTypes.bool,
role: PropTypes.string,
};

export default Aside;
28 changes: 26 additions & 2 deletions src/components/frontend/Board/Board.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
/* eslint-disable no-unused-vars */
import React from "react";
import React, { useContext, useEffect } from "react";
import PropTypes from "prop-types";
import { useSelector, useDispatch } from "react-redux";
import AuthContext from "@/contexts/AuthContext";
import Layout from "@/components/frontend/Layout/Layout";
import Aside from "@/components/frontend/Aside/Aside";
import {
getPatientInfo,
getDoctorInfo,
getAdminInfo,
} from "@/redux/actions/userActions";
import { patientItems } from "./items";
import { doctortItems } from "./items";
import "./board.css";
Expand All @@ -12,11 +19,28 @@ Board.propTypes = {
};

function Board({ children }) {
const { userData } = useContext(AuthContext);
const { userInfo, loading, error } = useSelector((state) => state.user);
const dispatch = useDispatch();
useEffect(() => {
if (userData?.role === "doctor") {
dispatch(getDoctorInfo(userData));
} else if (userData?.role === "admin") {
//
} else if (userData?.role === "patient") {
dispatch(getPatientInfo(userData));
}
}, [dispatch, userData]);
return (
<Layout>
<div className="p-3 lg:py-20 lg:px-32">
<main className="pfl_wrapper">
<Aside items={doctortItems} />
<Aside
items={userData.role === "doctor" ? doctortItems : patientItems}
userInfo={userInfo}
loading={loading}
role={userData.role}
/>
<div className="pfl_n2 border p-5">{children}</div>
</main>
</div>
Expand Down
31 changes: 25 additions & 6 deletions src/components/frontend/Navbar/NavDropdown.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import { LogOut, User, Wallet } from "lucide-react";
import { LogOut, User, Wallet, LayoutDashboard } from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
Expand Down Expand Up @@ -37,12 +37,31 @@ const NavDropdown = ({ user, userLogout }) => {
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<Link to={`/profile`} className="w-full h-full">
<DropdownMenuItem className="flex items-center gap-1 cursor-pointer">
<User className="inline-block text-zinc-700" size={20} /> Profile
</DropdownMenuItem>
<Link
to={user?.role === "doctor" ? "/doctor/dashboard" : `/profile`}
className="w-full h-full"
>
{user?.role === "doctor" ? (
<DropdownMenuItem className="flex items-center gap-1 cursor-pointer">
<LayoutDashboard
className="inline-block text-zinc-700"
size={20}
/>
Dashboard
</DropdownMenuItem>
) : (
<DropdownMenuItem className="flex items-center gap-1 cursor-pointer">
<User className="inline-block text-zinc-700" size={20} /> Profile
</DropdownMenuItem>
)}
</Link>
<Link to={`/profile/wallet`}>
<Link
to={
user?.role === "doctor"
? "/doctor/dashboard/wallet"
: `/profile/wallet`
}
>
<DropdownMenuItem className="flex justify-between items-center w-full cursor-pointer">
<span className="flex gap-1">
<Wallet className="inline-block text-zinc-700" size={20} />
Expand Down
23 changes: 23 additions & 0 deletions src/func/DOB.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export const stringDOB = (DOB) => {
let dobDate = new Date(DOB);
let options = { day: "2-digit", month: "long", year: "numeric" };
return dobDate.toLocaleDateString("en-US", options);
};

export const getAge = (DOB) => {
let dobDate = new Date(DOB);
let currentDate = new Date();
let age = currentDate.getFullYear() - dobDate.getFullYear();
if (
currentDate.getMonth() < dobDate.getMonth() ||
(currentDate.getMonth() === dobDate.getMonth() &&
currentDate.getDate() < dobDate.getDate())
) {
age--;
}
if (age < 1) {
return "Infant";
} else {
return age + " years";
}
};
21 changes: 15 additions & 6 deletions src/pages/frontend/Auth/OtpBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import OtpInput from "react-otp-input";
import axiosInstance from "@/services/axios";
import VerificationImg from "@/assets/images/verify.png";
import { DialogClose } from "@radix-ui/react-dialog";

function OtpBox({ email, setIsVerified, isEmailValid }) {
const [otp, setOtp] = useState(0);
Expand Down Expand Up @@ -67,11 +68,15 @@ function OtpBox({ email, setIsVerified, isEmailValid }) {
<div className="flex justify-center">
<img src={VerificationImg} alt="" className="w-[120px]" />
</div>
<DialogDescription className="text-center">
Enter the 6 digit code send to{" "}
<span className="font-bold text-primary">{email}</span>
<span className="block text-red-600">{error}</span>
</DialogDescription>
{!is409 && (
<DialogDescription className="text-center">
Enter the 6 digit code send to{" "}
<span className="font-bold text-primary">{email}</span>
</DialogDescription>
)}
{is409 && (
<span className="block text-red-600 text-center">{error}</span>
)}
</DialogHeader>
{!is409 && (
<div className="flex justify-center">
Expand All @@ -94,14 +99,18 @@ function OtpBox({ email, setIsVerified, isEmailValid }) {
</div>
)}
<DialogFooter>
{!is409 && (
{!is409 ? (
<button
type="button"
onClick={() => handleVerification(parseInt(otp, 10))}
className="bg-secondary text-white py-2 px-3 rounded-md"
>
Submit
</button>
) : (
<DialogClose className="bg-primary text-white py-2 px-3 rounded-md text-sm">
Close
</DialogClose>
)}
</DialogFooter>
</DialogContent>
Expand Down
Loading

0 comments on commit e4b1e96

Please sign in to comment.