Tul xxx Tul
User / IP
:
216.73.216.217
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
eventos
/
admin
/
pages
/
Viewing: settings.php
<?php $db = getDB(); // Obtener todos los settings agrupados $settings = []; $rows = $db->query('SELECT * FROM site_settings ORDER BY setting_group, id')->fetchAll(); foreach ($rows as $r) { $settings[$r['setting_key']] = $r['setting_value']; } ?> <!-- Predefined Themes Gallery --> <style> .theme-category { margin-top: 2rem; } .theme-category-title { font-size: 0.8rem; font-weight: bold; color: var(--admin-purple); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 1rem; display: flex; align-items: center; gap: 0.5rem; } .theme-category-title::after { content: ""; flex: 1; height: 1px; background: linear-gradient(to right, rgba(187, 134, 252, 0.2), transparent); } .theme-card { background: var(--admin-surface); border: 1px solid var(--admin-border); border-radius: 12px; padding: 1rem 0.8rem; cursor: pointer; transition: 0.3s; position: relative; text-align: center; } .theme-card:hover { border-color: var(--admin-purple) !important; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.05); } .theme-card.active { border-color: var(--admin-purple) !important; border-width: 2px !important; background: rgba(187, 134, 252, 0.05) !important; } .theme-preview-dots { display: flex; gap: 3px; margin-bottom: 0.8rem; height: 10px; } .theme-preview-dot { flex: 1; border-radius: 2px; border: 1px solid rgba(0,0,0,0.1); } </style> <div class="admin-card" style="margin-bottom:2rem; border:2px solid var(--admin-purple); position:relative; overflow:hidden;"> <div style="position:absolute; top:0; right:0; background:var(--admin-purple); color:#fff; padding:4px 12px; font-size:0.7rem; border-bottom-left-radius:8px; font-weight:bold; z-index:10;">SUITE DE DISEÑO</div> <div class="card-header" style="background:rgba(187, 134, 252, 0.05);"> <div class="card-title"><i class="ph-fill ph-palette"></i> Biblioteca de Temas por Evento</div> </div> <div class="card-body" style="padding:1.5rem;"> <p style="font-size:0.85rem; color:var(--admin-text-muted); margin-bottom:0.5rem;">Transforma instantáneamente tu invitación según el tipo de evento que estés organizando.</p> <!-- Tema Guardado / Actual --> <div class="form-group" style="margin-bottom:2rem;"> <div class="theme-category-title">Mi Configuración</div> <div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap:1rem;"> <div class="theme-card <?= ($settings['site_theme'] ?? '') === 'custom_saved' ? 'active' : '' ?>" onclick="applyTheme('custom_saved')" id="theme_card_custom_saved"> <div style="width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg, var(--admin-purple), var(--admin-gold));margin-bottom:0.5rem;box-shadow:0 4px 10px rgba(0,0,0,0.1);"></div> <div style="font-weight:bold; font-size:0.75rem; color:var(--admin-text);">Tema Guardado</div> <div style="font-size:0.6rem; color:var(--admin-text-muted);">Tu diseño inicial</div> </div> <div class="theme-card <?= ($settings['site_theme'] ?? '') === 'custom' ? 'active' : '' ?>" onclick="activateCustomTheme()" id="theme_card_custom"> <div style="width:40px;height:40px;border-radius:50%;background:var(--admin-surface);border:2px dashed var(--admin-border);margin-bottom:0.5rem;display:grid;place-items:center;"> <i class="ph-bold ph-palette" style="color:var(--admin-purple);"></i> </div> <div style="font-weight:bold; font-size:0.75rem; color:var(--admin-text);">Diseño Manual</div> <div style="font-size:0.6rem; color:var(--admin-text-muted);">Tus ajustes actuales</div> </div> </div> </div> <?php $categories = [ 'Sociales' => [ ['id' => 'wedding', 'name' => 'Boda Real', 'desc' => 'Elegancia Eterna', 'preview' => ['#ffffff','#c5a880','#c5a880','#8b6b8e']], ['id' => 'xv', 'name' => 'Quince Años', 'desc' => 'Mágica Noche', 'preview' => ['#4c0519','#fb7185','#fb7185','#fda4af']], ['id' => 'birthday', 'name' => 'Cumpleaños', 'desc' => 'Celebración Colorida', 'preview' => ['#ecfeff','#06b6d4','#06b6d4','#22d3ee']], ['id' => 'babyshower', 'name' => 'Baby Shower', 'desc' => 'Ternura Pastel', 'preview' => ['#fdf2f8','#f472b6','#fbcfe8','#f472b6']], ['id' => 'anniversary', 'name' => 'Aniversario', 'desc' => 'Pasión Rosa', 'preview' => ['#111827','#be123c','#be123c','#e11d48']], ['id' => 'party', 'name' => 'Fiesta', 'desc' => 'Noche de Luces', 'preview' => ['#1e1b4b','#a855f7','#a855f7','#7c3aed']], ], 'Empresariales & Pro' => [ ['id' => 'conference', 'name' => 'Conferencia', 'desc' => 'Visión Corporativa', 'preview' => ['#f8fafc','#1e293b','#334155','#475569']], ['id' => 'seminar', 'name' => 'Seminario', 'desc' => 'Enfoque Académico', 'preview' => ['#ffffff','#0369a1','#0ea5e9','#0284c7']], ['id' => 'networking', 'name' => 'Networking', 'desc' => 'Conexión Pro', 'preview' => ['#111827','#2dd4bf','#2dd4bf','#0d9488']], ['id' => 'launch', 'name' => 'Lanzamiento', 'desc' => 'Impacto Tech', 'preview' => ['#020617','#10b981','#10b981','#059669']], ['id' => 'fair', 'name' => 'Feria Empresarial', 'desc' => 'Innovación', 'preview' => ['#ecfdf5','#059669','#059669','#10b981']], ['id' => 'vip', 'name' => 'Evento VIP', 'desc' => 'Exclusividad', 'preview' => ['#0a0a0a','#c5a880','#c5a880','#1a1a1a']], ['id' => 'inauguration', 'name' => 'Inauguración', 'desc' => 'Corte de Cinta', 'preview' => ['#ffffff','#dc2626','#dc2626','#991b1b']], ['id' => 'commercial', 'name' => 'Comercial', 'desc' => 'Flash Sale', 'preview' => ['#fef2f2','#ef4444','#ef4444','#b91c1c']], ], 'Cultura & Show' => [ ['id' => 'concert', 'name' => 'Concierto', 'desc' => 'Rock & Glow', 'preview' => ['#020617','#facc15','#facc15','#ca8a04']], ['id' => 'cultural', 'name' => 'Evento Cultural', 'desc' => 'Herencia Artística', 'preview' => ['#fefae0','#bc6c25','#dda15e','#606c38']], ['id' => 'festival', 'name' => 'Festival', 'desc' => 'Vibras de Verano', 'preview' => ['#fff7ed','#fb923c','#fb923c','#ea580c']], ], 'Educación' => [ ['id' => 'graduation', 'name' => 'Graduación', 'desc' => 'Logro Maestro', 'preview' => ['#000000','#fbbf24','#fbbf24','#000000']], ['id' => 'talk', 'name' => 'Charla Educativa', 'desc' => 'Mente Abierta', 'preview' => ['#eff6ff','#2563eb','#60a5fa','#1d4ed8']], ['id' => 'workshop', 'name' => 'Curso/Taller', 'desc' => 'Creación Activa', 'preview' => ['#f5f3ff','#7c3ad6','#a78bfa','#6d28d9']], ], 'Deportes' => [ ['id' => 'tournament', 'name' => 'Torneo', 'desc' => 'Gloria Deportiva', 'preview' => ['#fef2f2','#1d4ed8','#dc2626','#1e40af']], ['id' => 'competition', 'name' => 'Competición', 'desc' => 'Máximo Desempeño', 'preview' => ['#18181b','#facc15','#facc15','#27272a']], ] ]; foreach ($categories as $catName => $themes): ?> <div class="theme-category"> <div class="theme-category-title"><?= $catName ?></div> <div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap:1rem;"> <?php foreach ($themes as $th): ?> <div class="theme-card <?= ($settings['site_theme'] ?? '') === $th['id'] ? 'active' : '' ?>" onclick="applyTheme('<?= $th['id'] ?>')" id="theme_card_<?= $th['id'] ?>"> <div class="theme-preview-dots"> <?php foreach($th['preview'] as $c): ?> <div class="theme-preview-dot" style="background:<?= $c ?>;"></div> <?php endforeach; ?> </div> <div style="font-weight:bold; font-size:0.75rem; color:var(--admin-text);"><?= $th['name'] ?></div> <div style="font-size:0.6rem; color:var(--admin-text-muted);"><?= $th['desc'] ?></div> </div> <?php endforeach; ?> </div> </div> <?php endforeach; ?> </div> </div> <form id="settingsForm" onsubmit="saveSettings(event)"> <input type="hidden" name="site_theme" id="site_theme_input" value="<?= htmlspecialchars($settings['site_theme'] ?? '') ?>"> <div class="admin-card"> <div class="card-header"> <div class="card-title"><i class="ph-fill ph-gear-six"></i> Configuración General</div> </div> <div class="form-row"> <div class="form-group"> <label class="form-label">Título del Sitio</label> <input type="text" name="site_title" class="form-control" value="<?= htmlspecialchars($settings['site_title'] ?? '') ?>"> </div> <div class="form-group"> <label class="form-label">Monogram (Navbar)</label> <input type="text" name="monogram" class="form-control" value="<?= htmlspecialchars($settings['monogram'] ?? '') ?>"> </div> </div> <div class="form-row"> <div class="form-group"> <label class="form-label">Número de WhatsApp</label> <input type="text" name="whatsapp_number" class="form-control" value="<?= htmlspecialchars($settings['whatsapp_number'] ?? '') ?>" placeholder="573001234567"> </div> </div> <div class="form-row"> <div class="form-group"> <label class="form-label">Footer - Texto</label> <input type="text" name="footer_text" class="form-control" value="<?= htmlspecialchars($settings['footer_text'] ?? '') ?>" placeholder="Ej: Celebrando en la granja"> </div> <div class="form-group"> <label class="form-label">Footer - Marca</label> <input type="text" name="footer_brand" class="form-control" value="<?= htmlspecialchars($settings['footer_brand'] ?? '') ?>"> </div> </div> <div class="form-group"> <label class="form-label">Footer - URL</label> <input type="url" name="footer_link" class="form-control" value="<?= htmlspecialchars($settings['footer_link'] ?? '') ?>"> </div> <!-- Background Music --> <div class="form-group" style="margin-top:1.5rem; padding-top:1.5rem; border-top:1px solid var(--admin-border);"> <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:1rem;"> <label class="form-label" style="margin-bottom:0;"><i class="ph-fill ph-music-notes"></i> Música de Fondo (MP3)</label> <div class="switch"> <input type="hidden" name="music_enabled" value="0"> <input type="checkbox" name="music_enabled" id="music_enabled" value="1" <?= ($settings['music_enabled'] ?? '1') === '1' ? 'checked' : '' ?> onchange="saveSettings(event)"> <label class="slider" for="music_enabled"></label> </div> </div> <div style="display:flex; gap:1.5rem; align-items:center; flex-wrap:wrap;"> <div style="flex:1; min-width:280px;"> <div class="upload-zone" onclick="document.getElementById('musicFileInput').click()" style="padding:1.5rem; border-style:dashed;"> <i class="ph-fill ph-music-note" style="font-size:1.5rem; color:var(--admin-purple);"></i> <p style="font-size:0.85rem; margin-top:0.5rem;">Haz clic para cambiar la canción</p> </div> <input type="file" id="musicFileInput" name="music_file" style="display:none;" accept="audio/mpeg,audio/ogg,audio/wav" onchange="previewMusic(this)"> </div> <div style="flex:1; min-width:280px; background:var(--admin-surface); padding:1rem; border-radius:12px; border:1px solid var(--admin-border);"> <p style="font-size:0.75rem; color:var(--admin-text-muted); margin-bottom:0.5rem;">Vista previa actual:</p> <audio id="musicPreview" controls style="width:100%; height:32px;"> <source src="../<?= htmlspecialchars($settings['music_file'] ?? 'public/assets/images/musica.mp3') ?>" type="audio/mpeg"> </audio> </div> </div> </div> <!-- Special Effects --> <div class="form-group" style="margin-top:2rem; padding-top:2rem; border-top:1px solid var(--admin-border);"> <label class="form-label"><i class="ph-fill ph-sparkles"></i> Efectos Especiales (Animación de fondo)</label> <div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap:1rem; margin-top:1rem;"> <?php $effects = [ ['id' => 'flowers', 'name' => 'Flores', 'icon' => 'ph-flower'], ['id' => 'hearts', 'name' => 'Corazones', 'icon' => 'ph-heart'], ['id' => 'stars', 'name' => 'Estrellas', 'icon' => 'ph-star'], ['id' => 'snow', 'name' => 'Nieve', 'icon' => 'ph-snowflake'], ['id' => 'confetti', 'name' => 'Confetti', 'icon' => 'ph-confetti'], ['id' => 'leaves', 'name' => 'Hojas', 'icon' => 'ph-leaf'], ['id' => 'bubbles', 'name' => 'Burbujas', 'icon' => 'ph-drop'], ['id' => 'none', 'name' => 'Ninguno', 'icon' => 'ph-prohibit'], ]; foreach ($effects as $ef): ?> <label class="radio-card <?= ($settings['special_effects_type'] ?? 'flowers') === $ef['id'] ? 'active' : '' ?>" style="padding:1rem 0.5rem; text-align:center;"> <input type="radio" name="special_effects_type" value="<?= $ef['id'] ?>" <?= ($settings['special_effects_type'] ?? 'flowers') === $ef['id'] ? 'checked' : '' ?> onchange="updateEffectActive(this); saveSettings()"> <i class="<?= $ef['icon'] ?>-fill" style="font-size:1.4rem; margin-bottom:0.4rem;"></i> <span style="font-size:0.8rem;"><?= $ef['name'] ?></span> </label> <?php endforeach; ?> </div> </div> </div> <!-- Overlay / Intro --> <div class="admin-card"> <div class="card-header"> <div class="card-title"><i class="ph-fill ph-envelope-simple"></i> Overlay de Bienvenida</div> </div> <div class="form-row"> <div class="form-group"> <label class="form-label">Título del Overlay</label> <input type="text" name="overlay_title" class="form-control" value="<?= htmlspecialchars($settings['overlay_title'] ?? '') ?>"> </div> <div class="form-group"> <label class="form-label">Subtítulo del Overlay</label> <input type="text" name="overlay_subtitle" class="form-control" value="<?= htmlspecialchars($settings['overlay_subtitle'] ?? '') ?>"> </div> </div> <div class="form-group"> <label class="form-label">Instrucción</label> <input type="text" name="overlay_instruction" class="form-control" value="<?= htmlspecialchars($settings['overlay_instruction'] ?? '') ?>"> </div> <div class="form-row"> <div class="form-group"> <label class="form-label">Texto Pre-Carta</label> <input type="text" name="overlay_letter_pre" class="form-control" value="<?= htmlspecialchars($settings['overlay_letter_pre'] ?? '') ?>"> </div> <div class="form-group"> <label class="form-label">Título de la Carta</label> <input type="text" name="overlay_letter_title" class="form-control" value="<?= htmlspecialchars($settings['overlay_letter_title'] ?? '') ?>"> </div> <div class="form-group"> <label class="form-label">Texto Post-Carta</label> <input type="text" name="overlay_letter_post" class="form-control" value="<?= htmlspecialchars($settings['overlay_letter_post'] ?? '') ?>"> </div> </div> <div class="form-group" style="margin-top:1rem; border-top:1px solid var(--admin-border); padding-top:1.5rem;"> <label class="form-label">Imagen Decorativa (Overlay & RSVP)</label> <div style="display:flex; gap:1.5rem; align-items:center; flex-wrap:wrap;"> <div style="width:120px; height:120px; border-radius:12px; background:var(--admin-surface); border:1px solid var(--admin-border); display:grid; place-items:center; overflow:hidden;"> <img id="overlayImgPreview" src="../<?= htmlspecialchars($settings['overlay_flowers_image'] ?? 'public/assets/images/flores.png') ?>" style="width:100%; height:100%; object-fit:contain;"> </div> <div style="flex:1; min-width:200px;"> <input type="file" name="overlay_flowers_image" class="form-control" accept="image/*" onchange="previewOverlayImg(this)"> <p style="font-size:0.75rem; color:var(--admin-text-muted); margin-top:0.5rem;"> <i class="ph-bold ph-info"></i> Esta imagen aparece al final del mensaje de bienvenida y en el encabezado del modal de confirmación. </p> </div> </div> </div> </div> <!-- Tipografías --> <div class="admin-card"> <div class="card-header"> <div class="card-title"><i class="ph-fill ph-text-aa"></i> Tipografías del Sitio</div> </div> <input type="hidden" name="site_font_primary" id="font_primary_input" value="<?= htmlspecialchars($settings['site_font_primary'] ?? 'Playfair Display') ?>"> <input type="hidden" name="site_font_secondary" id="font_secondary_input" value="<?= htmlspecialchars($settings['site_font_secondary'] ?? 'Quicksand') ?>"> <p style="font-size:0.85rem; color:var(--admin-text-muted); margin-bottom:1.5rem;">Personaliza la personalidad de tu invitación eligiendo las fuentes para títulos y cuerpo de texto.</p> <?php $fonts = [ 'Elegantes (Serif)' => ['Playfair Display', 'Cinzel', 'Cormorant Garamond', 'Lora', 'Prata'], 'Modernas (Sans)' => ['Montserrat', 'Quicksand', 'Raleway', 'Outfit', 'Poppins', 'Inter'], 'Handwriting (Script)' => ['Dancing Script', 'Great Vibes', 'Alex Brush', 'Parisienne', 'Pinyon Script', 'Cookie'], 'Divertidas (Display)' => ['Chewy', 'Balsamiq Sans', 'Bubblegum Sans', 'Fredericka the Great'] ]; ?> <!-- Fuente Primaria (Títulos) --> <div style="margin-bottom:2.5rem;"> <div style="font-weight:bold; font-size:0.9rem; margin-bottom:1rem; color:var(--admin-purple);">Fuente Primaria (Nombres y Títulos)</div> <div style="display:flex; flex-direction:column; gap:1.5rem;"> <?php foreach ($fonts as $cat => $fList): ?> <div> <div style="font-size:0.7rem; text-transform:uppercase; letter-spacing:1px; color:var(--admin-text-muted); margin-bottom:0.5rem;"><?= $cat ?></div> <div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap:0.8rem;"> <?php foreach ($fList as $f): ?> <div class="font-card <?= ($settings['site_font_primary'] ?? 'Playfair Display') === $f ? 'active' : '' ?>" onclick="selectFont('primary', '<?= $f ?>')" style="font-family: '<?= $f ?>';" id="font_primary_<?= str_replace(' ', '_', $f) ?>"> <div style="font-size:1.1rem;"><?= $f ?></div> <div style="font-size:0.6rem; opacity:0.6; margin-top:0.2rem;">ABC abc 123</div> </div> <?php endforeach; ?> </div> </div> <?php endforeach; ?> </div> </div> <!-- Fuente Secundaria (Cuerpo) --> <div> <div style="font-weight:bold; font-size:0.9rem; margin-bottom:1rem; color:var(--admin-purple);">Fuente Secundaria (Textos y Detalles)</div> <div style="display:flex; flex-direction:column; gap:1.5rem;"> <?php foreach ($fonts as $cat => $fList): ?> <div> <div style="font-size:0.7rem; text-transform:uppercase; letter-spacing:1px; color:var(--admin-text-muted); margin-bottom:0.5rem;"><?= $cat ?></div> <div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap:0.8rem;"> <?php foreach ($fList as $f): ?> <div class="font-card <?= ($settings['site_font_secondary'] ?? 'Quicksand') === $f ? 'active' : '' ?>" onclick="selectFont('secondary', '<?= $f ?>')" style="font-family: '<?= $f ?>';" id="font_secondary_<?= str_replace(' ', '_', $f) ?>"> <div style="font-size:1.1rem;"><?= $f ?></div> <div style="font-size:0.6rem; opacity:0.6; margin-top:0.2rem;">ABC abc 123</div> </div> <?php endforeach; ?> </div> </div> <?php endforeach; ?> </div> </div> </div> <!-- Compartir Invitación --> <div class="admin-card"> <div class="card-header"> <div class="card-title"><i class="ph-fill ph-share-network"></i> Configuración de Difusión</div> </div> <p style="font-size:0.85rem; color:var(--text); opacity:0.8; margin-bottom: 1rem;"> Personaliza cómo se verá la invitación al compartirla. El enlace se autodetecta según tu dominio actual. </p> <div class="form-row"> <div class="form-group"> <label class="form-label">Título de Compartición</label> <input type="text" name="share_title" class="form-control" value="<?= htmlspecialchars($settings['share_title'] ?? '') ?>" placeholder="Ej: ¡Estás Invitado!"> </div> </div> <div class="form-group"> <label class="form-label">Mensaje de Compartición</label> <textarea name="share_text" class="form-control" rows="3" placeholder="Escribe un mensaje bonito para acompañar el link..."><?= htmlspecialchars($settings['share_text'] ?? '') ?></textarea> <p style="font-size:0.75rem; color:var(--admin-text-muted); margin-top:0.5rem;"> <i class="ph-bold ph-info"></i> El link del sitio se añadirá automáticamente al final del mensaje. </p> </div> </div> <!-- Mensajes WhatsApp --> <div class="admin-card"> <div class="card-header"> <div class="card-title"><i class="ph-fill ph-whatsapp-logo"></i> Plantillas de WhatsApp (RSVP)</div> </div> <p style="font-size:0.85rem; color:var(--text); opacity:0.8; margin-bottom: 1rem;"> Puedes usar estas variables mágicas: <b>[NOMBRE]</b>, <b>[CANTIDAD]</b>, <b>[CONFIRMACION]</b>, <b>[TITULO]</b> (nombre del evento). </p> <div class="form-row"> <div class="form-group"> <label class="form-label">Mensaje cuando SÍ asisten</label> <textarea name="whatsapp_msg_yes" class="form-control" rows="4"><?= htmlspecialchars($settings['whatsapp_msg_yes'] ?? '') ?></textarea> </div> <div class="form-group"> <label class="form-label">Mensaje cuando NO asisten</label> <textarea name="whatsapp_msg_no" class="form-control" rows="4"><?= htmlspecialchars($settings['whatsapp_msg_no'] ?? '') ?></textarea> </div> </div> </div> <!-- Colores Light --> <div class="admin-card"> <div class="card-header" style="display:flex; justify-content:between; align-items:center;"> <div class="card-title"><i class="ph-fill ph-sun"></i> Colores — Tema Claro</div> <button type="button" class="btn btn-outline" style="padding:0.4rem 0.8rem; font-size:0.75rem;" onclick="activateCustomTheme()"> <i class="ph-bold ph-check"></i> Activar este diseño </button> </div> <div class="form-row"> <div class="form-group"> <label class="form-label">Fondo</label> <div style="display:flex;gap:.5rem;align-items:center;"> <input type="color" name="color_bg" value="<?= htmlspecialchars($settings['color_bg'] ?? '#faf8f5') ?>" onchange="this.nextElementSibling.value=this.value; markAsCustom()"> <input type="text" class="form-control" value="<?= htmlspecialchars($settings['color_bg'] ?? '#faf8f5') ?>" style="max-width:130px;" onchange="this.previousElementSibling.value=this.value; markAsCustom()" name="color_bg_text"> </div> </div> <div class="form-group"> <label class="form-label">Texto</label> <div style="display:flex;gap:.5rem;align-items:center;"> <input type="color" name="color_text" value="<?= htmlspecialchars($settings['color_text'] ?? '#4a4a4a') ?>" onchange="this.nextElementSibling.value=this.value; markAsCustom()"> <input type="text" class="form-control" value="<?= htmlspecialchars($settings['color_text'] ?? '#4a4a4a') ?>" style="max-width:130px;" onchange="this.previousElementSibling.value=this.value; markAsCustom()"> </div> </div> <div class="form-group"> <label class="form-label">Púrpura</label> <div style="display:flex;gap:.5rem;align-items:center;"> <input type="color" name="color_purple" value="<?= htmlspecialchars($settings['color_purple'] ?? '#8b6b8e') ?>" onchange="this.nextElementSibling.value=this.value; markAsCustom()"> <input type="text" class="form-control" value="<?= htmlspecialchars($settings['color_purple'] ?? '#8b6b8e') ?>" style="max-width:130px;" onchange="this.previousElementSibling.value=this.value; markAsCustom()"> </div> </div> <div class="form-group"> <label class="form-label">Dorado</label> <div style="display:flex;gap:.5rem;align-items:center;"> <input type="color" name="color_gold" value="<?= htmlspecialchars($settings['color_gold'] ?? '#c5a880') ?>" onchange="this.nextElementSibling.value=this.value; markAsCustom()"> <input type="text" class="form-control" value="<?= htmlspecialchars($settings['color_gold'] ?? '#c5a880') ?>" style="max-width:130px;" onchange="this.previousElementSibling.value=this.value; markAsCustom()"> </div> </div> </div> </div> <!-- Colores Dark --> <div class="admin-card"> <div class="card-header" style="display:flex; justify-content:between; align-items:center;"> <div class="card-title"><i class="ph-fill ph-moon"></i> Colores — Tema Oscuro</div> <button type="button" class="btn btn-outline" style="padding:0.4rem 0.8rem; font-size:0.75rem;" onclick="activateCustomTheme()"> <i class="ph-bold ph-check"></i> Activar este diseño </button> </div> <div class="form-row"> <div class="form-group"> <label class="form-label">Fondo Dark</label> <div style="display:flex;gap:.5rem;align-items:center;"> <input type="color" name="dark_bg" value="<?= htmlspecialchars($settings['dark_bg'] ?? '#1a151a') ?>" onchange="this.nextElementSibling.value=this.value; markAsCustom()"> <input type="text" class="form-control" value="<?= htmlspecialchars($settings['dark_bg'] ?? '#1a151a') ?>" style="max-width:130px;" onchange="this.previousElementSibling.value=this.value; markAsCustom()"> </div> </div> <div class="form-group"> <label class="form-label">Texto Dark</label> <div style="display:flex;gap:.5rem;align-items:center;"> <input type="color" name="dark_text" value="<?= htmlspecialchars($settings['dark_text'] ?? '#eaeaea') ?>" onchange="this.nextElementSibling.value=this.value; markAsCustom()"> <input type="text" class="form-control" value="<?= htmlspecialchars($settings['dark_text'] ?? '#eaeaea') ?>" style="max-width:130px;" onchange="this.previousElementSibling.value=this.value; markAsCustom()"> </div> </div> <div class="form-group"> <label class="form-label">Púrpura Dark</label> <div style="display:flex;gap:.5rem;align-items:center;"> <input type="color" name="dark_purple" value="<?= htmlspecialchars($settings['dark_purple'] ?? '#d0a9d3') ?>" onchange="this.nextElementSibling.value=this.value; markAsCustom()"> <input type="text" class="form-control" value="<?= htmlspecialchars($settings['dark_purple'] ?? '#d0a9d3') ?>" style="max-width:130px;" onchange="this.previousElementSibling.value=this.value; markAsCustom()"> </div> </div> <div class="form-group"> <label class="form-label">Dorado Dark</label> <div style="display:flex;gap:.5rem;align-items:center;"> <input type="color" name="dark_gold" value="<?= htmlspecialchars($settings['dark_gold'] ?? '#e6cc80') ?>" onchange="this.nextElementSibling.value=this.value; markAsCustom()"> <input type="text" class="form-control" value="<?= htmlspecialchars($settings['dark_gold'] ?? '#e6cc80') ?>" style="max-width:130px;" onchange="this.previousElementSibling.value=this.value; markAsCustom()"> </div> </div> </div> </div> <button type="submit" class="btn btn-gold" style="width:100%;justify-content:center;padding:1rem;"> <i class="ph-bold ph-floppy-disk"></i> Guardar Toda la Configuración </button> </form> <!-- Google Fonts Previews --> <link href="https://fonts.googleapis.com/css2?family=Alex+Brush&family=Balsamiq+Sans&family=Bubblegum+Sans&family=Chewy&family=Cinzel&family=Cookie&family=Cormorant+Garamond&family=Dancing+Script&family=Fredericka+the+Great&family=Great+Vibes&family=Inter&family=Lora&family=Montserrat&family=Outfit&family=Parisienne&family=Pinyon+Script&family=Playfair+Display&family=Poppins&family=Prata&family=Quicksand&family=Raleway&display=swap" rel="stylesheet"> <script> function selectFont(type, font) { // Actualizar input oculto document.getElementById(`font_${type}_input`).value = font; // Actualizar UI document.querySelectorAll(`.font-card[id^="font_${type}_"]`).forEach(el => el.classList.remove('active')); document.getElementById(`font_${type}_${font.replace(/\s+/g, '_')}`).classList.add('active'); // Auto-save saveSettings(new Event('submit')); showToast(`Fuente ${type === 'primary' ? 'Primaria' : 'Secundaria'} actualizada a ${font}`, 'success'); } async function saveSettings(e) { e.preventDefault(); const form = document.getElementById('settingsForm'); const formData = new FormData(form); // Recolectar solo los inputs con name (excluyendo los text duplicados de colores) const data = {}; const inputs = form.querySelectorAll('input[name], textarea[name], select[name]'); inputs.forEach(el => { if (el.type === 'file') { if (el.files && el.files[0]) { data[el.name] = el.files[0]; } } else if (el.type === 'radio' || el.type === 'checkbox') { if (el.checked) data[el.name] = el.value; } else if (el.name && (!el.name.endsWith('_text') || ['footer_text', 'share_text'].includes(el.name)) && el.type !== 'color') { data[el.name] = el.value; } else if (el.type === 'color') { data[el.name] = el.value; } }); await adminFetch('save_settings', data); } function updateEffectActive(input) { document.querySelectorAll('input[name="special_effects_type"]').forEach(i => { i.closest('.radio-card').classList.toggle('active', i.checked); }); } // Guardar los colores iniciales para el "Tema Guardado" const initialSettings = { color_bg: '<?= $settings['color_bg'] ?? '#ffffff' ?>', color_text: '<?= $settings['color_text'] ?? '#1a1a1a' ?>', color_purple: '<?= $settings['color_purple'] ?? '#8b6b8e' ?>', color_gold: '<?= $settings['color_gold'] ?? '#c5a880' ?>', dark_bg: '<?= $settings['dark_bg'] ?? '#0a0a0a' ?>', dark_text: '<?= $settings['dark_text'] ?? '#eaeaea' ?>', dark_purple: '<?= $settings['dark_purple'] ?? '#d0a9d3' ?>', dark_gold: '<?= $settings['dark_gold'] ?? '#e6cc80' ?>', special_effects_type: '<?= $settings['special_effects_type'] ?? 'flowers' ?>' }; function applyTheme(id) { const themes = { custom_saved: initialSettings, // SOCIALES wedding: { color_bg:'#ffffff', color_text:'#1a1a1a', color_purple:'#8b6b8e', color_gold:'#c5a880', dark_bg:'#0a0a0a', dark_text:'#eaeaea', dark_purple:'#d0a9d3', dark_gold:'#e6cc80', special_effects_type:'flowers' }, xv: { color_bg:'#fff1f2', color_text:'#4c0519', color_purple:'#fb7185', color_gold:'#fda4af', dark_bg:'#4c0519', dark_text:'#ffe4e6', dark_purple:'#be123c', dark_gold:'#fb7185', special_effects_type:'hearts' }, birthday: { color_bg:'#ecfeff', color_text:'#0c4a6e', color_purple:'#0ea5e9', color_gold:'#06b6d4', dark_bg:'#082f49', dark_text:'#e0f2fe', dark_purple:'#0284c7', dark_gold:'#0ea5e9', special_effects_type:'confetti' }, babyshower: { color_bg:'#fdf2f8', color_text:'#831843', color_purple:'#f472b6', color_gold:'#fbcfe8', dark_bg:'#500724', dark_text:'#fce7f3', dark_purple:'#db2777', dark_gold:'#f472b6', special_effects_type:'bubbles' }, anniversary: { color_bg:'#111827', color_text:'#f9fafb', color_purple:'#be123c', color_gold:'#e11d48', dark_bg:'#000000', dark_text:'#fff1f2', dark_purple:'#9f1239', dark_gold:'#be123c', special_effects_type:'hearts' }, party: { color_bg:'#1e1b4b', color_text:'#e0e7ff', color_purple:'#a855f7', color_gold:'#7c3aed', dark_bg:'#0f172a', dark_text:'#c7d2fe', dark_purple:'#6d28d9', dark_gold:'#4f46e5', special_effects_type:'confetti' }, // EMPRESARIALES conference: { color_bg:'#f8fafc', color_text:'#0f172a', color_purple:'#334155', color_gold:'#475569', dark_bg:'#020617', dark_text:'#f8fafc', dark_purple:'#1e293b', dark_gold:'#334155', special_effects_type:'none' }, seminar: { color_bg:'#ffffff', color_text:'#075985', color_purple:'#0ea5e9', color_gold:'#0284c7', dark_bg:'#082f49', dark_text:'#f0f9ff', dark_purple:'#0369a1', dark_gold:'#0ea5e9', special_effects_type:'none' }, networking: { color_bg:'#111827', color_text:'#f0fdfa', color_purple:'#2dd4bf', color_gold:'#0d9488', dark_bg:'#042f2e', dark_text:'#ccfbf1', dark_purple:'#14b8a6', dark_gold:'#2dd4bf', special_effects_type:'bubbles' }, launch: { color_bg:'#020617', color_text:'#ecfdf5', color_purple:'#10b981', color_gold:'#059669', dark_bg:'#064e3b', dark_text:'#d1fae5', dark_purple:'#047857', dark_gold:'#10b981', special_effects_type:'stars' }, fair: { color_bg:'#ecfdf5', color_text:'#064e3b', color_purple:'#059669', color_gold:'#10b981', dark_bg:'#064e3b', dark_text:'#d1fae5', dark_purple:'#047857', dark_gold:'#10b981', special_effects_type:'bubbles' }, vip: { color_bg:'#0a0a0a', color_text:'#ffffff', color_purple:'#c5a880', color_gold:'#1a1a1a', dark_bg:'#000000', dark_text:'#f3f4f6', dark_purple:'#a88b5e', dark_gold:'#c5a880', special_effects_type:'stars' }, inauguration: { color_bg:'#ffffff', color_text:'#1a1a1a', color_purple:'#dc2626', color_gold:'#991b1b', dark_bg:'#450a0a', dark_text:'#fef2f2', dark_purple:'#b91c1c', dark_gold:'#dc2626', special_effects_type:'confetti' }, commercial: { color_bg:'#fef2f2', color_text:'#991b1b', color_purple:'#ef4444', color_gold:'#b91c1c', dark_bg:'#450a0a', dark_text:'#fca5a5', dark_purple:'#dc2626', dark_gold:'#ef4444', special_effects_type:'none' }, // CULTURA concert: { color_bg:'#020617', color_text:'#fef9c3', color_purple:'#facc15', color_gold:'#ca8a04', dark_bg:'#000000', dark_text:'#fefce8', dark_purple:'#eab308', dark_gold:'#facc15', special_effects_type:'stars' }, cultural: { color_bg:'#fefae0', color_text:'#283618', color_purple:'#bc6c25', color_gold:'#dda15e', dark_bg:'#283618', dark_text:'#fefae0', dark_purple:'#dda15e', dark_gold:'#bc6c25', special_effects_type:'leaves' }, festival: { color_bg:'#fff7ed', color_text:'#7c2d12', color_purple:'#fb923c', color_gold:'#ea580c', dark_bg:'#431407', dark_text:'#ffedd5', dark_purple:'#ea580c', dark_gold:'#fb923c', special_effects_type:'confetti' }, // EDUCACION graduation: { color_bg:'#000000', color_text:'#ffffff', color_purple:'#fbbf24', color_gold:'#451a03', dark_bg:'#1c1917', dark_text:'#fde68a', dark_purple:'#d97706', dark_gold:'#fbbf24', special_effects_type:'stars' }, talk: { color_bg:'#eff6ff', color_text:'#1e3a8a', color_purple:'#2563eb', color_gold:'#1d4ed8', dark_bg:'#1e3a8a', dark_text:'#dbeafe', dark_purple:'#3b82f6', dark_gold:'#60a5fa', special_effects_type:'none' }, workshop: { color_bg:'#f5f3ff', color_text:'#4c1d95', color_purple:'#7c3ad6', color_gold:'#6d28d9', dark_bg:'#2e1065', dark_text:'#ede9fe', dark_purple:'#8b5cf6', dark_gold:'#a78bfa', special_effects_type:'bubbles' }, // DEPORTES tournament: { color_bg:'#fef2f2', color_text:'#1e40af', color_purple:'#1d4ed8', color_gold:'#dc2626', dark_bg:'#1e1b4b', dark_text:'#ffffff', dark_purple:'#1d4ed8', dark_gold:'#ef4444', special_effects_type:'none' }, competition: { color_bg:'#18181b', color_text:'#ffffff', color_purple:'#facc15', color_gold:'#27272a', dark_bg:'#09090b', dark_text:'#facc15', dark_purple:'#eab308', dark_gold:'#facc15', special_effects_type:'stars' } }; const t = themes[id]; if (!t) return; // Actualizar site_theme input document.getElementById('site_theme_input').value = id; // Actualizar UI de tarjetas de tema document.querySelectorAll('.theme-card').forEach(c => c.classList.remove('active')); document.getElementById('theme_card_' + id).classList.add('active'); // Actualizar todos los color pickers y text inputs for (let key in t) { if (key === 'special_effects_type') { const radio = document.querySelector(`input[name="special_effects_type"][value="${t[key]}"]`); if (radio) { radio.checked = true; updateEffectActive(radio); } } else { const picker = document.querySelector(`input[name="${key}"][type="color"]`); if (picker) { picker.value = t[key]; // También actualizar el input de texto hermano if (picker.nextElementSibling && picker.nextElementSibling.classList.contains('form-control')) { picker.nextElementSibling.value = t[key]; } } } } // Auto-guardar saveSettings(new Event('submit')); showToast(`Tema '${id}' aplicado correctamente`, 'success'); } function markAsCustom() { document.querySelectorAll('.theme-card').forEach(c => c.classList.remove('active')); document.getElementById('theme_card_custom').classList.add('active'); document.getElementById('site_theme_input').value = 'custom'; } function activateCustomTheme() { markAsCustom(); saveSettings(new Event('submit')); showToast('Diseño Manual activado correctamente', 'success'); } function previewOverlayImg(input) { if (input.files && input.files[0]) { const reader = new FileReader(); reader.onload = function(e) { document.getElementById('overlayImgPreview').src = e.target.result; } reader.readAsDataURL(input.files[0]); } } function previewMusic(input) { if (input.files && input.files[0]) { const reader = new FileReader(); reader.onload = function(e) { const player = document.getElementById('musicPreview'); player.src = e.target.result; player.load(); } reader.readAsDataURL(input.files[0]); } } </script>
Coded With 💗 by
0x6ick