diff --git a/components/incoming-call-notification.tsx b/components/incoming-call-notification.tsx new file mode 100644 index 0000000..d8e06ea --- /dev/null +++ b/components/incoming-call-notification.tsx @@ -0,0 +1,130 @@ +"use client"; + +import { useState, useEffect } from 'react'; +import { Phone, PhoneOff, X } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { useRouter } from 'next/navigation'; + +export interface IncomingCall { + from: { + userId: string; + username: string; + name: string; + }; + roomId: string; + roomName: string; + timestamp: Date; +} + +interface IncomingCallNotificationProps { + call: IncomingCall | null; + onDismiss: () => void; + onAccept: (roomId: string) => void; + onReject: () => void; +} + +export function IncomingCallNotification({ + call, + onDismiss, + onAccept, + onReject, +}: IncomingCallNotificationProps) { + const router = useRouter(); + const [isVisible, setIsVisible] = useState(false); + + useEffect(() => { + if (call) { + setIsVisible(true); + + // Auto-dismiss after 30 seconds if user doesn't interact + const autoDismissTimer = setTimeout(() => { + setIsVisible(false); + onDismiss(); + }, 30000); // 30 seconds + + return () => { + clearTimeout(autoDismissTimer); + }; + } else { + setIsVisible(false); + } + }, [call, onDismiss]); + + if (!call || !isVisible) { + return null; + } + + const handleAccept = () => { + onAccept(call.roomId); + // Navigate to parole page with room ID + router.push(`/parole?room=${call.roomId}`); + setIsVisible(false); + }; + + const handleReject = () => { + onReject(); + setIsVisible(false); + }; + + const handleDismiss = () => { + onDismiss(); + setIsVisible(false); + }; + + const callerName = call.from.name || call.from.username || 'Inconnu'; + + return ( +
+
+ {/* Header with Outlook-like style */} +
+
+
+ +
+
+

Parole

+

Appel entrant

+
+
+ +
+ + {/* Call Info - Outlook style message */} +
+

+ Vous avez un appel de {callerName} +

+ {call.roomName && call.roomName !== callerName && ( +

Dans {call.roomName}

+ )} +
+ + {/* Actions - Outlook style buttons */} +
+ + +
+
+
+ ); +} diff --git a/components/layout/layout-wrapper.tsx b/components/layout/layout-wrapper.tsx index 77ad7f0..3d234a6 100644 --- a/components/layout/layout-wrapper.tsx +++ b/components/layout/layout-wrapper.tsx @@ -9,6 +9,7 @@ import { Toaster } from "@/components/ui/toaster"; import { useBackgroundImage } from "@/components/background-switcher"; import { clearAuthCookies, clearKeycloakCookies } from "@/lib/session"; import { useRocketChatCalls } from "@/hooks/use-rocketchat-calls"; +import { IncomingCallNotification } from "@/components/incoming-call-notification"; interface LayoutWrapperProps { children: React.ReactNode; @@ -206,6 +207,23 @@ export function LayoutWrapper({ children, isSignInPage, isAuthenticated }: Layou {!isSignInPage && isAuthenticated &&