Skip to content

Commit

Permalink
🚀 video section notification icon added
Browse files Browse the repository at this point in the history
  • Loading branch information
sinanptm committed Sep 26, 2024
1 parent 5e6d2ef commit 87b4aaf
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 2 deletions.
58 changes: 58 additions & 0 deletions client/components/button/VideoButtonPatient.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client';

import React, { useState } from 'react';
import { ButtonV2 } from './ButtonV2';
import Image from 'next/image';
import { Badge } from '@/components/ui/badge'
import VideoCallModal from '../models/VideoCallModal';

type Appointment = {
_id: string;
patientName: string;
startTime: Date;
};

const VideoButtonPatient = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const [upcomingAppointments, setUpcomingAppointments] = useState<Appointment[]>([]);

const handleClick = () => {
const dummyAppointments: Appointment[] = [
{ _id: '1', patientName: 'John Doe', startTime: new Date(Date.now() + 30 * 60000) },
{ _id: '2', patientName: 'Jane Smith', startTime: new Date(Date.now() + 45 * 60000) },
];
setUpcomingAppointments(dummyAppointments);
setIsModalOpen(true);
}

return (
<>
<ButtonV2 variant="ghost" size="icon" className="relative" onClick={handleClick}>
<Image
src="/assets/icons/utils/video.svg"
width={20}
height={20}
alt="Video Calls"
className="text-muted-foreground"
/>
{upcomingAppointments.length > 0 && (
<Badge
variant="destructive"
className="absolute -right-1 -top-1 h-5 w-5 rounded-full p-0 text-xs flex items-center justify-center"
>
{upcomingAppointments.length}
</Badge>
)}
<span className="sr-only">View Upcoming Video Calls</span>
</ButtonV2>
<VideoCallModal
open={isModalOpen}
setOpen={setIsModalOpen}
appointments={upcomingAppointments}
link="/video-call"
/>
</>
)
}

export default VideoButtonPatient
1 change: 0 additions & 1 deletion client/components/layout/AdminLayoutWithSideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { cn } from "@/lib/utils";
import { Package2, PanelLeft, Search } from "lucide-react";

import { Button } from "@/components/ui/button";
import {
DropdownMenu,
Expand Down
5 changes: 4 additions & 1 deletion client/components/layout/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { useState } from "react";
import LogoutModel from "../models/LogoutModel";
import { ButtonV2 } from "../button/ButtonV2";
import NotificationButtonPatient from "../button/NotificationButtonPatient";
import VideoButtonPatient from "../button/VideoButtonPatient";

export const NavBar = () => {
const path = usePathname();
Expand All @@ -30,6 +31,7 @@ export const NavBar = () => {
const { patientToken, setCredentials, logout } = useAuth();
const [isLogoutModelOpen, setLogoutModelOpen] = useState(false);
const [isSheetOpen, setIsSheetOpen] = useState(false);
const isAuthorized = !!patientToken

if (path.includes("signup") || path.includes("admin") || path.includes("signin") || path.includes("doctor")) {
return null;
Expand Down Expand Up @@ -131,6 +133,7 @@ export const NavBar = () => {
</SheetContent>
</Sheet>
<div className="flex items-center gap-4">
<VideoButtonPatient />
<NotificationButtonPatient />
<DropdownMenu>
<DropdownMenuTrigger asChild>
Expand All @@ -146,7 +149,7 @@ export const NavBar = () => {
</ButtonV2>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="mt-3">
{patientToken !== "" ? (
{isAuthorized ? (
<>
<DropdownMenuLabel className="cursor-pointer">
<Link href={"/profile"}>My Account</Link>
Expand Down
113 changes: 113 additions & 0 deletions client/components/models/VideoCallModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client';

import { Dispatch, SetStateAction } from "react";
import Image from "next/image";
import {
AlertDialog,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Card, CardContent } from "@/components/ui/card";
import { XIcon, Video } from "lucide-react";
import { ButtonV2 } from "../button/ButtonV2";
import Link from "next/link";

type Appointment = {
_id: string;
patientName: string;
startTime: Date;
};

type Props = {
open: boolean;
setOpen: Dispatch<SetStateAction<boolean>>;
appointments: Appointment[];
link: string;
};

export default function VideoCallModal({
open,
setOpen,
appointments,
link
}: Props) {
const closeModal = () => {
setOpen(false);
};

const formatTimeLeft = (startTime: Date) => {
const now = new Date();
const diff = startTime.getTime() - now.getTime();
const minutes = Math.floor(diff / 60000);
return `${minutes} minute${minutes !== 1 ? 's' : ''} left`;
};

return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogContent className="max-w-3xl bg-dark-200">
<AlertDialogHeader>
<AlertDialogTitle className="flex items-center justify-between text-2xl font-semibold">
Upcoming Video Calls
<ButtonV2 variant="ghost" size="icon" onClick={closeModal} aria-label="Close">
<XIcon className="h-6 w-6" />
</ButtonV2>
</AlertDialogTitle>
</AlertDialogHeader>
<AlertDialogDescription></AlertDialogDescription>
<div className="space-y-4">
{appointments.length > 0 ? (
<>
{appointments.map((appointment) => (
<Link key={appointment._id} href={`${link}/${appointment._id}`} onClick={closeModal} >
<Card>
<CardContent className="flex items-center justify-between p-4">
<div className="flex items-center space-x-4">
<Video className="h-6 w-6 text-primary" />
<div>
<h3 className="font-semibold">{appointment.patientName}</h3>
<p className="text-sm text-muted-foreground">{formatTimeLeft(appointment.startTime)}</p>
</div>
</div>
<ButtonV2
variant="expandIcon"
size="icon"
iconPlacement="left"
Icon={Video}
className="text-primary hover:text-primary-foreground w-20"
aria-label="Join call"
>
Join
</ButtonV2>
</CardContent>
</Card>
</Link>
))}
</>
) : (
<div className="flex flex-col items-center justify-center space-y-2 py-6">
<Image
src="/assets/icons/emoji/😴.svg"
width={64}
height={64}
alt="No Upcoming Calls"
className="opacity-50"
/>
<p className="text-center text-muted-foreground text-sm">
No upcoming video calls in the next hour.
</p>
</div>
)}
</div>

<AlertDialogFooter>
<div className="flex justify-end space-x-2">
<ButtonV2 variant={'gooeyRight'} onClick={closeModal}>Close</ButtonV2>
</div>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}

1 comment on commit 87b4aaf

@vercel
Copy link

@vercel vercel bot commented on 87b4aaf Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.