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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue