feat: roadmap y diseño inicial — iteración 1 antes de feedback del usuario
Inventario de dispositivos electrónicos no prestables para administración pública. Esta primera iteración contiene el diseño y la planificación antes de contactar con el usuario para su validación. Contenido: - especificaciones.md: requisitos detallados del programa - docs/arquitectura.md: propuesta de arquitectura con alternativas - docs/roadmap-iteracion-1.md: plan de desarrollo iteración 1 - docs/arquitectura-diagrama.html: diagrama visual de arquitectura - sketches/: mockups de las 4 pantallas principales - 001-dashboard: vista resumen - 002-inventario: tabla de dispositivos - 003-formulario: alta/edición de dispositivos - 004-configuracion: ajustes generales Stack propuesto: Python + Flask + SQLite + Alpine.js Distribución: PyInstaller → un único .exe autocontenido Entorno: Windows 11 Pro unida a dominio, sin privilegios de admin
This commit is contained in:
commit
ee849eb9a8
14 changed files with 3761 additions and 0 deletions
18
sketches/001-dashboard/README.md
Normal file
18
sketches/001-dashboard/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Variant: Dashboard — Monitor Surface
|
||||
|
||||
## Design stance
|
||||
Data-first density: the user is watching state change. Stats cards at the top,
|
||||
recent items table, and distribution chart — no hero, no marketing.
|
||||
|
||||
## Key choices
|
||||
- **Layout:** Sidebar + main content, 4-column stats grid, 2-column lower section
|
||||
- **Typography:** Inter, 32px stat values, 13px body
|
||||
- **Color:** Neutral (#1a1a1a accent, #f7f7f5 background), status badges with semantic colors
|
||||
- **Interaction:** Hover on table rows, clickable chart bars, alert dismiss
|
||||
|
||||
## Trade-offs
|
||||
- Strong at: At-a-glance status, quick navigation, density without clutter
|
||||
- Weak at: On first use with 0 devices (needs empty state design)
|
||||
|
||||
## Best for
|
||||
Administrators who check the dashboard daily to monitor inventory status.
|
||||
526
sketches/001-dashboard/index.html
Normal file
526
sketches/001-dashboard/index.html
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Inventschario — Dashboard</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
color: #1a1a1a;
|
||||
background: #f7f7f5;
|
||||
line-height: 1.5;
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar {
|
||||
width: 240px;
|
||||
background: #ffffff;
|
||||
border-right: 1px solid #e5e5e3;
|
||||
padding: 20px 0;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.sidebar-logo {
|
||||
padding: 0 20px 20px;
|
||||
border-bottom: 1px solid #e5e5e3;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.sidebar-logo h1 {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
.sidebar-logo span {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.nav-section {
|
||||
padding: 8px 12px;
|
||||
}
|
||||
.nav-label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #999;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
padding: 8px 8px 4px;
|
||||
}
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
.nav-item:hover { background: #f0f0ee; color: #1a1a1a; }
|
||||
.nav-item.active { background: #f0f0ee; color: #1a1a1a; font-weight: 500; }
|
||||
.nav-item svg { width: 18px; height: 18px; flex-shrink: 0; }
|
||||
.nav-spacer { flex: 1; }
|
||||
.nav-footer {
|
||||
padding: 12px 20px;
|
||||
border-top: 1px solid #e5e5e3;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* Main content */
|
||||
.main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.topbar {
|
||||
background: #ffffff;
|
||||
border-bottom: 1px solid #e5e5e3;
|
||||
padding: 16px 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.topbar h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.topbar-actions { display: flex; gap: 10px; }
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
border: 1px solid #e5e5e3;
|
||||
background: #fff;
|
||||
color: #1a1a1a;
|
||||
transition: background 0.15s;
|
||||
font-family: inherit;
|
||||
}
|
||||
.btn:hover { background: #f0f0ee; }
|
||||
.btn-primary {
|
||||
background: #1a1a1a;
|
||||
color: #fff;
|
||||
border-color: #1a1a1a;
|
||||
}
|
||||
.btn-primary:hover { background: #333; }
|
||||
|
||||
.content {
|
||||
padding: 32px;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Stats grid */
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.stat-card {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e5e3;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin-top: 4px;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
.stat-change {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.stat-change .up { color: #16a34a; }
|
||||
.stat-change .down { color: #dc2626; }
|
||||
|
||||
/* Two-column layout */
|
||||
.two-col {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
/* Card */
|
||||
.card {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e5e3;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-header {
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid #e5e5e3;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.card-header h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.card-body { padding: 0; }
|
||||
.card-body.padded { padding: 20px; }
|
||||
|
||||
/* Table */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
padding: 10px 16px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #999;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
border-bottom: 1px solid #e5e5e3;
|
||||
background: #fafafa;
|
||||
}
|
||||
td {
|
||||
padding: 12px 16px;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid #f0f0ee;
|
||||
}
|
||||
tr:last-child td { border-bottom: none; }
|
||||
tr:hover td { background: #fafaf8; }
|
||||
|
||||
/* Badges */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.badge-active { background: #dcfce7; color: #166534; }
|
||||
.badge-available { background: #e0e7ff; color: #3730a3; }
|
||||
.badge-maintenance { background: #fef3c7; color: #92400e; }
|
||||
.badge-decommissioned { background: #f3f4f6; color: #6b7280; }
|
||||
.badge-computer { background: #f0f0ee; color: #555; }
|
||||
.badge-monitor { background: #eff6ff; color: #1d4ed8; }
|
||||
.badge-laptop { background: #fdf4ff; color: #9333ea; }
|
||||
|
||||
/* Chart placeholder */
|
||||
.chart-placeholder {
|
||||
height: 160px;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 8px;
|
||||
padding: 20px;
|
||||
}
|
||||
.chart-bar {
|
||||
flex: 1;
|
||||
background: #e5e5e3;
|
||||
border-radius: 4px 4px 0 0;
|
||||
position: relative;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.chart-bar:hover { background: #1a1a1a; }
|
||||
.chart-bar-label {
|
||||
position: absolute;
|
||||
bottom: -24px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 10px;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Alert banner */
|
||||
.alert {
|
||||
background: #fffbeb;
|
||||
border: 1px solid #fde68a;
|
||||
border-radius: 8px;
|
||||
padding: 14px 20px;
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.alert-icon { font-size: 18px; }
|
||||
.alert-text { flex: 1; color: #92400e; }
|
||||
.alert-action {
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
background: #fbbf24;
|
||||
color: #92400e;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
.alert-action:hover { background: #f59e0b; }
|
||||
|
||||
/* Quick actions */
|
||||
.quick-actions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
.quick-action {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 20px 12px;
|
||||
border: 1px solid #e5e5e3;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.15s, background 0.15s;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
.quick-action:hover { border-color: #ccc; background: #fafaf8; }
|
||||
.quick-action-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 8px;
|
||||
background: #f0f0ee;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
.quick-action-label {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Focus styles for accessibility */
|
||||
*:focus-visible {
|
||||
outline: 2px solid #1a1a1a;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Sidebar -->
|
||||
<nav class="sidebar" role="navigation" aria-label="Menú principal">
|
||||
<div class="sidebar-logo">
|
||||
<h1>Inventschario</h1>
|
||||
<span>Inventario Electrónico</span>
|
||||
</div>
|
||||
|
||||
<div class="nav-section">
|
||||
<div class="nav-label">Principal</div>
|
||||
<a class="nav-item active" href="#dashboard" aria-current="page">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
|
||||
Dashboard
|
||||
</a>
|
||||
<a class="nav-item" href="#inventory">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/></svg>
|
||||
Inventario
|
||||
</a>
|
||||
<a class="nav-item" href="#add">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>
|
||||
Agregar Dispositivo
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-section">
|
||||
<div class="nav-label">Herramientas</div>
|
||||
<a class="nav-item" href="#import">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
||||
Importar / Exportar
|
||||
</a>
|
||||
<a class="nav-item" href="#backups">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
||||
Copias de Seguridad
|
||||
</a>
|
||||
<a class="nav-item" href="#settings">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
|
||||
Configuración
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-spacer"></div>
|
||||
|
||||
<div class="nav-footer">
|
||||
v1.0.0 — 2026-08-03
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main" role="main">
|
||||
<header class="topbar">
|
||||
<h2>Dashboard</h2>
|
||||
<div class="topbar-actions">
|
||||
<button class="btn" aria-label="Crear backup manual">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align: middle; margin-right: 4px;"><path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/></svg>
|
||||
Backup
|
||||
</button>
|
||||
<button class="btn btn-primary" aria-label="Agregar nuevo dispositivo">+ Nuevo Dispositivo</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<!-- Alert: old backups -->
|
||||
<div class="alert" role="alert">
|
||||
<span class="alert-icon" aria-hidden="true">⚠️</span>
|
||||
<span class="alert-text">Hay <strong>3 copias de seguridad</strong> con más de 30 días. ¿Desea eliminar las antiguas?</span>
|
||||
<button class="alert-action" aria-label="Eliminar backups antiguos">Revisar</button>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Total Dispositivos</div>
|
||||
<div class="stat-value">247</div>
|
||||
<div class="stat-change"><span class="up">↑ 12</span> este mes</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">En Uso</div>
|
||||
<div class="stat-value">198</div>
|
||||
<div class="stat-change">80% del total</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Disponibles</div>
|
||||
<div class="stat-value">31</div>
|
||||
<div class="stat-change"><span class="up">↑ 5</span> desde el mes pasado</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">En Mantenimiento</div>
|
||||
<div class="stat-value">8</div>
|
||||
<div class="stat-change"><span class="down">↑ 3</span> esta semana</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Two column layout -->
|
||||
<div class="two-col">
|
||||
<!-- Recent devices -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Últimos Dispositivos Registrados</h3>
|
||||
<a href="#inventory" style="font-size: 12px; color: #666; text-decoration: none;">Ver todos →</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Catálogo</th>
|
||||
<th>Nombre</th>
|
||||
<th>Tipo</th>
|
||||
<th>Estado</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>INV-2024-0247</strong></td>
|
||||
<td>MacBook Pro 14"</td>
|
||||
<td><span class="badge badge-laptop">Portátil</span></td>
|
||||
<td><span class="badge badge-active">Activo</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>INV-2024-0246</strong></td>
|
||||
<td>Dell P2723QE</td>
|
||||
<td><span class="badge badge-monitor">Monitor</span></td>
|
||||
<td><span class="badge badge-available">Disponible</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>INV-2024-0245</strong></td>
|
||||
<td>Lenovo ThinkPad T14s</td>
|
||||
<td><span class="badge badge-laptop">Portátil</span></td>
|
||||
<td><span class="badge badge-active">Activo</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>INV-2024-0244</strong></td>
|
||||
<td>HP LaserJet Pro M404</td>
|
||||
<td><span class="badge badge-computer">Impresora</span></td>
|
||||
<td><span class="badge badge-maintenance">Mantenimiento</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>INV-2024-0243</strong></td>
|
||||
<td>Cisco Catalyst 2960</td>
|
||||
<td><span class="badge badge-computer">Red</span></td>
|
||||
<td><span class="badge badge-active">Activo</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Distribution by type -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Distribución por Tipo</h3>
|
||||
</div>
|
||||
<div class="card-body padded">
|
||||
<div class="chart-placeholder" style="padding-bottom: 36px;">
|
||||
<div class="chart-bar" style="height: 85%;">
|
||||
<span class="chart-bar-label">Portátiles</span>
|
||||
</div>
|
||||
<div class="chart-bar" style="height: 60%;">
|
||||
<span class="chart-bar-label">Monitores</span>
|
||||
</div>
|
||||
<div class="chart-bar" style="height: 45%;">
|
||||
<span class="chart-bar-label">Sobremesa</span>
|
||||
</div>
|
||||
<div class="chart-bar" style="height: 25%;">
|
||||
<span class="chart-bar-label">Impresoras</span>
|
||||
</div>
|
||||
<div class="chart-bar" style="height: 20%;">
|
||||
<span class="chart-bar-label">Red</span>
|
||||
</div>
|
||||
<div class="chart-bar" style="height: 15%;">
|
||||
<span class="chart-bar-label">Perif.</span>
|
||||
</div>
|
||||
<div class="chart-bar" style="height: 10%;">
|
||||
<span class="chart-bar-label">Otros</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick actions -->
|
||||
<div style="margin-top: 32px;">
|
||||
<h3 style="font-size: 14px; font-weight: 600; margin-bottom: 16px;">Acciones Rápidas</h3>
|
||||
<div class="quick-actions">
|
||||
<a class="quick-action" href="#add">
|
||||
<div class="quick-action-icon" aria-hidden="true">+</div>
|
||||
<div class="quick-action-label">Agregar<br>Dispositivo</div>
|
||||
</a>
|
||||
<a class="quick-action" href="#import">
|
||||
<div class="quick-action-icon" aria-hidden="true">⬆</div>
|
||||
<div class="quick-action-label">Importar<br>desde CSV</div>
|
||||
</a>
|
||||
<a class="quick-action" href="#export">
|
||||
<div class="quick-action-icon" aria-hidden="true">⬇</div>
|
||||
<div class="quick-action-label">Exportar<br>a CSV</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
18
sketches/002-inventario/README.md
Normal file
18
sketches/002-inventario/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Variant: Inventario — Operate Surface
|
||||
|
||||
## Design stance
|
||||
Action-oriented data table: the user is working with devices, not just viewing them.
|
||||
Every row has inline actions, the toolbar has filters, and bulk selection is available.
|
||||
|
||||
## Key choices
|
||||
- **Layout:** Full-width table with persistent toolbar, checkbox selection, pagination
|
||||
- **Typography:** Monospace for catalog numbers, Inter for everything else
|
||||
- **Color:** Status badges with semantic colors, row hover highlight
|
||||
- **Interaction:** Sortable columns, filter dropdowns, row-level actions (view, edit, delete)
|
||||
|
||||
## Trade-offs
|
||||
- Strong at: Scanning large lists, quick actions per device, bulk operations
|
||||
- Weak at: Needs mobile responsive design for tablet use
|
||||
|
||||
## Best for
|
||||
Daily inventory management — searching, filtering, and acting on specific devices.
|
||||
403
sketches/002-inventario/index.html
Normal file
403
sketches/002-inventario/index.html
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Inventschario — Inventario</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
color: #1a1a1a;
|
||||
background: #f7f7f5;
|
||||
line-height: 1.5;
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Sidebar — same as dashboard */
|
||||
.sidebar {
|
||||
width: 240px;
|
||||
background: #ffffff;
|
||||
border-right: 1px solid #e5e5e3;
|
||||
padding: 20px 0;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.sidebar-logo { padding: 0 20px 20px; border-bottom: 1px solid #e5e5e3; margin-bottom: 8px; }
|
||||
.sidebar-logo h1 { font-size: 16px; font-weight: 700; }
|
||||
.sidebar-logo span { font-size: 11px; color: #999; display: block; margin-top: 2px; }
|
||||
.nav-section { padding: 8px 12px; }
|
||||
.nav-label { font-size: 11px; font-weight: 600; color: #999; text-transform: uppercase; letter-spacing: 0.5px; padding: 8px 8px 4px; }
|
||||
.nav-item {
|
||||
display: flex; align-items: center; gap: 10px; padding: 8px 12px;
|
||||
border-radius: 6px; font-size: 14px; color: #666; cursor: pointer;
|
||||
text-decoration: none; transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
.nav-item:hover { background: #f0f0ee; color: #1a1a1a; }
|
||||
.nav-item.active { background: #f0f0ee; color: #1a1a1a; font-weight: 500; }
|
||||
.nav-item svg { width: 18px; height: 18px; flex-shrink: 0; }
|
||||
.nav-spacer { flex: 1; }
|
||||
.nav-footer { padding: 12px 20px; border-top: 1px solid #e5e5e3; font-size: 12px; color: #999; }
|
||||
|
||||
.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.topbar {
|
||||
background: #ffffff; border-bottom: 1px solid #e5e5e3;
|
||||
padding: 16px 32px; display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.topbar h2 { font-size: 18px; font-weight: 600; }
|
||||
.topbar-actions { display: flex; gap: 10px; }
|
||||
.btn {
|
||||
padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 500;
|
||||
cursor: pointer; border: 1px solid #e5e5e3; background: #fff; color: #1a1a1a;
|
||||
transition: background 0.15s; font-family: inherit;
|
||||
}
|
||||
.btn:hover { background: #f0f0ee; }
|
||||
.btn-primary { background: #1a1a1a; color: #fff; border-color: #1a1a1a; }
|
||||
.btn-primary:hover { background: #333; }
|
||||
.btn-danger { background: #fff; color: #dc2626; border-color: #fca5a5; }
|
||||
.btn-danger:hover { background: #fef2f2; }
|
||||
|
||||
.content { padding: 32px; overflow-y: auto; flex: 1; }
|
||||
|
||||
/* Toolbar */
|
||||
.toolbar {
|
||||
display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap;
|
||||
}
|
||||
.search-box {
|
||||
flex: 1; min-width: 240px; position: relative;
|
||||
}
|
||||
.search-box input {
|
||||
width: 100%; padding: 8px 12px 8px 36px; border: 1px solid #e5e5e3;
|
||||
border-radius: 6px; font-size: 13px; font-family: inherit; background: #fff;
|
||||
}
|
||||
.search-box input:focus { outline: 2px solid #1a1a1a; outline-offset: -1px; }
|
||||
.search-box svg {
|
||||
position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
|
||||
width: 16px; height: 16px; color: #999;
|
||||
}
|
||||
.filter-group { display: flex; gap: 8px; }
|
||||
.filter-select {
|
||||
padding: 8px 12px; border: 1px solid #e5e5e3; border-radius: 6px;
|
||||
font-size: 13px; font-family: inherit; background: #fff; color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
}
|
||||
.filter-select:focus { outline: 2px solid #1a1a1a; outline-offset: -1px; }
|
||||
|
||||
/* Selection bar */
|
||||
.selection-bar {
|
||||
background: #1a1a1a; color: #fff; padding: 10px 20px; border-radius: 8px;
|
||||
margin-bottom: 16px; display: flex; align-items: center; gap: 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.selection-bar .btn {
|
||||
background: transparent; color: #fff; border-color: rgba(255,255,255,0.2);
|
||||
padding: 4px 12px; font-size: 12px;
|
||||
}
|
||||
.selection-bar .btn:hover { background: rgba(255,255,255,0.1); }
|
||||
|
||||
/* Table */
|
||||
.table-card {
|
||||
background: #ffffff; border: 1px solid #e5e5e3; border-radius: 8px; overflow: hidden;
|
||||
}
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
th {
|
||||
text-align: left; padding: 10px 16px; font-size: 11px; font-weight: 600;
|
||||
color: #999; text-transform: uppercase; letter-spacing: 0.3px;
|
||||
border-bottom: 1px solid #e5e5e3; background: #fafafa; cursor: pointer;
|
||||
user-select: none; white-space: nowrap;
|
||||
}
|
||||
th:hover { color: #1a1a1a; }
|
||||
th .sort-icon { margin-left: 4px; opacity: 0.4; }
|
||||
th.sorted .sort-icon { opacity: 1; color: #1a1a1a; }
|
||||
td {
|
||||
padding: 12px 16px; font-size: 13px; border-bottom: 1px solid #f0f0ee;
|
||||
vertical-align: middle;
|
||||
}
|
||||
tr:last-child td { border-bottom: none; }
|
||||
tr:hover td { background: #fafaf8; }
|
||||
tr.selected td { background: #f0f0ee; }
|
||||
|
||||
/* Checkbox */
|
||||
.checkbox { width: 16px; height: 16px; cursor: pointer; accent-color: #1a1a1a; }
|
||||
|
||||
/* Badges */
|
||||
.badge {
|
||||
display: inline-block; padding: 2px 8px; border-radius: 4px;
|
||||
font-size: 11px; font-weight: 500;
|
||||
}
|
||||
.badge-active { background: #dcfce7; color: #166534; }
|
||||
.badge-available { background: #e0e7ff; color: #3730a3; }
|
||||
.badge-maintenance { background: #fef3c7; color: #92400e; }
|
||||
.badge-decommissioned { background: #f3f4f6; color: #6b7280; }
|
||||
.badge-disposed { background: #fee2e2; color: #991b1b; }
|
||||
.badge-computer { background: #f0f0ee; color: #555; }
|
||||
.badge-monitor { background: #eff6ff; color: #1d4ed8; }
|
||||
.badge-laptop { background: #fdf4ff; color: #9333ea; }
|
||||
.badge-printer { background: #fef3c7; color: #92400e; }
|
||||
.badge-network { background: #ecfdf5; color: #065f46; }
|
||||
|
||||
/* Row actions */
|
||||
.row-actions { display: flex; gap: 4px; }
|
||||
.row-action {
|
||||
width: 28px; height: 28px; border-radius: 4px; border: none;
|
||||
background: transparent; cursor: pointer; display: flex;
|
||||
align-items: center; justify-content: center; color: #999;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
.row-action:hover { background: #f0f0ee; color: #1a1a1a; }
|
||||
.row-action svg { width: 14px; height: 14px; }
|
||||
|
||||
/* Pagination */
|
||||
.pagination {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 12px 16px; border-top: 1px solid #e5e5e3; font-size: 13px; color: #666;
|
||||
}
|
||||
.pagination-info { font-size: 12px; }
|
||||
.pagination-controls { display: flex; gap: 4px; }
|
||||
.page-btn {
|
||||
padding: 4px 10px; border-radius: 4px; border: 1px solid #e5e5e3;
|
||||
background: #fff; cursor: pointer; font-size: 12px; font-family: inherit;
|
||||
}
|
||||
.page-btn:hover { background: #f0f0ee; }
|
||||
.page-btn.active { background: #1a1a1a; color: #fff; border-color: #1a1a1a; }
|
||||
|
||||
/* Focus styles */
|
||||
*:focus-visible { outline: 2px solid #1a1a1a; outline-offset: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Sidebar -->
|
||||
<nav class="sidebar" role="navigation" aria-label="Menú principal">
|
||||
<div class="sidebar-logo">
|
||||
<h1>Inventschario</h1>
|
||||
<span>Inventario Electrónico</span>
|
||||
</div>
|
||||
<div class="nav-section">
|
||||
<div class="nav-label">Principal</div>
|
||||
<a class="nav-item" href="#dashboard">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
|
||||
Dashboard
|
||||
</a>
|
||||
<a class="nav-item active" href="#inventory" aria-current="page">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/></svg>
|
||||
Inventario
|
||||
</a>
|
||||
<a class="nav-item" href="#add">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>
|
||||
Agregar Dispositivo
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-section">
|
||||
<div class="nav-label">Herramientas</div>
|
||||
<a class="nav-item" href="#import">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
||||
Importar / Exportar
|
||||
</a>
|
||||
<a class="nav-item" href="#backups">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
||||
Copias de Seguridad
|
||||
</a>
|
||||
<a class="nav-item" href="#settings">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9c.26.604.852.997 1.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
|
||||
Configuración
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-spacer"></div>
|
||||
<div class="nav-footer">v1.0.0 — 2026-08-03</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main" role="main">
|
||||
<header class="topbar">
|
||||
<h2>Inventario <span style="font-weight: 400; color: #999; font-size: 14px;">(247 dispositivos)</span></h2>
|
||||
<div class="topbar-actions">
|
||||
<button class="btn" aria-label="Exportar selección a CSV">⬇ Exportar</button>
|
||||
<button class="btn btn-primary" aria-label="Agregar nuevo dispositivo">+ Nuevo</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<!-- Toolbar -->
|
||||
<div class="toolbar" role="search">
|
||||
<div class="search-box">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
<input type="search" placeholder="Buscar por nombre, número de serie, catálogo..." aria-label="Buscar dispositivos">
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<select class="filter-select" aria-label="Filtrar por tipo">
|
||||
<option value="">Todos los tipos</option>
|
||||
<option>Portátil</option>
|
||||
<option>Sobremesa</option>
|
||||
<option>Monitor</option>
|
||||
<option>Impresora</option>
|
||||
<option>Red</option>
|
||||
<option>Periférico</option>
|
||||
</select>
|
||||
<select class="filter-select" aria-label="Filtrar por estado">
|
||||
<option value="">Todos los estados</option>
|
||||
<option>Activo</option>
|
||||
<option>Disponible</option>
|
||||
<option>Mantenimiento</option>
|
||||
<option>Baja</option>
|
||||
</select>
|
||||
<select class="filter-select" aria-label="Filtrar por departamento">
|
||||
<option value="">Todos los departamentos</option>
|
||||
<option>Informática</option>
|
||||
<option>Administración</option>
|
||||
<option>Recursos Humanos</option>
|
||||
<option>Contabilidad</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Selection bar (hidden by default, shown when items selected) -->
|
||||
<div class="selection-bar" role="status" aria-live="polite" style="display: none;">
|
||||
<span>3 seleccionados</span>
|
||||
<button class="btn">Exportar selección</button>
|
||||
<button class="btn">Cambiar estado</button>
|
||||
<button class="btn btn-danger">Eliminar</button>
|
||||
<button class="btn" style="margin-left: auto;">Cancelar selección</button>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div class="table-card">
|
||||
<table role="grid" aria-label="Lista de dispositivos">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;"><input type="checkbox" class="checkbox" aria-label="Seleccionar todos"></th>
|
||||
<th class="sorted">Catálogo <span class="sort-icon">↓</span></th>
|
||||
<th>Nombre / Descripción</th>
|
||||
<th>Tipo</th>
|
||||
<th>Marca / Modelo</th>
|
||||
<th>Ubicación</th>
|
||||
<th>Estado</th>
|
||||
<th style="width: 100px;">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><input type="checkbox" class="checkbox" aria-label="Seleccionar INV-2024-0247"></td>
|
||||
<td><strong>INV-2024-0247</strong></td>
|
||||
<td>MacBook Pro 14" — Oficina Dirección</td>
|
||||
<td><span class="badge badge-laptop">Portátil</span></td>
|
||||
<td>Apple / MacBook Pro M3</td>
|
||||
<td>Planta 2, Desp. 201</td>
|
||||
<td><span class="badge badge-active">Activo</span></td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<button class="row-action" title="Ver detalle" aria-label="Ver detalle de INV-2024-0247">
|
||||
<svg 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 class="row-action" title="Editar" aria-label="Editar INV-2024-0247">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
|
||||
</button>
|
||||
<button class="row-action" title="Dar de baja" aria-label="Dar de baja INV-2024-0247" style="color: #dc2626;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" class="checkbox" aria-label="Seleccionar INV-2024-0246"></td>
|
||||
<td><strong>INV-2024-0246</strong></td>
|
||||
<td>Dell P2723QE — Monitor 4K</td>
|
||||
<td><span class="badge badge-monitor">Monitor</span></td>
|
||||
<td>Dell / P2723QE</td>
|
||||
<td>Almacén</td>
|
||||
<td><span class="badge badge-available">Disponible</span></td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<button class="row-action" title="Ver detalle"><svg 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 class="row-action" title="Editar"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button>
|
||||
<button class="row-action" title="Dar de baja" style="color: #dc2626;"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/></svg></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" class="checkbox" aria-label="Seleccionar INV-2024-0245"></td>
|
||||
<td><strong>INV-2024-0245</strong></td>
|
||||
<td>Lenovo ThinkPad T14s — Desarrollo</td>
|
||||
<td><span class="badge badge-laptop">Portátil</span></td>
|
||||
<td>Lenovo / ThinkPad T14s Gen 4</td>
|
||||
<td>Planta 1, Open Space</td>
|
||||
<td><span class="badge badge-active">Activo</span></td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<button class="row-action" title="Ver detalle"><svg 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 class="row-action" title="Editar"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button>
|
||||
<button class="row-action" title="Dar de baja" style="color: #dc2626;"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/></svg></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" class="checkbox" aria-label="Seleccionar INV-2024-0244"></td>
|
||||
<td><strong>INV-2024-0244</strong></td>
|
||||
<td>HP LaserJet Pro M404dn</td>
|
||||
<td><span class="badge badge-printer">Impresora</span></td>
|
||||
<td>HP / LaserJet Pro M404dn</td>
|
||||
<td>Planta 1, Reprografía</td>
|
||||
<td><span class="badge badge-maintenance">Mantenimiento</span></td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<button class="row-action" title="Ver detalle"><svg 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 class="row-action" title="Editar"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button>
|
||||
<button class="row-action" title="Dar de baja" style="color: #dc2626;"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/></svg></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" class="checkbox" aria-label="Seleccionar INV-2024-0243"></td>
|
||||
<td><strong>INV-2024-0243</strong></td>
|
||||
<td>Cisco Catalyst 2960 — Switch Planta 1</td>
|
||||
<td><span class="badge badge-network">Red</span></td>
|
||||
<td>Cisco / Catalyst 2960-24TC-L</td>
|
||||
<td>Planta 1, Cuarto Redes</td>
|
||||
<td><span class="badge badge-active">Activo</span></td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<button class="row-action" title="Ver detalle"><svg 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 class="row-action" title="Editar"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button>
|
||||
<button class="row-action" title="Dar de baja" style="color: #dc2626;"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/></svg></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" class="checkbox" aria-label="Seleccionar INV-2024-0242"></td>
|
||||
<td><strong>INV-2024-0242</strong></td>
|
||||
<td>Dell OptiPlex 7090 — Recepción</td>
|
||||
<td><span class="badge badge-computer">Sobremesa</span></td>
|
||||
<td>Dell / OptiPlex 7090</td>
|
||||
<td>Planta 0, Recepción</td>
|
||||
<td><span class="badge badge-active">Activo</span></td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<button class="row-action" title="Ver detalle"><svg 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 class="row-action" title="Editar"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button>
|
||||
<button class="row-action" title="Dar de baja" style="color: #dc2626;"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/></svg></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="pagination">
|
||||
<div class="pagination-info">Mostrando 1-20 de 247 dispositivos</div>
|
||||
<div class="pagination-controls">
|
||||
<button class="page-btn" aria-label="Página anterior">←</button>
|
||||
<button class="page-btn active" aria-current="page">1</button>
|
||||
<button class="page-btn">2</button>
|
||||
<button class="page-btn">3</button>
|
||||
<button class="page-btn">…</button>
|
||||
<button class="page-btn">13</button>
|
||||
<button class="page-btn" aria-label="Página siguiente">→</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
19
sketches/003-formulario/README.md
Normal file
19
sketches/003-formulario/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Variant: Formulario — Configure Surface
|
||||
|
||||
## Design stance
|
||||
Progressive disclosure through logical sections: identification, device info,
|
||||
purchase, assignment, notes. Required fields marked clearly, inline validation.
|
||||
|
||||
## Key choices
|
||||
- **Layout:** Single-column form card, 2-column grid within sections
|
||||
- **Typography:** Clear section headers, field labels with required markers
|
||||
- **Color:** Minimal — white card on light gray background, red for required/errors
|
||||
- **Interaction:** Real-time validation, "Save and Add Another" for batch entry
|
||||
|
||||
## Trade-offs
|
||||
- Strong at: Clear data entry flow, reduced errors, batch-friendly
|
||||
- Weak at: Long form on small screens (needs responsive stacking)
|
||||
|
||||
## Best for
|
||||
Staff entering new devices — the form guides them through required fields
|
||||
and offers shortcuts for batch entry.
|
||||
351
sketches/003-formulario/index.html
Normal file
351
sketches/003-formulario/index.html
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Inventschario — Agregar Dispositivo</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
color: #1a1a1a; background: #f7f7f5; line-height: 1.5;
|
||||
display: flex; min-height: 100vh;
|
||||
}
|
||||
.sidebar {
|
||||
width: 240px; background: #fff; border-right: 1px solid #e5e5e3;
|
||||
padding: 20px 0; flex-shrink: 0; display: flex; flex-direction: column;
|
||||
}
|
||||
.sidebar-logo { padding: 0 20px 20px; border-bottom: 1px solid #e5e5e3; margin-bottom: 8px; }
|
||||
.sidebar-logo h1 { font-size: 16px; font-weight: 700; }
|
||||
.sidebar-logo span { font-size: 11px; color: #999; display: block; margin-top: 2px; }
|
||||
.nav-section { padding: 8px 12px; }
|
||||
.nav-label { font-size: 11px; font-weight: 600; color: #999; text-transform: uppercase; letter-spacing: 0.5px; padding: 8px 8px 4px; }
|
||||
.nav-item {
|
||||
display: flex; align-items: center; gap: 10px; padding: 8px 12px;
|
||||
border-radius: 6px; font-size: 14px; color: #666; cursor: pointer;
|
||||
text-decoration: none; transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
.nav-item:hover { background: #f0f0ee; color: #1a1a1a; }
|
||||
.nav-item.active { background: #f0f0ee; color: #1a1a1a; font-weight: 500; }
|
||||
.nav-item svg { width: 18px; height: 18px; flex-shrink: 0; }
|
||||
.nav-spacer { flex: 1; }
|
||||
.nav-footer { padding: 12px 20px; border-top: 1px solid #e5e5e3; font-size: 12px; color: #999; }
|
||||
|
||||
.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.topbar {
|
||||
background: #fff; border-bottom: 1px solid #e5e5e3;
|
||||
padding: 16px 32px; display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.topbar h2 { font-size: 18px; font-weight: 600; }
|
||||
.topbar-actions { display: flex; gap: 10px; }
|
||||
.btn {
|
||||
padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 500;
|
||||
cursor: pointer; border: 1px solid #e5e5e3; background: #fff; color: #1a1a1a;
|
||||
transition: background 0.15s; font-family: inherit;
|
||||
}
|
||||
.btn:hover { background: #f0f0ee; }
|
||||
.btn-primary { background: #1a1a1a; color: #fff; border-color: #1a1a1a; }
|
||||
.btn-primary:hover { background: #333; }
|
||||
.btn-ghost { border: none; background: transparent; color: #666; }
|
||||
.btn-ghost:hover { color: #1a1a1a; background: #f0f0ee; }
|
||||
|
||||
.content { padding: 32px; overflow-y: auto; flex: 1; max-width: 800px; }
|
||||
|
||||
/* Form */
|
||||
.form-card {
|
||||
background: #fff; border: 1px solid #e5e5e3; border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.form-header {
|
||||
padding: 20px 24px; border-bottom: 1px solid #e5e5e3;
|
||||
}
|
||||
.form-header h3 { font-size: 15px; font-weight: 600; }
|
||||
.form-header p { font-size: 13px; color: #666; margin-top: 4px; }
|
||||
.form-body { padding: 24px; }
|
||||
|
||||
.form-section {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
.form-section:last-child { margin-bottom: 0; }
|
||||
.form-section-title {
|
||||
font-size: 12px; font-weight: 600; color: #999; text-transform: uppercase;
|
||||
letter-spacing: 0.5px; margin-bottom: 16px; padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0ee;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
|
||||
}
|
||||
.form-grid .full-width { grid-column: 1 / -1; }
|
||||
|
||||
.form-group { display: flex; flex-direction: column; gap: 4px; }
|
||||
.form-label {
|
||||
font-size: 13px; font-weight: 500; color: #1a1a1a;
|
||||
}
|
||||
.form-label .required { color: #dc2626; margin-left: 2px; }
|
||||
.form-hint { font-size: 11px; color: #999; }
|
||||
.form-input, .form-select, .form-textarea {
|
||||
padding: 8px 12px; border: 1px solid #e5e5e3; border-radius: 6px;
|
||||
font-size: 13px; font-family: inherit; background: #fff; color: #1a1a1a;
|
||||
transition: border-color 0.15s;
|
||||
}
|
||||
.form-input:focus, .form-select:focus, .form-textarea:focus {
|
||||
outline: none; border-color: #1a1a1a; box-shadow: 0 0 0 1px #1a1a1a;
|
||||
}
|
||||
.form-input.error { border-color: #dc2626; }
|
||||
.form-error { font-size: 11px; color: #dc2626; margin-top: 2px; }
|
||||
.form-textarea { resize: vertical; min-height: 80px; }
|
||||
.form-select { cursor: pointer; }
|
||||
|
||||
/* Required fields note */
|
||||
.required-note {
|
||||
font-size: 12px; color: #999; margin-bottom: 20px;
|
||||
}
|
||||
.required-note .required { color: #dc2626; }
|
||||
|
||||
/* Form footer */
|
||||
.form-footer {
|
||||
padding: 16px 24px; border-top: 1px solid #e5e5e3;
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
background: #fafafa;
|
||||
}
|
||||
.form-footer-info { font-size: 12px; color: #999; }
|
||||
.form-footer-actions { display: flex; gap: 8px; }
|
||||
|
||||
/* Success toast */
|
||||
.toast {
|
||||
position: fixed; bottom: 24px; right: 24px; background: #166534;
|
||||
color: #fff; padding: 12px 20px; border-radius: 8px; font-size: 13px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15); display: flex; align-items: center;
|
||||
gap: 8px; z-index: 100;
|
||||
}
|
||||
.toast-icon { font-size: 16px; }
|
||||
|
||||
*:focus-visible { outline: 2px solid #1a1a1a; outline-offset: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Sidebar -->
|
||||
<nav class="sidebar" role="navigation" aria-label="Menú principal">
|
||||
<div class="sidebar-logo"><h1>Inventschario</h1><span>Inventario Electrónico</span></div>
|
||||
<div class="nav-section">
|
||||
<div class="nav-label">Principal</div>
|
||||
<a class="nav-item" href="#dashboard">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
|
||||
Dashboard
|
||||
</a>
|
||||
<a class="nav-item" href="#inventory">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/></svg>
|
||||
Inventario
|
||||
</a>
|
||||
<a class="nav-item active" href="#add" aria-current="page">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>
|
||||
Agregar Dispositivo
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-section">
|
||||
<div class="nav-label">Herramientas</div>
|
||||
<a class="nav-item" href="#import">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
||||
Importar / Exportar
|
||||
</a>
|
||||
<a class="nav-item" href="#backups">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
||||
Copias de Seguridad
|
||||
</a>
|
||||
<a class="nav-item" href="#settings">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9c.26.604.852.997 1.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
|
||||
Configuración
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-spacer"></div>
|
||||
<div class="nav-footer">v1.0.0 — 2026-08-03</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main" role="main">
|
||||
<header class="topbar">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<a href="#inventory" class="btn-ghost" style="padding: 4px; border: none; background: none; cursor: pointer; color: #666; text-decoration: none;" aria-label="Volver al inventario">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>
|
||||
</a>
|
||||
<h2>Agregar Dispositivo</h2>
|
||||
</div>
|
||||
<div class="topbar-actions">
|
||||
<button class="btn">Cancelar</button>
|
||||
<button class="btn btn-primary">Guardar Dispositivo</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<p class="required-note">Los campos marcados con <span class="required">*</span> son obligatorios.</p>
|
||||
|
||||
<form class="form-card" aria-label="Formulario de nuevo dispositivo">
|
||||
<!-- Identification -->
|
||||
<div class="form-section" style="padding: 24px; padding-bottom: 0;">
|
||||
<div class="form-section-title">Identificación</div>
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="catalog_number">Número de Catálogo Interno <span class="required">*</span></label>
|
||||
<input class="form-input" type="text" id="catalog_number" placeholder="INV-2024-0248" required aria-required="true">
|
||||
<span class="form-hint">Se genera automáticamente si se deja vacío</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="serial_number">Número de Serie <span class="required">*</span></label>
|
||||
<input class="form-input" type="text" id="serial_number" placeholder="C02X1234JHD5" required aria-required="true">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="service_tag">Service Tag</label>
|
||||
<input class="form-input" type="text" id="service_tag" placeholder="ABC1234">
|
||||
<span class="form-hint">Número de servicio del fabricante</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="additional_reg">Registro Adicional</label>
|
||||
<input class="form-input" type="text" id="additional_reg" placeholder="Cualquier otro número de registro">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Device info -->
|
||||
<div class="form-section" style="padding: 24px; padding-bottom: 0;">
|
||||
<div class="form-section-title">Información del Dispositivo</div>
|
||||
<div class="form-grid">
|
||||
<div class="form-group full-width">
|
||||
<label class="form-label" for="device_name">Nombre / Descripción <span class="required">*</span></label>
|
||||
<input class="form-input" type="text" id="device_name" placeholder="MacBook Pro 14" — Oficina Dirección" required aria-required="true">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="device_type">Tipo de Dispositivo <span class="required">*</span></label>
|
||||
<select class="form-select" id="device_type" required aria-required="true">
|
||||
<option value="">Seleccionar tipo...</option>
|
||||
<option>Ordenador de sobremesa</option>
|
||||
<option selected>Portátil</option>
|
||||
<option>Monitor / Pantalla</option>
|
||||
<option>Impresora</option>
|
||||
<option>Escáner</option>
|
||||
<option>Dispositivo de red</option>
|
||||
<option>Periférico</option>
|
||||
<option>Servidor</option>
|
||||
<option>SAI / Regulador</option>
|
||||
<option>Almacenamiento externo</option>
|
||||
<option>Otro</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="brand">Marca</label>
|
||||
<input class="form-input" type="text" id="brand" placeholder="Apple">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="model">Modelo</label>
|
||||
<input class="form-input" type="text" id="model" placeholder="MacBook Pro M3">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="serial_internal">N.º Serie Interno</label>
|
||||
<input class="form-input" type="text" id="serial_internal" placeholder="Número interno de control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="condition">Estado Físico</label>
|
||||
<select class="form-select" id="condition">
|
||||
<option value="excellent">Excelente</option>
|
||||
<option value="good" selected>Bueno</option>
|
||||
<option value="fair">Regular</option>
|
||||
<option value="poor">Malo</option>
|
||||
<option value="damaged">Dañado</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="status">Estado</label>
|
||||
<select class="form-select" id="status">
|
||||
<option value="active" selected>Activo</option>
|
||||
<option value="available">Disponible</option>
|
||||
<option value="reserved">Reservado</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Purchase info -->
|
||||
<div class="form-section" style="padding: 24px; padding-bottom: 0;">
|
||||
<div class="form-section-title">Compra y Garantía</div>
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="purchase_date">Fecha de Compra</label>
|
||||
<input class="form-input" type="date" id="purchase_date">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="warranty_expiry">Fin de Garantía</label>
|
||||
<input class="form-input" type="date" id="warranty_expiry">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="purchase_price">Precio de Compra (€)</label>
|
||||
<input class="form-input" type="number" id="purchase_price" placeholder="0.00" step="0.01" min="0">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Assignment -->
|
||||
<div class="form-section" style="padding: 24px; padding-bottom: 0;">
|
||||
<div class="form-section-title">Asignación</div>
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="location">Ubicación Asignada</label>
|
||||
<select class="form-select" id="location">
|
||||
<option value="">Seleccionar ubicación...</option>
|
||||
<option>Planta 0 — Recepción</option>
|
||||
<option>Planta 1 — Open Space</option>
|
||||
<option>Planta 1 — Reprografía</option>
|
||||
<option>Planta 1 — Cuarto Redes</option>
|
||||
<option>Planta 2 — Desp. Dirección</option>
|
||||
<option>Almacén</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="assigned_user">Usuario Asignado</label>
|
||||
<input class="form-input" type="text" id="assigned_user" placeholder="Nombre del usuario">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="department">Departamento</label>
|
||||
<select class="form-select" id="department">
|
||||
<option value="">Seleccionar departamento...</option>
|
||||
<option>Informática</option>
|
||||
<option>Administración</option>
|
||||
<option>Recursos Humanos</option>
|
||||
<option>Contabilidad</option>
|
||||
<option>Dirección</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notes -->
|
||||
<div class="form-section" style="padding: 24px;">
|
||||
<div class="form-section-title">Notas</div>
|
||||
<div class="form-grid">
|
||||
<div class="form-group full-width">
|
||||
<label class="form-label" for="notes">Observaciones</label>
|
||||
<textarea class="form-textarea" id="notes" placeholder="Notas adicionales sobre el dispositivo..." rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="form-footer">
|
||||
<span class="form-footer-info">Los cambios se guardan localmente</span>
|
||||
<div class="form-footer-actions">
|
||||
<button type="button" class="btn">Cancelar</button>
|
||||
<button type="button" class="btn" style="border-color: #e5e5e3;">Guardar y Agregar Otro</button>
|
||||
<button type="submit" class="btn btn-primary">Guardar Dispositivo</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Toast demo -->
|
||||
<div class="toast" role="alert" aria-live="polite">
|
||||
<span class="toast-icon" aria-hidden="true">✓</span>
|
||||
Dispositivo INV-2024-0247 guardado correctamente
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
20
sketches/004-configuracion/README.md
Normal file
20
sketches/004-configuracion/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Variant: Configuración — Configure Surface
|
||||
|
||||
## Design stance
|
||||
Tabbed settings with inline editing: each section is self-contained, changes
|
||||
are saved explicitly, and the field label editor shows the internal key alongside
|
||||
the user-facing label.
|
||||
|
||||
## Key choices
|
||||
- **Layout:** Tabbed navigation, settings sections as cards, inline list editors
|
||||
- **Typography:** Monospace for field keys, Inter for labels and values
|
||||
- **Color:** Minimal — toggle switches for boolean settings, danger color for delete
|
||||
- **Interaction:** Toggle switches, inline add/remove for locations/departments
|
||||
|
||||
## Trade-offs
|
||||
- Strong at: Organized settings, clear field mapping, backup management
|
||||
- Weak at: Many settings could overwhelm on first visit
|
||||
|
||||
## Best for
|
||||
Initial setup and ongoing configuration — the admin sets up the system once
|
||||
and revisits occasionally for adjustments.
|
||||
496
sketches/004-configuracion/index.html
Normal file
496
sketches/004-configuracion/index.html
Normal file
|
|
@ -0,0 +1,496 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Inventschario — Configuración</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
color: #1a1a1a; background: #f7f7f5; line-height: 1.5;
|
||||
display: flex; min-height: 100vh;
|
||||
}
|
||||
.sidebar {
|
||||
width: 240px; background: #fff; border-right: 1px solid #e5e5e3;
|
||||
padding: 20px 0; flex-shrink: 0; display: flex; flex-direction: column;
|
||||
}
|
||||
.sidebar-logo { padding: 0 20px 20px; border-bottom: 1px solid #e5e5e3; margin-bottom: 8px; }
|
||||
.sidebar-logo h1 { font-size: 16px; font-weight: 700; }
|
||||
.sidebar-logo span { font-size: 11px; color: #999; display: block; margin-top: 2px; }
|
||||
.nav-section { padding: 8px 12px; }
|
||||
.nav-label { font-size: 11px; font-weight: 600; color: #999; text-transform: uppercase; letter-spacing: 0.5px; padding: 8px 8px 4px; }
|
||||
.nav-item {
|
||||
display: flex; align-items: center; gap: 10px; padding: 8px 12px;
|
||||
border-radius: 6px; font-size: 14px; color: #666; cursor: pointer;
|
||||
text-decoration: none; transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
.nav-item:hover { background: #f0f0ee; color: #1a1a1a; }
|
||||
.nav-item.active { background: #f0f0ee; color: #1a1a1a; font-weight: 500; }
|
||||
.nav-item svg { width: 18px; height: 18px; flex-shrink: 0; }
|
||||
.nav-spacer { flex: 1; }
|
||||
.nav-footer { padding: 12px 20px; border-top: 1px solid #e5e5e3; font-size: 12px; color: #999; }
|
||||
|
||||
.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.topbar {
|
||||
background: #fff; border-bottom: 1px solid #e5e5e3;
|
||||
padding: 16px 32px; display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.topbar h2 { font-size: 18px; font-weight: 600; }
|
||||
.btn {
|
||||
padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 500;
|
||||
cursor: pointer; border: 1px solid #e5e5e3; background: #fff; color: #1a1a1a;
|
||||
transition: background 0.15s; font-family: inherit;
|
||||
}
|
||||
.btn:hover { background: #f0f0ee; }
|
||||
.btn-primary { background: #1a1a1a; color: #fff; border-color: #1a1a1a; }
|
||||
.btn-primary:hover { background: #333; }
|
||||
.btn-danger { color: #dc2626; border-color: #fca5a5; }
|
||||
.btn-danger:hover { background: #fef2f2; }
|
||||
.btn-sm { padding: 4px 10px; font-size: 12px; }
|
||||
|
||||
.content { padding: 32px; overflow-y: auto; flex: 1; max-width: 800px; }
|
||||
|
||||
/* Settings sections */
|
||||
.settings-section {
|
||||
background: #fff; border: 1px solid #e5e5e3; border-radius: 8px;
|
||||
margin-bottom: 24px; overflow: hidden;
|
||||
}
|
||||
.settings-header {
|
||||
padding: 16px 20px; border-bottom: 1px solid #e5e5e3;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.settings-header h3 { font-size: 14px; font-weight: 600; }
|
||||
.settings-header p { font-size: 12px; color: #999; }
|
||||
.settings-body { padding: 20px; }
|
||||
|
||||
.setting-row {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 12px 0; border-bottom: 1px solid #f0f0ee;
|
||||
}
|
||||
.setting-row:last-child { border-bottom: none; }
|
||||
.setting-info { flex: 1; }
|
||||
.setting-label { font-size: 13px; font-weight: 500; }
|
||||
.setting-desc { font-size: 12px; color: #999; margin-top: 2px; }
|
||||
.setting-control { margin-left: 20px; }
|
||||
|
||||
.form-input, .form-select {
|
||||
padding: 6px 10px; border: 1px solid #e5e5e3; border-radius: 4px;
|
||||
font-size: 13px; font-family: inherit; background: #fff;
|
||||
}
|
||||
.form-input:focus, .form-select:focus {
|
||||
outline: none; border-color: #1a1a1a; box-shadow: 0 0 0 1px #1a1a1a;
|
||||
}
|
||||
|
||||
/* Toggle switch */
|
||||
.toggle {
|
||||
width: 40px; height: 22px; background: #e5e5e3; border-radius: 11px;
|
||||
position: relative; cursor: pointer; transition: background 0.2s;
|
||||
border: none; padding: 0;
|
||||
}
|
||||
.toggle.active { background: #166534; }
|
||||
.toggle::after {
|
||||
content: ''; width: 18px; height: 18px; background: #fff;
|
||||
border-radius: 50%; position: absolute; top: 2px; left: 2px;
|
||||
transition: transform 0.2s; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
.toggle.active::after { transform: translateX(18px); }
|
||||
|
||||
/* Field labels editor */
|
||||
.label-editor { margin-top: 8px; }
|
||||
.label-row {
|
||||
display: flex; align-items: center; gap: 12px; padding: 8px 0;
|
||||
border-bottom: 1px solid #f0f0ee;
|
||||
}
|
||||
.label-row:last-child { border-bottom: none; }
|
||||
.label-key {
|
||||
font-size: 12px; color: #999; font-family: monospace;
|
||||
min-width: 160px;
|
||||
}
|
||||
.label-input {
|
||||
flex: 1; padding: 6px 10px; border: 1px solid #e5e5e3; border-radius: 4px;
|
||||
font-size: 13px; font-family: inherit;
|
||||
}
|
||||
.label-input:focus { outline: none; border-color: #1a1a1a; box-shadow: 0 0 0 1px #1a1a1a; }
|
||||
|
||||
/* Backup list */
|
||||
.backup-list { margin-top: 12px; }
|
||||
.backup-item {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 10px 12px; border: 1px solid #f0f0ee; border-radius: 6px;
|
||||
margin-bottom: 8px; font-size: 13px;
|
||||
}
|
||||
.backup-info { display: flex; align-items: center; gap: 12px; }
|
||||
.backup-icon { font-size: 16px; }
|
||||
.backup-name { font-weight: 500; }
|
||||
.backup-meta { font-size: 11px; color: #999; }
|
||||
.backup-actions { display: flex; gap: 4px; }
|
||||
|
||||
/* Tabs */
|
||||
.tabs {
|
||||
display: flex; gap: 0; border-bottom: 1px solid #e5e5e3; margin-bottom: 20px;
|
||||
}
|
||||
.tab {
|
||||
padding: 10px 16px; font-size: 13px; font-weight: 500; color: #666;
|
||||
cursor: pointer; border-bottom: 2px solid transparent; transition: all 0.15s;
|
||||
background: none; border-top: none; border-left: none; border-right: none;
|
||||
font-family: inherit;
|
||||
}
|
||||
.tab:hover { color: #1a1a1a; }
|
||||
.tab.active { color: #1a1a1a; border-bottom-color: #1a1a1a; }
|
||||
|
||||
*:focus-visible { outline: 2px solid #1a1a1a; outline-offset: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Sidebar -->
|
||||
<nav class="sidebar" role="navigation" aria-label="Menú principal">
|
||||
<div class="sidebar-logo"><h1>Inventschario</h1><span>Inventario Electrónico</span></div>
|
||||
<div class="nav-section">
|
||||
<div class="nav-label">Principal</div>
|
||||
<a class="nav-item" href="#dashboard">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
|
||||
Dashboard
|
||||
</a>
|
||||
<a class="nav-item" href="#inventory">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/></svg>
|
||||
Inventario
|
||||
</a>
|
||||
<a class="nav-item" href="#add">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>
|
||||
Agregar Dispositivo
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-section">
|
||||
<div class="nav-label">Herramientas</div>
|
||||
<a class="nav-item" href="#import">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
||||
Importar / Exportar
|
||||
</a>
|
||||
<a class="nav-item" href="#backups">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
||||
Copias de Seguridad
|
||||
</a>
|
||||
<a class="nav-item active" href="#settings" aria-current="page">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9c.26.604.852.997 1.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
|
||||
Configuración
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-spacer"></div>
|
||||
<div class="nav-footer">v1.0.0 — 2026-08-03</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main" role="main">
|
||||
<header class="topbar">
|
||||
<h2>Configuración</h2>
|
||||
<div class="topbar-actions">
|
||||
<button class="btn btn-primary">Guardar Cambios</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<!-- Tabs -->
|
||||
<div class="tabs" role="tablist">
|
||||
<button class="tab active" role="tab" aria-selected="true">General</button>
|
||||
<button class="tab" role="tab">Campos</button>
|
||||
<button class="tab" role="tab">Copias de Seguridad</button>
|
||||
<button class="tab" role="tab">Importar / Exportar</button>
|
||||
</div>
|
||||
|
||||
<!-- General Settings -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">
|
||||
<div>
|
||||
<h3>Información General</h3>
|
||||
<p>Datos de la institución y configuración básica</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-body">
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label">Nombre de la Institución</div>
|
||||
<div class="setting-desc">Aparece en el encabezado de exportaciones e informes</div>
|
||||
</div>
|
||||
<div class="setting-control">
|
||||
<input class="form-input" type="text" value="Ayuntamiento de Ejemplo" style="width: 280px;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label">Prefijo de Número de Catálogo</div>
|
||||
<div class="setting-desc">Prefijo para la generación automática de números de inventario</div>
|
||||
</div>
|
||||
<div class="setting-control">
|
||||
<input class="form-input" type="text" value="INV-" style="width: 120px;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label">Separador CSV por Defecto</div>
|
||||
<div class="setting-desc">Separador utilizado al exportar e importar archivos CSV</div>
|
||||
</div>
|
||||
<div class="setting-control">
|
||||
<select class="form-select">
|
||||
<option value=";">Punto y coma (;)</option>
|
||||
<option value=",">Coma (,)</option>
|
||||
<option value="\t">Tabulador</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Field Labels -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">
|
||||
<div>
|
||||
<h3>Etiquetas de Campos</h3>
|
||||
<p>Personaliza los nombres que aparecen en la interfaz. El nombre interno en la base de datos no cambia.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-body">
|
||||
<div class="label-editor">
|
||||
<div class="label-row">
|
||||
<span class="label-key">serial_number</span>
|
||||
<input class="label-input" type="text" value="Número de Serie">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">service_tag</span>
|
||||
<input class="label-input" type="text" value="Service Tag">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">catalog_number</span>
|
||||
<input class="label-input" type="text" value="Número de Catálogo Interno">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">additional_registry</span>
|
||||
<input class="label-input" type="text" value="Registro Adicional">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">device_name</span>
|
||||
<input class="label-input" type="text" value="Nombre / Descripción">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">device_type</span>
|
||||
<input class="label-input" type="text" value="Tipo de Dispositivo">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">brand</span>
|
||||
<input class="label-input" type="text" value="Marca">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">model</span>
|
||||
<input class="label-input" type="text" value="Modelo">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">purchase_date</span>
|
||||
<input class="label-input" type="text" value="Fecha de Compra">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">warranty_expiry</span>
|
||||
<input class="label-input" type="text" value="Fin de Garantía">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">purchase_price</span>
|
||||
<input class="label-input" type="text" value="Precio de Compra (€)">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">assigned_location</span>
|
||||
<input class="label-input" type="text" value="Ubicación Asignada">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">assigned_user</span>
|
||||
<input class="label-input" type="text" value="Usuario Asignado">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">department</span>
|
||||
<input class="label-input" type="text" value="Departamento">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">status</span>
|
||||
<input class="label-input" type="text" value="Estado">
|
||||
</div>
|
||||
<div class="label-row">
|
||||
<span class="label-key">condition</span>
|
||||
<input class="label-input" type="text" value="Estado Físico">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Backup Settings -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">
|
||||
<div>
|
||||
<h3>Copias de Seguridad</h3>
|
||||
<p>Configuración del backup automático y gestión de copias</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-body">
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label">Backup Automático</div>
|
||||
<div class="setting-desc">Crear una copia de seguridad de la base de datos cada día</div>
|
||||
</div>
|
||||
<div class="setting-control">
|
||||
<button class="toggle active" role="switch" aria-checked="true" aria-label="Activar backup automático"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label">Hora del Backup</div>
|
||||
<div class="setting-desc">Hora a la que se ejecuta el backup diario</div>
|
||||
</div>
|
||||
<div class="setting-control">
|
||||
<input class="form-input" type="time" value="02:00">
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label">Días de Retención</div>
|
||||
<div class="setting-desc">Número de días antes de sugerir la eliminación de backups antiguos</div>
|
||||
</div>
|
||||
<div class="setting-control">
|
||||
<input class="form-input" type="number" value="30" min="7" max="365" style="width: 80px;">
|
||||
<span style="font-size: 12px; color: #999; margin-left: 4px;">días</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label">Máximo de Backups</div>
|
||||
<div class="setting-desc">Número máximo de copias de seguridad a conservar</div>
|
||||
</div>
|
||||
<div class="setting-control">
|
||||
<input class="form-input" type="number" value="90" min="10" max="365" style="width: 80px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent backups -->
|
||||
<div style="margin-top: 20px; padding-top: 16px; border-top: 1px solid #e5e5e3;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
|
||||
<span style="font-size: 13px; font-weight: 500;">Copias Recientes</span>
|
||||
<button class="btn btn-sm">Crear Backup Manual</button>
|
||||
</div>
|
||||
<div class="backup-list">
|
||||
<div class="backup-item">
|
||||
<div class="backup-info">
|
||||
<span class="backup-icon" aria-hidden="true">💾</span>
|
||||
<div>
|
||||
<div class="backup-name">inventschario_20260803_020000.db.gz</div>
|
||||
<div class="backup-meta">3 de agosto 2026, 02:00 — 2.4 MB — Automático</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="backup-actions">
|
||||
<button class="btn btn-sm" aria-label="Restaurar este backup">Restaurar</button>
|
||||
<button class="btn btn-sm btn-danger" aria-label="Eliminar este backup">Eliminar</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="backup-item">
|
||||
<div class="backup-info">
|
||||
<span class="backup-icon" aria-hidden="true">💾</span>
|
||||
<div>
|
||||
<div class="backup-name">inventschario_20260802_020000.db.gz</div>
|
||||
<div class="backup-meta">2 de agosto 2026, 02:00 — 2.3 MB — Automático</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="backup-actions">
|
||||
<button class="btn btn-sm">Restaurar</button>
|
||||
<button class="btn btn-sm btn-danger">Eliminar</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="backup-item">
|
||||
<div class="backup-info">
|
||||
<span class="backup-icon" aria-hidden="true">💾</span>
|
||||
<div>
|
||||
<div class="backup-name">inventschario_20260801_143022.db.gz</div>
|
||||
<div class="backup-meta">1 de agosto 2026, 14:30 — 2.3 MB — <strong style="color: #92400e;">Manual</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="backup-actions">
|
||||
<button class="btn btn-sm">Restaurar</button>
|
||||
<button class="btn btn-sm btn-danger">Eliminar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Locations & Departments -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">
|
||||
<div>
|
||||
<h3>Ubicaciones y Departamentos</h3>
|
||||
<p>Gestiona las ubicaciones físicas y departamentos de la institución</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-body">
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 24px;">
|
||||
<!-- Locations -->
|
||||
<div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
|
||||
<span style="font-size: 13px; font-weight: 500;">Ubicaciones</span>
|
||||
<button class="btn btn-sm">+ Añadir</button>
|
||||
</div>
|
||||
<div style="border: 1px solid #e5e5e3; border-radius: 6px; overflow: hidden;">
|
||||
<div style="padding: 8px 12px; border-bottom: 1px solid #f0f0ee; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Planta 0 — Recepción</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
<div style="padding: 8px 12px; border-bottom: 1px solid #f0f0ee; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Planta 1 — Open Space</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
<div style="padding: 8px 12px; border-bottom: 1px solid #f0f0ee; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Planta 1 — Reprografía</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
<div style="padding: 8px 12px; border-bottom: 1px solid #f0f0ee; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Planta 2 — Desp. Dirección</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
<div style="padding: 8px 12px; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Almacén</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Departments -->
|
||||
<div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
|
||||
<span style="font-size: 13px; font-weight: 500;">Departamentos</span>
|
||||
<button class="btn btn-sm">+ Añadir</button>
|
||||
</div>
|
||||
<div style="border: 1px solid #e5e5e3; border-radius: 6px; overflow: hidden;">
|
||||
<div style="padding: 8px 12px; border-bottom: 1px solid #f0f0ee; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Informática</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
<div style="padding: 8px 12px; border-bottom: 1px solid #f0f0ee; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Administración</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
<div style="padding: 8px 12px; border-bottom: 1px solid #f0f0ee; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Recursos Humanos</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
<div style="padding: 8px 12px; border-bottom: 1px solid #f0f0ee; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Contabilidad</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
<div style="padding: 8px 12px; font-size: 13px; display: flex; justify-content: space-between;">
|
||||
<span>Dirección</span>
|
||||
<button class="btn btn-sm btn-danger" style="padding: 2px 6px; font-size: 11px;">×</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue