fix(admin): trend chart height 100px, logs 3-column layout, KPI cards clickable links, AI timeout 120s env var, X/Pinterest settings

This commit is contained in:
chattie
2026-08-24 22:09:12 +02:00
parent 30f0cb0702
commit 2ed2ac8cd1
11 changed files with 105 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
'use client';
import { useState, useEffect } from 'react';
import { api } from '@/lib/api-client';
import Link from 'next/link';
interface Stats {
ordersToday: number;
@@ -47,15 +48,17 @@ function KPICard({
sub,
icon,
trend,
href,
}: {
label: string;
value: string;
sub?: string;
icon: string;
trend?: 'up' | 'down' | 'neutral';
href?: string;
}) {
return (
<div className="bg-white border border-gray-200 rounded-xl p-5">
const inner = (
<div className="bg-white border border-gray-200 rounded-xl p-5 hover:shadow-md hover:border-[#2D6A4F]/30 transition-all cursor-pointer">
<div className="flex items-start justify-between">
<div>
<p className="text-sm font-medium text-gray-500">{label}</p>
@@ -66,6 +69,7 @@ function KPICard({
</div>
</div>
);
return href ? <Link href={href} className="block">{inner}</Link> : inner;
}
function OrderStateBar({ state, count, total }: { state: string; count: number; total: number }) {
@@ -177,12 +181,14 @@ export default function DashboardPage() {
<div className="grid grid-cols-2 lg:grid-cols-3 gap-4">
<KPICard
label="Clientes nuevos"
href="/customers"
value={String(stats.newCustomersThisMonth)}
sub="Este mes"
icon="👥"
/>
<KPICard
label="Total pedidos"
href="/orders"
value={String(totalOrders)}
sub="En el sistema"
icon="📋"
@@ -196,6 +202,7 @@ export default function DashboardPage() {
}
sub={stats.outOfStockVariants > 0 ? 'Revisar inventario' : 'Todo OK'}
icon={stats.outOfStockVariants > 0 ? '🔴' : '✅'}
href="/inventory"
/>
</div>

View File

@@ -79,7 +79,7 @@ function TrendDashboard({ filters }: { filters: FilterState }) {
const maxValue = Math.max(...points.map((p) => p.value), 1);
return <TrendChart data={points} maxValue={maxValue} height={140} />;
return <TrendChart data={points} maxValue={maxValue} height={100} />;
}
function ChannelDashboard({ filters }: { filters: FilterState }) {

View File

@@ -153,6 +153,8 @@ export default function SettingsPage() {
<div className="p-6 space-y-5">
{field('facebookUrl', 'Facebook', { placeholder: 'https://facebook.com/...' })}
{field('instagramUrl', 'Instagram', { placeholder: 'https://instagram.com/...' })}
{field('twitterUrl', 'X (Twitter)', { placeholder: 'https://x.com/...' })}
{field('pinterestUrl', 'Pinterest', { placeholder: 'https://pinterest.com/...' })}
</div>
</>
)}

View File

@@ -195,6 +195,11 @@ export function ServerLogViewer({ backendUrl = 'http://192.168.18.93:3000' }: Se
style={{ minHeight: 0 }}
>
<table className="w-full table-fixed">
<colgroup>
<col className="w-32 shrink-0" />
<col className="w-16 shrink-0" />
<col className="flex-1 min-w-0" />
</colgroup>
<tbody>
{logs.map((entry, i) => (
<tr
@@ -220,7 +225,7 @@ 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">
<td className="px-3 py-0.5 text-gray-300 select-all overflow-hidden text-ellipsis">
{/* Extra fields for HTTP request logs */}
{entry.method && entry.url && (
<span className="mr-2">

View File

@@ -13,7 +13,7 @@ interface TrendChartProps {
height?: number;
}
export function TrendChart({ data, maxValue, height = 200 }: TrendChartProps) {
export function TrendChart({ data, maxValue, height = 120 }: TrendChartProps) {
if (data.length === 0) return null;
const width = 100; // percentage-based SVG