Shift Management Dashboard - Copy this Html, Bootstrap Component to your project
Podrias mejorarme este script, es una paginde turnos y quiero mejorarlo visualmente: {% load compress %} <!DOCTYPE html> <html lang="es"> {% load static %} <head> <meta charset="utf 8" /> <meta http equiv="X UA Compatible" content="IE=edge" /> <meta name="viewport" content="width=device width, initial scale=1, shrink to fit=no" /> <title>Turnos</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/simple datatables@7.1.2/dist/style.min.css" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/swiper@11/swiper bundle.min.css" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/litepicker/dist/css/litepicker.css" rel="stylesheet" /> <link rel="icon" type="image/x icon" href="{% static 'img/icon_app.png' %}" /> <script data search pseudo elements defer src="https://cdnjs.cloudflare.com/ajax/libs/font awesome/6.3.0/js/all.min.js" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery 3.6.0.min.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script> {% compress css %} <link rel="stylesheet" href="{% static 'css/styles_turnos.css' %}"> <style> #modalHoras .modal body { max height: 500px; overflow y: auto; } .custom bg card { background color: #4a4a4a; } .card container.top right { position: absolute; top: 25vh; /* Esto ajusta la posición para que respete la altura de .nav */ right: 10px; z index: 1000; } .card container.center { text align: center; width: 70%; /* Reduce un poco el ancho total */ margin top: 25px; right: 100px; } .card.center card { display: inline block; margin: 0 auto; /* Permite centrar el contenido dentro del contenedor */ width: auto; max width: 100%; } .btn custom { background color: #4e73df; color: white; } .btn custom:hover { background color: #2e59d9; color: white; } .btn red { background color: #e74a3b; color: white; } .btn red:hover { background color: #e02d1b; color: white; } .btn green { background color: #1cc88a; color: white; } .btn green:hover { background color: #17a673; color: white; } .exchange icon { font size: 24px; margin: 0 10px; vertical align: middle; cursor: pointer; } .w 40 { width: 40%; } </style> <style> .nav { display: flex; flex direction: column; justify content: center; align items: center; height: 25vh; position: relative; background: transparent; text align: center; padding: 0 2em; } .nav h1, .slider h1 { font family: "Josefin Sans", sans serif; font size: 5vw; margin: 0; padding bottom: 0.5rem; letter spacing: 0.5rem; color: #03dac6; transition: all 0.3s ease; z index: 3; } .slider h2 { font size: 2vw; letter spacing: 0.3rem; font family: "ROBOTO", sans serif; font weight: 300; color: #faebd7; z index: 4; } h3.span { font size: 2vw; letter spacing: 0.7em; font family: "ROBOTO", sans serif; font weight: 300; color: #faebd7; z index: 4; } a { text decoration: none; } .nav container { display: flex; flex direction: row; position: absolute; bottom: 0; width: 100%; height: 75px; box shadow: 20px 20px 50px rgba(0, 0, 0, 0.5); background: #1e1f26; z index: 10; transition: all 0.3s cubic bezier(0.19, 1, 0.22, 1); } .nav container top first { position: fixed; top: 75px; transition: all 0.3s cubic bezier(0.19, 1, 0.22, 1); } .nav container top second { position: fixed; top: 0; } .nav tab { display: flex; justify content: center; align items: center; flex: 1; color: #03dac6; letter spacing: 0.1rem; transition: all 0.5s ease; font size: 2vw; } .nav tab:hover { color: #1e1f26; background: #03dac6; transition: all 0.5s ease; } .nav tab slider { position: absolute; bottom: 0; width: 0; height: 2px; background: #03dac6; transition: left 0.3s ease; } .background { position: absolute; height: 90vh; top: 0; bottom: 0; left: 0; right: 0; z index: auto; } @media (min width: 800px) { .nav h1, .slider h1 { font size: 5vw; } .nav h2, .slider h2 { font size: 3vw; } .nav tab { font size: 3vw; } } @media screen only (min width: 360px) { .nav h1, .slider h1 { font size: 8vw; } .nav h2, .slider h2 { font size: 2vw; letter spacing: 0.2vw; } .nav tab { font size: 1.2vw; } } .background { position: absolute; height: 100vh; top: 0; bottom: 0; left: 0; right: 0; z index: 0; } .loader .span turnos { color: #faebd7; text shadow: 0 0 0 #faebd7; webkit animation: loading 1s ease in out infinite alternate; } @ webkit keyframes loading { to { text shadow: 20px 0 70px #00b4d8; color: #00b4d8; } } .loader .span turnos:nth child(2) { webkit animation delay: 0.1s; } .loader .span turnos:nth child(3) { webkit animation delay: 0.2s; } .loader .span turnos:nth child(4) { webkit animation delay: 0.3s; } .loader .span turnos:nth child(5) { webkit animation delay: 0.4s; } .loader .span turnos:nth child(6) { webkit animation delay: 0.5s; } .loader .span turnos:nth child(7) { webkit animation delay: 0.6s; } .loader .span turnos:nth child(8) { webkit animation delay: 0.7s; } .loader .span turnos:nth child(9) { webkit animation delay: 0.8s; } .loader .span turnos:nth child(10) { webkit animation delay: 0.9s; } .loader .span turnos:nth child(11) { webkit animation delay: 1s; } .loader .span turnos:nth child(12) { webkit animation delay: 1.1s; } .loader .span turnos:nth child(13) { webkit animation delay: 1.2s; } .loader .span turnos:nth child(14) { webkit animation delay: 1.3s; } .loader .span turnos:nth child(15) { webkit animation delay: 1.4s; } .loader .span turnos:nth child(16) { webkit animation delay: 1.5s; } .loader .span turnos:nth child(17) { webkit animation delay: 1.6s; } .loader .span turnos:nth child(18) { webkit animation delay: 1.7s; } .loader .span turnos:nth child(19) { webkit animation delay: 1.8s; } .loader .span turnos:nth child(20) { webkit animation delay: 1.9s; } .loader .span turnos:nth child(21) { webkit animation delay: 2s; } .loader .span turnos:nth child(22) { webkit animation delay: 2.1s; } </style> <style> @media (max width: 768px) { /* Ajustes para pantallas de tamaño de tablet y móvil */ /* Ajustar el contenedor del calendario para que ocupe todo el ancho */ .card container.center { width: 100%; margin: 0; /* Eliminar márgenes */ padding: 0 10px; /* Añadir algo de espacio alrededor */ } .center card { width: 100%; /* Que ocupe todo el ancho */ max width: 100%; /* Ajusta el máximo */ } /* Reorganizar las tarjetas de turnos */ .card container.top right { position: relative; /* Cambiar posición absoluta a relativa para evitar superposición */ top: 0; /* Eliminar la distancia superior */ right: 0; /* Eliminar el margen derecho */ margin bottom: 20px; /* Añadir espacio inferior */ padding: 0 10px; /* Añadir un margen lateral */ width: 100%; /* Que ocupe todo el ancho en móviles */ } /* Reorganizar las tarjetas individuales dentro del contenedor */ .card.card header actions { margin bottom: 15px; /* Añadir separación entre tarjetas */ width: 100%; /* Que ocupe todo el ancho en móvil */ } /* Ajuste del calendario para que no se vea oculto en móvil */ .calendar container { overflow x: scroll; /* Permitir desplazamiento si es necesario */ padding: 10px; /* Espacio alrededor */ } /* Ajustes para las imágenes y los textos en la lista de perfiles */ .card item.swiper slide { width: 100%; /* Que cada tarjeta de perfil ocupe el ancho completo */ text align: center; /* Centrar contenido en móvil */ margin bottom: 20px; /* Añadir separación entre perfiles */ } /* Ajustes para el contenedor del slider */ .slider wrapper { padding: 10px; /* Añadir espacio alrededor del slider */ } /* Ajustar tamaño de texto en móvil para mejorar la legibilidad */ .nav h1, .slider h1 { font size: 8vw; /* Reducir tamaño del título */ } /* Asegurarse de que el botón Cambiar Turno tenga espacio en móvil */ .btn { width: 100%; /* Ocupa el ancho completo en móvil */ margin top: 10px; /* Añadir separación superior */ } } </style> {% endcompress %} </head> <body> <! Contenido principal > <div id="mainContent"> <section class="nav"> <h3 class="span loader"> <span class="span turnos">T</span> <span class="span turnos">U</span> <span class="span turnos">R</span> <span class="span turnos">N</span> <span class="span turnos">O</span> <span class="span turnos">S</span> <span class="span turnos"> </span> <span class="span turnos">C</span> <span class="span turnos">A</span> <span class="span turnos">P</span> <span class="span turnos">J</span> </h3> <canvas class="background"></canvas> </section> {% if success %} <div class="alert alert success" role="alert"> {{ success }} </div> <script> setTimeout(function(){ window.location.href = "/turnos"; // Redirigir a /turnos después de 3 segundos }, 3000); </script> {% elif error %} <div class="alert alert danger" role="alert"> {{ error }} </div> {% endif %} <div class="card container top right"> <p></p> <! <p id="fechaSimulada"></p> > {% if request.user.username == "root" or request.user.username == "doyarcea" %} <button type="button" class="btn btn primary" data bs toggle="modal" data bs target="#cambioTurnoModal"> Cambiar Turno </button> <! <button id="adelantarDia" class="btn btn primary">Adelantar un día</button> > <p></p> {% endif %} <div class="card mt 2"> <div class="card header"> Fecha del turno: {{ rango_fecha_ing }} </div> </div> <p></p> <div class="card card header actions"> <div class="card border start lg border start blue"> <div class="card header"> Turno de Ingeniería </div> <div class="card body"> {{ persona_turno_ing|linebreaksbr }} </div> </div> </div> <p></p> <div class="card card header actions"> <div class="card border start lg border start green"> <div class="card header"> Turno de Comunicaciones </div> <div class="card body"> {{ persona_turno_redes|linebreaksbr }} </div> </div> </div> <p></p> <div class="cardrt"> <svg class="wavert" viewBox="0 0 1440 320" xmlns="http://www.w3.org/2000/svg"> <path d="M0,256L11.4,240C22.9,224,46,192,69,192C91.4,192,114,224,137,234.7C160,245,183,235,206,213.3C228.6,192,251,160,274,149.3C297.1,139,320,149,343,181.3C365.7,213,389,267,411,282.7C434.3,299,457,277,480,250.7C502.9,224,526,192,549,181.3C571.4,171,594,181,617,208C640,235,663,277,686,256C708.6,235,731,149,754,122.7C777.1,96,800,128,823,165.3C845.7,203,869,245,891,224C914.3,203,937,117,960,112C982.9,107,1006,181,1029,197.3C1051.4,213,1074,171,1097,144C1120,117,1143,107,1166,133.3C1188.6,160,1211,224,1234,218.7C1257.1,213,1280,139,1303,133.3C1325.7,128,1349,192,1371,192C1394.3,192,1417,128,1429,96L1440,64L1440,320L1428.6,320C1417.1,320,1394,320,1371,320C1348.6,320,1326,320,1303,320C1280,320,1257,320,1234,320C1211.4,320,1189,320,1166,320C1142.9,320,1120,320,1097,320C1074.3,320,1051,320,1029,320C1005.7,320,983,320,960,320C937.1,320,914,320,891,320C868.6,320,846,320,823,320C800,320,777,320,754,320C731.4,320,709,320,686,320C662.9,320,640,320,617,320C594.3,320,571,320,549,320C525.7,320,503,320,480,320C457.1,320,434,320,411,320C388.6,320,366,320,343,320C320,320,297,320,274,320C251.4,320,229,320,206,320C182.9,320,160,320,137,320C114.3,320,91,320,69,320C45.7,320,23,320,11,320L0,320Z" fill opacity="1" ></path> </svg> <div class="icon containerrt"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" stroke width="0" fill="currentColor" stroke="currentColor" class="iconrt" > <path d="M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0 42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33 12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1 7.48,4.2H40.55a8.5,8.5,0,0,1 7.48 4.2,7.59,7.59,0,0,1,0 7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1 16,0Zm20,36a12,12,0,1,1 12 12A12,12,0,0,1,140,180Z" ></path> </svg> </div> <div class="message text container"> <p class="message text">Soporte para eventos SOC</p> <p class="sub text">📧 soporte@nastec.cl</p> <p class="sub text">📱 +569 32307004</p> </div> </div> <p></p> </div> <div class="card container center"> <div class="card mb 3 center card custom bg card text white"> <div class="card header">Calendario</div> <div class="card body calendar container"> <div id="calendar"></div> </div> </div> </div> <div style="margin bottom: 70px;"></div> <hr style="border: 2px solid white; width: 100%; margin top: 30px; margin bottom: 30px;"> <! Slider de perfiles de usuarios > <! Slider de perfiles de usuarios > <div id="craouselContainer" class="swiper container"> <div class="swiper wrapper" id="slideHolder"> {% for usuario in usuarios_operaciones %} {% if usuario.username != 'root' %} <! Oculta el usuario "Root Administrador" > <div class="swiper slide"> <div class="profile section"> <! Imagen del usuario > <img src="{{ usuario.profile_image.url }}" alt="User Image"> </div> <div class="details section"> <! Nombre del usuario > <h3>{{ usuario.first_name }} {{ usuario.last_name }}</h3> <! Email > <p>{{ usuario.email }}</p> <! Grupos > <div class="user groups"> {% for group in usuario.groups.all %} {% if group.name != 'Operaciones' %} <span class="badge">{{ group.name }}</span> {% endif %} {% endfor %} </div> <! Teléfono > <p class="user phone">Tel. {{ usuario.telefono }}</p> </div> </div> {% endif %} {% endfor %} </div> <! Paginación > <div class="swiper pagination"></div> </div> <footer class="footer admin mt auto footer light"> <div class="container xl px 4"> <div class="row"> <div class="col md 6 small">Copyright © CAPJ, todos los derechos reservados 2025</div> <div class="col md 6 text md end small"> <! <a href="#!">Política de Privacidad</a> > · <a href="#!">Información</a> </div> </div> </div> </footer> </div> <div class="modal fade" id="cambioTurnoModal" tabindex=" 1" role="dialog" aria labelledby="cambioTurnoModalLabel" aria hidden="true"> <div class="modal dialog" role="document"> <div class="modal content"> <div class="modal header"> <h5 class="modal title" id="cambioTurnoModalLabel">Cambio de Turno</h5> <button type="button" class="close" data bs dismiss="modal" aria label="Close"> <span aria hidden="true">×</span> </button> </div> <div class="modal body"> <form id="cambioTurnoForm" method="POST" action="{% url 'cambiar_turno' %}"> {% csrf_token %} <div class="form group"> <label for="persona1">Seleccionar primera persona</label> <select class="form control" id="persona1" name="persona_actual"> {% for persona in personas %} <option value="{{ persona.0 }}">{{ persona.1 }}</option> {% endfor %} </select> </div> <div class="form group"> <label for="persona2">Seleccionar segunda persona</label> <select class="form control" id="persona2" name="nueva_persona"> {% for persona in personas %} <option value="{{ persona.0 }}">{{ persona.1 }}</option> {% endfor %} </select> </div> <div class="form group text center mt 3"> <button type="button" class="btn btn primary" id="buscarHorasBtn">Buscar</button> </div> <div class="form group mt 3 d flex justify content around align items center"> <div class="w 40"> <h6 id="nombrePersona1"></h6> <! Nombre de la primera persona > <select class="form control" id="hora1" name="hora1" disabled> <option value="">Seleccione una hora</option> </select> </div> <i class="fas fa exchange alt exchange icon"></i> <div class="w 40"> <h6 id="nombrePersona2"></h6> <! Nombre de la segunda persona > <select class="form control" id="hora2" name="hora2" disabled> <option value="">Seleccione una hora</option> </select> </div> </div> <p></p> <div class="modal footer"> <button type="button" class="btn btn secondary" data bs dismiss="modal">Cerrar</button> <button type="submit" form="cambioTurnoForm" class="btn btn primary">Guardar cambios</button> </div> </form> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/feather icons/dist/feather.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/locale/es.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper bundle.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script> <script> document.addEventListener('DOMContentLoaded', function () { const swiper = new Swiper('#craouselContainer', { grabCursor: true, centeredSlides: true, slidesPerView: 2.3, loop: true, spaceBetween: 30, effect: "coverflow", coverflowEffect: { rotate: 0, depth: 800, slideShadows: false, }, pagination: { el: '.swiper pagination', clickable: true, }, autoplay: { delay: 3000, // Cambia cada 5 segundos }, }); // Ajuste dinámico de slidesPerView según el tamaño de la pantalla window.onresize = queryResizer; queryResizer(); function queryResizer() { if (window.innerWidth < 501) swiper.params.slidesPerView = 1; else if (window.innerWidth < 724) swiper.params.slidesPerView = 2; else swiper.params.slidesPerView = 2.3; swiper.update(); } }); </script> {% compress js %} <! <script src="https://cdn.jsdelivr.net/npm/particlesjs@2.2.3/dist/particles.min.js"></script> > <script src="{% static 'js/turnos.js' %}"></script> <script src="{% static 'js/min/particles.min.js' %}"></script> <script> document.addEventListener('DOMContentLoaded', function () { document.getElementById('buscarHorasBtn').addEventListener('click', function () { var persona1Select = document.getElementById('persona1'); var persona2Select = document.getElementById('persona2'); var persona1Id = persona1Select.value; var persona2Id = persona2Select.value; // Mostrar los nombres de las personas seleccionadas document.getElementById('nombrePersona1').textContent = persona1Select.options[persona1Select.selectedIndex].text; document.getElementById('nombrePersona2').textContent = persona2Select.options[persona2Select.selectedIndex].text; if (persona1Id && persona2Id) { fetchHoras(persona1Id, 'hora1'); fetchHoras(persona2Id, 'hora2'); } else { alert('Seleccione ambas personas antes de buscar las horas.'); } }); function fetchHoras(personaId, selectId) { $.ajax({ url: "{% url 'buscar_horas_turno' %}", method: "GET", data: { persona_id: personaId }, success: function(data) { var select = document.getElementById(selectId); select.innerHTML = '<option value="">Seleccione una hora</option>'; data.turnos.forEach(function(turno) { var option = document.createElement('option'); option.value = turno.id; // Usamos el ID como valor del option option.text = `ID: ${turno.id}| ${turno.fecha_inicio} a ${turno.fecha_fin}`; select.appendChild(option); }); select.disabled = false; }, error: function(xhr, status, error) { console.error('Error al buscar horas:', error); alert('Hubo un error al buscar las horas.'); } }); } }); </script> <script> document.addEventListener("DOMContentLoaded", function() { feather.replace(); }); </script> <script> document.addEventListener("DOMContentLoaded", function() { let fechaSimulada = new Date(); // Fecha actual // Función para formatear la fecha a un formato amigable function formatearFecha(fecha) { let dia = ("0" + fecha.getDate()).slice( 2); let mes = ("0" + (fecha.getMonth() + 1)).slice( 2); // Meses comienzan en 0 let ano = fecha.getFullYear(); return `${dia}/${mes}/${ano}`; } // Mostrar la fecha simulada en algún lugar de la página //document.getElementById("fechaSimulada").innerText = formatearFecha(fechaSimulada); // Función para adelantar un día y hacer la solicitud AJAX function adelantarUnDia() { //fechaSimulada.setDate(fechaSimulada.getDate() + 1); //document.getElementById("fechaSimulada").innerText = formatearFecha(fechaSimulada); // Hacer una solicitud AJAX al servidor para obtener los turnos actualizados fetch('/turnos/', { method: 'POST', headers: { 'Content Type': 'application/json', 'X CSRFToken': '{{ csrf_token }}' // Token CSRF para Django }, body: JSON.stringify({ fecha: fechaSimulada.toISOString().split('T')[0] // Enviar fecha en formato YYYY MM DD }) }) .then(response => response.json()) .then(data => { // Actualizar los turnos en la página actualizarTurnos(data.turnos); }) .catch(error => { console.error('Error al actualizar los turnos:', error); }); } // Asignar la función al botón //document.getElementById("adelantarDia").addEventListener("click", adelantarUnDia); // Función para actualizar los turnos en el front end function actualizarTurnos(turnos) { const contenedorTurnos = document.getElementById("contenedorTurnos"); contenedorTurnos.innerHTML = ''; // Limpiar los turnos anteriores // Renderizar los nuevos turnos turnos.forEach(turno => { const turnoElement = document.createElement("div"); turnoElement.innerText = `Turno: ${turno.nombre} Inicio: ${turno.fecha_inicio} Fin: ${turno.fecha_fin}`; contenedorTurnos.appendChild(turnoElement); }); } }); </script> <script> window.onload = function () { Particles.init({ selector: ".background" }); }; const particles = Particles.init({ selector: ".background", color: ["#03dac6", "#a7c957", "#6c757d"], connectParticles: true, maxParticles: 70, responsive: [ { breakpoint: 368, options: { color: ["#faebd7", "#03dac6", "#a7c957"], maxParticles: 25, connectParticles: false } } ] }); class NavigationPage { constructor() { this.currentId = null; this.currentTab = null; this.tabContainerHeight = 70; this.lastScroll = 0; let self = this; $(".nav tab").click(function () { self.onTabClick(event, $(this)); }); $(window).scroll(() => { this.onScroll(); }); $(window).resize(() => { this.onResize(); }); } onTabClick(event, element) { event.preventDefault(); let scrollTop = $(element.attr("href")).offset().top this.tabContainerHeight + 1; $("html, body").animate({ scrollTop: scrollTop }, 600); } onScroll() { this.checkHeaderPosition(); this.findCurrentTabSelector(); this.lastScroll = $(window).scrollTop(); } onResize() { if (this.currentId) { this.setSliderCss(); } } checkHeaderPosition() { const headerHeight = 75; if ($(window).scrollTop() > headerHeight) { $(".nav container").addClass("nav container scrolled"); } else { $(".nav container").removeClass("nav container scrolled"); } let offset = $(".nav").offset().top + $(".nav").height() this.tabContainerHeight headerHeight; if ( $(window).scrollTop() > this.lastScroll && $(window).scrollTop() > offset ) { $(".nav container").addClass("nav container move up"); $(".nav container").removeClass("nav container top first"); $(".nav container").addClass("nav container top second"); } else if ( $(window).scrollTop() < this.lastScroll && $(window).scrollTop() > offset ) { $(".nav container").removeClass("nav container move up"); $(".nav container").removeClass("nav container top second"); $(".nav container container").addClass("nav container top first"); } else { $(".nav container").removeClass("nav container move up"); $(".nav container").removeClass("nav container top first"); $(".nav container").removeClass("nav container top second"); } } findCurrentTabSelector(element) { let newCurrentId; let newCurrentTab; let self = this; $(".nav tab").each(function () { let id = $(this).attr("href"); let offsetTop = $(id).offset().top self.tabContainerHeight; let offsetBottom = $(id).offset().top + $(id).height() self.tabContainerHeight; if ( $(window).scrollTop() > offsetTop && $(window).scrollTop() < offsetBottom ) { newCurrentId = id; newCurrentTab = $(this); } }); if (this.currentId != newCurrentId || this.currentId === null) { this.currentId = newCurrentId; this.currentTab = newCurrentTab; this.setSliderCss(); } } setSliderCss() { let width = 0; let left = 0; if (this.currentTab) { width = this.currentTab.css("width"); left = this.currentTab.offset().left; } $(".nav tab slider").css("width", width); $(".nav tab slider").css("left", left); } } new NavigationPage(); </script> <script> document.addEventListener('contextmenu', event => event.preventDefault()); document.addEventListener('keydown', event => { if (event.key === 'F12' || (event.ctrlKey && event.shiftKey && event.key === 'I')) { event.preventDefault(); } }); </script> <script> document.querySelectorAll('.cardrt').forEach(ticket => { let rect, centerPoint; ticket.addEventListener('mouseenter', () => { rect = ticket.getBoundingClientRect(); centerPoint = { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, }; }); ticket.addEventListener('mousemove', (e) => { const degreeX = (e.clientY centerPoint.y) * 0.05; const degreeY = (e.clientX centerPoint.x) * 0.05; ticket.style.transform = `perspective(1000px) rotateX(${degreeX}deg) rotateY(${degreeY}deg)`; }); ticket.addEventListener('mouseleave', () => { ticket.style.transform = 'perspective(1000px) rotateX(0deg) rotateY(0deg)'; }); }); </script> {% endcompress %} </body> </html>
