Files
mkd/components/finance/PaymentSchedule.tsx
2026-02-04 00:17:04 +05:00

102 lines
6.6 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
};