frontend-config

este archivo esta alojado en: Working-English-System / modules / config/ templates/frontend-config.php el codigo es el siguiente:

<?php

// Verificar permisos

if (!current_user_can(‘manage_options’)) {

    wp_die(__(‘No tienes permisos para acceder a esta página.’, ‘working-english-system’));

}

// Desactivar caché para datos dinámicos

if (!defined(‘DONOTCACHEPAGE’)) {

    define(‘DONOTCACHEPAGE’, true);

}

nocache_headers();

?>

<!DOCTYPE html>

<html <?php language_attributes(); ?>>

<head>

    <meta charset=”<?php bloginfo(‘charset’); ?>”>

    <meta name=”viewport” content=”width=device-width, initial-scale=1″>

    <title>Configuración – Working English International</title>

    <?php wp_head(); ?>

</head>

<body <?php body_class(); ?>>

<!– CSS PROFESIONAL –>

<style>

/* Variables CSS */

:root {

    –wes-primary: #B19CD9;

    –wes-secondary: #9B59B6;

    –wes-success: #9DFF70;

    –wes-warning: #FFE066;

    –wes-danger: #FF6B6B;

    –wes-info: #74B9FF;

    –wes-light: #f6f7f7;

    –wes-dark: #1d2327;

    –wes-border: #c3c4c7;

    –wes-shadow: 0 2px 8px rgba(0,0,0,0.1);

}

/* Encabezado corporativo igual al de estudiantes */

.wes-corporate-header {

    background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);

    position: relative;

    overflow: hidden;

    padding: 0;

    margin: 0;

    box-shadow: 0 10px 40px rgba(0,0,0,0.15);

}

.wes-corporate-header::before {

    content: ”;

    position: absolute;

    top: 0;

    left: 0;

    right: 0;

    bottom: 0;

    background:

        radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),

        radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%),

        radial-gradient(circle at 40% 80%, rgba(120, 198, 121, 0.3) 0%, transparent 50%);

    animation: gradientShift 15s ease-in-out infinite;

}

@keyframes gradientShift {

    0%, 100% { opacity: 1; transform: scale(1); }

    50% { opacity: 0.8; transform: scale(1.05); }

}

.corporate-content {

    position: relative;

    z-index: 2;

    display: grid;

    grid-template-columns: auto 1fr auto;

    align-items: center;

    padding: 25px 40px;

    gap: 30px;

    backdrop-filter: blur(10px);

    background: rgba(255,255,255,0.05);

}

.company-logo {

    display: flex;

    align-items: center;

    gap: 20px;

}

.logo-image {

    width: 120px;

    height: auto;

    filter: drop-shadow(0 4px 20px rgba(0,0,0,0.3));

    transition: all 0.3s ease;

}

.company-info {

    text-align: center;

    color: white;

}

.company-name {

    font-size: 36px;

    font-weight: 800;

    margin: 0;

    color: white;

    text-shadow: 0 2px 10px rgba(0,0,0,0.3);

}

.company-tagline {

    font-size: 16px;

    margin: 8px 0 0;

    opacity: 0.95;

    font-weight: 500;

    letter-spacing: 1px;

}

.contact-info {

    text-align: right;

    color: white;

}

.contact-item {

    display: flex;

    align-items: center;

    justify-content: flex-end;

    gap: 10px;

    margin: 8px 0;

    font-size: 14px;

    opacity: 0.9;

}

.contact-item i {

    width: 20px;

    text-align: center;

    background: rgba(255,255,255,0.2);

    padding: 8px;

    border-radius: 50%;

    font-size: 12px;

}

.contact-item a {

    color: white;

    text-decoration: none;

}

/* Navbar de navegación */

.wes-navbar {

    background: linear-gradient(135deg, var(–wes-primary), var(–wes-secondary));

    padding: 0 20px;

    display: flex;

    align-items: center;

    justify-content: space-between;

    box-shadow: 0 4px 20px rgba(0,0,0,0.1);

    position: sticky;

    top: 0;

    z-index: 1000;

    backdrop-filter: blur(10px);

    border-bottom: 1px solid rgba(255,255,255,0.1);

}

.nav-brand {

    display: flex;

    align-items: center;

    gap: 12px;

    color: white;

    font-size: 20px;

    font-weight: 700;

    padding: 15px 0;

}

.nav-brand i {

    font-size: 24px;

    color: var(–wes-warning);

}

.nav-menu {

    display: flex;

    align-items: center;

    gap: 5px;

}

.nav-item {

    display: flex;

    align-items: center;

    gap: 8px;

    padding: 12px 20px;

    color: rgba(255,255,255,0.9);

    text-decoration: none;

    border-radius: 8px;

    font-weight: 500;

    font-size: 14px;

    transition: all 0.3s ease;

    position: relative;

    overflow: hidden;

}

.nav-item:hover {

    background: rgba(255,255,255,0.15);

    color: white;

    text-decoration: none;

    transform: translateY(-2px);

    box-shadow: 0 4px 15px rgba(0,0,0,0.2);

}

.nav-item.active {

    background: rgba(255,255,255,0.25);

    color: white;

    box-shadow: inset 0 2px 4px rgba(0,0,0,0.2);

}

.nav-item i {

    font-size: 16px;

    width: 20px;

    text-align: center;

}

/* Contenedor principal */

.wes-config-container {

    max-width: 1200px;

    margin: 0 auto;

    padding: 20px;

    font-family: -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, sans-serif;

}

/* Header del módulo */

.wes-config-header {

    display: flex;

    justify-content: space-between;

    align-items: center;

    margin-bottom: 30px;

    padding: 25px;

    background: linear-gradient(135deg, var(–wes-primary), var(–wes-secondary));

    border-radius: 12px;

    color: white;

    box-shadow: var(–wes-shadow);

}

.wes-config-header h1 {

    margin: 0;

    font-size: 28px;

    font-weight: 600;

    display: flex;

    align-items: center;

    gap: 15px;

}

.wes-config-header p {

    margin: 8px 0 0;

    opacity: 0.9;

    font-size: 16px;

}

/* Tabs de configuración */

.config-tabs {

    display: flex;

    background: white;

    border-radius: 12px;

    box-shadow: var(–wes-shadow);

    margin-bottom: 20px;

    overflow: hidden;

}

.config-tab {

    flex: 1;

    padding: 20px;

    text-align: center;

    background: #f8f9fa;

    border: none;

    cursor: pointer;

    transition: all 0.3s ease;

    color: #666;

    font-weight: 500;

    border-bottom: 3px solid transparent;

}

.config-tab:hover {

    background: #e9ecef;

    color: var(–wes-primary);

}

.config-tab.active {

    background: white;

    color: var(–wes-primary);

    border-bottom-color: var(–wes-primary);

}

.config-tab i {

    display: block;

    font-size: 2rem;

    margin-bottom: 10px;

}

/* Contenido de las tabs */

.tab-content {

    display: none;

    background: white;

    border-radius: 12px;

    box-shadow: var(–wes-shadow);

    overflow: hidden;

}

.tab-content.active {

    display: block;

}

.tab-header {

    padding: 20px 25px;

    background: var(–wes-light);

    border-bottom: 1px solid var(–wes-border);

    display: flex;

    justify-content: space-between;

    align-items: center;

}

.tab-title {

    margin: 0;

    font-size: 20px;

    color: var(–wes-dark);

    display: flex;

    align-items: center;

    gap: 10px;

}

.tab-body {

    padding: 25px;

}

/* Botones de acción – MÁS PEQUEÑOS */

.btn {

    padding: 8px 16px;

    border: none;

    border-radius: 6px;

    font-weight: 600;

    cursor: pointer;

    transition: all 0.3s ease;

    text-decoration: none;

    display: inline-flex;

    align-items: center;

    gap: 6px;

    font-size: 13px;

    line-height: 1.2;

}

.btn-primary {

    background: var(–wes-primary);

    color: white;

}

.btn-primary:hover {

    background: var(–wes-secondary);

    transform: translateY(-1px);

    color: white;

    text-decoration: none;

}

.btn-success {

    background: var(–wes-success);

    color: #333;

}

.btn-warning {

    background: var(–wes-warning);

    color: #333;

}

.btn-danger {

    background: var(–wes-danger);

    color: white;

}

.btn-sm {

    padding: 8px 16px;

    font-size: 12px;

}

/* Tabla de datos */

.data-table {

    width: 100%;

    border-collapse: collapse;

    margin-top: 20px;

}

.data-table th {

    background: #f8f9fa;

    padding: 12px;

    text-align: left;

    font-weight: 600;

    color: var(–wes-dark);

    border-bottom: 2px solid var(–wes-border);

}

.data-table td {

    padding: 12px;

    border-bottom: 1px solid #f0f0f0;

    vertical-align: middle;

}

.data-table tbody tr:hover {

    background: #f8f9ff;

}

/* Estado de carga */

.loading-state {

    text-align: center;

    padding: 3rem;

    color: #666;

}

.spinner {

    width: 40px;

    height: 40px;

    border: 3px solid #f3f3f3;

    border-top: 3px solid var(–wes-primary);

    border-radius: 50%;

    animation: spin 1s linear infinite;

    margin: 0 auto 1rem;

}

@keyframes spin {

    0% { transform: rotate(0deg); }

    100% { transform: rotate(360deg); }

}

/* Modal para formularios – AJUSTADO PARA MEJOR VISUALIZACIÓN */

.modal-overlay {

    position: fixed;

    top: 0;

    left: 0;

    right: 0;

    bottom: 0;

    background: rgba(0, 0, 0, 0.7);

    z-index: 999999;

    display: flex;

    align-items: center;

    justify-content: center;

    opacity: 0;

    visibility: hidden;

    transition: all 0.3s ease;

    padding: 20px;

}

.modal-overlay.show {

    opacity: 1;

    visibility: visible;

}

.modal-content {

    background: white;

    border-radius: 12px;

    max-width: 1000px;

    width: 95%;

    max-height: 95vh;

    overflow: hidden;

    transform: scale(0.9);

    transition: all 0.3s ease;

    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);

    display: flex;

    flex-direction: column;

}

.modal-overlay.show .modal-content {

    transform: scale(1);

}

/* Modal header – MÁS COMPACTO */

.modal-header {

    padding: 15px 20px;

    background: linear-gradient(135deg, var(–wes-primary), var(–wes-secondary));

    color: white;

    position: relative;

    flex-shrink: 0;

}

.modal-title {

    margin: 0;

    font-size: 18px;

    font-weight: 600;

}

.btn-close {

    position: absolute;

    top: 10px;

    right: 15px;

    background: rgba(255,255,255,0.2);

    border: none;

    color: white;

    font-size: 20px;

    cursor: pointer;

    padding: 5px 10px;

    border-radius: 6px;

    transition: all 0.3s ease;

    line-height: 1;

}

.btn-close:hover {

    background: rgba(255,255,255,0.3);

}

/* Modal body – MÁS COMPACTO */

.modal-body {

    padding: 15px 20px;

    flex-grow: 1;

    overflow-y: auto;

    max-height: 60vh;

    font-size: 13px;

}

.modal-footer {

    padding: 12px 20px;

    background: #f8f9fa;

    border-top: 1px solid var(–wes-border);

    display: flex;

    justify-content: flex-end;

    gap: 8px;

    flex-shrink: 0;

}

/* Formularios – MÁS COMPACTOS Y PEQUEÑOS */

.form-group {

    margin-bottom: 12px;

}

.form-label {

    display: block;

    margin-bottom: 4px;

    font-weight: 600;

    color: var(–wes-dark);

    font-size: 12px;

}

.form-label.required::after {

    content: ‘ *’;

    color: var(–wes-danger);

}

.form-control {

    width: 100%;

    padding: 8px 10px;

    border: 2px solid #e0e0e0;

    border-radius: 6px;

    font-size: 13px;

    transition: all 0.3s ease;

    height: 38px;

}

.form-control:focus {

    outline: none;

    border-color: var(–wes-primary);

    box-shadow: 0 0 0 3px rgba(177, 156, 217, 0.1);

}

.form-control[type=”textarea”],

textarea.form-control {

    height: auto;

    min-height: 60px;

    resize: vertical;

}

.form-grid {

    display: grid;

    grid-template-columns: 1fr 1fr;

    gap: 12px;

}

.form-help {

    font-size: 10px;

    color: #666;

    margin-top: 2px;

    line-height: 1.2;

}

/* Responsive – MEJOR PARA MODALES */

@media (max-width: 768px) {

    .wes-config-container {

        padding: 10px;

    }

    .config-tabs {

        flex-direction: column;

    }

    .config-tab {

        text-align: left;

        padding: 15px 20px;

    }

    .config-tab i {

        display: inline-block;

        margin-right: 10px;

        margin-bottom: 0;

        font-size: 1.2rem;

    }

    .form-grid {

        grid-template-columns: 1fr;

    }

    .modal-content {

        width: 98%;

        margin: 5px;

        max-height: 98vh;

    }

    .modal-body {

        padding: 15px;

        max-height: 70vh;

    }

    .modal-header {

        padding: 12px 15px;

    }

    .modal-footer {

        padding: 12px 15px;

    }

}

</style>

<!– Cargar Font Awesome –>

<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css”>

<!– Encabezado Corporativo Premium –>

<div class=”wes-corporate-header”>

    <div class=”corporate-content”>

        <div class=”company-logo”>

            <img src=”http://workingenglishadmin.com/wp-content/uploads/2025/07/letras-1_Mesa-de-trabajo-1.png” alt=”Working English International” class=”logo-image”>

        </div>

        <div class=”company-info”>

            <h1 class=”company-name”>Working English International</h1>

            <p class=”company-tagline”>Learn With Us</p>

        </div>

        <div class=”contact-info”>

            <div class=”contact-item”>

                <i class=”fas fa-map-marker-alt”></i>

                <span>Casper, Wyoming, USA</span>

            </div>

            <div class=”contact-item”>

                <i class=”fas fa-globe”></i>

                <a href=”https://www.workingenglishonline.com” target=”_blank”>www.workingenglishonline.com</a>

            </div>

            <div class=”contact-item”>

                <i class=”fas fa-graduation-cap”></i>

                <span>Academic Management System</span>

            </div>

        </div>

    </div>

</div>

<!– Barra de navegación –>

<div class=”wes-navbar”>

    <div class=”nav-brand”>

        <i class=”fas fa-graduation-cap”></i>

        <span>WE System</span>

    </div>

    <nav class=”nav-menu”>

        <a href=”/dashboard” class=”nav-item”>

            <i class=”fas fa-tachometer-alt”></i>

            Dashboard

        </a>

        <a href=”/estudiantes” class=”nav-item”>

            <i class=”fas fa-users”></i>

            Estudiantes

        </a>

        <a href=”/configuracion” class=”nav-item active”>

            <i class=”fas fa-cogs”></i>

            Configuración

        </a>

    </nav>

</div>

<div class=”wes-config-container”>

    <!– Header –>

    <div class=”wes-config-header”>

        <div>

            <h1>

                <i class=”fas fa-cogs”></i>

                Configuración del Sistema

            </h1>

            <p>Gestiona sedes, idiomas, programas y niveles de forma fácil</p>

        </div>

    </div>

    <!– Tabs de configuración –>

    <div class=”config-tabs”>

        <button class=”config-tab active” data-tab=”branches”>

            <i class=”fas fa-building”></i>

            Sedes

        </button>

        <button class=”config-tab” data-tab=”languages”>

            <i class=”fas fa-language”></i>

            Idiomas

        </button>

        <button class=”config-tab” data-tab=”programs”>

            <i class=”fas fa-graduation-cap”></i>

            Programas

        </button>

        <button class=”config-tab” data-tab=”levels”>

            <i class=”fas fa-layer-group”></i>

            Niveles

        </button>

    </div>

    <!– Tab 1: Sedes –>

    <div class=”tab-content active” id=”branches-tab”>

        <div class=”tab-header”>

            <h2 class=”tab-title”>

                <i class=”fas fa-building”></i>

                Gestión de Sedes

            </h2>

            <button class=”btn btn-primary” onclick=”openBranchModal()”>

                <i class=”fas fa-plus”></i>

                Nueva Sede

            </button>

        </div>

        <div class=”tab-body”>

            <div class=”loading-state” id=”branches-loading”>

                <div class=”spinner”></div>

                <p>Cargando sedes…</p>

            </div>

            <div id=”branches-content” style=”display: none;”>

                <table class=”data-table” id=”branches-table”>

                    <thead>

                        <tr>

                            <th>Código</th>

                            <th>Nombre</th>

                            <th>Ciudad</th>

                            <th>País</th>

                            <th>Estado</th>

                            <th>Acciones</th>

                        </tr>

                    </thead>

                    <tbody id=”branches-tbody”>

                    </tbody>

                </table>

            </div>

        </div>

    </div>

    <!– Tab 2: Idiomas –>

    <div class=”tab-content” id=”languages-tab”>

        <div class=”tab-header”>

            <h2 class=”tab-title”>

                <i class=”fas fa-language”></i>

                Gestión de Idiomas

            </h2>

            <button class=”btn btn-primary” onclick=”openLanguageModal()”>

                <i class=”fas fa-plus”></i>

                Nuevo Idioma

            </button>

        </div>

        <div class=”tab-body”>

            <div class=”loading-state” id=”languages-loading”>

                <div class=”spinner”></div>

                <p>Cargando idiomas…</p>

            </div>

            <div id=”languages-content” style=”display: none;”>

                <table class=”data-table” id=”languages-table”>

                    <thead>

                        <tr>

                            <th>Código</th>

                            <th>Nombre</th>

                            <th>Estado</th>

                            <th>Acciones</th>

                        </tr>

                    </thead>

                    <tbody id=”languages-tbody”>

                    </tbody>

                </table>

            </div>

        </div>

    </div>

    <!– Tab 3: Programas –>

    <div class=”tab-content” id=”programs-tab”>

        <div class=”tab-header”>

            <h2 class=”tab-title”>

                <i class=”fas fa-graduation-cap”></i>

                Gestión de Programas

            </h2>

            <button class=”btn btn-primary” onclick=”openProgramModal()”>

                <i class=”fas fa-plus”></i>

                Nuevo Programa

            </button>

        </div>

        <div class=”tab-body”>

            <div class=”loading-state” id=”programs-loading”>

                <div class=”spinner”></div>

                <p>Cargando programas…</p>

            </div>

            <div id=”programs-content” style=”display: none;”>

                <table class=”data-table” id=”programs-table”>

                    <thead>

                        <tr>

                            <th>Idioma</th>

                            <th>Código</th>

                            <th>Nombre</th>

                            <th>Descripción</th>

                            <th>Estado</th>

                            <th>Acciones</th>

                        </tr>

                    </thead>

                    <tbody id=”programs-tbody”>

                    </tbody>

                </table>

            </div>

        </div>

    </div>

    <!– Tab 4: Niveles –>

    <div class=”tab-content” id=”levels-tab”>

        <div class=”tab-header”>

            <h2 class=”tab-title”>

                <i class=”fas fa-layer-group”></i>

                Gestión de Niveles

            </h2>

            <button class=”btn btn-primary” onclick=”openLevelModal()”>

                <i class=”fas fa-plus”></i>

                Nuevo Nivel

            </button>

        </div>

        <div class=”tab-body”>

            <div class=”loading-state” id=”levels-loading”>

                <div class=”spinner”></div>

                <p>Cargando niveles…</p>

            </div>

            <div id=”levels-content” style=”display: none;”>

                <table class=”data-table” id=”levels-table”>

                    <thead>

                        <tr>

                            <th>Idioma</th>

                            <th>Programa</th>

                            <th>Orden</th>

                            <th>Código</th>

                            <th>Nombre</th>

                            <th>Estado</th>

                            <th>Acciones</th>

                        </tr>

                    </thead>

                    <tbody id=”levels-tbody”>

                    </tbody>

                </table>

            </div>

        </div>

    </div>

</div>

<!– Modales para formularios –>

<!– Modal de Sede –>

<div class=”modal-overlay” id=”branch-modal”>

    <div class=”modal-content”>

        <div class=”modal-header”>

            <h3 class=”modal-title” id=”branch-modal-title”>Nueva Sede</h3>

            <button class=”btn-close” onclick=”closeBranchModal()”>&times;</button>

        </div>

        <form id=”branch-form”>

            <div class=”modal-body”>

                <div class=”form-grid”>

                    <div class=”form-group”>

                        <label class=”form-label required”>Nombre</label>

                        <input type=”text” name=”name” id=”branch-name” class=”form-control” required>

                    </div>

                    <div class=”form-group”>

                        <label class=”form-label required”>Código</label>

                        <input type=”text” name=”code” id=”branch-code” class=”form-control” required>

                        <div class=”form-help”>Código único, ej: MAIN, NORTH</div>

                    </div>

                </div>

                <div class=”form-grid”>

                    <div class=”form-group”>

                        <label class=”form-label”>Ciudad</label>

                        <input type=”text” name=”city” id=”branch-city” class=”form-control”>

                    </div>

                    <div class=”form-group”>

                        <label class=”form-label”>País</label>

                        <select name=”country” id=”branch-country” class=”form-control”>

                            <option value=””>Seleccionar país…</option>

                        </select>

                    </div>

                </div>

                <div class=”form-group”>

                    <label class=”form-label”>Dirección</label>

                    <textarea name=”address” id=”branch-address” class=”form-control” rows=”3″></textarea>

                </div>

                <div class=”form-grid”>

                    <div class=”form-group”>

                        <label class=”form-label”>Gerente</label>

                        <input type=”text” name=”manager_name” id=”branch-manager” class=”form-control”>

                    </div>

                    <div class=”form-group”>

                        <label class=”form-label”>Teléfono</label>

                        <input type=”text” name=”phone” id=”branch-phone” class=”form-control”>

                    </div>

                </div>

                <div class=”form-group”>

                    <label class=”form-label”>Email</label>

                    <input type=”email” name=”email” id=”branch-email” class=”form-control”>

                </div>

            </div>

            <div class=”modal-footer”>

                <button type=”button” class=”btn btn-secondary” onclick=”closeBranchModal()”>Cancelar</button>

                <button type=”submit” class=”btn btn-primary” id=”save-branch-btn”>

                    <i class=”fas fa-save”></i> Guardar Sede

                </button>

            </div>

            <input type=”hidden” name=”branch_id” id=”branch-id” value=”0″>

        </form>

    </div>

</div>

<!– Modal de Idioma –>

<div class=”modal-overlay” id=”language-modal”>

    <div class=”modal-content”>

        <div class=”modal-header”>

            <h3 class=”modal-title” id=”language-modal-title”>Nuevo Idioma</h3>

            <button class=”btn-close” onclick=”closeLanguageModal()”>&times;</button>

        </div>

        <form id=”language-form”>

            <div class=”modal-body”>

                <div class=”form-grid”>

                    <div class=”form-group”>

                        <label class=”form-label required”>Nombre</label>

                        <input type=”text” name=”name” id=”language-name” class=”form-control” required>

                        <div class=”form-help”>Ej: English, Spanish, French</div>

                    </div>

                    <div class=”form-group”>

                        <label class=”form-label required”>Código</label>

                        <input type=”text” name=”code” id=”language-code” class=”form-control” required maxlength=”3″>

                        <div class=”form-help”>Código de 2-3 letras, ej: EN, ES, FR</div>

                    </div>

                </div>

            </div>

            <div class=”modal-footer”>

                <button type=”button” class=”btn btn-secondary” onclick=”closeLanguageModal()”>Cancelar</button>

                <button type=”submit” class=”btn btn-primary” id=”save-language-btn”>

                    <i class=”fas fa-save”></i> Guardar Idioma

                </button>

            </div>

            <input type=”hidden” name=”language_id” id=”language-id” value=”0″>

        </form>

    </div>

</div>

<!– Modal de Programa –>

<div class=”modal-overlay” id=”program-modal”>

    <div class=”modal-content”>

        <div class=”modal-header”>

            <h3 class=”modal-title” id=”program-modal-title”>Nuevo Programa</h3>

            <button class=”btn-close” onclick=”closeProgramModal()”>&times;</button>

        </div>

        <form id=”program-form”>

            <div class=”modal-body”>

                <div class=”form-group”>

                    <label class=”form-label required”>Idioma</label>

                    <select name=”language_id” id=”program-language” class=”form-control” required>

                        <option value=””>Seleccionar idioma…</option>

                    </select>

                </div>

                <div class=”form-grid”>

                    <div class=”form-group”>

                        <label class=”form-label required”>Nombre</label>

                        <input type=”text” name=”name” id=”program-name” class=”form-control” required>

                        <div class=”form-help”>Ej: Kids Program, Professional</div>

                    </div>

                    <div class=”form-group”>

                        <label class=”form-label required”>Código</label>

                        <input type=”text” name=”code” id=”program-code” class=”form-control” required>

                        <div class=”form-help”>Ej: KIDS, PROF, BIZ</div>

                    </div>

                </div>

                <div class=”form-group”>

                    <label class=”form-label”>Descripción</label>

                    <textarea name=”description” id=”program-description” class=”form-control” rows=”3″></textarea>

                </div>

            </div>

            <div class=”modal-footer”>

                <button type=”button” class=”btn btn-secondary” onclick=”closeProgramModal()”>Cancelar</button>

                <button type=”submit” class=”btn btn-primary” id=”save-program-btn”>

                    <i class=”fas fa-save”></i> Guardar Programa

                </button>

            </div>

            <input type=”hidden” name=”program_id” id=”program-id” value=”0″>

        </form>

    </div>

</div>

<!– Modal de Nivel –>

<div class=”modal-overlay” id=”level-modal”>

    <div class=”modal-content”>

        <div class=”modal-header”>

            <h3 class=”modal-title” id=”level-modal-title”>Nuevo Nivel</h3>

            <button class=”btn-close” onclick=”closeLevelModal()”>&times;</button>

        </div>

        <form id=”level-form”>

            <div class=”modal-body”>

                <div class=”form-group”>

                    <label class=”form-label required”>Programa</label>

                    <select name=”program_id” id=”level-program” class=”form-control” required>

                        <option value=””>Seleccionar programa…</option>

                    </select>

                </div>

                <div class=”form-grid”>

                    <div class=”form-group”>

                        <label class=”form-label required”>Nombre</label>

                        <input type=”text” name=”name” id=”level-name” class=”form-control” required>

                        <div class=”form-help”>Ej: Beginner, A1, Intermediate</div>

                    </div>

                    <div class=”form-group”>

                        <label class=”form-label required”>Código</label>

                        <input type=”text” name=”code” id=”level-code” class=”form-control” required>

                        <div class=”form-help”>Ej: BEG, A1, INT</div>

                    </div>

                </div>

                <div class=”form-group”>

                    <label class=”form-label required”>Orden</label>

                    <input type=”number” name=”order_number” id=”level-order” class=”form-control” required min=”1″>

                    <div class=”form-help”>Número que define el orden del nivel</div>

                </div>

            </div>

            <div class=”modal-footer”>

                <button type=”button” class=”btn btn-secondary” onclick=”closeLevelModal()”>Cancelar</button>

                <button type=”submit” class=”btn btn-primary” id=”save-level-btn”>

                    <i class=”fas fa-save”></i> Guardar Nivel

                </button>

            </div>

            <input type=”hidden” name=”level_id” id=”level-id” value=”0″>

        </form>

    </div>

</div>

<!– JavaScript principal –>

<script src=”https://code.jquery.com/jquery-3.6.0.min.js”></script>

<script>

jQuery(document).ready(function($) {

    // Variables globales

    let currentTab = ‘branches’;

    let languages = [];

    let programs = [];

    let countries = [];

    // Inicializar

    initializeTabs();

    loadBranches();

    loadCountries();

    // ===================================

    // CARGAR PAÍSES

    // ===================================

    function loadCountries() {

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_get_countries’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’

        })

        .done(function(response) {

            if (response.success) {

                countries = response.data;

                updateCountryOptions();

            }

        });

    }

    function updateCountryOptions() {

        const select = $(‘#branch-country’);

        select.find(‘option:not(:first)’).remove();

        countries.forEach(country => {

            select.append(`<option value=”${country}”>${country}</option>`);

        });

    }

    // ===================================

    // MANEJO DE TABS

    // ===================================

    function initializeTabs() {

        $(‘.config-tab’).click(function() {

            const tab = $(this).data(‘tab’);

            switchTab(tab);

        });

    }

    function switchTab(tab) {

        currentTab = tab;

        // Actualizar tabs

        $(‘.config-tab’).removeClass(‘active’);

        $(`.config-tab[data-tab=”${tab}”]`).addClass(‘active’);

        // Actualizar contenido

        $(‘.tab-content’).removeClass(‘active’);

        $(`#${tab}-tab`).addClass(‘active’);

        // Cargar datos según el tab

        switch(tab) {

            case ‘branches’:

                loadBranches();

                break;

            case ‘languages’:

                loadLanguages();

                break;

            case ‘programs’:

                loadPrograms();

                break;

            case ‘levels’:

                loadLevels();

                break;

        }

    }

    // ===================================

    // SEDES

    // ===================================

    function loadBranches() {

        $(‘#branches-loading’).show();

        $(‘#branches-content’).hide();

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_get_branches’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’

        })

        .done(function(response) {

            if (response.success) {

                renderBranches(response.data);

                $(‘#branches-content’).show();

            } else {

                showNotification(‘Error al cargar sedes’, ‘error’);

            }

        })

        .always(function() {

            $(‘#branches-loading’).hide();

        });

    }

    function renderBranches(branches) {

        const tbody = $(‘#branches-tbody’);

        tbody.empty();

        branches.forEach(branch => {

            const statusClass = branch.status === ‘active’ ? ‘success’ : ‘warning’;

            const statusText = branch.status === ‘active’ ? ‘Activo’ : ‘Inactivo’;

            tbody.append(`

                <tr>

                    <td><strong>${branch.code}</strong></td>

                    <td>${branch.name}</td>

                    <td>${branch.city || ‘-‘}</td>

                    <td>${branch.country || ‘-‘}</td>

                    <td><span class=”btn btn-${statusClass} btn-sm”>${statusText}</span></td>

                    <td>

                        <button class=”btn btn-primary btn-sm” onclick=”editBranch(${branch.id})”>

                            <i class=”fas fa-edit”></i>

                        </button>

                        <button class=”btn btn-danger btn-sm” onclick=”deleteBranch(${branch.id})”>

                            <i class=”fas fa-trash”></i>

                        </button>

                        <button class=”btn btn-warning btn-sm” onclick=”manageBranchLanguages(${branch.id}, ‘${branch.name}’)”>

                            <i class=”fas fa-language”></i>

                        </button>

                    </td>

                </tr>

            `);

        });

    }

    window.openBranchModal = function(branchId = 0) {

        $(‘#branch-id’).val(branchId);

        // Asegurar que los países estén cargados

        if (countries.length === 0) {

            loadCountries();

        }

        if (branchId > 0) {

            $(‘#branch-modal-title’).text(‘Editar Sede’);

            // Cargar datos de la sede

            loadBranchData(branchId);

        } else {

            $(‘#branch-modal-title’).text(‘Nueva Sede’);

            $(‘#branch-form’)[0].reset();

            $(‘#branch-id’).val(‘0’);

        }

        $(‘#branch-modal’).addClass(‘show’);

    };

    window.closeBranchModal = function() {

        $(‘#branch-modal’).removeClass(‘show’);

    };

    window.editBranch = function(branchId) {

        openBranchModal(branchId);

    };

    window.deleteBranch = function(branchId) {

        if (!confirm(‘¿Estás seguro de eliminar esta sede?’)) return;

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_delete_branch’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’,

            branch_id: branchId

        })

        .done(function(response) {

            if (response.success) {

                showNotification(response.data, ‘success’);

                loadBranches();

            } else {

                showNotification(response.data, ‘error’);

            }

        });

    };

    function loadBranchData(branchId) {

        // Buscar en los datos ya cargados

        const branches = $(‘#branches-tbody tr’);

        // Por simplicidad, solo limpiar el formulario por ahora

        // En implementación real cargaríamos datos específicos

        $(‘#branch-form’)[0].reset();

        $(‘#branch-id’).val(branchId);

    }

    $(‘#branch-form’).submit(function(e) {

        e.preventDefault();

        const formData = {

            action: ‘wes_save_branch’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’,

            branch_id: $(‘#branch-id’).val(),

            name: $(‘#branch-name’).val(),

            code: $(‘#branch-code’).val(),

            address: $(‘#branch-address’).val(),

            city: $(‘#branch-city’).val(),

            country: $(‘#branch-country’).val(),

            manager_name: $(‘#branch-manager’).val(),

            phone: $(‘#branch-phone’).val(),

            email: $(‘#branch-email’).val(),

            status: ‘active’

        };

        const $btn = $(‘#save-branch-btn’);

        const originalText = $btn.html();

        $btn.html(‘<i class=”fas fa-spinner fa-spin”></i> Guardando…’).prop(‘disabled’, true);

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, formData)

        .done(function(response) {

            if (response.success) {

                showNotification(response.data, ‘success’);

                closeBranchModal();

                loadBranches();

            } else {

                showNotification(response.data, ‘error’);

            }

        })

        .always(function() {

            $btn.html(originalText).prop(‘disabled’, false);

        });

    });

    // ===================================

    // IDIOMAS

    // ===================================

    function loadLanguages() {

        $(‘#languages-loading’).show();

        $(‘#languages-content’).hide();

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_get_languages’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’

        })

        .done(function(response) {

            if (response.success) {

                languages = response.data;

                renderLanguages(response.data);

                $(‘#languages-content’).show();

                updateProgramLanguageOptions();

            } else {

                showNotification(‘Error al cargar idiomas’, ‘error’);

            }

        })

        .always(function() {

            $(‘#languages-loading’).hide();

        });

    }

    function renderLanguages(languages) {

        const tbody = $(‘#languages-tbody’);

        tbody.empty();

        languages.forEach(language => {

            const statusClass = language.status === ‘active’ ? ‘success’ : ‘warning’;

            const statusText = language.status === ‘active’ ? ‘Activo’ : ‘Inactivo’;

            tbody.append(`

                <tr>

                    <td><strong>${language.code}</strong></td>

                    <td>${language.name}</td>

                    <td><span class=”btn btn-${statusClass} btn-sm”>${statusText}</span></td>

                    <td>

                        <button class=”btn btn-primary btn-sm” onclick=”editLanguage(${language.id})”>

                            <i class=”fas fa-edit”></i>

                        </button>

                        <button class=”btn btn-danger btn-sm” onclick=”deleteLanguage(${language.id})”>

                            <i class=”fas fa-trash”></i>

                        </button>

                    </td>

                </tr>

            `);

        });

    }

    function updateProgramLanguageOptions() {

        const select = $(‘#program-language’);

        select.find(‘option:not(:first)’).remove();

        languages.forEach(language => {

            if (language.status === ‘active’) {

                select.append(`<option value=”${language.id}”>${language.name}</option>`);

            }

        });

    }

    window.openLanguageModal = function(languageId = 0) {

        $(‘#language-id’).val(languageId);

        if (languageId > 0) {

            $(‘#language-modal-title’).text(‘Editar Idioma’);

            loadLanguageData(languageId);

        } else {

            $(‘#language-modal-title’).text(‘Nuevo Idioma’);

            $(‘#language-form’)[0].reset();

            $(‘#language-id’).val(‘0’);

        }

        $(‘#language-modal’).addClass(‘show’);

    };

    window.closeLanguageModal = function() {

        $(‘#language-modal’).removeClass(‘show’);

    };

    window.editLanguage = function(languageId) {

        openLanguageModal(languageId);

    };

    window.deleteLanguage = function(languageId) {

        if (!confirm(‘¿Estás seguro de eliminar este idioma?’)) return;

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_delete_language’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’,

            language_id: languageId

        })

        .done(function(response) {

            if (response.success) {

                showNotification(response.data, ‘success’);

                loadLanguages();

            } else {

                showNotification(response.data, ‘error’);

            }

        });

    };

    function loadLanguageData(languageId) {

        const language = languages.find(l => l.id == languageId);

        if (language) {

            $(‘#language-name’).val(language.name);

            $(‘#language-code’).val(language.code);

        }

    }

    $(‘#language-form’).submit(function(e) {

        e.preventDefault();

        const formData = {

            action: ‘wes_save_language’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’,

            language_id: $(‘#language-id’).val(),

            name: $(‘#language-name’).val(),

            code: $(‘#language-code’).val().toUpperCase(),

            status: ‘active’

        };

        const $btn = $(‘#save-language-btn’);

        const originalText = $btn.html();

        $btn.html(‘<i class=”fas fa-spinner fa-spin”></i> Guardando…’).prop(‘disabled’, true);

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, formData)

        .done(function(response) {

            if (response.success) {

                showNotification(response.data, ‘success’);

                closeLanguageModal();

                loadLanguages();

            } else {

                showNotification(response.data, ‘error’);

            }

        })

        .always(function() {

            $btn.html(originalText).prop(‘disabled’, false);

        });

    });

    // ===================================

    // PROGRAMAS

    // ===================================

    function loadPrograms() {

        $(‘#programs-loading’).show();

        $(‘#programs-content’).hide();

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_get_programs’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’

        })

        .done(function(response) {

            if (response.success) {

                programs = response.data;

                renderPrograms(response.data);

                $(‘#programs-content’).show();

                updateLevelProgramOptions();

            } else {

                showNotification(‘Error al cargar programas’, ‘error’);

            }

        })

        .always(function() {

            $(‘#programs-loading’).hide();

        });

    }

    function renderPrograms(programs) {

        const tbody = $(‘#programs-tbody’);

        tbody.empty();

        programs.forEach(program => {

            const statusClass = program.status === ‘active’ ? ‘success’ : ‘warning’;

            const statusText = program.status === ‘active’ ? ‘Activo’ : ‘Inactivo’;

            tbody.append(`

                <tr>

                    <td>${program.language_name}</td>

                    <td><strong>${program.code}</strong></td>

                    <td>${program.name}</td>

                    <td>${program.description || ‘-‘}</td>

                    <td><span class=”btn btn-${statusClass} btn-sm”>${statusText}</span></td>

                    <td>

                        <button class=”btn btn-primary btn-sm” onclick=”editProgram(${program.id})”>

                            <i class=”fas fa-edit”></i>

                        </button>

                        <button class=”btn btn-danger btn-sm” onclick=”deleteProgram(${program.id})”>

                            <i class=”fas fa-trash”></i>

                        </button>

                    </td>

                </tr>

            `);

        });

    }

    function updateLevelProgramOptions() {

        const select = $(‘#level-program’);

        select.find(‘option:not(:first)’).remove();

        programs.forEach(program => {

            if (program.status === ‘active’) {

                select.append(`<option value=”${program.id}”>${program.language_name} – ${program.name}</option>`);

            }

        });

    }

    window.openProgramModal = function(programId = 0) {

        $(‘#program-id’).val(programId);

        if (programId > 0) {

            $(‘#program-modal-title’).text(‘Editar Programa’);

            loadProgramData(programId);

        } else {

            $(‘#program-modal-title’).text(‘Nuevo Programa’);

            $(‘#program-form’)[0].reset();

            $(‘#program-id’).val(‘0’);

        }

        $(‘#program-modal’).addClass(‘show’);

    };

    window.closeProgramModal = function() {

        $(‘#program-modal’).removeClass(‘show’);

    };

    window.editProgram = function(programId) {

        openProgramModal(programId);

    };

    window.deleteProgram = function(programId) {

        if (!confirm(‘¿Estás seguro de eliminar este programa?’)) return;

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_delete_program’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’,

            program_id: programId

        })

        .done(function(response) {

            if (response.success) {

                showNotification(response.data, ‘success’);

                loadPrograms();

            } else {

                showNotification(response.data, ‘error’);

            }

        });

    };

    function loadProgramData(programId) {

        const program = programs.find(p => p.id == programId);

        if (program) {

            $(‘#program-language’).val(program.language_id);

            $(‘#program-name’).val(program.name);

            $(‘#program-code’).val(program.code);

            $(‘#program-description’).val(program.description);

        }

    }

    $(‘#program-form’).submit(function(e) {

        e.preventDefault();

        const formData = {

            action: ‘wes_save_program’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’,

            program_id: $(‘#program-id’).val(),

            language_id: $(‘#program-language’).val(),

            name: $(‘#program-name’).val(),

            code: $(‘#program-code’).val().toUpperCase(),

            description: $(‘#program-description’).val(),

            status: ‘active’

        };

        const $btn = $(‘#save-program-btn’);

        const originalText = $btn.html();

        $btn.html(‘<i class=”fas fa-spinner fa-spin”></i> Guardando…’).prop(‘disabled’, true);

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, formData)

        .done(function(response) {

            if (response.success) {

                showNotification(response.data, ‘success’);

                closeProgramModal();

                loadPrograms();

            } else {

                showNotification(response.data, ‘error’);

            }

        })

        .always(function() {

            $btn.html(originalText).prop(‘disabled’, false);

        });

    });

    // ===================================

    // NIVELES

    // ===================================

    function loadLevels() {

        $(‘#levels-loading’).show();

        $(‘#levels-content’).hide();

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_get_levels’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’

        })

        .done(function(response) {

            if (response.success) {

                renderLevels(response.data);

                $(‘#levels-content’).show();

            } else {

                showNotification(‘Error al cargar niveles’, ‘error’);

            }

        })

        .always(function() {

            $(‘#levels-loading’).hide();

        });

    }

    function renderLevels(levels) {

        const tbody = $(‘#levels-tbody’);

        tbody.empty();

        levels.forEach(level => {

            const statusClass = level.status === ‘active’ ? ‘success’ : ‘warning’;

            const statusText = level.status === ‘active’ ? ‘Activo’ : ‘Inactivo’;

            tbody.append(`

                <tr>

                    <td>${level.language_name}</td>

                    <td>${level.program_name}</td>

                    <td><strong>${level.order_number}</strong></td>

                    <td><strong>${level.code}</strong></td>

                    <td>${level.name}</td>

                    <td><span class=”btn btn-${statusClass} btn-sm”>${statusText}</span></td>

                    <td>

                        <button class=”btn btn-primary btn-sm” onclick=”editLevel(${level.id})”>

                            <i class=”fas fa-edit”></i>

                        </button>

                        <button class=”btn btn-danger btn-sm” onclick=”deleteLevel(${level.id})”>

                            <i class=”fas fa-trash”></i>

                        </button>

                    </td>

                </tr>

            `);

        });

    }

    window.openLevelModal = function(levelId = 0) {

        $(‘#level-id’).val(levelId);

        if (levelId > 0) {

            $(‘#level-modal-title’).text(‘Editar Nivel’);

            loadLevelData(levelId);

        } else {

            $(‘#level-modal-title’).text(‘Nuevo Nivel’);

            $(‘#level-form’)[0].reset();

            $(‘#level-id’).val(‘0’);

        }

        $(‘#level-modal’).addClass(‘show’);

    };

    window.closeLevelModal = function() {

        $(‘#level-modal’).removeClass(‘show’);

    };

    window.editLevel = function(levelId) {

        openLevelModal(levelId);

    };

    window.deleteLevel = function(levelId) {

        if (!confirm(‘¿Estás seguro de eliminar este nivel?’)) return;

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, {

            action: ‘wes_delete_level’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’,

            level_id: levelId

        })

        .done(function(response) {

            if (response.success) {

                showNotification(response.data, ‘success’);

                loadLevels();

            } else {

                showNotification(response.data, ‘error’);

            }

        });

    };

    function loadLevelData(levelId) {

        // Por simplicidad, solo resetear el formulario

        // En implementación real cargaríamos datos específicos

        $(‘#level-form’)[0].reset();

        $(‘#level-id’).val(levelId);

    }

    $(‘#level-form’).submit(function(e) {

        e.preventDefault();

        const formData = {

            action: ‘wes_save_level’,

            nonce: ‘<?php echo wp_create_nonce(‘wes_nonce’); ?>’,

            level_id: $(‘#level-id’).val(),

            program_id: $(‘#level-program’).val(),

            name: $(‘#level-name’).val(),

            code: $(‘#level-code’).val().toUpperCase(),

            order_number: $(‘#level-order’).val(),

            status: ‘active’

        };

        const $btn = $(‘#save-level-btn’);

        const originalText = $btn.html();

        $btn.html(‘<i class=”fas fa-spinner fa-spin”></i> Guardando…’).prop(‘disabled’, true);

        $.post(‘<?php echo admin_url(‘admin-ajax.php’); ?>’, formData)

        .done(function(response) {

            if (response.success) {

                showNotification(response.data, ‘success’);

                closeLevelModal();

                loadLevels();

            } else {

                showNotification(response.data, ‘error’);

            }

        })

        .always(function() {

            $btn.html(originalText).prop(‘disabled’, false);

        });

    });

    // ===================================

    // UTILIDADES

    // ===================================

    function showNotification(message, type = ‘info’) {

        // Crear notificación temporal

        const alertClass = type === ‘success’ ? ‘success’ : type === ‘error’ ? ‘danger’ : ‘info’;

        const notification = $(`

            <div class=”alert alert-${alertClass}” style=”

                position: fixed;

                top: 20px;

                right: 20px;

                z-index: 1000000;

                min-width: 300px;

                box-shadow: 0 4px 12px rgba(0,0,0,0.15);

            “>

                <strong>${message}</strong>

                <button type=”button” class=”btn-close” style=”float: right; background: none; border: none; font-size: 20px; line-height: 1; opacity: 0.5; cursor: pointer;”>&times;</button>

            </div>

        `);

        $(‘body’).append(notification);

        // Auto remove

        setTimeout(function() {

            notification.fadeOut(function() {

                $(this).remove();

            });

        }, 5000);

        // Manual close

        notification.find(‘.btn-close’).click(function() {

            notification.fadeOut(function() {

                $(this).remove();

            });

        });

    }

    // Cerrar modales con ESC

    $(document).keydown(function(e) {

        if (e.keyCode === 27) { // ESC

            $(‘.modal-overlay’).removeClass(‘show’);

        }

    });

    // Cerrar modales al hacer clic fuera

    $(‘.modal-overlay’).click(function(e) {

        if (e.target === this) {

            $(this).removeClass(‘show’);

        }

    });

});

</script>

<?php wp_footer(); ?>

</body>

</html>