// Consolidated staff Messages shell (Slice 2a). Role-gated top tabs; each tab renders a self-contained // panel that owns its own list/browse + . Backends unchanged per panel. import React, { useEffect, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { useAuthServiceContext, useStaffPermissionServiceContext } from '../../../services'; import clsx from 'clsx'; import { ColleaguesPanel } from './panels/ColleaguesPanel'; import { PatientsPanel } from './panels/PatientsPanel'; import { CollaborationTeamsPanel } from './panels/CollaborationTeamsPanel'; import { PatientMessagingToggle } from './PatientMessagingToggle'; import { Card, CardContent, CardTitle } from '../../../components/ui/card'; import { MESSAGES_PAGE_BODY, MESSAGES_PAGE_HEIGHT } from '../../../utils/messagesLayout'; import { DeskMessages, useMessagesTop } from './DeskMessages'; import './ClinicMessages.css'; type StaffTab = 'patients' | 'colleagues' | 'teams'; interface MessagesDeepLink { tab?: StaffTab; openRequestId?: string; openWith?: string; openTeamId?: string; openVariant?: 'public' | 'aside' } const StaffMessagesPage: React.FC = () => { const { userRole, USER_ROLES, selectedWorkspace } = useAuthServiceContext(); const { activeWorkspace } = useStaffPermissionServiceContext(); const activeUserRole = activeWorkspace ?? selectedWorkspace ?? userRole; const location = useLocation(); const navigate = useNavigate(); const canSeePatients = activeUserRole === USER_ROLES.PRACTITIONER || activeUserRole === USER_ROLES.RECEPTIONIST; const isPractitioner = activeUserRole === USER_ROLES.PRACTITIONER; const deepLink = (location.state as MessagesDeepLink | null) || {}; const [activeTab, setActiveTab] = useState( deepLink.tab === 'patients' && canSeePatients ? 'patients' : deepLink.tab === 'teams' && isPractitioner ? 'teams' : deepLink.tab === 'colleagues' ? 'colleagues' : (canSeePatients ? 'patients' : 'colleagues'), ); // Capture the deep-link open intent once, then clear router state so a refresh doesn't reopen. const [pending] = useState(deepLink); useEffect(() => { if (deepLink.tab || deepLink.openRequestId || deepLink.openWith || deepLink.openTeamId) { navigate(location.pathname, { replace: true, state: null }); } }, []); // eslint-disable-line react-hooks/exhaustive-deps const fitRef = useMessagesTop(); if (activeUserRole === USER_ROLES.RECEPTIONIST) { return ; } const tabs: { id: StaffTab; label: string }[] = [ ...(canSeePatients ? [{ id: 'patients' as const, label: 'Patients' }] : []), { id: 'colleagues', label: 'Colleagues' }, ...(isPractitioner ? [{ id: 'teams' as const, label: 'Collaboration Teams' }] : []), ]; return (
Messages {!canSeePatients && !isPractitioner &&

Conversations with your practice colleagues.

} {/* The practitioner's own switch lives on their Messages page, above the tabs. */} {(canSeePatients || isPractitioner) && } {/* A workspace that can message colleagues alone shows the colleague panel's own row instead. */} {(canSeePatients || isPractitioner) && (
{tabs.map(({ id, label }) => ( ))}
)} {activeTab === 'teams' && isPractitioner ? ( ) : activeTab === 'patients' && canSeePatients ? ( ) : ( )}
); }; export default StaffMessagesPage;