Files
mkd/components/finance/PaymentSchedule.tsx

102 lines
6.6 KiB
TypeScript
Raw Permalink Normal View History

2026-02-04 00:17:04 +05:00
import React from 'react';
import { Invoice, InvoiceStatus } from '../../types';
import { Calendar, Clock, CheckCircle2, X } from 'lucide-react';
export const PaymentSchedule: React.FC<{
approvedInvoices: Invoice[],
scheduledInvoices: Invoice[],
onUpdateStatus: (id: string, s: InvoiceStatus, extra?: any) => void,
currentBalance: number
}> = ({ approvedInvoices, scheduledInvoices, onUpdateStatus, currentBalance }) => {
return (
<div className="space-y-6 animate-fade-in">
{/* Approved but not scheduled */}
{approvedInvoices.length > 0 && (
<div className="bg-white p-5 rounded-2xl border-2 border-dashed border-primary-200">
<h3 className="font-bold text-primary-700 text-sm mb-4 flex items-center gap-2">
<Clock className="w-5 h-5"/> Очередь на оплату ({approvedInvoices.length})
</h3>
<div className="space-y-2">
{approvedInvoices.map(inv => (
<div key={inv.id} className="flex items-center justify-between p-3 bg-primary-50/50 rounded-xl border border-primary-100">
<div className="flex-1 min-w-0 pr-4">
<p className="text-xs font-bold text-slate-800 truncate">{inv.contractorName}</p>
<p className="text-[10px] text-slate-500">{inv.address}</p>
</div>
<div className="flex items-center gap-3">
<span className="text-xs font-black text-primary-700">{inv.amount.toLocaleString()}</span>
<button
onClick={() => onUpdateStatus(inv.id, 'scheduled', { scheduledDate: new Date().toISOString().split('T')[0] })}
className="bg-primary-600 text-white px-3 py-1.5 rounded-lg text-[10px] font-black uppercase hover:bg-primary-700 transition-colors flex items-center gap-1"
>
<Calendar className="w-3 h-3"/> В график
</button>
</div>
</div>
))}
</div>
</div>
)}
{/* The Calendar List */}
<div className="bg-white rounded-2xl border border-slate-200 shadow-sm overflow-hidden">
<div className="p-4 bg-slate-900 text-white flex justify-between items-center">
<div className="flex items-center gap-3">
<div className="p-2 bg-white/10 rounded-lg"><Calendar className="w-5 h-5"/></div>
<div>
<h3 className="font-bold leading-none">График платежей</h3>
<p className="text-[10px] text-slate-400 mt-1 uppercase font-bold tracking-widest">Июнь 2024</p>
</div>
</div>
<div className="text-right">
<p className="text-lg font-black">{scheduledInvoices.reduce((s, i) => s + i.amount, 0).toLocaleString()} </p>
<p className="text-[10px] text-slate-400 uppercase font-bold">К оплате</p>
</div>
</div>
<div className="divide-y divide-slate-100">
{scheduledInvoices.length === 0 && <div className="p-12 text-center text-slate-400 italic">График выплат пуст</div>}
{scheduledInvoices.map(inv => (
<div key={inv.id} className="p-4 flex items-center gap-4 hover:bg-slate-50 transition-colors group">
<div className={`p-2 rounded-xl text-center min-w-[50px] ${inv.status === 'overdue' ? 'bg-red-50 text-red-600' : 'bg-slate-50 text-slate-500'}`}>
<p className="text-xs font-black leading-none">{inv.scheduledDate?.split('-')[2] || '??'}</p>
<p className="text-[9px] font-bold uppercase mt-1">июн</p>
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-0.5">
<p className="text-sm font-bold text-slate-800 truncate">{inv.contractorName}</p>
{inv.status === 'overdue' && <span className="bg-red-500 text-white text-[8px] font-black px-1.5 rounded-full uppercase animate-pulse">Просрочен</span>}
</div>
<p className="text-[10px] text-slate-500 truncate">{inv.address} {inv.serviceName}</p>
</div>
<div className="text-right flex items-center gap-4">
<div>
<p className="text-sm font-black text-slate-900">{inv.amount.toLocaleString()} </p>
<p className="text-[9px] text-slate-400 font-bold uppercase">Баланс: {(currentBalance/1000).toFixed(0)}k</p>
</div>
<div className="flex gap-1">
<button
onClick={() => onUpdateStatus(inv.id, 'paid')}
className="p-2 bg-emerald-50 text-emerald-600 rounded-lg hover:bg-emerald-100 shadow-sm transition-colors border border-emerald-100"
title="Оплачено"
>
<CheckCircle2 className="w-5 h-5"/>
</button>
<button
onClick={() => onUpdateStatus(inv.id, 'approved', { scheduledDate: undefined })}
className="p-2 bg-slate-50 text-slate-400 rounded-lg hover:bg-red-50 hover:text-red-500 transition-colors"
title="Убрать"
>
<X className="w-5 h-5"/>
</button>
</div>
</div>
</div>
))}
</div>
</div>
</div>
);
};