import { useState, useEffect } from "react"; import { Modal, Button, Form, Table, Alert } from "react-bootstrap"; import { generateQr, OrderGroup, OrderGroupMember, QrRecipient } from "../../../../types"; type Props = { isOpen: boolean; onClose: () => void; group: OrderGroup; payerLogin: string; bankAccount: string; bankAccountHolder: string; groupId?: string; }; type DinerEntry = { login: string; member: OrderGroupMember; included: boolean; }; export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, bankAccount, bankAccountHolder, groupId }: Readonly) { const [diners, setDiners] = useState([]); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); useEffect(() => { if (!isOpen) return; const entries: DinerEntry[] = (Object.entries(group.members) as [string, OrderGroupMember][]).map(([login, member]) => ({ login, member, included: login !== payerLogin, })); setDiners(entries); setError(null); setSuccess(false); }, [isOpen, group, payerLogin]); const memberCount = diners.length; const fees = group.fees ?? 0; const shipping = group.shipping ?? 0; const tip = group.tip ?? 0; const totalFees = fees + shipping + tip; const feeShare = memberCount > 0 ? Math.round(totalFees / memberCount * 100) / 100 : 0; const getMemberTotal = (entry: DinerEntry): number => { const base = entry.member.amount ?? 0; const surcharge = entry.member.surchargeAmount ?? 0; const discountType = group.discountType; const discountValue = group.discountValue ?? 0; const discount = discountValue > 0 ? (discountType === 'percent' ? Math.round((base + surcharge) * discountValue / 100 * 100) / 100 : Math.round(discountValue / memberCount * 100) / 100) : 0; return Math.round((base + surcharge + feeShare - discount) * 100) / 100; }; const includedNonPayers = diners.filter(d => d.included && d.login !== payerLogin); const handleInclude = (login: string, checked: boolean) => { setDiners(prev => prev.map(d => d.login === login ? { ...d, included: checked } : d)); }; const handleGenerate = async () => { setError(null); const recipients: QrRecipient[] = []; for (const d of diners) { if (!d.included || d.login === payerLogin) continue; const total = getMemberTotal(d); if (total <= 0) { setError(`Celková částka pro ${d.login} musí být kladná`); return; } const amountStr = total.toString(); if (amountStr.includes('.') && amountStr.split('.')[1].length > 2) { setError(`Částka pro ${d.login} má více než 2 desetinná místa`); return; } recipients.push({ login: d.login, purpose: `Objednávka ${group.name}`.substring(0, 60), amount: total, }); } if (recipients.length === 0) { setError("Nebyl vybrán žádný příjemce"); return; } setLoading(true); try { const response = await generateQr({ body: { recipients, bankAccount, bankAccountHolder, ...(groupId ? { groupId } : {}) }, }); if (response.error) { setError((response.error as any).error || 'Nastala chyba při generování QR kódů'); } else { setSuccess(true); setTimeout(() => onClose(), 2000); } } catch (e: any) { setError(e.message || 'Nastala chyba při generování QR kódů'); } finally { setLoading(false); } }; const hasFees = totalFees > 0; return (

Generovat QR — {group.name}

{success ? ( QR kódy byly úspěšně vygenerovány! Uživatelé je uvidí v sekci „Nevyřízené platby". ) : ( <>

Zaplatili jste za skupinu. Vyberte, komu vygenerovat QR kód k úhradě.

{error && ( setError(null)} dismissible> {error} )} {hasFees && (
{fees > 0 && Poplatky: {fees} Kč} {shipping > 0 && Doprava: {shipping} Kč} {tip > 0 && Spropitné: {tip} Kč} → {feeShare} Kč/os.
)} {group.discountValue != null && group.discountValue > 0 && (
Sleva: {group.discountType === 'percent' ? `${group.discountValue}%` : `${group.discountValue} Kč`}
)} {hasFees && } {diners.map(d => { const isPayer = d.login === payerLogin; const total = getMemberTotal(d); const surcharge = d.member.surchargeAmount ?? 0; return ( {hasFees && ( )} ); })}
Člen Základ PříplatekPoplatekCelkem
{isPayer ? ( plátce ) : ( handleInclude(d.login, e.target.checked)} /> )} {d.login} {d.member.surchargeText && ( ({d.member.surchargeText}) )} {(d.member.amount ?? 0) > 0 ? `${d.member.amount} Kč` : } {surcharge > 0 ? `${surcharge} Kč` : } {feeShare > 0 ? `${feeShare} Kč` : '—'} {total > 0 ? `${total} Kč` : }
)}
{!success && ( <> Příjemci: {includedNonPayers.length} )} {success && ( )}
); }