Refactor invoice components for improved structure and styling
This commit is contained in:
parent
84c99b8155
commit
c5aab5e1fc
|
|
@ -1,5 +1,5 @@
|
||||||
export function InvoiceItem(invoice, onView) {
|
export function InvoiceItem(invoice, onView) {
|
||||||
const item = document.createElement('div');
|
const item = document.createElement('tr');
|
||||||
item.className = 'invoice-item';
|
item.className = 'invoice-item';
|
||||||
|
|
||||||
// Formatear fecha
|
// Formatear fecha
|
||||||
|
|
@ -41,27 +41,24 @@ export function InvoiceItem(invoice, onView) {
|
||||||
};
|
};
|
||||||
|
|
||||||
item.innerHTML = /*html*/`
|
item.innerHTML = /*html*/`
|
||||||
<div class="invoice-checkbox">
|
<td class="invoice-number">${invoice.number}</td>
|
||||||
<input type="checkbox" id="invoice-${invoice.id}" />
|
<td class="invoice-status">
|
||||||
</div>
|
|
||||||
<div class="invoice-number">${invoice.number}</div>
|
|
||||||
<div class="invoice-status">
|
|
||||||
<span class="status-badge ${getStatusClass(invoice.status)}">
|
<span class="status-badge ${getStatusClass(invoice.status)}">
|
||||||
${getStatusText(invoice.status)}
|
${getStatusText(invoice.status)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</td>
|
||||||
<div class="invoice-client">
|
<td class="invoice-client">
|
||||||
<span class="client-icon">👤</span>
|
<span class="client-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg></span>
|
||||||
${invoice.clientName || 'Sin nombre'}
|
${invoice.clientName || 'Sin nombre'}
|
||||||
</div>
|
</td>
|
||||||
<div class="invoice-date">${formatDate(invoice.date)}</div>
|
<td class="invoice-date">${formatDate(invoice.date)}</td>
|
||||||
<div class="invoice-total">${formatCurrency(invoice.total)}</div>
|
<td class="invoice-total">${formatCurrency(invoice.total)}</td>
|
||||||
<div class="invoice-remain">${formatCurrency(invoice.remainToPay)}</div>
|
<td class="invoice-remain">${formatCurrency(invoice.remainToPay)}</td>
|
||||||
<div class="invoice-actions">
|
<td class="invoice-actions">
|
||||||
<button class="btn-action btn-view" data-invoice-id="${invoice.id}" title="Ver/Editar detalles">
|
<button class="btn-action btn-view" data-invoice-id="${invoice.id}" title="Ver/Editar detalles">
|
||||||
👁️
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Event listener para el botón de ver
|
// Event listener para el botón de ver
|
||||||
|
|
|
||||||
|
|
@ -138,20 +138,14 @@ export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group full-width">
|
<div class="form-group full-width">
|
||||||
<label>Nota Pública</label>
|
<label>Nota Pública</label>
|
||||||
<textarea
|
<textarea name="note_public" rows="3">${invoice.note_public || ''}</textarea>
|
||||||
name="notePublic"
|
|
||||||
rows="3"
|
|
||||||
>${invoice.notePublic || ''}</textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group full-width">
|
<div class="form-group full-width">
|
||||||
<label>Nota Privada</label>
|
<label>Nota Privada</label>
|
||||||
<textarea
|
<textarea name="note_private" rows="3">${invoice.note_private || ''}</textarea>
|
||||||
name="notePrivate"
|
|
||||||
rows="3"
|
|
||||||
>${invoice.notePrivate || ''}</textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -239,7 +233,7 @@ export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<div class="footer-actions-left">
|
<div class="footer-actions-left">
|
||||||
${isDraft ? '<button type="button" class="btn-validate btn-success">✓ Validar Factura</button>' : ''}
|
${isDraft ? '<button type="button" class="btn-validate btn-success"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align: middle; margin-right: 4px;"><polyline points="20 6 9 17 4 12"/></svg>Validar Factura</button>' : ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-actions-right">
|
<div class="footer-actions-right">
|
||||||
<button type="button" class="btn-cancel-modal">Cancelar</button>
|
<button type="button" class="btn-cancel-modal">Cancelar</button>
|
||||||
|
|
@ -303,11 +297,12 @@ export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
||||||
const form = modal.querySelector('#invoice-form');
|
const form = modal.querySelector('#invoice-form');
|
||||||
const formData = new FormData(form);
|
const formData = new FormData(form);
|
||||||
|
|
||||||
|
// La API espera camelCase en el PUT (notePublic/notePrivate)
|
||||||
const data = {
|
const data = {
|
||||||
number: formData.get('number') || undefined,
|
number: formData.get('number') || undefined,
|
||||||
expireDate: formData.get('expireDate') || undefined,
|
expireDate: formData.get('expireDate') || undefined,
|
||||||
notePublic: formData.get('notePublic') || undefined,
|
notePublic: formData.get('note_public') || undefined,
|
||||||
notePrivate: formData.get('notePrivate') || undefined
|
notePrivate: formData.get('note_private') || undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
// Filtrar valores undefined
|
// Filtrar valores undefined
|
||||||
|
|
@ -364,7 +359,7 @@ export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
||||||
const validateBtn = modal.querySelector('.btn-validate');
|
const validateBtn = modal.querySelector('.btn-validate');
|
||||||
if (validateBtn) {
|
if (validateBtn) {
|
||||||
validateBtn.disabled = false;
|
validateBtn.disabled = false;
|
||||||
validateBtn.textContent = '✓ Validar Factura';
|
validateBtn.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align: middle; margin-right: 4px;"><polyline points="20 6 9 17 4 12"/></svg>Validar Factura';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -31,22 +31,25 @@ export function renderFacturasPage() {
|
||||||
<button class="btn-new-invoice">+ Nueva Factura</button>
|
<button class="btn-new-invoice">+ Nueva Factura</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="invoices-table">
|
<div class="invoices-table-container">
|
||||||
<div class="invoices-header">
|
<table class="invoices-table">
|
||||||
<div class="invoice-checkbox">
|
<thead>
|
||||||
<input type="checkbox" id="select-all" />
|
<tr>
|
||||||
</div>
|
<th class="invoice-number">Número</th>
|
||||||
<div class="invoice-number">Número</div>
|
<th class="invoice-status">Estado</th>
|
||||||
<div class="invoice-status">Estado</div>
|
<th class="invoice-client">Cliente</th>
|
||||||
<div class="invoice-client">Cliente</div>
|
<th class="invoice-date">Fecha</th>
|
||||||
<div class="invoice-date">Fecha</div>
|
<th class="invoice-total">Total</th>
|
||||||
<div class="invoice-total">Total</div>
|
<th class="invoice-remain">Pendiente</th>
|
||||||
<div class="invoice-remain">Pendiente</div>
|
<th class="invoice-actions">Acciones</th>
|
||||||
<div class="invoice-actions">Acciones</div>
|
</tr>
|
||||||
</div>
|
</thead>
|
||||||
<div class="invoices-list">
|
<tbody class="invoices-list">
|
||||||
<div class="loading">Cargando facturas...</div>
|
<tr>
|
||||||
</div>
|
<td colspan="7" class="loading">Cargando facturas...</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
|
|
@ -86,7 +89,7 @@ export function renderFacturasPage() {
|
||||||
|
|
||||||
// Si no hay facturas
|
// Si no hay facturas
|
||||||
if (invoices.length === 0) {
|
if (invoices.length === 0) {
|
||||||
invoicesList.innerHTML = '<div class="no-invoices">No hay facturas disponibles</div>';
|
invoicesList.innerHTML = '<tr><td colspan="7" class="no-invoices">No hay facturas disponibles</td></tr>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +114,7 @@ export function renderFacturasPage() {
|
||||||
const invoicesList = container.querySelector('.invoices-list');
|
const invoicesList = container.querySelector('.invoices-list');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
invoicesList.innerHTML = '<div class="loading">Cargando facturas...</div>';
|
invoicesList.innerHTML = '<tr><td colspan="7" class="loading">Cargando facturas...</td></tr>';
|
||||||
|
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
|
|
@ -151,7 +154,7 @@ export function renderFacturasPage() {
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error al cargar facturas:', error);
|
console.error('Error al cargar facturas:', error);
|
||||||
invoicesList.innerHTML = '<div class="error">Error al cargar las facturas. Por favor, intenta de nuevo.</div>';
|
invoicesList.innerHTML = '<tr><td colspan="7" class="error">Error al cargar las facturas. Por favor, intenta de nuevo.</td></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,12 +187,6 @@ export function renderFacturasPage() {
|
||||||
window.location.hash = '#create-invoice';
|
window.location.hash = '#create-invoice';
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectAllCheckbox = container.querySelector('#select-all');
|
|
||||||
selectAllCheckbox.addEventListener('change', (e) => {
|
|
||||||
const checkboxes = container.querySelectorAll('.invoice-item input[type="checkbox"]');
|
|
||||||
checkboxes.forEach(cb => cb.checked = e.target.checked);
|
|
||||||
});
|
|
||||||
|
|
||||||
const searchInput = container.querySelector('.search-input');
|
const searchInput = container.querySelector('.search-input');
|
||||||
searchInput.addEventListener('input', (e) => {
|
searchInput.addEventListener('input', (e) => {
|
||||||
const inputValue = e.target.value.trim();
|
const inputValue = e.target.value.trim();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { renderDashboard } from './DashboardPage.js';
|
import { renderDashboard } from './DashboardPage.js';
|
||||||
import { renderTestPage } from './test.js';
|
|
||||||
import { renderFacturasPage } from './Facturas.js';
|
import { renderFacturasPage } from './Facturas.js';
|
||||||
import { renderCreateInvoicePage } from './CreateInvoicePage.js';
|
import { renderCreateInvoicePage } from './CreateInvoicePage.js';
|
||||||
|
|
||||||
|
|
@ -8,23 +7,15 @@ export const pagesRegistry = [
|
||||||
{
|
{
|
||||||
route: 'dashboard',
|
route: 'dashboard',
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
icon: '🏠',
|
icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
showInSidebar: true,
|
showInSidebar: true,
|
||||||
render: renderDashboard
|
render: renderDashboard
|
||||||
},
|
},
|
||||||
{
|
|
||||||
route: 'test',
|
|
||||||
name: 'Test Page',
|
|
||||||
icon: '🧪',
|
|
||||||
requiresAuth: true,
|
|
||||||
showInSidebar: true,
|
|
||||||
render: renderTestPage
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
route: 'invoices',
|
route: 'invoices',
|
||||||
name: 'Facturas',
|
name: 'Facturas',
|
||||||
icon: '📄',
|
icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
showInSidebar: true,
|
showInSidebar: true,
|
||||||
render: renderFacturasPage
|
render: renderFacturasPage
|
||||||
|
|
@ -32,7 +23,7 @@ export const pagesRegistry = [
|
||||||
{
|
{
|
||||||
route: 'create-invoice',
|
route: 'create-invoice',
|
||||||
name: 'Nueva Factura',
|
name: 'Nueva Factura',
|
||||||
icon: '➕',
|
icon: '+',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
showInSidebar: false, // No mostrar en sidebar
|
showInSidebar: false, // No mostrar en sidebar
|
||||||
render: renderCreateInvoicePage
|
render: renderCreateInvoicePage
|
||||||
|
|
@ -40,7 +31,7 @@ export const pagesRegistry = [
|
||||||
{
|
{
|
||||||
route: 'clients',
|
route: 'clients',
|
||||||
name: 'Clientes',
|
name: 'Clientes',
|
||||||
icon: '👥',
|
icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
showInSidebar: true,
|
showInSidebar: true,
|
||||||
render: () => {
|
render: () => {
|
||||||
|
|
@ -52,7 +43,7 @@ export const pagesRegistry = [
|
||||||
{
|
{
|
||||||
route: 'settings',
|
route: 'settings',
|
||||||
name: 'Configuración',
|
name: 'Configuración',
|
||||||
icon: '⚙️',
|
icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M12 1v6m0 6v6M5.64 5.64l4.24 4.24m4.24 4.24l4.24 4.24M1 12h6m6 0h6M5.64 18.36l4.24-4.24m4.24-4.24l4.24-4.24"/></svg>',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
showInSidebar: true,
|
showInSidebar: true,
|
||||||
render: () => {
|
render: () => {
|
||||||
|
|
|
||||||
222
src/style.css
222
src/style.css
|
|
@ -498,48 +498,49 @@ button:focus-visible {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoices-table {
|
/* Invoices Table Styles */
|
||||||
|
.invoices-table-container {
|
||||||
background: var(--card-bg);
|
background: var(--card-bg);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoices-header,
|
.invoices-table {
|
||||||
.invoice-item {
|
width: 100%;
|
||||||
display: grid;
|
border-collapse: collapse;
|
||||||
grid-template-columns: 40px 150px 120px 120px 120px 120px 120px 120px 80px;
|
|
||||||
gap: 1rem;
|
|
||||||
padding: 1rem 1.5rem;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoices-header {
|
.invoices-table thead {
|
||||||
background: #f8fafc;
|
background: #f8fafc;
|
||||||
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoices-table th {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border-bottom: 1px solid var(--border-color);
|
padding: 1rem 1.5rem;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-item {
|
.invoices-table tbody tr {
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-item:hover {
|
.invoices-table tbody tr:hover {
|
||||||
background-color: #f8fafc;
|
background-color: #f8fafc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-item:last-child {
|
.invoices-table tbody tr:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-checkbox input {
|
.invoices-table td {
|
||||||
width: 18px;
|
padding: 1rem 1.5rem;
|
||||||
height: 18px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-number {
|
.invoice-number {
|
||||||
|
|
@ -547,7 +548,7 @@ button:focus-visible {
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-badge {
|
.invoice-status .status-badge {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.4rem 0.8rem;
|
padding: 0.4rem 0.8rem;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
|
|
@ -612,18 +613,20 @@ button:focus-visible {
|
||||||
|
|
||||||
.btn-view {
|
.btn-view {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: 1px solid var(--border-color);
|
border: none;
|
||||||
padding: 0.5rem;
|
padding: 0.25rem;
|
||||||
border-radius: 6px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1.1rem;
|
color: var(--text-secondary);
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-view:hover {
|
.btn-view:hover {
|
||||||
background: var(--primary);
|
color: var(--primary);
|
||||||
border-color: var(--primary);
|
transform: scale(1.1);
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading,
|
.loading,
|
||||||
|
|
@ -776,41 +779,6 @@ button:focus-visible {
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-checkbox {
|
|
||||||
position: absolute;
|
|
||||||
top: 1rem;
|
|
||||||
right: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.test-page h1 {
|
|
||||||
color: var(--text-primary);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.test-content {
|
|
||||||
background: var(--card-bg);
|
|
||||||
padding: 2rem;
|
|
||||||
border-radius: 12px;
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.test-button {
|
|
||||||
background-color: var(--success);
|
|
||||||
color: white;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
border: none;
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.test-button:hover {
|
|
||||||
background-color: var(--success-hover);
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust dashboard and login for new layout */
|
/* Adjust dashboard and login for new layout */
|
||||||
|
|
@ -824,8 +792,8 @@ button:focus-visible {
|
||||||
|
|
||||||
/* Create Invoice Page - Ultra Compact */
|
/* Create Invoice Page - Ultra Compact */
|
||||||
.create-invoice-page {
|
.create-invoice-page {
|
||||||
padding: 1rem;
|
padding: 2rem;
|
||||||
max-width: 1400px;
|
max-width: 1000px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
@ -834,7 +802,7 @@ button:focus-visible {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 2rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -842,14 +810,15 @@ button:focus-visible {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-back {
|
.btn-back {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: #64748b;
|
color: var(--text-secondary);
|
||||||
border: 1px solid #e2e8f0;
|
border: 1px solid var(--border-color);
|
||||||
padding: 0.4rem 0.8rem;
|
padding: 0.5rem 1rem;
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
|
|
@ -857,31 +826,32 @@ button:focus-visible {
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-back:hover {
|
.btn-back:hover {
|
||||||
background: #f1f5f9;
|
background: #f8fafc;
|
||||||
color: #475569;
|
color: var(--text-primary);
|
||||||
border-color: #cbd5e1;
|
border-color: #cbd5e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-form-compact {
|
.invoice-form-compact {
|
||||||
background: var(--card-bg);
|
background: var(--card-bg);
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
padding: 1rem;
|
padding: 2rem;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-grid-compact {
|
.form-grid-compact {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 2fr 1fr 1fr;
|
grid-template-columns: 2fr 1fr 1fr;
|
||||||
gap: 0.75rem;
|
gap: 1rem;
|
||||||
margin-bottom: 0.75rem;
|
margin-bottom: 1.5rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notes-grid-compact {
|
.notes-grid-compact {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
gap: 0.75rem;
|
gap: 1rem;
|
||||||
margin-bottom: 0.75rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-field-compact {
|
.form-field-compact {
|
||||||
|
|
@ -895,22 +865,24 @@ button:focus-visible {
|
||||||
|
|
||||||
.form-field-compact label {
|
.form-field-compact label {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-bottom: 0.25rem;
|
margin-bottom: 0.5rem;
|
||||||
color: var(--text-primary);
|
color: var(--text-secondary);
|
||||||
font-size: 0.8rem;
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-field-compact input,
|
.form-field-compact input,
|
||||||
.form-field-compact select,
|
.form-field-compact select,
|
||||||
.form-field-compact textarea {
|
.form-field-compact textarea {
|
||||||
padding: 0.4rem 0.5rem;
|
padding: 0.625rem 0.75rem;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9375rem;
|
||||||
color: #000000;
|
color: var(--text-primary);
|
||||||
background: var(--card-bg);
|
background: #ffffff;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
min-height: 38px;
|
min-height: 38px;
|
||||||
|
font-family: inherit;
|
||||||
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-field-compact input:focus,
|
.form-field-compact input:focus,
|
||||||
|
|
@ -918,6 +890,7 @@ button:focus-visible {
|
||||||
.form-field-compact textarea:focus {
|
.form-field-compact textarea:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: var(--primary);
|
border-color: var(--primary);
|
||||||
|
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lines-section-compact {
|
.lines-section-compact {
|
||||||
|
|
@ -925,36 +898,38 @@ button:focus-visible {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lines-header-compact {
|
.lines-header-compact {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 1rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lines-header-compact h3 {
|
.lines-header-compact h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 0.95rem;
|
font-size: 1.125rem;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-add-compact {
|
.btn-add-compact {
|
||||||
background: #f1f5f9;
|
background: #f8fafc;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
padding: 0.3rem 0.6rem;
|
padding: 0.5rem 1rem;
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 0.85rem;
|
font-size: 0.875rem;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-add-compact:hover {
|
.btn-add-compact:hover {
|
||||||
background: #e2e8f0;
|
background: #f1f5f9;
|
||||||
border-color: #cbd5e1;
|
border-color: #cbd5e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -963,30 +938,36 @@ button:focus-visible {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-row-compact {
|
.line-row-compact {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 4fr 0.8fr 1.2fr 0.8fr 1.2fr auto;
|
grid-template-columns: 4fr 0.8fr 1.2fr 0.8fr 1.2fr auto;
|
||||||
gap: 0.5rem;
|
gap: 0.75rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: #f8fafc;
|
background: #f8fafc;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
padding: 0.4rem;
|
padding: 0.75rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-row-compact:hover {
|
||||||
|
background: #f1f5f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-desc-compact,
|
.line-desc-compact,
|
||||||
.line-qty-compact,
|
.line-qty-compact,
|
||||||
.line-price-compact,
|
.line-price-compact,
|
||||||
.line-tax-compact {
|
.line-tax-compact {
|
||||||
padding: 0.35rem 0.4rem;
|
padding: 0.5rem 0.625rem;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 3px;
|
border-radius: 4px;
|
||||||
font-size: 0.85rem;
|
font-size: 0.875rem;
|
||||||
background: white;
|
background: white;
|
||||||
color: #000000;
|
color: var(--text-primary);
|
||||||
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-desc-compact {
|
.line-desc-compact {
|
||||||
|
|
@ -999,12 +980,13 @@ button:focus-visible {
|
||||||
.line-tax-compact:focus {
|
.line-tax-compact:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: var(--primary);
|
border-color: var(--primary);
|
||||||
|
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-total-compact {
|
.line-total-compact {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9375rem;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
@ -1013,11 +995,11 @@ button:focus-visible {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: #94a3b8;
|
color: #94a3b8;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
width: 28px;
|
width: 32px;
|
||||||
height: 28px;
|
height: 32px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1.4rem;
|
font-size: 1.5rem;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -1028,52 +1010,52 @@ button:focus-visible {
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-delete-compact:hover {
|
.btn-delete-compact:hover {
|
||||||
color: #64748b;
|
color: #ef4444;
|
||||||
background: #f1f5f9;
|
background: #fee2e2;
|
||||||
border-color: #e2e8f0;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-actions-compact {
|
.form-actions-compact {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
margin-top: 1rem;
|
margin-top: 0;
|
||||||
padding-top: 0.75rem;
|
padding-top: 1.5rem;
|
||||||
border-top: 1px solid var(--border-color);
|
border-top: 1px solid var(--border-color);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-cancel-compact {
|
.btn-cancel-compact {
|
||||||
background: #f8fafc;
|
background: transparent;
|
||||||
color: #64748b;
|
color: var(--text-secondary);
|
||||||
border: 1px solid #e2e8f0;
|
border: 1px solid var(--border-color);
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.625rem 1.25rem;
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9375rem;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-cancel-compact:hover {
|
.btn-cancel-compact:hover {
|
||||||
background: #f1f5f9;
|
background: #f8fafc;
|
||||||
color: #475569;
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-submit-compact {
|
.btn-submit-compact {
|
||||||
background: #334155;
|
background: var(--primary);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0.5rem 1.5rem;
|
padding: 0.625rem 1.5rem;
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9375rem;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-submit-compact:hover {
|
.btn-submit-compact:hover {
|
||||||
background: #475569;
|
background: var(--primary-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-submit-compact:disabled {
|
.btn-submit-compact:disabled {
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,7 @@
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group input:focus,
|
.form-group input:focus,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue