jQuery(document).ready(function($) { 'use strict'; // Variáveis globais let currentModal = null; let isModalOpen = false; // Inicializar funcionalidades initProgramDetails(); initModal(); initTimelinePointer(); initResponsiveBehavior(); /** * Inicializar botões de detalhes dos programas */ function initProgramDetails() { // Clicar nos blocos de programa $(document).on('click', '.program-block', function(e) { e.preventDefault(); e.stopPropagation(); const programaId = $(this).data('programa-id'); if (programaId) { loadProgramDetails(programaId); } }); // Navegação entre dias $(document).on('click', '.day-tab', function(e) { e.preventDefault(); const dayKey = $(this).data('day'); // Atualizar tabs ativas $('.day-tab').removeClass('active'); $(this).addClass('active'); // Mostrar coluna do dia selecionado $('.day-column').removeClass('active'); $(`.day-column[data-day="${dayKey}"]`).addClass('active'); }); } /** * Carregar detalhes do programa via AJAX */ function loadProgramDetails(programaId) { const $programItem = $(`.program-item[data-programa-id="${programaId}"]`); // Adicionar estado de loading $programItem.addClass('loading'); $.ajax({ url: tv_programacao_ajax.ajax_url, type: 'POST', data: { action: 'get_programa_info', programa_id: programaId, nonce: tv_programacao_ajax.nonce }, success: function(response) { if (response.success) { populateModal(response.data); openModal(); } else { showError('Erro ao carregar informações do programa'); } }, error: function() { showError('Erro de conexão. Tente novamente.'); }, complete: function() { $programItem.removeClass('loading'); } }); } /** * Preencher modal com dados do programa */ function populateModal(data) { $('#modal-title').text(data.titulo); $('#modal-time').text(data.horario_inicio + ' - ' + data.horario_fim); $('#modal-duration').text(data.duracao + ' minutos'); $('#modal-presenter').text(data.apresentador || 'Não informado'); $('#modal-rating').text(getRatingText(data.classificacao)); $('#modal-categories').text(data.categorias ? data.categorias.join(', ') : 'Não categorizado'); $('#modal-synopsis').html(data.sinopse || 'Sinopse não disponível'); $('#modal-description').html(data.conteudo || 'Descrição não disponível'); if (data.imagem) { $('#modal-image').attr('src', data.imagem).show(); } else { $('#modal-image').hide(); } } /** * Obter texto da classificação indicativa */ function getRatingText(rating) { const ratings = { 'L': 'Livre', '10': '10 anos', '12': '12 anos', '14': '14 anos', '16': '16 anos', '18': '18 anos' }; return ratings[rating] || 'Não informado'; } /** * Inicializar modal */ function initModal() { // Fechar modal ao clicar no botão X $(document).on('click', '.modal-close', function() { closeModal(); }); // Fechar modal ao clicar fora dele $(document).on('click', '.programa-modal', function(e) { if (e.target === this) { closeModal(); } }); // Fechar modal com ESC $(document).on('keydown', function(e) { if (e.key === 'Escape' && isModalOpen) { closeModal(); } }); } /** * Abrir modal */ function openModal() { $('#programa-modal').fadeIn(300); isModalOpen = true; $('body').addClass('modal-open'); // Focar no modal para acessibilidade setTimeout(function() { $('#programa-modal').focus(); }, 300); } /** * Fechar modal */ function closeModal() { $('#programa-modal').fadeOut(300); isModalOpen = false; $('body').removeClass('modal-open'); } /** * Inicializar pointer da timeline */ function initTimelinePointer() { updateTimelinePointer(); // Atualizar a cada minuto setInterval(updateTimelinePointer, 60000); } /** * Atualizar posição do pointer da timeline */ function updateTimelinePointer() { const now = new Date(); const currentHour = now.getHours(); const currentMinute = now.getMinutes(); // Calcular posição (timeline de 24h) const minutesSinceMidnight = currentHour * 60 + currentMinute; const position = minutesSinceMidnight * 0.5; // 0.5px por minuto // Atualizar pointer da timeline $('.timeline-pointer').css('left', position + 'px'); // Atualizar estado dos programas (passado, atual, futuro) updateProgramStates(); } /** * Atualizar estados dos programas */ function updateProgramStates() { const now = new Date(); const currentTime = now.getHours() * 60 + now.getMinutes(); $('.program-block').each(function() { const $item = $(this); const timeText = $item.find('.program-time-range').text(); const [startTime, endTime] = timeText.split(' - '); if (startTime && endTime) { const startMinutes = timeToMinutes(startTime); const endMinutes = timeToMinutes(endTime); $item.removeClass('past current future'); if (currentTime >= startMinutes && currentTime <= endMinutes) { $item.addClass('current'); } else if (currentTime > endMinutes) { $item.addClass('past'); } else { $item.addClass('future'); } } }); } /** * Converter horário para minutos */ function timeToMinutes(timeString) { const [hours, minutes] = timeString.split(':').map(Number); return hours * 60 + minutes; } /** * Inicializar comportamento responsivo */ function initResponsiveBehavior() { // Ajustar layout em telas pequenas function adjustLayout() { const width = $(window).width(); if (width < 768) { $('.program-block').css('padding', '4px'); $('.program-title').css('font-size', '10px'); $('.program-time-range').css('font-size', '8px'); } else { $('.program-block').css('padding', '8px'); $('.program-title').css('font-size', '12px'); $('.program-time-range').css('font-size', '10px'); } } // Executar na inicialização adjustLayout(); // Executar no redimensionamento $(window).on('resize', debounce(adjustLayout, 250)); } /** * Função debounce para otimizar performance */ function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } /** * Mostrar mensagem de erro */ function showError(message) { // Criar toast de erro const $toast = $(`
${message}
`); $('body').append($toast); // Mostrar toast setTimeout(() => { $toast.addClass('show'); }, 100); // Auto-remover após 5 segundos setTimeout(() => { $toast.removeClass('show'); setTimeout(() => { $toast.remove(); }, 300); }, 5000); // Permitir fechar manualmente $toast.find('.toast-close').on('click', function() { $toast.removeClass('show'); setTimeout(() => { $toast.remove(); }, 300); }); } /** * Animações suaves para elementos */ function initSmoothAnimations() { // Animar entrada dos programas $('.program-block').each(function(index) { const $item = $(this); setTimeout(() => { $item.addClass('animate-in'); }, index * 50); }); // Animar hover dos programas $('.program-block').hover( function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); } ); } // Inicializar animações após carregamento setTimeout(initSmoothAnimations, 500); /** * Melhorar acessibilidade */ function initAccessibility() { // Adicionar atributos ARIA $('.program-block').attr('role', 'button'); $('.program-block').attr('tabindex', '0'); // Permitir navegação por teclado $('.program-block').on('keydown', function(e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); const programaId = $(this).data('programa-id'); if (programaId) { loadProgramDetails(programaId); } } }); // Foco visual melhorado $('.program-block').on('focus', function() { $(this).addClass('focused'); }).on('blur', function() { $(this).removeClass('focused'); }); } // Inicializar acessibilidade initAccessibility(); /** * Atualizar dados em tempo real (opcional) */ function initRealTimeUpdates() { // Atualizar dados a cada 5 minutos setInterval(function() { // Aqui você pode adicionar lógica para atualizar dados // Por exemplo, verificar se há novos programas console.log('Verificando atualizações...'); }, 300000); } // Inicializar atualizações em tempo real initRealTimeUpdates(); }); // Adicionar CSS para toast e animações const additionalCSS = ` .tv-toast { position: fixed; top: 20px; right: 20px; background: #ff6b35; color: white; padding: 15px 20px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000; transform: translateX(100%); transition: transform 0.3s ease; max-width: 300px; display: flex; align-items: center; gap: 10px; } .tv-toast.show { transform: translateX(0); } .tv-toast-error { background: #e74c3c; } .toast-content { display: flex; align-items: center; gap: 8px; flex: 1; } .toast-close { background: none; border: none; color: white; font-size: 18px; cursor: pointer; padding: 0; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; } .program-item.animate-in { animation: slideInUp 0.5s ease-out; } .program-item.hover { transform: translateY(-4px) scale(1.02); } .program-item.focused { outline: 2px solid #ff6b35; outline-offset: 2px; } @keyframes slideInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } body.modal-open { overflow: hidden; } `; // Injetar CSS adicional const style = document.createElement('style'); style.textContent = additionalCSS; document.head.appendChild(style);