Files
roi-theme/_planificacion/01-design-system/13-PANEL-ADMINISTRACION.md
FrankZamora 0f6387ab46 refactor: reorganizar openspec y planificacion con spec recaptcha
- renombrar openspec/ a _openspec/ (carpeta auxiliar)
- mover specs de features a changes/
- crear specs base: arquitectura-limpia, estandares-codigo, nomenclatura
- migrar _planificacion/ con design-system y roi-theme-template
- agregar especificacion recaptcha anti-spam (proposal, tasks, spec)
- corregir rutas y referencias en todas las specs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 15:30:45 -06:00

474 lines
13 KiB
Markdown

# 🎛️ PANEL DE ADMINISTRACIÓN PRINCIPAL
## Arquitectura del Sistema
El panel de administración utiliza un **sistema de tabs (pestañas)** de Bootstrap 5, donde todos los componentes existen en una sola página y se alternan mediante JavaScript.
### Características Principales
-**Single Page**: Todos los componentes en un solo archivo `main.php`
-**Bootstrap Tabs**: Navegación mediante `nav-tabs` y `tab-pane`
-**Carga Modular**: Cada componente se incluye con `require_once`
-**Botones Globales**: Save/Cancel compartidos para todos los componentes
-**Sin Recargas**: Cambio de tabs sin reload de página
---
## Estructura del main.php
```php
<?php
/**
* Admin Panel - Main Page
*/
if (!defined('ABSPATH')) {
exit;
}
?>
<div class="wrap apus-admin">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<p class="description">Configure los componentes del tema</p>
<!-- Navigation Tabs -->
<ul class="nav nav-tabs" role="tablist">
<!-- Tabs aquí -->
</ul>
<!-- Tab Content -->
<div class="tab-content mt-3">
<?php
// Componentes incluidos aquí
?>
</div>
<!-- Action Buttons (Global) -->
<div class="d-flex justify-content-end gap-2 p-3 rounded border mt-4"
style="background-color: #f8f9fa;">
<button type="button" class="btn btn-outline-secondary" id="cancelChanges">
<i class="bi bi-x-circle me-1"></i>
Cancelar
</button>
<button type="button" id="saveSettings"
class="btn fw-semibold text-white"
style="background-color: #FF8600; border-color: #FF8600;">
<i class="bi bi-check-circle me-1"></i>
Guardar Cambios
</button>
</div>
</div>
```
---
## Agregar un Nuevo Tab
### Paso 1: Agregar el Tab en la Navegación
```php
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active"
data-bs-toggle="tab"
data-bs-target="#[tabId]"
href="#[tabId]"
role="tab">
<i class="bi bi-[icon-class] me-2"></i>
[Nombre del Componente]
</a>
</li>
<!-- Más tabs... -->
</ul>
```
**Reemplazar:**
- `[tabId]`: ID único del tab (ej: `notificationBarTab`, `siteFooterTab`)
- `[icon-class]`: Clase del icono de Bootstrap Icons (ej: `megaphone-fill`)
- `[Nombre del Componente]`: Nombre visible del tab (ej: "Barra de Notificaciones")
### Paso 2: Incluir el Componente en Tab Content
```php
<div class="tab-content mt-3">
<?php
/**
* [Component Name] Component
* Archivo: Admin/Components/component-[name].php
*/
require_once APUS_ADMIN_PANEL_PATH . 'Admin/Components/component-[name].php';
?>
<!-- Más componentes... -->
</div>
```
**Reemplazar:**
- `[Component Name]`: Nombre descriptivo del componente
- `[name]`: Nombre del archivo (ej: `notification-bar`, `site-footer`)
### Paso 3: Crear el Archivo del Componente
Crear `Admin/Components/component-[name].php`:
```php
<!-- Tab Pane: [Component Name] -->
<div class="tab-pane fade show active" id="[tabId]" role="tabpanel">
<!-- Header del Tab -->
<div class="rounded p-4 mb-4 shadow text-white"
style="background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%);
border-left: 4px solid #FF8600;">
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
<div>
<h3 class="h4 mb-1 fw-bold">
<i class="bi bi-[icon-class] me-2" style="color: #FF8600;"></i>
[Título del Componente]
</h3>
<p class="mb-0 small" style="opacity: 0.85;">
[Descripción breve del componente]
</p>
</div>
<button type="button" class="btn btn-sm btn-outline-light" id="reset[Component]Defaults">
<i class="bi bi-arrow-counterclockwise me-1"></i>
Restaurar valores por defecto
</button>
</div>
</div>
<!-- Grid de Configuración -->
<div class="row g-3">
<!-- Columna izquierda: Configuración -->
<div class="col-lg-6">
<!-- Cards de configuración -->
</div>
<!-- Columna derecha: Preview -->
<div class="col-lg-6">
<!-- Card de vista previa -->
</div>
</div>
</div><!-- /tab-pane -->
```
---
## Iconos Sugeridos por Tipo de Componente
| Tipo de Componente | Icono | Clase Bootstrap Icons |
|--------------------|-------|----------------------|
| Notificaciones/Anuncios | 📢 | `bi-megaphone-fill` |
| Navegación/Menú | 📋 | `bi-layout-text-window` |
| Sección Hero | 🖼️ | `bi-image` |
| Footer | ⬇️ | `bi-box-arrow-down` |
| Formularios | 📝 | `bi-clipboard-check` |
| Call-to-Action | 👆 | `bi-cursor-fill` |
| Testimonios | 💬 | `bi-chat-quote` |
| Configuración | ⚙️ | `bi-gear-fill` |
---
## Ejemplo Completo: Agregar Componente de Navegación
### 1. Agregar Tab en main.php
```php
<ul class="nav nav-tabs" role="tablist">
<!-- Tab existente -->
<li class="nav-item">
<a class="nav-link active"
data-bs-toggle="tab"
data-bs-target="#topBarTab"
href="#topBarTab"
role="tab">
<i class="bi bi-megaphone-fill me-2"></i>
Top Bar
</a>
</li>
<!-- NUEVO TAB -->
<li class="nav-item">
<a class="nav-link"
data-bs-toggle="tab"
data-bs-target="#navbarTab"
href="#navbarTab"
role="tab">
<i class="bi bi-layout-text-window me-2"></i>
Navbar
</a>
</li>
</ul>
```
**Notas:**
- El primer tab tiene `class="nav-link active"`
- Los demás tabs solo tienen `class="nav-link"`
### 2. Incluir Componente en Tab Content
```php
<div class="tab-content mt-3">
<?php
// Componente existente
require_once APUS_ADMIN_PANEL_PATH . 'Admin/Components/component-top-bar.php';
// NUEVO COMPONENTE
require_once APUS_ADMIN_PANEL_PATH . 'Admin/Components/component-navbar.php';
?>
</div>
```
### 3. Crear component-navbar.php
Crear archivo: `Admin/Components/component-navbar.php`
```php
<!-- Tab Pane: Navbar -->
<div class="tab-pane fade" id="navbarTab" role="tabpanel">
<!-- Header del Tab -->
<div class="rounded p-4 mb-4 shadow text-white"
style="background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%);
border-left: 4px solid #FF8600;">
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
<div>
<h3 class="h4 mb-1 fw-bold">
<i class="bi bi-layout-text-window me-2" style="color: #FF8600;"></i>
Configuración del Navbar
</h3>
<p class="mb-0 small" style="opacity: 0.85;">
Gestiona los colores, estilo y comportamiento del menú de navegación
</p>
</div>
<button type="button" class="btn btn-sm btn-outline-light" id="resetNavbarDefaults">
<i class="bi bi-arrow-counterclockwise me-1"></i>
Restaurar valores por defecto
</button>
</div>
</div>
<!-- Grid de Configuración -->
<div class="row g-3">
<!-- Configuración -->
<div class="col-lg-6">
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-palette me-2" style="color: #FF8600;"></i>
Colores
</h5>
<!-- Campos de configuración aquí -->
</div>
</div>
</div>
<!-- Vista Previa -->
<div class="col-lg-6">
<div class="card shadow-sm mb-3" style="border-left: 4px solid #FF8600;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-eye me-2" style="color: #FF8600;"></i>
Vista Previa
</h5>
<!-- Preview del componente aquí -->
<div id="navbarPreview">
<!-- HTML idéntico al front-end -->
</div>
</div>
</div>
</div>
</div>
</div><!-- /tab-pane -->
```
**Notas:**
- El primer tab-pane tiene `class="tab-pane fade show active"`
- Los demás tab-panes tienen `class="tab-pane fade"`
---
## Orden de los Tabs
### Por Prioridad
Organizar los tabs de más importante a menos importante:
1. Componentes críticos/visibles (Header, Navbar, Hero)
2. Componentes de contenido (Secciones, CTAs)
3. Componentes complementarios (Footer, Forms)
4. Configuraciones generales
### Ejemplo de Orden
```php
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item"><!-- Barra de Notificaciones --></li>
<li class="nav-item"><!-- Navbar --></li>
<li class="nav-item"><!-- Hero Section --></li>
<li class="nav-item"><!-- Call-to-Action --></li>
<li class="nav-item"><!-- Footer --></li>
<li class="nav-item"><!-- Configuración General --></li>
</ul>
```
---
## Botones Globales Save/Cancel
Los botones de guardar y cancelar son **globales** para todos los tabs:
```php
<div class="d-flex justify-content-end gap-2 p-3 rounded border mt-4"
style="background-color: #f8f9fa; border-color: #e9ecef !important;">
<!-- Cancelar -->
<button type="button" class="btn btn-outline-secondary" id="cancelChanges">
<i class="bi bi-x-circle me-1"></i>
Cancelar
</button>
<!-- Guardar -->
<button type="button" id="saveSettings"
class="btn fw-semibold text-white"
style="background-color: #FF8600; border-color: #FF8600;"
disabled>
<i class="bi bi-check-circle me-1"></i>
Guardar Cambios
</button>
</div>
```
### JavaScript para Activar/Desactivar Guardar
```javascript
// Detectar cambios en cualquier campo
document.querySelectorAll('input, select, textarea').forEach(field => {
field.addEventListener('change', function() {
// Activar botón de guardar
document.getElementById('saveSettings').disabled = false;
});
});
// Guardar cambios
document.getElementById('saveSettings').addEventListener('click', function() {
// Guardar configuración de todos los componentes
saveAllConfigs();
// Desactivar botón de guardar
this.disabled = true;
});
// Cancelar cambios
document.getElementById('cancelChanges').addEventListener('click', function() {
if (confirm('¿Descartar todos los cambios sin guardar?')) {
// Recargar configuraciones originales
loadAllConfigs();
// Desactivar botón de guardar
document.getElementById('saveSettings').disabled = true;
}
});
```
---
## Responsive Behavior
### Desktop (≥992px)
- Tabs en una sola línea horizontal
- Grid de 2 columnas (configuración + preview)
- Espaciado completo
### Tablet (768px - 991px)
- Tabs pueden hacer wrap a 2 líneas
- Grid de 2 columnas (se mantiene)
- Espaciado reducido
### Mobile (<768px)
- Tabs en scroll horizontal o stacked vertical
- Grid stacked (1 columna)
- Botones Save/Cancel pueden hacer stack
```css
@media (max-width: 991px) {
.nav-tabs {
flex-wrap: wrap;
}
.nav-tabs .nav-link {
font-size: 0.9rem;
padding: 0.5rem 0.75rem;
}
}
@media (max-width: 767px) {
.nav-tabs {
overflow-x: auto;
flex-wrap: nowrap;
}
.nav-tabs .nav-item {
white-space: nowrap;
}
}
```
---
## Funcionalidad Adicional (Opcional)
### Badges de Estado en Tabs
```php
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#[tabId]" role="tab">
<i class="bi bi-[icon-class] me-2"></i>
[Nombre del Componente]
<span class="badge bg-success ms-2" style="font-size: 0.65rem;">Activo</span>
</a>
</li>
```
**Estados posibles:**
- `bg-success`: Activo
- `bg-secondary`: Inactivo
- `bg-warning text-dark`: Requiere atención
### Indicador de Cambios Sin Guardar
```javascript
// Agregar asterisco al tab si tiene cambios sin guardar
function markTabAsModified(tabId) {
const tabLink = document.querySelector(`a[data-bs-target="#${tabId}"]`);
if (!tabLink.querySelector('.modified-indicator')) {
tabLink.innerHTML += ' <span class="modified-indicator" style="color: #FF8600;">*</span>';
}
}
```
---
## Checklist de Implementación
Cuando agregues un nuevo componente al panel, asegúrate de:
- [ ] Agregar el tab en la navegación (`<ul class="nav nav-tabs">`)
- [ ] Crear el archivo PHP del componente (`component-[name].php`)
- [ ] Incluir el componente en tab-content con `require_once`
- [ ] Crear archivo CSS del componente (`component-[name].css`)
- [ ] Crear archivo JS del componente (`component-[name].js`)
- [ ] Crear archivo de configuración JSON (`[name]-config.json`)
- [ ] Agregar estilos específicos del componente
- [ ] Implementar vista previa en tiempo real
- [ ] Conectar con sistema de guardar/cancelar global
- [ ] Probar responsive behavior
- [ ] Verificar que el tab-pane tenga el ID correcto
- [ ] Verificar que el primer tab y tab-pane tengan `active` y `show`
---
## Volver al Índice
[← Volver al README](README.md)