feat: remove image preview panel and make manual labeling form full-width

This commit is contained in:
Rafhan Mazaya Fathurrahman committed 2026-07-02 15:51:27 +07:00
1 parent 5a097c457f
commit ab21d1ca5d
1 file changed
+4 -110
@@ -38,12 +38,6 @@ export default function ManualLabelPage() {
items: [{ kodeBarang: "", namaBarang: "", banyak: "", jumlah: "" }] items: [{ kodeBarang: "", namaBarang: "", banyak: "", jumlah: "" }]
}); });
// Transform states
const [scale, setScale] = useState<number>(1.0);
const [rotation, setRotation] = useState<number>(0);
const [isDragging, setIsDragging] = useState<boolean>(false);
const dragStart = useRef({ x: 0, y: 0, scrollLeft: 0, scrollTop: 0 });
const viewportRef = useRef<HTMLDivElement>(null);
// Status indicators // Status indicators
const [toast, setToast] = useState<{ message: string; show: boolean; isError: boolean }>({ const [toast, setToast] = useState<{ message: string; show: boolean; isError: boolean }>({
@@ -109,9 +103,6 @@ export default function ManualLabelPage() {
} }
}; };
// Reset view
setScale(1.0);
setRotation(0);
fetchLabel(); fetchLabel();
}, [currentIndex, files]); }, [currentIndex, files]);
@@ -217,39 +208,6 @@ export default function ManualLabelPage() {
} }
}; };
// Panning functionality
const handleMouseDown = (e: React.MouseEvent) => {
if (e.target instanceof HTMLImageElement || e.target === viewportRef.current) {
setIsDragging(true);
const vp = viewportRef.current;
if (vp) {
dragStart.current = {
x: e.pageX - vp.offsetLeft,
y: e.pageY - vp.offsetTop,
scrollLeft: vp.scrollLeft,
scrollTop: vp.scrollTop
};
}
}
};
const handleMouseMove = (e: React.MouseEvent) => {
if (!isDragging) return;
e.preventDefault();
const vp = viewportRef.current;
if (vp) {
const x = e.pageX - vp.offsetLeft;
const y = e.pageY - vp.offsetTop;
const walkX = (x - dragStart.current.x) * 1.5;
const walkY = (y - dragStart.current.y) * 1.5;
vp.scrollLeft = dragStart.current.scrollLeft - walkX;
vp.scrollTop = dragStart.current.scrollTop - walkY;
}
};
const handleMouseUpOrLeave = () => {
setIsDragging(false);
};
return ( return (
<div className="h-screen w-screen flex flex-col bg-slate-950 text-slate-100 overflow-hidden font-sans"> <div className="h-screen w-screen flex flex-col bg-slate-950 text-slate-100 overflow-hidden font-sans">
@@ -317,11 +275,11 @@ export default function ManualLabelPage() {
</div> </div>
</header> </header>
{/* Main Split Layout */} {/* Centered Form Layout */}
<div className="flex-1 flex overflow-hidden w-full"> <div className="flex-1 flex overflow-hidden w-full justify-center bg-slate-950">
{/* Left Form Viewport */} {/* Form Viewport */}
<div className="w-[45%] border-r border-slate-800 overflow-y-auto p-6 space-y-6 flex flex-col bg-slate-950"> <div className="w-full max-w-4xl border-x border-slate-800/60 overflow-y-auto p-8 space-y-6 flex flex-col bg-slate-900/10">
{/* Metadata Card */} {/* Metadata Card */}
<div className="rounded-xl border border-slate-800 bg-slate-900/40 p-5 space-y-5"> <div className="rounded-xl border border-slate-800 bg-slate-900/40 p-5 space-y-5">
@@ -518,70 +476,6 @@ export default function ManualLabelPage() {
</div> </div>
{/* Right Image Panning Viewport */}
<div className="w-[55%] bg-slate-950 flex flex-col relative select-none">
<div
ref={viewportRef}
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUpOrLeave}
onMouseLeave={handleMouseUpOrLeave}
className="flex-1 overflow-auto flex items-center justify-center cursor-grab active:cursor-grabbing p-6"
>
{files[currentIndex] ? (
<img
src={`/test-images/${files[currentIndex]}`}
alt={files[currentIndex]}
style={{
transform: `scale(${scale}) rotate(${rotation}deg)`,
transformOrigin: "center center",
transition: isDragging ? "none" : "transform 0.1s ease-out"
}}
draggable={false}
className="max-w-[90%] max-h-[90%] object-contain rounded shadow-2xl shadow-black/80 border border-slate-900"
/>
) : (
<div className="text-slate-500 text-sm font-medium">Select an image to load</div>
)}
</div>
{/* Interactive controls */}
<div className="absolute bottom-6 right-6 flex items-center gap-2 px-3 py-1.5 bg-slate-900/90 backdrop-blur-md border border-slate-800 rounded-full shadow-lg shadow-black/40">
<button
onClick={() => setScale(s => Math.min(4.0, s + 0.15))}
title="Zoom In"
className="w-8 h-8 rounded-full flex items-center justify-center text-sm hover:bg-slate-800 active:scale-95 text-slate-100"
>
➕
</button>
<button
onClick={() => setScale(s => Math.max(0.2, s - 0.15))}
title="Zoom Out"
className="w-8 h-8 rounded-full flex items-center justify-center text-sm hover:bg-slate-800 active:scale-95 text-slate-100"
>
➖
</button>
<button
onClick={() => {
setScale(1.0);
setRotation(0);
}}
title="Reset View"
className="w-8 h-8 rounded-full flex items-center justify-center text-sm hover:bg-slate-800 active:scale-95 text-slate-100"
>
🔄
</button>
<button
onClick={() => setRotation(r => (r + 90) % 360)}
title="Rotate Clockwise"
className="w-8 h-8 rounded-full flex items-center justify-center text-sm hover:bg-slate-800 active:scale-95 text-slate-100"
>
↪️
</button>
</div>
</div>
</div> </div>
{/* Alert toast notifications */} {/* Alert toast notifications */}