import { useState, useEffect } from "react"; import { Modal, Button, Form, Table, Alert } from "react-bootstrap"; import { updateGroupFees, OrderGroup, OrderGroupMember } from "../../../../types"; import { computeFeeShare, computeMemberTotal, countActiveMembers, isActiveMember } from "../../utils/groupFees"; type Props = { isOpen: boolean; onClose: () => void; group: OrderGroup; onSaved: (data: any) => void; }; function parseHal(s: string): number { const n = parseFloat(s.replace(',', '.')); return isNaN(n) || n < 0 ? 0 : Math.round(n * 100); } function parsePercent(s: string): number { const n = parseFloat(s.replace(',', '.')); return isNaN(n) || n < 0 ? 0 : Math.round(n); } export default function EditGroupFeesModal({ isOpen, onClose, group, onSaved }: Readonly) { const [fees, setFees] = useState(''); const [shipping, setShipping] = useState(''); const [tip, setTip] = useState(''); const [discountType, setDiscountType] = useState<'percent' | 'fixed'>('percent'); const [discountValue, setDiscountValue] = useState(''); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); useEffect(() => { if (!isOpen) return; setFees(group.fees ? String(group.fees / 100) : ''); setShipping(group.shipping ? String(group.shipping / 100) : ''); setTip(group.tip ? String(group.tip / 100) : ''); setDiscountType((group.discountType as 'percent' | 'fixed') ?? 'percent'); setDiscountValue(group.discountValue ? ((group.discountType as string) === 'fixed' ? String(group.discountValue / 100) : String(group.discountValue)) : ''); setError(null); }, [isOpen, group]); const memberEntries = Object.entries(group.members) as [string, OrderGroupMember][]; // Poplatky se dělí jen mezi aktivní strávníky (kdo si reálně něco objednal). const activeCount = countActiveMembers(group.members); const feesNum = parseHal(fees); const shippingNum = parseHal(shipping); const tipNum = parseHal(tip); const discountNum = discountType === 'percent' ? parsePercent(discountValue) : parseHal(discountValue); const totalFees = feesNum + shippingNum + tipNum; const feeShare = computeFeeShare(totalFees, activeCount); const feeParams = { totalFees, discountType, discountValue: discountNum }; const handleSave = async () => { setError(null); setLoading(true); try { const res = await updateGroupFees({ body: { id: group.id, fees: feesNum, shipping: shippingNum, tip: tipNum, discountType: discountNum > 0 ? discountType : undefined, discountValue: discountNum > 0 ? discountNum : undefined, } }); if (res.error) { setError((res.error as any).error || 'Nastala chyba'); } else { onSaved(res.data); onClose(); } } catch (e: any) { setError(e.message || 'Nastala chyba'); } finally { setLoading(false); } }; return (

Poplatky skupiny — {group.name}

{error && ( setError(null)} dismissible>{error} )}
Poplatky (Kč) setFees(e.target.value)} placeholder="0" style={{ width: 110 }} onKeyDown={e => e.stopPropagation()} /> Doprava (Kč) setShipping(e.target.value)} placeholder="0" style={{ width: 110 }} onKeyDown={e => e.stopPropagation()} /> Spropitné (Kč) setTip(e.target.value)} placeholder="0" style={{ width: 110 }} onKeyDown={e => e.stopPropagation()} />
Sleva
setDiscountType(e.target.value as 'percent' | 'fixed')} style={{ width: 160 }} > setDiscountValue(e.target.value)} placeholder="0" style={{ width: 100 }} onKeyDown={e => e.stopPropagation()} /> {discountType === 'percent' ? '%' : 'Kč'}

Náhled celkových částek ({activeCount} {activeCount === 1 ? 'strávník' : 'strávníků'} s objednávkou, {feeShare > 0 ? `poplatek ${feeShare / 100} Kč/os.` : 'bez poplatku'})
{memberEntries.map(([login, member]) => { const base = member.amount ?? 0; const surcharge = member.surchargeAmount ?? 0; const active = isActiveMember(member); const total = computeMemberTotal(member, feeParams, feeShare, activeCount); // Sleva i poplatek se týkají jen aktivních strávníků. const discount = active && discountNum > 0 ? (discountType === 'percent' ? Math.round((base + surcharge) * discountNum / 100) : Math.round(discountNum / activeCount)) : 0; return ( ); })}
Člen Základ Příplatek Poplatek Sleva Celkem
{login}{!active && (jen objednává)} {base > 0 ? `${base / 100} Kč` : '—'} {surcharge > 0 ? `${surcharge / 100} Kč` : '—'} {active && feeShare > 0 ? `${feeShare / 100} Kč` : '—'} {discount > 0 ? `-${discount / 100} Kč` : '—'} {total > 0 ? `${total / 100} Kč` : '—'}
); }