commit
32a36cceff
444 files changed
+67186
No files matched your search
@@ -0,0 +1,91 @@
|
||||
import React from 'react';
|
||||
import { FeedSackLogEntry } from '../../types.ts';
|
||||
|
||||
const BoundingBox: React.FC<{
|
||||
top: string;
|
||||
left: string;
|
||||
width: string;
|
||||
height: string;
|
||||
delay: string;
|
||||
color: string;
|
||||
}> = ({ top, left, width, height, delay, color }) => (
|
||||
<div
|
||||
className={`absolute border-2 bg-opacity-20 rounded-sm animate-pulse`}
|
||||
style={{
|
||||
top,
|
||||
left,
|
||||
width,
|
||||
height,
|
||||
animationDelay: delay,
|
||||
borderColor: color,
|
||||
backgroundColor: color,
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
|
||||
interface LiveFeedViewProps {
|
||||
mode: 'inbound' | 'usage';
|
||||
latestLog?: FeedSackLogEntry;
|
||||
}
|
||||
|
||||
const LiveFeedView: React.FC<LiveFeedViewProps> = ({ mode, latestLog }) => {
|
||||
const config = {
|
||||
inbound: {
|
||||
title: 'Kamera Pintu Masuk Gudang',
|
||||
image: 'https://i.imgur.com/rLd7gP9.jpg', // Warehouse entrance
|
||||
color: '#22c55e', // green-500
|
||||
textColor: 'text-green-400',
|
||||
boxes: [
|
||||
{ top: '40%', left: '55%', width: '12%', height: '25%', delay: '0s' },
|
||||
{ top: '42%', left: '40%', width: '12%', height: '26%', delay: '0.2s' },
|
||||
{ top: '45%', left: '25%', width: '12%', height: '24%', delay: '0.4s' },
|
||||
],
|
||||
},
|
||||
usage: {
|
||||
title: 'Kamera Area Feeder',
|
||||
image: 'https://i.imgur.com/8p8Yq3g.jpg', // Coop interior
|
||||
color: '#f97316', // orange-500
|
||||
textColor: 'text-orange-400',
|
||||
boxes: [{ top: '60%', left: '20%', width: '15%', height: '28%', delay: '0.1s' }],
|
||||
},
|
||||
};
|
||||
|
||||
const currentConfig = config[mode];
|
||||
const count = latestLog ? latestLog.count : 0;
|
||||
|
||||
return (
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-xl font-bold">{currentConfig.title}</h2>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="relative flex h-3 w-3">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
|
||||
<span className="relative inline-flex rounded-full h-3 w-3 bg-red-500"></span>
|
||||
</span>
|
||||
<span className="text-red-600 font-semibold">LIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative w-full aspect-video bg-gray-800 rounded-lg overflow-hidden shadow-inner">
|
||||
<img
|
||||
src={currentConfig.image}
|
||||
alt="Live camera feed"
|
||||
className="w-full h-full object-cover opacity-80"
|
||||
/>
|
||||
|
||||
{currentConfig.boxes.map((box, i) => (
|
||||
<BoundingBox key={i} {...box} color={currentConfig.color} />
|
||||
))}
|
||||
|
||||
<div className="absolute bottom-2 right-2 bg-black/60 backdrop-blur-sm text-white p-2 rounded-lg text-sm font-mono">
|
||||
<p>
|
||||
Terdeteksi:{' '}
|
||||
<span className={`font-bold ${currentConfig.textColor}`}>{count} karung</span>
|
||||
</p>
|
||||
<p>Lokasi: {latestLog?.location || 'N/A'}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LiveFeedView;
|
||||
Reference in new issue
Block a user