feat: 불량 수량 입력에 숫자 키패드 모달 추가

This commit is contained in:
SeongHyun Kim
2026-04-06 15:35:55 +09:00
parent fb3ecff02d
commit 684d23cc38

View File

@@ -45,27 +45,89 @@ function QtyInput({
onChange: (v: number) => void;
max: number;
}) {
const [padOpen, setPadOpen] = useState(false);
const [padValue, setPadValue] = useState(String(value));
const handlePadOpen = () => {
setPadValue(String(value));
setPadOpen(true);
};
const handlePadKey = (key: string) => {
if (key === "backspace") {
setPadValue((prev) => prev.length > 1 ? prev.slice(0, -1) : "0");
} else if (key === "clear") {
setPadValue("0");
} else if (key === "max") {
setPadValue(String(max));
} else {
setPadValue((prev) => prev === "0" ? key : prev + key);
}
};
const handlePadConfirm = () => {
const num = Math.min(Math.max(0, parseInt(padValue, 10) || 0), max);
onChange(num);
setPadOpen(false);
};
return (
<div className="flex items-center gap-2">
<button
onClick={() => onChange(Math.max(0, value - 1))}
className="w-10 h-10 rounded-lg bg-gray-100 text-gray-600 text-lg font-bold flex items-center justify-center active:scale-95 transition-all hover:bg-gray-200"
>
-
</button>
<span
className="w-12 text-center text-lg font-bold text-gray-900"
style={{ fontVariantNumeric: "tabular-nums" }}
>
{value}
</span>
<button
onClick={() => onChange(Math.min(max, value + 1))}
className="w-10 h-10 rounded-lg bg-gray-100 text-gray-600 text-lg font-bold flex items-center justify-center active:scale-95 transition-all hover:bg-gray-200"
>
+
</button>
</div>
<>
<div className="flex items-center gap-2">
<button
onClick={() => onChange(Math.max(0, value - 1))}
className="w-10 h-10 rounded-lg bg-gray-100 text-gray-600 text-lg font-bold flex items-center justify-center active:scale-95 transition-all hover:bg-gray-200"
>
-
</button>
<button
onClick={handlePadOpen}
className="w-16 h-10 text-center text-lg font-bold text-gray-900 bg-gray-50 rounded-lg border-2 border-gray-200 hover:border-red-300 active:scale-95 transition-all"
style={{ fontVariantNumeric: "tabular-nums" }}
>
{value}
</button>
<button
onClick={() => onChange(Math.min(max, value + 1))}
className="w-10 h-10 rounded-lg bg-gray-100 text-gray-600 text-lg font-bold flex items-center justify-center active:scale-95 transition-all hover:bg-gray-200"
>
+
</button>
</div>
{/* 숫자 키패드 모달 */}
{padOpen && (
<div className="fixed inset-0 z-[60] flex items-center justify-center">
<div className="absolute inset-0 bg-black/40" onClick={() => setPadOpen(false)} />
<div className="relative bg-white rounded-2xl shadow-2xl p-4 w-[280px] z-10">
<div className="text-center mb-3">
<p className="text-sm text-gray-500"> ( {max})</p>
<p className="text-3xl font-bold text-gray-900 mt-1" style={{ fontVariantNumeric: "tabular-nums" }}>{padValue}</p>
</div>
<div className="grid grid-cols-3 gap-2 mb-3">
{["1","2","3","4","5","6","7","8","9"].map((k) => (
<button key={k} onClick={() => handlePadKey(k)}
className="h-12 rounded-xl bg-gray-100 text-lg font-bold text-gray-800 active:scale-95 active:bg-gray-200 transition-all">{k}</button>
))}
<button onClick={() => handlePadKey("clear")}
className="h-12 rounded-xl bg-gray-200 text-sm font-bold text-gray-600 active:scale-95 transition-all">C</button>
<button onClick={() => handlePadKey("0")}
className="h-12 rounded-xl bg-gray-100 text-lg font-bold text-gray-800 active:scale-95 transition-all">0</button>
<button onClick={() => handlePadKey("backspace")}
className="h-12 rounded-xl bg-gray-200 text-sm font-bold text-gray-600 active:scale-95 transition-all"></button>
</div>
<button onClick={() => handlePadKey("max")}
className="w-full h-10 rounded-xl bg-red-50 text-red-600 text-sm font-bold mb-2 active:scale-95 transition-all">MAX ({max})</button>
<div className="flex gap-2">
<button onClick={() => setPadOpen(false)}
className="flex-1 h-11 rounded-xl bg-gray-100 text-gray-700 font-semibold active:scale-95 transition-all"></button>
<button onClick={handlePadConfirm}
className="flex-1 h-11 rounded-xl bg-red-500 text-white font-bold active:scale-95 transition-all"></button>
</div>
</div>
</div>
)}
</>
);
}