v1.43.5 - Otimização mobile da página Liabilities
- Header responsivo: flex-column mobile, botão full-width - Summary cards: Grid 2x2 mobile, fontes compactas (0.65-0.9rem) - Filtros: Layout 50/50 sem label em mobile - Cards contratos: col-12 mobile, padding reduzido, fontes ajustadas - Progress bar: 6px mobile vs 8px desktop - Botões e valores: fontes menores (0.75rem) para melhor legibilidade
This commit is contained in:
parent
5f3bf18b99
commit
d84da4b6b7
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.5] - 2025-12-16
|
||||
|
||||
### Improved
|
||||
- **Página Liabilities - Mobile Otimizado** - Contas Passivo adaptadas para mobile
|
||||
- Header: Layout flex-column, botão full-width, fontes reduzidas (1.1rem/0.75rem)
|
||||
- Summary Cards: Grid 2 colunas mobile, sem ícones laterais, texto truncado
|
||||
- Valores compactos: 0.9rem mobile vs 1.25rem desktop
|
||||
- Filtros: Grid 50/50 mobile sem label, fontes 0.8rem
|
||||
- Cards de Contratos: col-12 mobile, padding 0.75rem, fontes 0.65-0.85rem
|
||||
- Progress bar: 6px mobile vs 8px desktop
|
||||
- Botões: fontes 0.75rem mobile, mantém ícones e funcionalidade
|
||||
- Desktop: Layout original preservado
|
||||
|
||||
|
||||
## [1.43.4] - 2025-12-16
|
||||
|
||||
### Improved
|
||||
|
||||
@ -10,6 +10,15 @@ const LiabilityAccounts = () => {
|
||||
const toast = useToast();
|
||||
const { currency: formatCurrency } = useFormatters();
|
||||
|
||||
// Mobile detection
|
||||
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => setIsMobile(window.innerWidth < 768);
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
// States
|
||||
const [accounts, setAccounts] = useState([]);
|
||||
const [summary, setSummary] = useState(null);
|
||||
@ -347,20 +356,22 @@ const LiabilityAccounts = () => {
|
||||
return (
|
||||
<div className="container-fluid py-3">
|
||||
{/* Header */}
|
||||
<div className="d-flex justify-content-between align-items-center mb-4">
|
||||
<div className={`d-flex ${isMobile ? 'flex-column gap-2' : 'justify-content-between align-items-center'} mb-4`}>
|
||||
<div>
|
||||
<h4 className="mb-1">
|
||||
<h4 className="mb-1" style={{ fontSize: isMobile ? '1.1rem' : '1.5rem' }}>
|
||||
<i className="bi bi-file-earmark-text me-2"></i>
|
||||
{t('liabilities.title')}
|
||||
</h4>
|
||||
<small className="text-muted">{t('liabilities.subtitle')}</small>
|
||||
<small className="text-muted" style={{ fontSize: isMobile ? '0.75rem' : '0.875rem' }}>
|
||||
{t('liabilities.subtitle')}
|
||||
</small>
|
||||
</div>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
className={`btn btn-primary ${isMobile ? 'w-100' : ''}`}
|
||||
onClick={handleOpenImportModal}
|
||||
>
|
||||
<i className="bi bi-upload me-2"></i>
|
||||
{t('liabilities.importContract')}
|
||||
{isMobile ? t('common.import') : t('liabilities.importContract')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -369,9 +380,9 @@ const LiabilityAccounts = () => {
|
||||
<div className="row g-3 mb-4">
|
||||
{Object.entries(totalsByCurrency).map(([currency, totals]) => (
|
||||
<React.Fragment key={currency}>
|
||||
<div className="col-md-3">
|
||||
<div className={isMobile ? "col-6" : "col-md-3"}>
|
||||
<div className="card bg-danger text-white h-100">
|
||||
<div className="card-body py-3">
|
||||
<div className="card-body" style={{ padding: isMobile ? '0.75rem' : '1rem' }}>
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<div className="small opacity-75">{t('liabilities.totalDebt')} ({currency})</div>
|
||||
@ -428,16 +439,19 @@ const LiabilityAccounts = () => {
|
||||
|
||||
{/* Filters */}
|
||||
<div className="card mb-4">
|
||||
<div className="card-body py-2">
|
||||
<div className="row g-2 align-items-center">
|
||||
<div className="col-auto">
|
||||
<label className="col-form-label">{t('common.filter')}:</label>
|
||||
</div>
|
||||
<div className="col-auto">
|
||||
<div className="card-body" style={{ padding: isMobile ? '0.75rem' : '1rem' }}>
|
||||
<div className={`row g-2 ${isMobile ? '' : 'align-items-center'}`}>
|
||||
{!isMobile && (
|
||||
<div className="col-auto">
|
||||
<label className="col-form-label">{t('common.filter')}:</label>
|
||||
</div>
|
||||
)}
|
||||
<div className={isMobile ? "col-6" : "col-auto"}>
|
||||
<select
|
||||
className="form-select form-select-sm"
|
||||
value={filter.status}
|
||||
onChange={(e) => setFilter(prev => ({ ...prev, status: e.target.value }))}
|
||||
style={{ fontSize: isMobile ? '0.8rem' : '0.875rem' }}
|
||||
>
|
||||
<option value="">{t('liabilities.allStatuses')}</option>
|
||||
{Object.entries(liabilityAccountService.statuses).map(([key, label]) => (
|
||||
@ -445,11 +459,12 @@ const LiabilityAccounts = () => {
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="col-auto">
|
||||
<div className={isMobile ? "col-6" : "col-auto"}>
|
||||
<select
|
||||
className="form-select form-select-sm"
|
||||
value={filter.is_active}
|
||||
onChange={(e) => setFilter(prev => ({ ...prev, is_active: e.target.value }))}
|
||||
style={{ fontSize: isMobile ? '0.8rem' : '0.875rem' }}
|
||||
>
|
||||
<option value="">{t('common.all')}</option>
|
||||
<option value="1">{t('common.active')}</option>
|
||||
@ -482,21 +497,25 @@ const LiabilityAccounts = () => {
|
||||
) : (
|
||||
<div className="row g-3">
|
||||
{accounts.map(account => (
|
||||
<div key={account.id} className="col-md-6 col-lg-4">
|
||||
<div key={account.id} className={isMobile ? "col-12" : "col-md-6 col-lg-4"}>
|
||||
<div className="card h-100">
|
||||
<div className="card-header d-flex justify-content-between align-items-center">
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="card-header d-flex justify-content-between align-items-center"
|
||||
style={{ padding: isMobile ? '0.75rem' : '1rem' }}>
|
||||
<div className="d-flex align-items-center" style={{ minWidth: 0, flex: 1, marginRight: '0.5rem' }}>
|
||||
<i className={`${account.icon || 'bi-file-earmark-text'} me-2`}
|
||||
style={{ color: account.color || '#DC2626' }}></i>
|
||||
<strong>{account.name}</strong>
|
||||
style={{ color: account.color || '#DC2626', fontSize: isMobile ? '0.9rem' : '1rem' }}></i>
|
||||
<strong style={{ fontSize: isMobile ? '0.85rem' : '1rem' }} className="text-truncate">
|
||||
{account.name}
|
||||
</strong>
|
||||
</div>
|
||||
<span className={`badge ${getStatusBadge(account.status)}`}>
|
||||
<span className={`badge ${getStatusBadge(account.status)}`}
|
||||
style={{ fontSize: isMobile ? '0.65rem' : '0.75rem', flexShrink: 0 }}>
|
||||
{getStatusLabel(account.status)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<div className="card-body" style={{ padding: isMobile ? '0.75rem' : '1rem' }}>
|
||||
{account.creditor && (
|
||||
<div className="small text-muted mb-2">
|
||||
<div className="text-muted mb-2" style={{ fontSize: isMobile ? '0.7rem' : '0.875rem' }}>
|
||||
<i className="bi bi-building me-1"></i>
|
||||
{account.creditor}
|
||||
</div>
|
||||
@ -504,11 +523,12 @@ const LiabilityAccounts = () => {
|
||||
|
||||
{/* Progress Bar */}
|
||||
<div className="mb-3">
|
||||
<div className="d-flex justify-content-between small mb-1">
|
||||
<div className="d-flex justify-content-between mb-1"
|
||||
style={{ fontSize: isMobile ? '0.7rem' : '0.875rem' }}>
|
||||
<span>{t('liabilities.progress')}</span>
|
||||
<span>{account.progress_percentage || 0}%</span>
|
||||
<span className="fw-bold">{account.progress_percentage || 0}%</span>
|
||||
</div>
|
||||
<div className="progress" style={{ height: '8px' }}>
|
||||
<div className="progress" style={{ height: isMobile ? '6px' : '8px' }}>
|
||||
<div
|
||||
className="progress-bar bg-success"
|
||||
style={{ width: `${account.progress_percentage || 0}%` }}
|
||||
@ -517,30 +537,39 @@ const LiabilityAccounts = () => {
|
||||
</div>
|
||||
|
||||
{/* Values */}
|
||||
<div className="row g-2 small">
|
||||
<div className="row g-2" style={{ fontSize: isMobile ? '0.75rem' : '0.875rem' }}>
|
||||
<div className="col-6">
|
||||
<div className="text-muted">{t('liabilities.principal')}</div>
|
||||
<div className="text-muted" style={{ fontSize: isMobile ? '0.65rem' : '0.75rem' }}>
|
||||
{t('liabilities.principal')}
|
||||
</div>
|
||||
<div className="fw-bold">{formatCurrency(account.principal_amount, account.currency)}</div>
|
||||
</div>
|
||||
<div className="col-6">
|
||||
<div className="text-muted">{t('liabilities.remaining')}</div>
|
||||
<div className="text-muted" style={{ fontSize: isMobile ? '0.65rem' : '0.75rem' }}>
|
||||
{t('liabilities.remaining')}
|
||||
</div>
|
||||
<div className="fw-bold text-danger">{formatCurrency(account.remaining_balance, account.currency)}</div>
|
||||
</div>
|
||||
<div className="col-6">
|
||||
<div className="text-muted">{t('liabilities.installments')}</div>
|
||||
<div className="text-muted" style={{ fontSize: isMobile ? '0.65rem' : '0.75rem' }}>
|
||||
{t('liabilities.installments')}
|
||||
</div>
|
||||
<div className="fw-bold">{account.paid_installments}/{account.total_installments}</div>
|
||||
</div>
|
||||
<div className="col-6">
|
||||
<div className="text-muted">{t('liabilities.monthlyRate')}</div>
|
||||
<div className="text-muted" style={{ fontSize: isMobile ? '0.65rem' : '0.75rem' }}>
|
||||
{t('liabilities.monthlyRate')}
|
||||
</div>
|
||||
<div className="fw-bold">{formatPercent(account.monthly_interest_rate)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-footer bg-transparent">
|
||||
<div className="card-footer bg-transparent" style={{ padding: isMobile ? '0.75rem' : '1rem' }}>
|
||||
<div className="d-flex gap-2">
|
||||
<button
|
||||
className="btn btn-sm btn-outline-primary flex-grow-1"
|
||||
onClick={() => handleOpenDetail(account)}
|
||||
style={{ fontSize: isMobile ? '0.75rem' : '0.875rem' }}
|
||||
>
|
||||
<i className="bi bi-eye me-1"></i>
|
||||
{t('common.details')}
|
||||
@ -551,6 +580,7 @@ const LiabilityAccounts = () => {
|
||||
setSelectedAccount(account);
|
||||
setShowDeleteModal(true);
|
||||
}}
|
||||
style={{ fontSize: isMobile ? '0.75rem' : '0.875rem' }}
|
||||
>
|
||||
<i className="bi bi-trash"></i>
|
||||
</button>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user