wip-error-fix api post new-p

This commit is contained in:
2025-11-24 15:20:45 -05:00
parent e3cb804671
commit 9a50ce6f2a
12 changed files with 736 additions and 250 deletions
+165 -3
View File
@@ -365,14 +365,176 @@ function App() {
)}
</>
) : (
/* Wristbands tab - your existing code stays the same */
<div className="space-y-6">
{/* ... your existing wristband code ... */}
<div className="bg-white rounded-lg shadow-sm p-6">
<h2 className="text-2xl font-bold mb-4">Wristband Inventory</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{wristbands.map(band => (
<div
key={band.band_id}
onClick={() => setSelectedWristband(band)}
className={`p-4 rounded-lg border-2 cursor-pointer transition-all ${
band.status === 'in_use'
? 'bg-blue-50 border-blue-300 hover:border-blue-400'
: 'bg-gray-50 border-gray-300 hover:border-gray-400'
}`}
>
<div className="flex items-center justify-between mb-2">
<span className="font-mono font-bold text-lg">
{band.type === 'real' ? '🔵' : '🟢'} {band.band_id}
</span>
<span className={`px-2 py-1 rounded text-xs font-semibold ${
band.status === 'in_use' ? 'bg-blue-600 text-white' :
band.status === 'available' ? 'bg-green-600 text-white' :
'bg-gray-400 text-white'
}`}>
{band.status.toUpperCase().replace('_', ' ')}
</span>
</div>
{band.patient_id && (
<div className="text-sm text-gray-600 mb-2">
Patient: <span className="font-mono font-semibold">{band.patient_id}</span>
</div>
)}
<div className="text-xs text-gray-500 flex justify-between">
<span>Packets: {band.packet_count}</span>
{band.is_monitoring && (
<span className="text-green-600 font-semibold"> LIVE</span>
)}
</div>
</div>
))}
</div>
{wristbands.length === 0 && (
<p className="text-gray-500 text-center py-8">No wristbands configured</p>
)}
</div>
{selectedWristband && selectedWristband.last_raw_packet && (
<div className="bg-white rounded-lg shadow-lg p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-xl font-bold flex items-center gap-2">
<span>Packet Details: {selectedWristband.band_id}</span>
{selectedWristband.type === 'simulated' && (
<span className="text-sm bg-green-100 text-green-800 px-2 py-1 rounded">MOCK</span>
)}
</h3>
<button
onClick={() => setSelectedWristband(null)}
className="text-gray-500 hover:text-gray-700 text-2xl font-bold"
>
</button>
</div>
<div className="mb-4">
<h4 className="font-semibold text-sm text-gray-600 mb-2">Raw Packet (16 bytes, Hex):</h4>
<div className="bg-gray-900 text-green-400 p-4 rounded font-mono text-sm overflow-x-auto">
{selectedWristband.last_raw_packet.hex.toUpperCase().match(/.{1,2}/g).join(' ')}
</div>
<p className="text-xs text-gray-500 mt-1">
Format: [ver][seq][timestamp][flags][hr][spo2][temp_x100][activity_x100][checksum][rfu]
</p>
</div>
{selectedWristband.last_raw_packet.decoded && (
<>
<div className="mb-4">
<h4 className="font-semibold text-sm text-gray-600 mb-3">Decoded Fields:</h4>
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
<div className="bg-gray-50 p-3 rounded border">
<div className="text-xs text-gray-600 mb-1">Version</div>
<div className="font-mono text-lg font-bold">0x{selectedWristband.last_raw_packet.decoded.version.toString(16).padStart(2, '0')}</div>
</div>
<div className="bg-gray-50 p-3 rounded border">
<div className="text-xs text-gray-600 mb-1">Sequence #</div>
<div className="font-mono text-lg font-bold">{selectedWristband.last_raw_packet.decoded.sequence}</div>
</div>
<div className="bg-gray-50 p-3 rounded border col-span-2">
<div className="text-xs text-gray-600 mb-1">Timestamp (ms)</div>
<div className="font-mono text-lg font-bold">{selectedWristband.last_raw_packet.decoded.timestamp_ms.toLocaleString()}</div>
</div>
<div className="bg-blue-50 p-3 rounded border">
<div className="text-xs text-gray-600 mb-1">Heart Rate</div>
<div className="font-mono text-2xl font-bold text-blue-600">{selectedWristband.last_raw_packet.decoded.hr_bpm}</div>
<div className="text-xs text-gray-500">bpm</div>
</div>
<div className="bg-green-50 p-3 rounded border">
<div className="text-xs text-gray-600 mb-1">SpO₂</div>
<div className="font-mono text-2xl font-bold text-green-600">{selectedWristband.last_raw_packet.decoded.spo2}</div>
<div className="text-xs text-gray-500">%</div>
</div>
<div className="bg-orange-50 p-3 rounded border">
<div className="text-xs text-gray-600 mb-1">Temperature</div>
<div className="font-mono text-2xl font-bold text-orange-600">{selectedWristband.last_raw_packet.decoded.temperature_c.toFixed(2)}</div>
<div className="text-xs text-gray-500">°C</div>
</div>
<div className="bg-purple-50 p-3 rounded border">
<div className="text-xs text-gray-600 mb-1">Activity</div>
<div className="font-mono text-2xl font-bold text-purple-600">{selectedWristband.last_raw_packet.decoded.activity.toFixed(2)}</div>
<div className="text-xs text-gray-500">RMS</div>
</div>
<div className="bg-gray-50 p-3 rounded border">
<div className="text-xs text-gray-600 mb-1">Checksum</div>
<div className="font-mono text-lg font-bold">{selectedWristband.last_raw_packet.decoded.checksum}</div>
</div>
<div className="bg-gray-50 p-3 rounded border">
<div className="text-xs text-gray-600 mb-1">Flags (raw)</div>
<div className="font-mono text-lg font-bold">0x{selectedWristband.last_raw_packet.decoded.flags.raw.toString(16).padStart(2, '0')}</div>
</div>
</div>
</div>
{selectedWristband.last_raw_packet.decoded.flags && (
<div className="mt-4">
<h4 className="font-semibold text-sm text-gray-600 mb-2">Status Flags:</h4>
<div className="flex flex-wrap gap-2">
{selectedWristband.last_raw_packet.decoded.flags.emergency && (
<span className="px-3 py-1 bg-red-100 text-red-800 rounded-full text-sm font-semibold border border-red-300">
🚨 Bit 4: Emergency
</span>
)}
{selectedWristband.last_raw_packet.decoded.flags.alert && (
<span className="px-3 py-1 bg-yellow-100 text-yellow-800 rounded-full text-sm font-semibold border border-yellow-300">
Bit 3: Alert
</span>
)}
{selectedWristband.last_raw_packet.decoded.flags.sensor_fault && (
<span className="px-3 py-1 bg-purple-100 text-purple-800 rounded-full text-sm font-semibold border border-purple-300">
Bit 2: Sensor Fault
</span>
)}
{selectedWristband.last_raw_packet.decoded.flags.low_battery && (
<span className="px-3 py-1 bg-orange-100 text-orange-800 rounded-full text-sm font-semibold border border-orange-300">
🔋 Bit 1: Low Battery
</span>
)}
{selectedWristband.last_raw_packet.decoded.flags.motion_artifact && (
<span className="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-semibold border border-blue-300">
👋 Bit 0: Motion Artifact
</span>
)}
{!Object.values(selectedWristband.last_raw_packet.decoded.flags).some(v => v === true) && (
<span className="px-3 py-1 bg-gray-100 text-gray-600 rounded-full text-sm font-semibold">
No flags set (all normal)
</span>
)}
</div>
</div>
)}
</>
)}
</div>
)}
</div>
)}
</div>
{/* Patient Detail Modal - ADD THIS */}
{/* Patient Detail Modal */}
{selectedPatient && (
<PatientDetailModal
patient={selectedPatient}