From 92c7ed6cb8f789948f1b7194b0761d2bc6cdd066 Mon Sep 17 00:00:00 2001 From: Sinan Date: Fri, 27 Sep 2024 13:25:25 +0530 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20video=20section=20pages=20updated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../video-section/[sectionId]/layout.tsx | 12 +++++++ .../video-section/{ => [sectionId]}/page.tsx | 12 ++++--- .../components/button/VideoButtonPatient.tsx | 32 +++++------------ ...eoCallModal.tsx => VideoSectionsModel.tsx} | 34 +++++++----------- .../page-components/video/ControlPanel.tsx | 14 ++++---- .../video/PatientVideoLayout.tsx | 35 +++++++++++++++++++ client/components/skeletons/VideoSection.tsx | 15 ++++++++ client/types/entities.ts | 20 +++++++++-- client/types/enum.ts | 24 +++++++------ 9 files changed, 129 insertions(+), 69 deletions(-) create mode 100644 client/app/(patient)/video-section/[sectionId]/layout.tsx rename client/app/(patient)/video-section/{ => [sectionId]}/page.tsx (87%) rename client/components/models/{VideoCallModal.tsx => VideoSectionsModel.tsx} (78%) create mode 100644 client/components/page-components/video/PatientVideoLayout.tsx create mode 100644 client/components/skeletons/VideoSection.tsx diff --git a/client/app/(patient)/video-section/[sectionId]/layout.tsx b/client/app/(patient)/video-section/[sectionId]/layout.tsx new file mode 100644 index 00000000..612e3cbd --- /dev/null +++ b/client/app/(patient)/video-section/[sectionId]/layout.tsx @@ -0,0 +1,12 @@ +import PatientVideoLayout from '@/components/page-components/video/PatientVideoLayout'; +import { ReactNode } from 'react'; + +const layout = ({ children }: { children: ReactNode; }) => { + return ( + + {children} + + ) +} + +export default layout \ No newline at end of file diff --git a/client/app/(patient)/video-section/page.tsx b/client/app/(patient)/video-section/[sectionId]/page.tsx similarity index 87% rename from client/app/(patient)/video-section/page.tsx rename to client/app/(patient)/video-section/[sectionId]/page.tsx index c4b22927..8a33c782 100644 --- a/client/app/(patient)/video-section/page.tsx +++ b/client/app/(patient)/video-section/[sectionId]/page.tsx @@ -5,11 +5,13 @@ import { VideoIcon, PhoneIcon } from "lucide-react" import VideoChat from '@/components/page-components/video/VideoChat' import { ButtonV2 } from '@/components/button/ButtonV2' import { useState } from "react" +import { useParams } from "next/navigation" export default function VideoCallPage() { - const [isCalling, setIsCalling] = useState(false) - const [localStream, setLocalStream] = useState(null) - + const [isCalling, setIsCalling] = useState(false); + const [localStream, setLocalStream] = useState(null); + const sectionId = useParams().sectionId as string; + const handleStartCall = async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true }) @@ -25,8 +27,8 @@ export default function VideoCallPage() { if (localStream) { localStream.getTracks().forEach(track => track.stop()) } - setLocalStream(null) - setIsCalling(false) + setLocalStream(null); + setIsCalling(false); } return ( diff --git a/client/components/button/VideoButtonPatient.tsx b/client/components/button/VideoButtonPatient.tsx index 7ab97f6f..a39ebe23 100644 --- a/client/components/button/VideoButtonPatient.tsx +++ b/client/components/button/VideoButtonPatient.tsx @@ -4,53 +4,39 @@ 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; -}; +import VideoCallModal from '../models/VideoSectionsModel'; const VideoButtonPatient = () => { - const [isModalOpen, setIsModalOpen] = useState(false); - const [upcomingAppointments, setUpcomingAppointments] = useState([]); - 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); + console.log('Video button clicked'); } return ( <> - Video Calls - {upcomingAppointments.length > 0 && ( + {upcomingSections.length > 0 && ( - {upcomingAppointments.length} + {upcomingSections.length} - )} + )} */} View Upcoming Video Calls - + /> */} ) } diff --git a/client/components/models/VideoCallModal.tsx b/client/components/models/VideoSectionsModel.tsx similarity index 78% rename from client/components/models/VideoCallModal.tsx rename to client/components/models/VideoSectionsModel.tsx index 6de0319a..aa45ac1b 100644 --- a/client/components/models/VideoCallModal.tsx +++ b/client/components/models/VideoSectionsModel.tsx @@ -14,38 +14,28 @@ import { Card, CardContent } from "@/components/ui/card"; import { XIcon, Video } from "lucide-react"; import { ButtonV2 } from "../button/ButtonV2"; import Link from "next/link"; +import IVideoSection from "@/types/entities"; +import { format } from "date-fns" -type Appointment = { - _id: string; - patientName: string; - startTime: Date; -}; type Props = { open: boolean; setOpen: Dispatch>; - appointments: Appointment[]; + sections: IVideoSection[]; link: string; }; export default function VideoCallModal({ open, setOpen, - appointments, + sections, 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 ( + return ( @@ -58,17 +48,17 @@ export default function VideoCallModal({
- {appointments.length > 0 ? ( + {sections.length > 0 ? ( <> - {appointments.map((appointment) => ( - + {sections.map((section) => ( +

- No upcoming video calls in the next hour. + No upcoming video Sections in the next hour.

)} diff --git a/client/components/page-components/video/ControlPanel.tsx b/client/components/page-components/video/ControlPanel.tsx index dfd60559..adbcfc0d 100644 --- a/client/components/page-components/video/ControlPanel.tsx +++ b/client/components/page-components/video/ControlPanel.tsx @@ -1,4 +1,4 @@ -import { Button } from "@/components/ui/button" +import { ButtonV2 } from "@/components/button/ButtonV2" import { Mic, MicOff, Video, VideoOff, PhoneOff } from 'lucide-react' import { useState } from "react" @@ -23,30 +23,30 @@ export default function ControlPanel({ onEndCall }: ControlPanelProps) { return (
- - - +
) diff --git a/client/components/page-components/video/PatientVideoLayout.tsx b/client/components/page-components/video/PatientVideoLayout.tsx new file mode 100644 index 00000000..b5fc198b --- /dev/null +++ b/client/components/page-components/video/PatientVideoLayout.tsx @@ -0,0 +1,35 @@ +'use client' +import { useAuth } from '@/lib/hooks/useAuth'; +import { ReactNode, useEffect, useState } from 'react' +import { notFound } from 'next/navigation'; +import VideoCallSkeleton from '@/components/skeletons/VideoSection'; + +const PatientVideoLayout = ({ children }: { children: ReactNode }) => { + const [isLoading, setLoading] = useState(true); + const { patientToken } = useAuth(); + const isPatient = !!patientToken; + + useEffect(() => { + if (isPatient) { + const timer = setTimeout(() => { + setLoading(false); + }, 0); + return () => clearTimeout(timer); + } else { + setLoading(false); + } + }, [isPatient]); + + if(isLoading){ + return + } + + if (!isPatient) { + notFound() + } + return ( +
{children}
+ ) +} + +export default PatientVideoLayout \ No newline at end of file diff --git a/client/components/skeletons/VideoSection.tsx b/client/components/skeletons/VideoSection.tsx new file mode 100644 index 00000000..5b73ca55 --- /dev/null +++ b/client/components/skeletons/VideoSection.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import { Card } from "@/components/ui/card" +import { Skeleton } from "@/components/ui/skeleton" + +export default function VideoCallSkeleton() { + return ( +
+ + + + + +
+ ) +} \ No newline at end of file diff --git a/client/types/entities.ts b/client/types/entities.ts index 3f2ca91c..0e22a5db 100644 --- a/client/types/entities.ts +++ b/client/types/entities.ts @@ -1,4 +1,4 @@ -import { AppointmentStatus, AppointmentType, Days, NotificationTypes } from "./enum"; +import { AppointmentStatus, AppointmentType, Days, NotificationTypes, VideoSectionStatus } from "./enum"; export interface IPatient { _id?: string; @@ -36,7 +36,7 @@ export interface ISlot { day?: Days; startTime?: string; endTime?: string; - status?: "available" | "booked"; + status?: "available" | "booked"; } export interface IAppointment { @@ -95,3 +95,19 @@ export interface IMessage { readonly isReceived?: boolean; } +export default interface IVideoSection { + _id?: string; + appointmentId?: string; + doctorName?: string; + patientName?: string; + doctorProfile?: string; + doctorId?: string; + patientProfile?: string; + patientId?: string; + createdAt?: Date; + updatedAt?: Date; + startTime?: Date | string; + endTime?: Date | string; + link?: string; + status?: VideoSectionStatus; +} diff --git a/client/types/enum.ts b/client/types/enum.ts index e2ed6c4b..b1a7c91f 100644 --- a/client/types/enum.ts +++ b/client/types/enum.ts @@ -12,7 +12,7 @@ export enum Days { Friday = "friday", Saturday = "saturday", Sunday = "sunday" -}export enum AppointmentStatus { +} export enum AppointmentStatus { // PAYMENT_PENDING = "payment-pending", PENDING = "pending", CONFIRMED = "confirmed", @@ -29,13 +29,17 @@ export enum NotificationTypes { APPOINTMENT_REMINDER = 'appointment_reminder' } export enum FormFieldType { - INPUT = "input", - TEXTAREA = "textarea", - PHONE_INPUT = "phoneInput", - CHECKBOX = "checkbox", - DATE_PICKER = "datePicker", - SELECT = "select", - SKELETON = "skeleton", - PASSWORD = "password" + INPUT = "input", + TEXTAREA = "textarea", + PHONE_INPUT = "phoneInput", + CHECKBOX = "checkbox", + DATE_PICKER = "datePicker", + SELECT = "select", + SKELETON = "skeleton", + PASSWORD = "password" +} +export enum VideoSectionStatus { + PENDING = 'pending', + IN_PROGRESS = 'in_progress', + COMPLETED = 'completed', } -