feat(POS-FIX-6): completed feature

This commit is contained in:
chattie
2026-08-24 15:40:01 +02:00
parent 3cb7325a42
commit 0dcb0f63a0
19 changed files with 687 additions and 233 deletions

View File

@@ -153,7 +153,7 @@ export default function OrdersPage() {
<table className="w-full">
<thead>
<tr className="bg-gray-50 border-b border-gray-200">
{['ID', 'Fecha', 'Total', 'Estado'].map((h) => (
{['ID', 'Fecha', 'Cliente', 'Total', 'Estado'].map((h) => (
<th
key={h}
className="text-left text-xs font-semibold text-gray-500 uppercase tracking-wide px-4 py-3"
@@ -183,6 +183,10 @@ export default function OrdersPage() {
})}
</p>
</td>
<td className="px-4 py-3">
<p className="text-sm text-gray-600">{o.email || o.customerName || '—'}</p>
{o.email && <p className="text-xs text-gray-400">{o.email}</p>}
</td>
<td className="px-4 py-3">
<p className="text-sm font-bold text-gray-900">{formatPrice(o.totalCents)}</p>
</td>

View File

@@ -7,6 +7,14 @@ interface LogEntry {
levelName: string;
msg: string;
err?: Record<string, unknown>;
method?: string;
url?: string;
statusCode?: number;
durationMs?: number;
ip?: string;
remoteIp?: string;
userAgent?: string;
referer?: string | null;
raw: string;
}
@@ -39,6 +47,13 @@ function parseLine(line: string): LogEntry {
levelName: LEVEL_NAMES[level] ?? 'INFO',
msg: obj.msg ?? '',
err: obj.err,
method: obj.method,
url: obj.url,
statusCode: obj.statusCode,
durationMs: obj.durationMs,
ip: obj.ip ?? obj.remoteIp,
userAgent: obj.userAgent,
referer: obj.referer,
raw: line,
};
} catch {
@@ -206,6 +221,44 @@ export function ServerLogViewer({ backendUrl = 'http://192.168.18.93:3000' }: Se
</td>
{/* Message */}
<td className="px-3 py-0.5 text-gray-300 select-all">
{/* Extra fields for HTTP request logs */}
{entry.method && entry.url && (
<span className="mr-2">
<span className={`font-bold ${
entry.statusCode && entry.statusCode >= 500 ? 'text-red-400' :
entry.statusCode && entry.statusCode >= 400 ? 'text-amber-400' :
entry.statusCode && entry.statusCode >= 300 ? 'text-blue-400' :
'text-green-400'
}`}>{entry.method}</span>
<span className="text-gray-400 ml-1">{entry.url}</span>
{entry.statusCode && (
<span className={`ml-2 font-bold ${
entry.statusCode >= 500 ? 'text-red-400' :
entry.statusCode >= 400 ? 'text-amber-400' :
entry.statusCode >= 300 ? 'text-blue-400' :
'text-green-400'
}`}>{entry.statusCode}</span>
)}
{entry.durationMs !== undefined && (
<span className="ml-1 text-gray-500">{entry.durationMs}ms</span>
)}
<span className="ml-2 text-gray-600">·</span>
{entry.ip && (
<span className="ml-2 text-gray-500" title="IP origen">🌐 {entry.ip}</span>
)}
{entry.referer && (
<span className="ml-2 text-gray-500" title="Desde"> {entry.referer.replace(/^https?:\/\//, '').slice(0, 60)}</span>
)}
{entry.userAgent && (
<span className="ml-2 text-gray-600" title="User-Agent">
{entry.userAgent.includes('Postman') ? '📮 Postman' :
entry.userAgent.includes('curl') ? '📡 curl' :
entry.userAgent.includes('node') ? '⚙️ Node' :
'🖥️ Browser'}
</span>
)}
</span>
)}
{entry.msg}
{entry.err && (
<span className="ml-2 text-red-400">