Files
TeleEms-Dashboard/src/pages/hospital/TeleLinkHub.tsx

219 lines
8.5 KiB
TypeScript

import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
Video,
VideoOff,
Mic,
MicOff,
PhoneOff,
User,
Activity,
MessageSquare,
ClipboardList,
AlertCircle,
MoreVertical,
Shield,
Clock,
CheckCircle2,
XCircle,
MessageCircle
} from 'lucide-react';
import { Card } from '../../components/Common';
export const TeleLinkHub: React.FC = () => {
const [activeCall, setActiveCall] = useState<any>(null);
const [activeTab, setActiveTab] = useState<'CALL' | 'HISTORY'>('CALL');
const incomingRequests = [
{ id: 'TL-101', patient: 'Rajesh Khanna', triage: 'RED', wait: '1:45', complaint: 'Cardiac Arrest', symptoms: 'Ongoing CPR, 2 shocks delivered' },
{ id: 'TL-102', patient: 'Unknown Male', triage: 'RED', wait: '0:30', complaint: 'Potential Stroke', symptoms: 'GCS 12, unilateral weakness' },
];
const callHistory = [
{ id: 'TL-098', date: '2026-05-04', duration: '12m 45s', patient: 'Amit Shah', outcome: 'Admission Admitted', emt: 'Arjun K.' },
{ id: 'TL-095', date: '2026-05-04', duration: '08m 20s', patient: 'Priya Verma', outcome: 'Consult Completed', emt: 'Suman R.' },
];
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="module-content"
>
<div className="module-header-modern">
<div className="title-wrap">
<h3>TELELINK COMMAND CENTER</h3>
<div className="live-pill">
<span className="pulse" /> ERCP PHYSICIAN CONSOLE
</div>
</div>
<div className="tab-switcher-premium">
<button
className={`tab-btn ${activeTab === 'CALL' ? 'active' : ''}`}
onClick={() => setActiveTab('CALL')}
>
ACTIVE SESSIONS
</button>
<button
className={`tab-btn ${activeTab === 'HISTORY' ? 'active' : ''}`}
onClick={() => setActiveTab('HISTORY')}
>
CONSULT HISTORY
</button>
</div>
</div>
{activeTab === 'CALL' ? (
<div className="telelink-main-grid">
{/* Call Queue */}
<div className="call-queue-panel">
<div className="panel-header-mini">
<h4>INCOMING REQUESTS</h4>
<span className="count-badge">{incomingRequests.length}</span>
</div>
<div className="queue-list">
{incomingRequests.map(req => (
<div key={req.id} className={`queue-item triage-${req.triage.toLowerCase()}`}>
<div className="q-header">
<span className="q-id">{req.id}</span>
<span className="q-wait"><Clock size={12} /> {req.wait}</span>
</div>
<div className="q-body">
<div className="q-patient">{req.patient}</div>
<div className="q-complaint">{req.complaint}</div>
</div>
<div className="q-actions">
<button className="q-btn accept" onClick={() => setActiveCall(req)}>ACCEPT</button>
<button className="q-btn decline">DECLINE</button>
</div>
</div>
))}
</div>
</div>
{/* Active Call Surface */}
<div className="call-surface-panel-premium">
<div className="surface-glass-glow" />
{activeCall ? (
<div className="active-call-grid">
<div className="video-workspace">
<div className="video-feed-main">
<div className="feed-header-overlay">
<div className="secure-badge">
<Shield size={14} /> 256-BIT ENCRYPTED
</div>
<div className="call-duration">12:45</div>
</div>
<div className="video-placeholder-premium">
<div className="video-pulse-icon">
<Video size={48} />
</div>
<p>INITIALIZING SECURE VIDEO FEED...</p>
<div className="patient-id-overlay">
<span className="p-triage" data-triage={activeCall.triage.toLowerCase()}>{activeCall.triage}</span>
<div className="p-name-stack">
<span className="name">{activeCall.patient}</span>
<span className="id">CASE: {activeCall.id}</span>
</div>
</div>
</div>
<div className="video-actions-floating">
<button className="v-float-btn"><Mic size={20} /></button>
<button className="v-float-btn active"><Video size={20} /></button>
<button className="v-float-btn end-session" onClick={() => setActiveCall(null)}><PhoneOff size={20} /></button>
<div className="v-divider-vertical" />
<button className="v-float-btn"><MessageCircle size={20} /></button>
</div>
</div>
</div>
<div className="clinical-data-rail">
<div className="rail-section">
<div className="rail-head">
<Activity size={16} /> <h4>LIVE VITALS</h4>
</div>
<div className="vitals-mini-grid">
<div className="v-stat-card">
<label>HEART RATE</label>
<div className="val">102<small>BPM</small></div>
</div>
<div className="v-stat-card">
<label>SPO2</label>
<div className="val">94%</div>
</div>
<div className="v-stat-card">
<label>BP</label>
<div className="val">130/85</div>
</div>
<div className="v-stat-card warning">
<label>TEMP</label>
<div className="val">101.4<small>°F</small></div>
</div>
</div>
</div>
<div className="rail-section grow">
<div className="rail-head">
<ClipboardList size={16} /> <h4>TELE-CONSULT NOTES</h4>
</div>
<textarea className="clinical-input" placeholder="Type clinical advice, prescriptions, or observations..." />
<button className="commit-btn">COMMIT TO EPCR</button>
</div>
</div>
</div>
) : (
<div className="idle-surface-placeholder">
<div className="idle-icon-wrap">
<VideoOff size={64} />
<div className="idle-ring" />
</div>
<h3>READY FOR UPLINK</h3>
<p>Select a pending triage request from the queue to bridge TeleLink session</p>
</div>
)}
</div>
</div>
) : (
<div className="history-panel-full">
<table className="staff-table-premium">
<thead>
<tr>
<th>Session ID & Date</th>
<th>Patient</th>
<th>Duration</th>
<th>EMT / Field Provider</th>
<th>Clinical Outcome</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{callHistory.map(h => (
<tr key={h.id}>
<td>
<div style={{ fontWeight: 700 }}>{h.id}</div>
<div style={{ fontSize: '0.75rem', color: 'var(--text-secondary)' }}>{h.date}</div>
</td>
<td>{h.patient}</td>
<td>{h.duration}</td>
<td>{h.emt}</td>
<td>
<span className="status-badge" style={{ background: 'rgba(16, 185, 129, 0.1)', color: 'var(--accent-green)' }}>
{h.outcome}
</span>
</td>
<td>
<button className="tag-btn"><ClipboardList size={14} /></button>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</motion.div>
);
};