v1.43.2 - Mobile: Contas Passivo otimizadas
This commit is contained in:
parent
a244632e0a
commit
be7bed5c99
14
CHANGELOG.md
14
CHANGELOG.md
@ -5,6 +5,20 @@ O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/).
|
||||
Este projeto adota [Versionamento Semântico](https://semver.org/pt-BR/).
|
||||
|
||||
|
||||
## [1.43.2] - 2025-12-16
|
||||
|
||||
### Improved
|
||||
- **Página Accounts - Contas Passivo Mobile** - Layout em cards para mobile
|
||||
- Seção "Passivos" convertida para cards em dispositivos mobile
|
||||
- Cards mostram: ícone + nome + status + número contrato + credor
|
||||
- Valores principal e saldo devedor lado a lado
|
||||
- Barra de progresso com percentagem visual
|
||||
- Fontes otimizadas: 0.65-0.85rem para legibilidade mobile
|
||||
- Padding compacto: p-3, background escuro (#0f172a)
|
||||
- Mantém onClick para navegar para /liabilities
|
||||
- Desktop mantém layout de tabela completo
|
||||
|
||||
|
||||
## [1.43.1] - 2025-12-16
|
||||
|
||||
### Fixed
|
||||
|
||||
@ -26,6 +26,7 @@ const Accounts = () => {
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [recalculating, setRecalculating] = useState(false);
|
||||
const [filter, setFilter] = useState({ type: '', is_active: '' });
|
||||
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
@ -45,6 +46,12 @@ const Accounts = () => {
|
||||
const accountTypes = accountService.types;
|
||||
const accountIcons = accountService.icons;
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => setIsMobile(window.innerWidth < 768);
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
loadAccounts();
|
||||
}, [filter]);
|
||||
@ -293,53 +300,55 @@ const Accounts = () => {
|
||||
{/* Header */}
|
||||
<div className="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 className="text-white mb-1">
|
||||
<h2 className={`text-white ${isMobile ? 'mb-0 fs-4' : 'mb-1'}`}>
|
||||
<i className="bi bi-wallet2 me-2 text-primary"></i>
|
||||
{t('nav.accounts')}
|
||||
</h2>
|
||||
<p className="text-slate-400 mb-0">{t('accounts.title')}</p>
|
||||
{!isMobile && <p className="text-slate-400 mb-0">{t('accounts.title')}</p>}
|
||||
</div>
|
||||
<div className="d-flex gap-2">
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={handleRecalculateBalances}
|
||||
disabled={recalculating}
|
||||
title={t('accounts.recalculateBalances')}
|
||||
>
|
||||
{recalculating ? (
|
||||
<span className="spinner-border spinner-border-sm me-2" role="status"></span>
|
||||
) : (
|
||||
<i className="bi bi-arrow-repeat me-2"></i>
|
||||
)}
|
||||
{t('accounts.recalculate')}
|
||||
</button>
|
||||
<button className="btn btn-primary" onClick={() => handleOpenModal()}>
|
||||
{!isMobile && (
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={handleRecalculateBalances}
|
||||
disabled={recalculating}
|
||||
title={t('accounts.recalculateBalances')}
|
||||
>
|
||||
{recalculating ? (
|
||||
<span className="spinner-border spinner-border-sm me-2" role="status"></span>
|
||||
) : (
|
||||
<i className="bi bi-arrow-repeat me-2"></i>
|
||||
)}
|
||||
{t('accounts.recalculate')}
|
||||
</button>
|
||||
)}
|
||||
<button className={`btn btn-primary ${isMobile ? 'btn-sm' : ''}`} onClick={() => handleOpenModal()}>
|
||||
<i className="bi bi-plus-lg me-2"></i>
|
||||
{t('accounts.newAccount')}
|
||||
{isMobile ? t('common.add') : t('accounts.newAccount')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Summary Cards */}
|
||||
<div className="row mb-4">
|
||||
<div className={`row ${isMobile ? 'g-2 mb-3' : 'mb-4'}`}>
|
||||
{/* Total por Moeda */}
|
||||
<div className="col-md-6">
|
||||
<div className="card border-0 h-100" style={{ background: '#1e293b' }}>
|
||||
<div className="card-body">
|
||||
<div className={`card border-0 ${!isMobile ? 'h-100' : ''}`} style={{ background: '#1e293b' }}>
|
||||
<div className={`card-body ${isMobile ? 'p-3' : ''}`}>
|
||||
<div className="d-flex align-items-start">
|
||||
<div className="rounded-circle bg-primary bg-opacity-25 p-3 me-3">
|
||||
<i className="bi bi-wallet2 text-primary fs-4"></i>
|
||||
<div className={`rounded-circle bg-primary bg-opacity-25 ${isMobile ? 'p-2 me-2' : 'p-3 me-3'}`}>
|
||||
<i className={`bi bi-wallet2 text-primary ${isMobile ? 'fs-5' : 'fs-4'}`}></i>
|
||||
</div>
|
||||
<div className="flex-grow-1">
|
||||
<p className="text-slate-400 mb-2 small">{t('dashboard.totalBalance')}</p>
|
||||
<p className={`text-slate-400 mb-2 ${isMobile ? '' : 'small'}`} style={isMobile ? { fontSize: '0.75rem' } : undefined}>{t('dashboard.totalBalance')}</p>
|
||||
{Object.keys(getTotalsByCurrency()).length > 0 ? (
|
||||
<div className="d-flex flex-wrap gap-3">
|
||||
<div className={`d-flex flex-wrap ${isMobile ? 'gap-2' : 'gap-3'}`}>
|
||||
{Object.entries(getTotalsByCurrency()).map(([currency, total]) => (
|
||||
<div key={currency} className="text-center">
|
||||
<h4 className={`mb-0 ${total >= 0 ? 'text-success' : 'text-danger'}`}>
|
||||
<h4 className={`mb-0 ${total >= 0 ? 'text-success' : 'text-danger'} ${isMobile ? 'fs-6' : ''}`} style={isMobile ? { fontSize: '1rem' } : undefined}>
|
||||
{formatCurrency(total, currency)}
|
||||
</h4>
|
||||
<small className="text-slate-500">{currency}</small>
|
||||
<small className="text-slate-500" style={isMobile ? { fontSize: '0.65rem' } : undefined}>{currency}</small>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@ -353,16 +362,16 @@ const Accounts = () => {
|
||||
</div>
|
||||
|
||||
{/* Contas Ativas e Total */}
|
||||
<div className="col-md-3">
|
||||
<div className="card border-0 h-100" style={{ background: '#1e293b' }}>
|
||||
<div className="card-body">
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="rounded-circle bg-success bg-opacity-25 p-3 me-3">
|
||||
<i className="bi bi-check-circle text-success fs-4"></i>
|
||||
<div className="col-md-3 col-6">
|
||||
<div className={`card border-0 ${!isMobile ? 'h-100' : ''}`} style={{ background: '#1e293b' }}>
|
||||
<div className={`card-body ${isMobile ? 'p-3' : ''}`}>
|
||||
<div className={`d-flex ${isMobile ? 'flex-column align-items-start' : 'align-items-center'}`}>
|
||||
<div className={`rounded-circle bg-success bg-opacity-25 ${isMobile ? 'p-2 mb-2' : 'p-3 me-3'}`}>
|
||||
<i className={`bi bi-check-circle text-success ${isMobile ? 'fs-6' : 'fs-4'}`}></i>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-slate-400 mb-0 small">{t('common.active')}</p>
|
||||
<h3 className="mb-0 text-white">
|
||||
<p className={`text-slate-400 mb-0 ${isMobile ? '' : 'small'}`} style={isMobile ? { fontSize: '0.7rem' } : undefined}>{t('common.active')}</p>
|
||||
<h3 className={`mb-0 text-white ${isMobile ? 'fs-5' : ''}`}>
|
||||
{getTotalActiveAccounts()}
|
||||
</h3>
|
||||
</div>
|
||||
@ -370,16 +379,16 @@ const Accounts = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-3">
|
||||
<div className="card border-0 h-100" style={{ background: '#1e293b' }}>
|
||||
<div className="card-body">
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="rounded-circle bg-info bg-opacity-25 p-3 me-3">
|
||||
<i className="bi bi-credit-card text-info fs-4"></i>
|
||||
<div className="col-md-3 col-6">
|
||||
<div className={`card border-0 ${!isMobile ? 'h-100' : ''}`} style={{ background: '#1e293b' }}>
|
||||
<div className={`card-body ${isMobile ? 'p-3' : ''}`}>
|
||||
<div className={`d-flex ${isMobile ? 'flex-column align-items-start' : 'align-items-center'}`}>
|
||||
<div className={`rounded-circle bg-info bg-opacity-25 ${isMobile ? 'p-2 mb-2' : 'p-3 me-3'}`}>
|
||||
<i className={`bi bi-credit-card text-info ${isMobile ? 'fs-6' : 'fs-4'}`}></i>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-slate-400 mb-0 small">{t('common.total')}</p>
|
||||
<h3 className="mb-0 text-white">{getTotalAccounts()}</h3>
|
||||
<p className={`text-slate-400 mb-0 ${isMobile ? '' : 'small'}`} style={isMobile ? { fontSize: '0.7rem' } : undefined}>{t('common.total')}</p>
|
||||
<h3 className={`mb-0 text-white ${isMobile ? 'fs-5' : ''}`}>{getTotalAccounts()}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -422,7 +431,7 @@ const Accounts = () => {
|
||||
|
||||
{/* Accounts List */}
|
||||
<div className="card border-0" style={{ background: '#1e293b' }}>
|
||||
<div className="card-body p-0">
|
||||
<div className={`card-body ${isMobile ? 'p-2' : 'p-0'}`}>
|
||||
{loading ? (
|
||||
<div className="text-center py-5">
|
||||
<div className="spinner-border text-primary" role="status">
|
||||
@ -438,7 +447,88 @@ const Accounts = () => {
|
||||
{t('accounts.newAccount')}
|
||||
</button>
|
||||
</div>
|
||||
) : isMobile ? (
|
||||
/* Mobile: Cards Layout */
|
||||
<div className="d-flex flex-column gap-2">
|
||||
{accounts.map((account) => (
|
||||
<div
|
||||
key={account.id}
|
||||
className="p-3 rounded"
|
||||
style={{
|
||||
background: '#0f172a',
|
||||
border: '1px solid #334155'
|
||||
}}
|
||||
>
|
||||
<div className="d-flex justify-content-between align-items-start mb-2">
|
||||
<div className="d-flex align-items-center flex-grow-1">
|
||||
<div
|
||||
className="rounded-circle d-flex align-items-center justify-content-center me-2"
|
||||
style={{
|
||||
width: '36px',
|
||||
height: '36px',
|
||||
backgroundColor: account.color + '25',
|
||||
}}
|
||||
>
|
||||
<i className={`bi ${account.icon}`} style={{ color: account.color, fontSize: '1rem' }}></i>
|
||||
</div>
|
||||
<div className="flex-grow-1">
|
||||
<div className="text-white fw-medium" style={{ fontSize: '0.9rem' }}>{account.name}</div>
|
||||
{account.account_number && (
|
||||
<small className="text-slate-400" style={{ fontSize: '0.7rem' }}>Nº {account.account_number}</small>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex gap-1">
|
||||
<button
|
||||
className="btn btn-link text-success p-1"
|
||||
onClick={() => openAdjustModal(account)}
|
||||
style={{ fontSize: '1rem' }}
|
||||
>
|
||||
<i className="bi bi-sliders"></i>
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link text-info p-1"
|
||||
onClick={() => handleOpenModal(account)}
|
||||
style={{ fontSize: '1rem' }}
|
||||
>
|
||||
<i className="bi bi-pencil"></i>
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link text-danger p-1"
|
||||
onClick={() => handleDeleteClick(account)}
|
||||
style={{ fontSize: '1rem' }}
|
||||
>
|
||||
<i className="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<div className="d-flex gap-2 align-items-center">
|
||||
<span className="badge" style={{ backgroundColor: '#334155', fontSize: '0.65rem' }}>
|
||||
{accountTypes[account.type] || account.type}
|
||||
</span>
|
||||
{account.is_active ? (
|
||||
<span className="badge bg-success bg-opacity-25 text-success" style={{ fontSize: '0.65rem' }}>{t('common.active')}</span>
|
||||
) : (
|
||||
<span className="badge bg-secondary bg-opacity-25 text-secondary" style={{ fontSize: '0.65rem' }}>{t('common.inactive')}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className={`fw-bold ${parseFloat(account.current_balance) >= 0 ? 'text-success' : 'text-danger'}`} style={{ fontSize: '0.95rem' }}>
|
||||
{formatCurrency(account.current_balance, account.currency)}
|
||||
</div>
|
||||
</div>
|
||||
{account.bank_name && (
|
||||
<div className="mt-2 pt-2" style={{ borderTop: '1px solid #334155' }}>
|
||||
<small className="text-slate-400" style={{ fontSize: '0.7rem' }}>
|
||||
<i className="bi bi-bank me-1"></i>{account.bank_name}
|
||||
</small>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
/* Desktop: Table Layout */
|
||||
<div className="table-responsive">
|
||||
<table className="table table-hover mb-0" style={{ '--bs-table-bg': 'transparent', backgroundColor: 'transparent' }}>
|
||||
<thead style={{ backgroundColor: 'transparent' }}>
|
||||
@ -525,8 +615,8 @@ const Accounts = () => {
|
||||
{/* Liability Accounts Section */}
|
||||
{liabilityAccounts.length > 0 && (filter.type === '' || filter.type === 'liability') && (
|
||||
<div className="card border-0 mt-4" style={{ background: '#1e293b' }}>
|
||||
<div className="card-header border-0 d-flex justify-content-between align-items-center" style={{ background: '#1e293b', borderBottom: '1px solid #334155' }}>
|
||||
<h5 className="mb-0 text-white">
|
||||
<div className={`card-header border-0 d-flex justify-content-between align-items-center ${isMobile ? 'py-2 px-3' : ''}`} style={{ background: '#1e293b', borderBottom: '1px solid #334155' }}>
|
||||
<h5 className={`mb-0 text-white ${isMobile ? 'fs-6' : ''}`}>
|
||||
<i className="bi bi-file-earmark-text me-2 text-danger"></i>
|
||||
{t('liabilities.title')}
|
||||
</h5>
|
||||
@ -538,78 +628,174 @@ const Accounts = () => {
|
||||
{t('common.details')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="card-body p-0">
|
||||
<div className="table-responsive">
|
||||
<table className="table table-hover mb-0" style={{ '--bs-table-bg': 'transparent', backgroundColor: 'transparent' }}>
|
||||
<thead style={{ backgroundColor: 'transparent' }}>
|
||||
<tr style={{ borderBottom: '1px solid #334155', backgroundColor: 'transparent' }}>
|
||||
<th className="text-slate-400 fw-normal py-3 ps-4" style={{ backgroundColor: 'transparent' }}>{t('liabilities.contractName')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3" style={{ backgroundColor: 'transparent' }}>{t('liabilities.creditor')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3 text-end" style={{ backgroundColor: 'transparent' }}>{t('liabilities.principal')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3 text-end" style={{ backgroundColor: 'transparent' }}>{t('liabilities.remaining')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3 text-center" style={{ backgroundColor: 'transparent' }}>{t('liabilities.progress')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3 text-center" style={{ backgroundColor: 'transparent' }}>{t('common.status')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style={{ backgroundColor: 'transparent' }}>
|
||||
{liabilityAccounts.map((liability) => (
|
||||
<tr
|
||||
key={`liability-${liability.id}`}
|
||||
style={{ borderBottom: '1px solid #334155', backgroundColor: 'transparent', cursor: 'pointer' }}
|
||||
onClick={() => navigate('/liabilities')}
|
||||
>
|
||||
<td className="py-3 ps-4" style={{ backgroundColor: 'transparent' }}>
|
||||
<div className="d-flex align-items-center">
|
||||
<div className={`card-body ${isMobile ? 'p-2' : 'p-0'}`}>
|
||||
{isMobile ? (
|
||||
// Mobile: Cards Layout
|
||||
<div className="d-flex flex-column gap-2">
|
||||
{liabilityAccounts.map((liability) => (
|
||||
<div
|
||||
key={`liability-${liability.id}`}
|
||||
className="card border-secondary"
|
||||
style={{ cursor: 'pointer', background: '#0f172a' }}
|
||||
onClick={() => navigate('/liabilities')}
|
||||
>
|
||||
<div className="card-body p-3">
|
||||
{/* Header with Icon and Name */}
|
||||
<div className="d-flex align-items-start gap-2 mb-2">
|
||||
<div
|
||||
className="rounded-circle d-flex align-items-center justify-content-center flex-shrink-0"
|
||||
style={{
|
||||
width: '35px',
|
||||
height: '35px',
|
||||
backgroundColor: (liability.color || '#DC2626') + '25',
|
||||
}}
|
||||
>
|
||||
<i className={`bi ${liability.icon || 'bi-file-earmark-text'} fs-6`} style={{ color: liability.color || '#DC2626' }}></i>
|
||||
</div>
|
||||
<div className="flex-grow-1" style={{ minWidth: 0 }}>
|
||||
<div className="text-white fw-medium mb-1" style={{ fontSize: '0.85rem' }}>
|
||||
{liability.name}
|
||||
</div>
|
||||
{liability.contract_number && (
|
||||
<div className="text-slate-400 mb-1" style={{ fontSize: '0.65rem' }}>
|
||||
Nº {liability.contract_number}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{liability.status === 'active' ? (
|
||||
<span className="badge bg-primary bg-opacity-25 text-primary" style={{ fontSize: '0.65rem' }}>
|
||||
{t('common.active')}
|
||||
</span>
|
||||
) : liability.status === 'paid_off' ? (
|
||||
<span className="badge bg-success bg-opacity-25 text-success" style={{ fontSize: '0.65rem' }}>
|
||||
{t('liabilities.paid')}
|
||||
</span>
|
||||
) : (
|
||||
<span className="badge bg-secondary bg-opacity-25 text-secondary" style={{ fontSize: '0.65rem' }}>
|
||||
{liability.status}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Creditor */}
|
||||
{liability.creditor && (
|
||||
<div className="text-slate-400 mb-2" style={{ fontSize: '0.7rem' }}>
|
||||
<i className="bi bi-building me-1"></i>
|
||||
{liability.creditor}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Amounts */}
|
||||
<div className="d-flex justify-content-between align-items-center mb-2 pt-2" style={{ borderTop: '1px solid #334155' }}>
|
||||
<div>
|
||||
<div className="text-slate-400" style={{ fontSize: '0.65rem' }}>Principal</div>
|
||||
<div className="text-slate-300 fw-medium" style={{ fontSize: '0.75rem' }}>
|
||||
{formatCurrency(liability.principal_amount, liability.currency)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-end">
|
||||
<div className="text-slate-400" style={{ fontSize: '0.65rem' }}>Saldo Devedor</div>
|
||||
<div className="text-danger fw-medium" style={{ fontSize: '0.75rem' }}>
|
||||
-{formatCurrency(liability.remaining_balance, liability.currency)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Progress Bar */}
|
||||
<div>
|
||||
<div className="d-flex justify-content-between align-items-center mb-1">
|
||||
<span className="text-slate-400" style={{ fontSize: '0.65rem' }}>Progresso</span>
|
||||
<span className="text-slate-400 fw-medium" style={{ fontSize: '0.7rem' }}>
|
||||
{liability.progress_percentage || 0}%
|
||||
</span>
|
||||
</div>
|
||||
<div className="progress" style={{ height: '6px', backgroundColor: '#334155' }}>
|
||||
<div
|
||||
className="rounded-circle d-flex align-items-center justify-content-center me-3"
|
||||
style={{
|
||||
width: '40px',
|
||||
height: '40px',
|
||||
backgroundColor: (liability.color || '#DC2626') + '25',
|
||||
}}
|
||||
>
|
||||
<i className={`bi ${liability.icon || 'bi-file-earmark-text'}`} style={{ color: liability.color || '#DC2626' }}></i>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-white fw-medium">{liability.name}</div>
|
||||
{liability.contract_number && (
|
||||
<small className="text-slate-400">Nº {liability.contract_number}</small>
|
||||
)}
|
||||
</div>
|
||||
className="progress-bar bg-success"
|
||||
style={{ width: `${liability.progress_percentage || 0}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-3 text-slate-300" style={{ backgroundColor: 'transparent' }}>{liability.creditor || '-'}</td>
|
||||
<td className="py-3 text-end text-slate-300" style={{ backgroundColor: 'transparent' }}>
|
||||
{formatCurrency(liability.principal_amount, liability.currency)}
|
||||
</td>
|
||||
<td className="py-3 text-end fw-medium text-danger" style={{ backgroundColor: 'transparent' }}>
|
||||
-{formatCurrency(liability.remaining_balance, liability.currency)}
|
||||
</td>
|
||||
<td className="py-3 text-center" style={{ backgroundColor: 'transparent' }}>
|
||||
<div className="d-flex align-items-center justify-content-center gap-2">
|
||||
<div className="progress" style={{ width: '80px', height: '6px', backgroundColor: '#334155' }}>
|
||||
<div
|
||||
className="progress-bar bg-success"
|
||||
style={{ width: `${liability.progress_percentage || 0}%` }}
|
||||
></div>
|
||||
</div>
|
||||
<small className="text-slate-400">{liability.progress_percentage || 0}%</small>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-3 text-center" style={{ backgroundColor: 'transparent' }}>
|
||||
{liability.status === 'active' ? (
|
||||
<span className="badge bg-primary bg-opacity-25 text-primary">{t('common.active')}</span>
|
||||
) : liability.status === 'paid_off' ? (
|
||||
<span className="badge bg-success bg-opacity-25 text-success">{t('liabilities.paid')}</span>
|
||||
) : (
|
||||
<span className="badge bg-secondary bg-opacity-25 text-secondary">{liability.status}</span>
|
||||
)}
|
||||
</td>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
// Desktop: Table Layout
|
||||
<div className="table-responsive">
|
||||
<table className="table table-hover mb-0" style={{ '--bs-table-bg': 'transparent', backgroundColor: 'transparent' }}>
|
||||
<thead style={{ backgroundColor: 'transparent' }}>
|
||||
<tr style={{ borderBottom: '1px solid #334155', backgroundColor: 'transparent' }}>
|
||||
<th className="text-slate-400 fw-normal py-3 ps-4" style={{ backgroundColor: 'transparent' }}>{t('liabilities.contractName')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3" style={{ backgroundColor: 'transparent' }}>{t('liabilities.creditor')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3 text-end" style={{ backgroundColor: 'transparent' }}>{t('liabilities.principal')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3 text-end" style={{ backgroundColor: 'transparent' }}>{t('liabilities.remaining')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3 text-center" style={{ backgroundColor: 'transparent' }}>{t('liabilities.progress')}</th>
|
||||
<th className="text-slate-400 fw-normal py-3 text-center" style={{ backgroundColor: 'transparent' }}>{t('common.status')}</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</thead>
|
||||
<tbody style={{ backgroundColor: 'transparent' }}>
|
||||
{liabilityAccounts.map((liability) => (
|
||||
<tr
|
||||
key={`liability-${liability.id}`}
|
||||
style={{ borderBottom: '1px solid #334155', backgroundColor: 'transparent', cursor: 'pointer' }}
|
||||
onClick={() => navigate('/liabilities')}
|
||||
>
|
||||
<td className="py-3 ps-4" style={{ backgroundColor: 'transparent' }}>
|
||||
<div className="d-flex align-items-center">
|
||||
<div
|
||||
className="rounded-circle d-flex align-items-center justify-content-center me-3"
|
||||
style={{
|
||||
width: '40px',
|
||||
height: '40px',
|
||||
backgroundColor: (liability.color || '#DC2626') + '25',
|
||||
}}
|
||||
>
|
||||
<i className={`bi ${liability.icon || 'bi-file-earmark-text'}`} style={{ color: liability.color || '#DC2626' }}></i>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-white fw-medium">{liability.name}</div>
|
||||
{liability.contract_number && (
|
||||
<small className="text-slate-400">Nº {liability.contract_number}</small>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-3 text-slate-300" style={{ backgroundColor: 'transparent' }}>{liability.creditor || '-'}</td>
|
||||
<td className="py-3 text-end text-slate-300" style={{ backgroundColor: 'transparent' }}>
|
||||
{formatCurrency(liability.principal_amount, liability.currency)}
|
||||
</td>
|
||||
<td className="py-3 text-end fw-medium text-danger" style={{ backgroundColor: 'transparent' }}>
|
||||
-{formatCurrency(liability.remaining_balance, liability.currency)}
|
||||
</td>
|
||||
<td className="py-3 text-center" style={{ backgroundColor: 'transparent' }}>
|
||||
<div className="d-flex align-items-center justify-content-center gap-2">
|
||||
<div className="progress" style={{ width: '80px', height: '6px', backgroundColor: '#334155' }}>
|
||||
<div
|
||||
className="progress-bar bg-success"
|
||||
style={{ width: `${liability.progress_percentage || 0}%` }}
|
||||
></div>
|
||||
</div>
|
||||
<small className="text-slate-400">{liability.progress_percentage || 0}%</small>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-3 text-center" style={{ backgroundColor: 'transparent' }}>
|
||||
{liability.status === 'active' ? (
|
||||
<span className="badge bg-primary bg-opacity-25 text-primary">{t('common.active')}</span>
|
||||
) : liability.status === 'paid_off' ? (
|
||||
<span className="badge bg-success bg-opacity-25 text-success">{t('liabilities.paid')}</span>
|
||||
) : (
|
||||
<span className="badge bg-secondary bg-opacity-25 text-secondary">{liability.status}</span>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user