feat(POS-010): completed feature

This commit is contained in:
chattie
2026-08-22 13:44:04 +02:00
parent 2c8a6f52ad
commit c089a4073a
11 changed files with 201 additions and 10 deletions

View File

@@ -0,0 +1,81 @@
'use client';
import { useState } from 'react';
import { formatPrice } from '@/lib/money';
interface DiscountPanelProps {
/** Unit price in cents of the selected item. */
unitPriceCents: number;
/** Called when a discount is applied. */
onApply: (discountCents: number) => void;
onClose: () => void;
}
export default function DiscountPanel({ unitPriceCents, onApply, onClose }: DiscountPanelProps) {
const [mode, setMode] = useState<'percent' | 'fixed'>('percent');
const [value, setValue] = useState('');
const [error, setError] = useState('');
const discountCents =
mode === 'percent'
? Math.round(((Number(value) || 0) / 100) * unitPriceCents)
: Number(value) || 0;
const handleApply = () => {
if (!value) return;
if (discountCents > unitPriceCents) { setError('Descuento mayor al precio'); return; }
onApply(discountCents);
onClose();
};
return (
<div className="bg-white rounded-2xl shadow-xl p-6 w-80 space-y-4">
<div className="flex justify-between items-center">
<h2 className="text-lg font-bold" style={{ color: 'var(--color-primary)' }}>Aplicar descuento</h2>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-xl"></button>
</div>
<div className="flex gap-2">
<button
onClick={() => setMode('percent')}
className={`flex-1 py-2 rounded-xl font-medium ${mode === 'percent' ? 'bg-[#2D6A4F] text-white' : 'bg-gray-100'}`}
>
%
</button>
<button
onClick={() => setMode('fixed')}
className={`flex-1 py-2 rounded-xl font-medium ${mode === 'fixed' ? 'bg-[#2D6A4F] text-white' : 'bg-gray-100'}`}
>
Fijo
</button>
</div>
<div>
<input
type="number"
value={value}
onChange={(e) => { setValue(e.target.value); setError(''); }}
placeholder={mode === 'percent' ? 'Porcentaje (%)' : 'Cantidad (céntimos)'}
className="w-full px-4 py-3 border-2 border-gray-200 rounded-xl text-lg focus:border-[#2D6A4F] outline-none"
min={0}
max={mode === 'percent' ? 100 : unitPriceCents}
autoFocus
/>
{error && <p className="text-sm text-red-500 mt-1">{error}</p>}
</div>
<div className="bg-gray-50 rounded-xl p-3 space-y-1 text-sm">
<div className="flex justify-between"><span>Precio original</span><span className="font-medium">{formatPrice(unitPriceCents)}</span></div>
<div className="flex justify-between"><span>Descuento</span><span className="font-medium text-red-500">-{formatPrice(discountCents)}</span></div>
<div className="flex justify-between border-t pt-1"><span>Precio final</span><span className="font-bold" style={{ color: 'var(--color-primary)' }}>{formatPrice(unitPriceCents - discountCents)}</span></div>
</div>
<button
onClick={handleApply}
disabled={!value || discountCents <= 0 || discountCents > unitPriceCents}
className="w-full py-3 bg-[#2D6A4F] hover:bg-[#1B4332] disabled:opacity-40 text-white font-bold rounded-xl transition-colors"
>
Aplicar
</button>
</div>
);
}