Carregando...

Configuração do Ambiente HTML

Html-Setup é a base fundamental de qualquer website, como construir os alicerces de uma casa antes de erguer as paredes. É o processo de criar a estrutura inicial de um documento HTML que diz ao navegador como exibir seu conteúdo. O Html-Setup inclui a declaração DOCTYPE, a tag html, a seção head e a seção body. Esta etapa é essencial para qualquer projeto web - seja criando um website de portfólio, desenvolvendo um blog pessoal, construindo uma loja e-commerce, criando um site de notícias ou projetando uma plataforma social. Sem um Html-Setup adequado, seu website seria como uma biblioteca sem organização, onde os livros estão espalhados sem ordem. Neste tutorial, você aprenderá como criar uma estrutura HTML limpa e profissional, usar elementos básicos corretamente e evitar erros comuns. Esta base permitirá que você adicione posteriormente estilização CSS e funcionalidades JavaScript. Dominar o Html-Setup é como aprender a escrever uma carta corretamente - você precisa conhecer o formato padrão antes de personalizar o conteúdo.

Exemplo de configuração básica de HTML

html
HTML Code
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<title>Meu Website</title> <!-- Page title for browser tab -->
</head>
<body>
<h1>Bem-vindo ao Meu Website</h1> <!-- Main heading -->
<p>Esta é minha primeira página web!</p> <!-- Paragraph text -->
</body>
</html>

O código acima mostra a estrutura básica de um documento HTML completo. A declaração <!DOCTYPE html> informa ao navegador que este é um documento HTML5. A tag envolve todo o documento e o atributo lang especifica o idioma português. A seção contém metadados que não são visíveis na página, mas são importantes para o navegador. A tag garante a codificação adequada de caracteres para que acentos e caracteres especiais sejam exibidos corretamente. A tag define o texto que aparece na aba do navegador. A seção <body> contém o conteúdo real que os usuários veem. A tag <h1> é usada para o título principal e <p> para texto de parágrafo. Esta estrutura é a fundação de toda página HTML, seja escrevendo um post simples de blog ou construindo um site de e-commerce complexo. Sem esta configuração adequada, seu conteúdo não será renderizado corretamente nos navegadores. Cada elemento tem sua função específica, como cômodos diferentes em uma casa bem organizada.</p> </div> <!-- Enhanced Code Block --> <div class="code-editor-container"> <div class="code-editor-header"> <h3 class="code-title">Exemplo prático de configuração de HTML</h3> <span class="code-language-badge html">html</span> </div> <div class="code-display"> <div class="code-display-header"> <span>HTML Code</span> <div class="flex flex-col sm:flex-row gap-2"> <button type="button" class="copy-button" onclick="copyStaticCode('code-38', this)"> 📋 Copiar </button> <button type="button" class="copy-button bg-green-600 hover:bg-green-700 text-white" onclick="openCodeRunner('html', 'Exemplo prático de configuração de HTML', 38)"> 🚀 Experimente ao Vivo </button> </div> </div> <div class="code-block"> <pre><code id="code-38" class="language-html"><!DOCTYPE html> <html lang="pt"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content="Portfólio de Maria Silva - Desenvolvedora Web"> <title>Maria Silva | Portfólio - Desenvolvedora Web</title> </head> <body> <header> <h1>Maria Silva</h1> <nav> <a href="#sobre">Sobre</a> <a href="#projetos">Projetos</a> <a href="#contato">Contato</a> </nav> </header> <main> <section id="sobre"> <h2>Sobre Mim</h2> <p>Sou uma desenvolvedora web apaixonada com 5 anos de experiência.</p> </section> </main> </body> </html></code></pre> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>As melhores práticas incluem usar HTML semântico - elementos como header, nav, main e section que têm significado específico. A meta tag viewport é essencial para responsividade móvel. Sempre mantenha uma estrutura de documento adequada com metadados no head e conteúdo no body. Use elementos semânticos ao invés de div genérico quando possível. Os erros mais comuns incluem esquecer a declaração DOCTYPE, o que faz os navegadores entrarem em modo quirks. Não definir meta charset pode causar problemas de exibição de caracteres especiais. Aninhamento inadequado como colocar div dentro de p é inválido. Esquecer a tag title prejudica o SEO. Para debugging, use as ferramentas de desenvolvedor do navegador pressionando F12 para inspecionar a estrutura HTML. Use ferramentas de validação como W3C Markup Validator. Mantenha sempre indentação consistente para legibilidade. Adicione comentários para seções complexas. Teste em diferentes navegadores para garantir compatibilidade. Organize seu código logicamente, como decorar cômodos de uma casa de forma funcional e esteticamente agradável.</p> </div> <!-- Enhanced Reference Table --> <div class="table-responsive"> <div class="bg-white p-6"> <h3 class="text-xl font-semibold mb-4 text-gray-800">📊 Referência rápida de configuração de HTML</h3> <div class="overflow-x-auto"> <table class="w-full table-auto border-collapse"> <thead> <tr class="bg-gradient-to-r from-gray-50 to-gray-100"> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">Elemento</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">Descrição</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">Exemplo</th> </tr> </thead> <tbody> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><!DOCTYPE html></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Declara documento HTML5</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><!DOCTYPE html></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><html lang="pt"></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Elemento raiz com idioma</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><html lang="pt"></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta charset="UTF-8"></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Codificação de caracteres</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta charset="UTF-8"></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><title></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Título da página para aba do navegador</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><title>Meu Website</title></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta name="viewport"></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Meta tag para responsividade móvel</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta name="viewport" content="width=device-width, initial-scale=1.0"></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta name="description"></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Descrição da página para SEO</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta name="description" content="Descrição da página"></td> </tr> </tbody> </table> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>Neste tutorial você aprendeu a criar a estrutura adequada de um documento HTML. Os pontos-chave incluem que toda página HTML deve ter elementos DOCTYPE, html, head e body. As meta tags são importantes para SEO e acessibilidade. A estrutura HTML semântica cria código mais limpo e significativo. Esta base permitirá que você adicione estilização CSS onde definirá cores, fontes e layouts. Para interações JavaScript, uma estrutura HTML adequada também é fundamental. Os próximos tópicos a estudar incluem fundamentos de CSS, design responsivo e elementos de formulário. Para praticar, crie estruturas básicas para diferentes tipos de websites. Sempre use ferramentas de validação e verifique compatibilidade entre navegadores. Com prática regular, você poderá construir websites de qualidade profissional. Lembre-se que Html-Setup é como organizar uma biblioteca - uma boa organização inicial facilita encontrar e usar tudo mais tarde. Continue praticando e experimentando com diferentes estruturas para solidificar seu conhecimento.</p> </div> </div> <!-- Keywords Section --> <!-- Content Reporting Widget --> <!-- Content Reporting Widget --> <div class="content-report-container" id="report-container" data-content-type-id="10" data-object-id="2"> <div class="report-dropdown" id="report-dropdown"> <button type="button" class="report-button" id="report-button"> <span>👋</span> <span>Report Issue</span> </button> <div class="dropdown-menu" id="dropdown-menu"> <!-- Categories will be loaded dynamically by JavaScript --> </div> </div> </div> <!-- Load Required CSS and JS --> <link rel="stylesheet" href="/static/css/content-reporting.3f7dc51ec48b.css"> <script src="/static/js/content-reporting.37a7bd46d1db.js" defer></script> <!-- Enhanced Quiz Section --> <div class="mb-8"> <h2 class="text-2xl md:text-3xl font-bold mb-6 bg-clip-text"> 🧠 Teste Seu Conhecimento </h2> <!-- Modern Quiz Container - Direct Display --> <div id="quiz-container" class="quiz-modern-container"> <!-- Hidden CSRF Token --> <input type="hidden" name="csrfmiddlewaretoken" value="WYz1teUA2tD5cWU1Y4nZ6CK8MXmvvoxg7MaO1dBDy4wZz0YVmE4IU70v7SJwLvkZ"> <!-- Quiz Header with Progress --> <div class="quiz-header"> <div class="quiz-progress-wrapper"> <div class="quiz-progress-track"> <div id="quiz-progress-fill" class="quiz-progress-fill"></div> </div> <div class="quiz-progress-info"> <span id="progress-text" class="progress-current">Pronto para Começar</span> <span id="progress-stats" class="progress-stats"></span> </div> </div> <!-- Timer (if applicable) --> <div id="quiz-timer-wrapper" class="quiz-timer-wrapper" style="display: none;"> <div class="timer-icon">⏱️</div> <span id="timer-display" class="timer-display">10:00</span> </div> </div> <!-- Quiz Content Area --> <div class="quiz-content-area"> <!-- Quiz Introduction - Now Always Visible --> <div id="quiz-intro" class="quiz-intro-section"> <div class="quiz-intro-icon"> <div class="icon-circle"> <svg class="brain-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/> </svg> </div> </div> <h3 class="quiz-intro-title">Test Your Html-Setup Knowledge</h3> <p class="quiz-intro-subtitle">Challenge yourself with this interactive quiz and see how well you understand the topic</p> <!-- Quiz Stats Grid --> <div id="quiz-stats-grid" class="quiz-stats-grid"> <div class="quiz-stat-card"> <span class="stat-icon">❓</span> <div class="stat-value">3</div> <div class="stat-label">Perguntas</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">🎯</span> <div class="stat-value">70%</div> <div class="stat-label">Para Passar</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">♾️</span> <div class="stat-value">∞</div> <div class="stat-label">Tempo</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">🔄</span> <div class="stat-value">∞</div> <div class="stat-label">Tentativas</div> </div> </div> <!-- Quiz Instructions --> <div class="quiz-instructions"> <h4 class="instructions-title">📝 Instruções</h4> <ul class="instructions-list"> <li>Leia cada pergunta cuidadosamente</li> <li>Selecione a melhor resposta para cada pergunta</li> <li>Você pode refazer o quiz quantas vezes quiser</li> <li>Seu progresso será mostrado no topo</li> </ul> </div> <button id="start-quiz-btn" class="quiz-start-button" onclick="startQuiz(2)"> <span class="button-content"> <svg class="button-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1m-6 4h8"/> </svg> Iniciar Quiz </span> <div class="button-ripple"></div> </button> </div> <!-- Quiz Questions Section --> <div id="quiz-questions" class="quiz-questions-section" style="display: none;"> <!-- Question Header --> <div class="question-header"> <div class="question-meta"> <span id="question-number" class="question-counter">Pergunta 1</span> <div class="question-type-badge" id="question-type"> <span>📝</span> </div> </div> </div> <!-- Question Content --> <div id="current-question" class="question-content"> <!-- Question will be loaded here --> </div> <!-- Question Actions --> <div class="question-actions"> <button id="submit-answer" class="submit-answer-btn" onclick="submitAnswer()" disabled> <span class="btn-text">Enviar Resposta</span> <div class="btn-loader" style="display: none;"> <div class="loader-spinner"></div> </div> </button> </div> </div> <!-- Quiz Results Section --> <div id="quiz-results" class="quiz-results-section" style="display: none;"> <!-- Results will be populated here --> </div> <!-- Loading State --> <div id="quiz-loading" class="quiz-loading-section" style="display: none;"> <div class="loading-animation"> <div class="loading-spinner"></div> <div class="loading-dots"> <span></span> <span></span> <span></span> </div> </div> <p class="loading-text">Carregando seu quiz...</p> </div> </div> <!-- Error Display --> <div id="quiz-error" class="quiz-error-display" style="display: none;"> <div class="error-content"> <div class="error-icon">⚠️</div> <div class="error-message"></div> <button class="error-close" onclick="hideError()">✕</button> </div> </div> </div> <script> let currentQuiz = null; let currentQuestionIndex = 0; let selectedAnswer = null; let quizTimer = null; let timeRemaining = null; let currentQuestionData = null; let quizSessionData = null; // Store quiz session data for answer sheet function getCsrfToken() { let token = null; const quizContainer = document.getElementById('quiz-container'); if (quizContainer) { const tokenInput = quizContainer.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { token = tokenInput.value; } } if (!token) { const tokenInput = document.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { token = tokenInput.value; } } if (!token) { const cookieMatch = document.cookie.match(/csrftoken=([^;]+)/); if (cookieMatch) { token = cookieMatch[1]; } } return token; } function startQuiz(topicId) { console.log('Starting quiz for topic:', topicId); // Reset quiz session data quizSessionData = { questions: [], answers: {}, correctAnswers: {}, explanations: {}, startTime: new Date().toISOString() }; // Show loading showSection('quiz-loading'); updateProgress(0, 'Inicializando Quiz...', ''); const csrfToken = getCsrfToken(); if (!csrfToken) { console.error('CSRF token not found'); showError('Security token not found. Please refresh the page.'); showSection('quiz-intro'); return; } const formData = new FormData(); formData.append('csrfmiddlewaretoken', csrfToken); const url = `/pt/quiz/${topicId}/start/`; fetch(url, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { if (data.success) { currentQuiz = data.quiz; currentQuestionIndex = 0; // Setup timer if quiz has time limit if (currentQuiz.time_limit) { setupTimer(currentQuiz.time_limit); } // Show quiz questions section showSection('quiz-questions'); // Load first question loadQuestion(data.current_question, data.question_number, data.total_questions); } else { console.error('Quiz start failed:', data.error); showError(data.error || 'Failed to start quiz'); showSection('quiz-intro'); } }) .catch(error => { console.error('Fetch error:', error); showError('Falha ao iniciar o quiz. Por favor, tente novamente.'); showSection('quiz-intro'); }); } function loadQuestion(question, questionNumber, totalQuestions) { console.log('Loading question:', question); // Store current question data currentQuestionData = question; // Store question in session data quizSessionData.questions[questionNumber - 1] = question; // Update progress const progressPercent = (questionNumber / totalQuestions) * 100; updateProgress(progressPercent, `Pergunta ${questionNumber}`, `${questionNumber} de ${totalQuestions}`); // Update question number const questionNumberEl = document.getElementById('question-number'); if (questionNumberEl) { questionNumberEl.textContent = `Pergunta ${questionNumber}`; } // Update question type badge const questionTypeEl = document.getElementById('question-type'); if (questionTypeEl) { const typeIcons = { 'multiple_choice': '📝', 'true_false': '✅', 'fill_code': '💻' }; questionTypeEl.innerHTML = `<span>${typeIcons[question.type] || '📝'}</span>`; } // Reset selected answer selectedAnswer = null; const submitBtn = document.getElementById('submit-answer'); if (submitBtn) { submitBtn.disabled = true; submitBtn.querySelector('.btn-text').textContent = 'Enviar Resposta'; } // Generate question HTML let questionHTML = ` <div class="question-text">${escapeHtml(question.text)}</div> `; // Add code template if exists if (question.code_template && question.code_template.trim()) { questionHTML += ` <div class="code-block"> <pre><code>${escapeHtml(question.code_template)}</code></pre> </div> `; } // Add options questionHTML += '<div class="options-container">'; if (question.options && question.options.length > 0) { question.options.forEach((option, index) => { questionHTML += ` <div class="option-item" onclick="selectOption(${option.id}, this)"> <input type="radio" name="quiz-option" value="${option.id}" style="display: none;"> <div class="option-content"> <div class="option-indicator"></div> <div class="option-text">${escapeHtml(option.text)}</div> </div> </div> `; }); } else { questionHTML += '<p class="error-message">No options available for this question.</p>'; } questionHTML += '</div>'; // Insert question content with animation const questionContainer = document.getElementById('current-question'); if (questionContainer) { questionContainer.style.opacity = '0'; questionContainer.innerHTML = questionHTML; // Animate in setTimeout(() => { questionContainer.style.transition = 'opacity 0.3s ease'; questionContainer.style.opacity = '1'; }, 100); } } function selectOption(optionId, element) { console.log('Option selected:', optionId); selectedAnswer = optionId; // Update visual feedback document.querySelectorAll('.option-item').forEach(item => { item.classList.remove('selected'); }); element.classList.add('selected'); // Enable submit button const submitBtn = document.getElementById('submit-answer'); if (submitBtn) { submitBtn.disabled = false; } } function submitAnswer() { if (!selectedAnswer || !currentQuestionData) { console.log('No answer selected or no question data'); return; } console.log('Submitting answer:', selectedAnswer, 'for question:', currentQuestionData.id); // Store user answer in session data quizSessionData.answers[currentQuestionData.id] = { selectedOptionId: selectedAnswer, selectedOptionText: getSelectedOptionText(selectedAnswer) }; const submitBtn = document.getElementById('submit-answer'); if (!submitBtn) return; // Show loading state submitBtn.disabled = true; submitBtn.querySelector('.btn-text').style.opacity = '0'; submitBtn.querySelector('.btn-loader').style.display = 'block'; const csrfToken = getCsrfToken(); if (!csrfToken) { console.error('CSRF token not found for submit'); showError('Security token not found. Please refresh the page.'); resetSubmitButton(submitBtn); return; } const formData = new FormData(); formData.append('question_id', currentQuestionData.id); formData.append('selected_option', selectedAnswer); formData.append('csrfmiddlewaretoken', csrfToken); const url = `/pt/quiz/${currentQuiz.id}/submit/`; fetch(url, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { if (data.success) { if (data.completed) { // Quiz completed - load results loadQuizResults(data.redirect_url); } else { // Load next question setTimeout(() => { loadQuestion(data.current_question, data.question_number, data.total_questions); resetSubmitButton(submitBtn); }, 500); } } else { console.error('Submit failed:', data.error); showError(data.error || 'Failed to submit answer'); resetSubmitButton(submitBtn); } }) .catch(error => { console.error('Submit fetch error:', error); showError('Falha ao enviar resposta. Por favor, tente novamente.'); resetSubmitButton(submitBtn); }); } function getSelectedOptionText(optionId) { if (!currentQuestionData || !currentQuestionData.options) return ''; const option = currentQuestionData.options.find(opt => opt.id == optionId); return option ? option.text : ''; } function loadQuizResults(resultUrl) { console.log('Loading results from:', resultUrl); // Show loading while fetching results showSection('quiz-loading'); updateProgress(100, 'Calculando Resultados...', 'Por favor, aguarde'); fetch(resultUrl, { headers: { 'HX-Request': 'true' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.text(); }) .then(html => { // Parse the results and extract detailed information const tempDiv = document.createElement('div'); tempDiv.innerHTML = html; // Extract score data from the response const scoreElement = tempDiv.querySelector('.score-percentage') || tempDiv.querySelector('[data-score]'); let scoreValue = 0; if (scoreElement) { const scoreText = scoreElement.textContent || scoreElement.getAttribute('data-score') || '0'; scoreValue = parseInt(scoreText.replace('%', '')) || 0; } const correctElement = tempDiv.querySelector('.correct-answers') || tempDiv.querySelector('[data-correct]'); let correctAnswers = 0; if (correctElement) { const correctText = correctElement.textContent || correctElement.getAttribute('data-correct') || '0'; correctAnswers = parseInt(correctText) || 0; } const totalElement = tempDiv.querySelector('.total-questions') || tempDiv.querySelector('[data-total]'); let totalQuestions = currentQuiz.total_questions || 0; if (totalElement) { const totalText = totalElement.textContent || totalElement.getAttribute('data-total') || '0'; totalQuestions = parseInt(totalText) || totalQuestions; } // Extract detailed question results extractQuestionResults(tempDiv); // Save quiz result for authenticated users if (window.siteConfig && window.siteConfig.isAuthenticated && window.saveQuizResult) { const quizData = { quiz_id: currentQuiz.id, score: correctAnswers, total_questions: totalQuestions, correct_answers: correctAnswers, time_spent: calculateQuizTime(), answers: quizSessionData, passing_score: currentQuiz.passing_score || 70 }; window.saveQuizResult(quizData).catch(error => { console.error('Failed to save quiz result:', error); }); } displayResults(scoreValue, correctAnswers, totalQuestions); // Stop timer if running if (quizTimer) { clearInterval(quizTimer); hideTimer(); } }) .catch(error => { console.error('Results fetch error:', error); showError('Falha ao carregar resultados. Por favor, atualize a página.'); showSection('quiz-questions'); }); } function calculateQuizTime() { // Calculate time spent from quiz session start if (quizSessionData && quizSessionData.startTime) { const startTime = new Date(quizSessionData.startTime); const endTime = new Date(); return Math.floor((endTime - startTime) / 1000); // Return seconds } return 0; } function extractQuestionResults(resultContainer) { // Extract detailed results from the Django-generated HTML const questionContainers = resultContainer.querySelectorAll('.border-b, .border'); questionContainers.forEach((container, index) => { try { // Extract question text const questionTextEl = container.querySelector('p.text-gray-700, .text-gray-700'); const questionText = questionTextEl ? questionTextEl.textContent.trim() : `Question ${index + 1}`; // Extract correct/incorrect status const correctSpan = container.querySelector('.bg-green-100'); const incorrectSpan = container.querySelector('.bg-red-100'); const isCorrect = correctSpan !== null; // Extract user's answer let userAnswer = ''; const userAnswerSpans = container.querySelectorAll('.text-red-600, .text-green-600'); for (let span of userAnswerSpans) { const text = span.textContent; if (text.includes('Your answer:')) { userAnswer = text.replace('Your answer:', '').trim(); break; } } // Extract correct answer let correctAnswer = ''; const greenSpans = container.querySelectorAll('.text-green-600'); for (let span of greenSpans) { const text = span.textContent.trim(); const parentText = span.parentElement ? span.parentElement.textContent : ''; // Check if this span contains "Correct answer:" in its parent context if (parentText.includes('Correct answer:') && !text.includes('Your answer:')) { // Extract only the answer part after "Correct answer:" const parts = parentText.split('Correct answer:'); if (parts.length > 1) { correctAnswer = parts[1].split('Explanation:')[0].trim(); break; } } } // Fallback: if still empty, use user answer for correct questions if (!correctAnswer && isCorrect) { correctAnswer = userAnswer; } // Extract explanation let explanation = ''; const explanationEl = container.querySelector('.bg-blue-50 p'); if (explanationEl) { explanation = explanationEl.textContent.replace('Explanation:', '').trim(); } // Store in session data const questionId = quizSessionData.questions[index] ? quizSessionData.questions[index].id : index + 1; quizSessionData.correctAnswers[questionId] = { isCorrect: isCorrect, correctAnswer: correctAnswer, explanation: explanation, questionText: questionText }; } catch (error) { console.error('Error extracting question result:', error); } }); } function displayResults(scoreValue, correctAnswers, totalQuestions) { const passed = scoreValue >= (currentQuiz.passing_score || 70); const resultsSection = document.getElementById('quiz-results'); if (!resultsSection) return; resultsSection.innerHTML = ` <div class="result-header"> <div class="result-status-icon ${passed ? 'passed' : 'failed'}"> ${passed ? '🎉' : '📚'} </div> <h3 class="result-title"> ${passed ? 'Parabéns!' : 'Continue Aprendendo!'} </h3> <p class="result-subtitle"> ${passed ? 'Você passou no quiz!' : 'Você pode fazer melhor. Tente novamente!'} </p> </div> <div class="score-display"> <div class="score-percentage ${passed ? 'passed' : 'failed'}">${scoreValue}%</div> <div class="score-details"> ${correctAnswers} de ${totalQuestions} corretas </div> <div class="score-bar"> <div class="score-fill" style="width: 0%"></div> </div> <div style="margin-top: 1rem; font-size: 0.875rem; opacity: 0.8;"> Nota para passar: ${currentQuiz.passing_score || 70}% </div> </div> <div class="result-actions"> <button class="result-btn primary" onclick="retakeQuiz()"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/> </svg> Refazer Quiz </button> <button class="result-btn secondary" onclick="toggleAnswerSheet()" id="view-answers-btn"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> </svg> Ver Respostas </button> <button class="result-btn secondary" onclick="closeQuiz()"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/> </svg> Fechar </button> </div> <!-- Answer Sheet Section --> <div id="answer-sheet" class="answer-sheet-section" style="display: none;"> <div class="answer-sheet-header"> <h4>📋 Folha de Respostas</h4> <button class="close-answer-sheet" onclick="toggleAnswerSheet()">✕</button> </div> <div id="answer-sheet-content" class="answer-sheet-content"> Carregando respostas... </div> </div> `; // Show results section showSection('quiz-results'); updateProgress(100, 'Quiz Concluído!', `${scoreValue}% Pontuação`); // Animate score bar setTimeout(() => { const scoreFill = resultsSection.querySelector('.score-fill'); if (scoreFill) { scoreFill.style.width = `${scoreValue}%`; } }, 500); } // Answer sheet functions function toggleAnswerSheet() { const answerSheet = document.getElementById('answer-sheet'); const btn = document.getElementById('view-answers-btn'); if (answerSheet.style.display === 'none' || answerSheet.style.display === '') { answerSheet.style.display = 'block'; loadAnswerSheet(); btn.innerHTML = ` <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/> </svg> Ocultar Respostas `; } else { answerSheet.style.display = 'none'; btn.innerHTML = ` <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> </svg> Ver Respostas `; } } function loadAnswerSheet() { const answerSheetContent = document.getElementById('answer-sheet-content'); if (!answerSheetContent || !quizSessionData) return; let correctCount = 0; let incorrectCount = 0; let answerSheetHTML = ` <div class="answer-summary"> <div class="summary-stat total"> <div class="number">${currentQuiz.total_questions || 0}</div> <div class="label">Total de Perguntas</div> </div> <div class="summary-stat correct"> <div class="number" id="correct-count">0</div> <div class="label">Correto</div> </div> <div class="summary-stat incorrect"> <div class="number" id="incorrect-count">0</div> <div class="label">Incorreto</div> </div> </div> <div class="answer-grid"> `; // Generate answer sheet for each question quizSessionData.questions.forEach((question, index) => { if (!question) return; const questionId = question.id; const userAnswer = quizSessionData.answers[questionId]; const correctInfo = quizSessionData.correctAnswers[questionId]; if (!userAnswer || !correctInfo) return; const isCorrect = correctInfo.isCorrect; if (isCorrect) { correctCount++; } else { incorrectCount++; } answerSheetHTML += ` <div class="answer-item ${isCorrect ? 'correct' : 'incorrect'}"> <div class="question-number">Q${index + 1}</div> <div class="question-details"> <div class="question-text">${escapeHtml(correctInfo.questionText || question.text)}</div> <div class="answer-comparison"> <div class="user-answer"> <span class="label">Your Answer:</span> <span class="value ${isCorrect ? 'correct' : 'incorrect'}">${escapeHtml(userAnswer.selectedOptionText)}</span> </div> ${!isCorrect ? ` <div class="correct-answer"> <span class="label">Correct Answer:</span> <span class="value correct">${escapeHtml(correctInfo.correctAnswer)}</span> </div> ` : ''} ${correctInfo.explanation ? ` <div class="explanation"> <span class="label">Explicação:</span> <span class="explanation-text">${escapeHtml(correctInfo.explanation)}</span> </div> ` : ''} </div> </div> <div class="result-icon"> ${isCorrect ? '✅' : '❌'} </div> </div> `; }); answerSheetHTML += '</div>'; answerSheetContent.innerHTML = answerSheetHTML; // Update summary counts document.getElementById('correct-count').textContent = correctCount; document.getElementById('incorrect-count').textContent = incorrectCount; } function retakeQuiz() { // Reset quiz state currentQuiz = null; currentQuestionIndex = 0; selectedAnswer = null; currentQuestionData = null; quizSessionData = null; if (quizTimer) { clearInterval(quizTimer); hideTimer(); } // Show intro section showSection('quiz-intro'); updateProgress(0, 'Pronto para Começar', ''); } function closeQuiz() { // Just reset and hide for now since we're directly displaying retakeQuiz(); } function showSection(sectionId) { const sections = ['quiz-intro', 'quiz-questions', 'quiz-results', 'quiz-loading']; sections.forEach(id => { const element = document.getElementById(id); if (element) { element.style.display = id === sectionId ? 'block' : 'none'; } }); } function updateProgress(percentage, currentText, statsText) { const progressFill = document.getElementById('quiz-progress-fill'); const progressText = document.getElementById('progress-text'); const progressStats = document.getElementById('progress-stats'); if (progressFill) { progressFill.style.width = `${percentage}%`; } if (progressText) { progressText.textContent = currentText; } if (progressStats) { progressStats.textContent = statsText; } } function setupTimer(timeLimit) { const timerWrapper = document.getElementById('quiz-timer-wrapper'); const timerDisplay = document.getElementById('timer-display'); if (!timerWrapper || !timerDisplay) return; timeRemaining = timeLimit * 60; // Convert to seconds timerWrapper.style.display = 'flex'; quizTimer = setInterval(() => { const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; timerDisplay.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; // Warning when time is running out if (timeRemaining <= 60) { timerWrapper.style.color = '#ef4444'; timerWrapper.style.animation = 'pulse 1s infinite'; } if (timeRemaining <= 0) { clearInterval(quizTimer); if (selectedAnswer) { submitAnswer(); } else { showError('O tempo acabou! O quiz será enviado automaticamente.'); } } timeRemaining--; }, 1000); } function hideTimer() { const timerWrapper = document.getElementById('quiz-timer-wrapper'); if (timerWrapper) { timerWrapper.style.display = 'none'; } } function resetSubmitButton(button) { if (!button) return; button.disabled = false; button.querySelector('.btn-text').style.opacity = '1'; button.querySelector('.btn-loader').style.display = 'none'; } function showError(message) { console.log('Showing error:', message); const errorDisplay = document.getElementById('quiz-error'); if (!errorDisplay) return; const errorMessage = errorDisplay.querySelector('.error-message'); if (errorMessage) { errorMessage.textContent = message; } errorDisplay.style.display = 'block'; // Auto-hide after 5 seconds setTimeout(() => { hideError(); }, 5000); } function hideError() { const errorDisplay = document.getElementById('quiz-error'); if (errorDisplay) { errorDisplay.style.display = 'none'; } } function escapeHtml(unsafe) { if (typeof unsafe !== 'string') { return unsafe; } return unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // Initialize quiz when page loads document.addEventListener('DOMContentLoaded', function() { // Quiz is now directly visible, no need for showQuiz() function console.log('Quiz components loaded'); }); // HTMX after-swap event document.body.addEventListener('htmx:afterSwap', function() { // Reinitialize quiz if it exists on the swapped content console.log('Quiz components reloaded after HTMX swap'); }); </script> </div> <!-- Enhanced Navigation --> <div class="topic-navigation"> <div class="nav-links"> <div></div> <div class="nav-center"> <div class="text-sm font-semibold">Tópico 1 de 1</div> <div class="text-xs mt-1 opacity-75">Html Tutorial</div> </div> <div></div> </div> </div> </div> <script> const sessionKey = `code_session_${codeExampleId}`; // Smart Link Click Tracking document.addEventListener('click', function(event) { const smartLink = event.target.closest('.smart-link'); if (smartLink) { const keywordId = smartLink.getAttribute('data-keyword-id'); if (keywordId) { // Track click asynchronously fetch('/pt/api/smart-link-click/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': 'WYz1teUA2tD5cWU1Y4nZ6CK8MXmvvoxg7MaO1dBDy4wZz0YVmE4IU70v7SJwLvkZ' }, body: JSON.stringify({ keyword_id: keywordId, source_content_type: 'topic', source_content_id: 2, user_agent: navigator.userAgent }) }).catch(error => { console.debug('Smart link tracking failed:', error); }); } } }); function openCodeRunner(language, title, codeExampleId) { const codeElement = document.getElementById('code-' + codeExampleId); const code = codeElement.textContent; const formData = new FormData(); formData.append('language', language); formData.append('title', title); formData.append('code', code); formData.append('source_example_id', codeExampleId); formData.append('csrfmiddlewaretoken', 'WYz1teUA2tD5cWU1Y4nZ6CK8MXmvvoxg7MaO1dBDy4wZz0YVmE4IU70v7SJwLvkZ'); fetch('/pt/create-code-session/', { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => response.json()) .then(data => { if (data.success) { window.open(data.url, '_blank'); } else { console.error('Error creating session:', data.error); window.open('/pt/try-it/' + language + '/', '_blank'); } }) .catch(error => { console.error('Error:', error); window.open('/pt/try-it/' + language + '/', '_blank'); }); } document.body.addEventListener('htmx:afterSwap', function() { window.scrollTo({ top: 0, behavior: 'smooth' }); if (typeof Prism !== 'undefined') { Prism.highlightAll(); } if (typeof populateQuizStats === 'function') { populateQuizStats(); } if (window.mobileMenu && window.mobileMenu.isMenuOpen && window.mobileMenu.isMenuOpen()) { window.mobileMenu.forceClose(); } initializeEnhancedFeatures(); }); function initializeEnhancedFeatures() { // Initialize topic tracking for authenticated users if (window.siteConfig && window.siteConfig.isAuthenticated) { initializeTopicTracking(); } document.querySelectorAll('.nav-link, .custom-sidebar-item').forEach(link => { link.addEventListener('click', function() { if (this.hasAttribute('hx-get')) { this.classList.add('loading'); setTimeout(() => { this.classList.remove('loading'); }, 1000); } }); }); document.querySelectorAll('.code-block pre').forEach(pre => { const code = pre.querySelector('code'); if (code && code.textContent.split('\n').length > 3) { pre.classList.add('line-numbers'); } }); } function initializeTopicTracking() { // Track topic view for authenticated users const topicId = getTopicIdFromCurrentUrl(); const categorySlug = getCategorySlugFromCurrentUrl(); if (topicId && categorySlug) { // Track initial view trackTopicView({ topic_id: topicId, category_slug: categorySlug }); // Track scroll percentage let maxScrollPercentage = 0; let timeSpent = 0; let startTime = Date.now(); window.addEventListener('scroll', throttle(function() { const scrollPercentage = calculateScrollPercentage(); if (scrollPercentage > maxScrollPercentage) { maxScrollPercentage = scrollPercentage; } }, 1000)); // Track time spent setInterval(() => { if (!document.hidden) { timeSpent += 5; // Add 5 seconds } }, 5000); // Send final data on page unload window.addEventListener('beforeunload', function() { if (maxScrollPercentage > 0 || timeSpent > 0) { trackTopicView({ topic_id: topicId, category_slug: categorySlug, scroll_percentage: maxScrollPercentage, time_spent: timeSpent, completed: maxScrollPercentage >= 80 // Consider 80% as completed }); } }); } } function getTopicIdFromCurrentUrl() { const pathParts = window.location.pathname.split('/').filter(Boolean); const languages = ['en', 'fa', 'ar', 'zh', 'hi', 'fr', 'de', 'ru', 'tr', 'pt', 'es']; let startIndex = 0; if (languages.includes(pathParts[0])) { startIndex = 1; } if (pathParts.length >= startIndex + 2) { return pathParts[startIndex + 1]; // Return topic slug } return null; } function getCategorySlugFromCurrentUrl() { const pathParts = window.location.pathname.split('/').filter(Boolean); const languages = ['en', 'fa', 'ar', 'zh', 'hi', 'fr', 'de', 'ru', 'tr', 'pt', 'es']; let startIndex = 0; if (languages.includes(pathParts[0])) { startIndex = 1; } if (pathParts.length >= startIndex + 1) { return pathParts[startIndex]; // Return category slug } return null; } function trackTopicView(data) { if (!window.siteConfig || !window.siteConfig.isAuthenticated) { return Promise.resolve(); } return fetch('/account/ajax/track-topic-view/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': window.siteConfig.csrfToken || getCsrfToken() }, body: JSON.stringify(data) }).catch(error => { console.debug('Topic view tracking failed:', error); }); } function calculateScrollPercentage() { const scrollTop = window.pageYOffset; const docHeight = document.documentElement.scrollHeight - window.innerHeight; return Math.min(100, Math.max(0, (scrollTop / docHeight) * 100)); } function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } function getCsrfToken() { const tokenInput = document.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { return tokenInput.value; } const cookieMatch = document.cookie.match(/csrftoken=([^;]+)/); return cookieMatch ? cookieMatch[1] : null; } document.addEventListener('DOMContentLoaded', function() { initializeEnhancedFeatures(); if (typeof Prism !== 'undefined') { Prism.highlightAll(); } document.body.addEventListener('htmx:beforeRequest', function(event) { const target = event.target; if (target.classList.contains('nav-link') || target.classList.contains('custom-sidebar-item')) { target.style.opacity = '0.7'; target.style.pointerEvents = 'none'; } }); document.body.addEventListener('htmx:afterRequest', function(event) { const target = event.target; if (target.classList.contains('nav-link') || target.classList.contains('custom-sidebar-item')) { target.style.opacity = '1'; target.style.pointerEvents = 'auto'; } }); }); window.addEventListener('error', function(event) { console.error('JavaScript error:', event.error); if (window.innerWidth <= 768) { const errorDiv = document.createElement('div'); errorDiv.className = 'fixed top-4 left-4 right-4 bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg z-50 shadow-lg'; errorDiv.innerHTML = ` <div class="flex items-center justify-between"> <div class="flex items-center"> <span class="text-red-500 mr-2">⚠️</span> <span><strong>Erro:</strong> Algo deu errado. Por favor, atualize a página.</span> </div> <button onclick="this.parentElement.parentElement.remove()" class="text-red-500 hover:text-red-700 ml-2">✕</button> </div> `; document.body.appendChild(errorDiv); setTimeout(() => { if (errorDiv.parentElement) { errorDiv.remove(); } }, 5000); } }); const style = document.createElement('style'); style.textContent = ` @keyframes ripple { to { transform: scale(4); opacity: 0; } } .copy-button { position: relative; overflow: hidden; } `; document.head.appendChild(style); </script> </main> </div> <!-- Coming Soon Course Modal --> <div id="coming-soon-modal" class="coming-soon-modal hidden"> <div class="coming-soon-backdrop"></div> <div class="coming-soon-content"> <!-- Modal Header --> <div class="coming-soon-header"> <div class="flex items-center space-x-3 "> <div class="coming-soon-icon"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path> </svg> </div> <h3 class="coming-soon-title"> 🚧 Curso em Breve </h3> </div> <button id="close-coming-soon-modal" class="coming-soon-close"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> <!-- Modal Body --> <div class="coming-soon-body"> <div class="course-info-section"> <h4 id="course-name" class="course-name">Course Name</h4> <div class="course-status"> <span class="status-badge">Em Desenvolvimento</span> </div> <p class="course-description"> Este curso abrangente está atualmente sendo desenvolvido com os mais recentes padrões da indústria e melhores práticas. Nossa equipe especializada está criando conteúdo de alta qualidade para garantir que você tenha a melhor experiência de aprendizado. </p> </div> <div class="estimated-release"> <div class="flex items-center space-x-2 "> <svg class="w-4 h-4 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path> </svg> <span class="text-sm text-gray-600 dark:text-gray-400"> Lançamento Estimado: 2-4 semanas </span> </div> </div> <!-- Notify Me Section --> <div class="notify-section"> <h5 class="notify-title">Ser Notificado Quando Disponível</h5> <form id="notify-form" class="notify-form"> <div class="email-input-group"> <input type="email" id="notify-email" name="email" placeholder="Digite seu endereço de e-mail" class="notify-email-input" required> <button type="submit" class="notify-submit-btn"> <span class="btn-text">Me Notificar</span> <svg class="btn-icon w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path> </svg> </button> </div> <p class="email-disclaimer"> Enviaremos uma única notificação quando este curso estiver disponível. Sem spam, prometemos! </p> </form> </div> <!-- Related Courses --> <div class="related-courses"> <h5 class="related-title">Disponível Agora</h5> <div class="related-links"> <a href="/pt/html/" class="related-link"> <i class="fab fa-html5 text-orange-500"></i> <span>Tutorial HTML</span> </a> <a href="/pt/css/" class="related-link"> <i class="fab fa-css3-alt text-blue-500"></i> <span>Guia Completo CSS</span> </a> <a href="/pt/javascript/" class="related-link"> <i class="fab fa-js-square text-yellow-500"></i> <span>Fundamentos JavaScript</span> </a> </div> </div> </div> </div> </div> <!-- Coming Soon Modal --> <div id="coming-soon-modal" class="coming-soon-modal"> <div class="coming-soon-backdrop"></div> <div class="coming-soon-content"> <div class="coming-soon-header"> <div class="coming-soon-icon"> <i class="fas fa-clock"></i> </div> <h3 class="coming-soon-title">Coming Soon</h3> <button class="coming-soon-close" id="close-coming-soon"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> <div class="coming-soon-body"> <div class="course-info-section"> <h4 class="course-name" id="modal-course-name">Course Name</h4> <div class="course-status"> <span class="status-badge"> <i class="fas fa-hammer mr-1"></i> Em Desenvolvimento </span> </div> <p class="course-description" id="modal-course-description"> This course is currently under development. We're working hard to bring you high-quality content. </p> </div> <div class="estimated-release"> <div class="flex items-center space-x-2 mb-2"> <i class="fas fa-calendar-alt text-blue-600"></i> <span class="font-semibold text-blue-600">Estimated Release</span> </div> <p class="text-sm text-blue-700" id="modal-release-date">Q2 2025</p> </div> </div> </div> </div> <!-- Include Footer --> <footer class="bg-gray-900 text-white"> <div class=""> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 grid grid-cols-2 md:grid-cols-6 gap-8"> <!-- Frontend Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Frontend</h3> <ul class="space-y-1"> <li><a href="/pt/html/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">HTML Tutorial</a></li> <li><a href="/pt/css/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">CSS Complete Guide</a></li> <li><a href="/pt/javascript/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">JavaScript Fundamentals</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="react">React Development</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="vue">Vue.js Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="angular">Angular Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="typescript">TypeScript Guide</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="bootstrap">Bootstrap Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="tailwind">Tailwind CSS</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sass">Sass & SCSS</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="jquery">jQuery Library</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="webcomponents">Web Components</a></li> </ul> </div> <!-- Backend Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Backend</h3> <ul class="space-y-1"> <li><a href="/pt/python/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Python Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="django">Django Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="flask">Flask Framework</a></li> <li><a href="/pt/nodejs/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Node.js Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="express">Express.js Framework</a></li> <li><a href="/pt/php/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">PHP Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="laravel">Laravel Framework</a></li> <li><a href="/pt/java/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Java Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="spring">Spring Boot</a></li> <li><a href="/pt/c-sharp/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C# Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="dotnet">ASP.NET Core</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ruby">Ruby on Rails</a></li> </ul> </div> <!-- Database Programming --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Banco de Dados</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sql">SQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mysql">MySQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="postgresql">PostgreSQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mongodb">MongoDB Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="redis">Redis Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sqlite">SQLite Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="database-design">Database Design</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sqlserver">SQL Server Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="oracle">Oracle Database</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mariadb">MariaDB Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="firebase">Firebase Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="elasticsearch">Elasticsearch Tutorial</a></li> </ul> </div> <!-- Mobile Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Mobile</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="react-native">React Native Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="flutter">Flutter Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="dart">Dart Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="swift">iOS Swift Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="swiftui">SwiftUI Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="kotlin">Android Kotlin</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="android-java">Android Java</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="xamarin">Xamarin Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ionic">Ionic Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="phonegap">PhoneGap Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="pwa">Progressive Web Apps</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mobile-ui">Mobile UI Design</a></li> </ul> </div> <!-- Advanced Topics --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Avançado</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="data-structures">Data Structures</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="algorithms">Algorithms Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="oop">Object Oriented Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="design-patterns">Design Patterns</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="api-development">API Development</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="rest-api">REST API Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="graphql">GraphQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="microservices">Microservices</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="machine-learning">Machine Learning</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ai">Artificial Intelligence</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="blockchain">Blockchain Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="game-dev">Game Development</a></li> </ul> </div> <!-- Programming Languages --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Linguagens de Programação</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="c">C Programming</a></li> <li><a href="/pt/c-plus-plus/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C++ Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="go">Go Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="rust">Rust Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ruby">Ruby Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="scala">Scala Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="kotlin">Kotlin Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="r">R Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="matlab">MATLAB Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="perl">Perl Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="assembly">Assembly Language</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="lua">Lua Programming</a></li> </ul> </div> </div> <!-- Brand Section --> <div class="border-t border-gray-800 mt-12 pt-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row justify-between items-center"> <div class="flex flex-col items-center text-center mb-6 md:mb-0"> <img src="/static/images/logo.6fecbe0a2cbf.png" alt="Mrebi Logo" class="h-12 w-auto object-contain mb-2"> <div> <p class="text-sm text-gray-400 mt-1">Aprenda, Pratique, Domine</p> </div> </div> <div class="text-center md:text-right"> <div class="flex flex-wrap justify-center md:justify-end gap-6 mb-4"> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Sobre Nós</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Contato</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Política de Privacidade</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Termos de Serviço</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Blog</a> </div> <div class="text-gray-400"> <p class="text-sm mb-2"> Domine a programação com tutoriais interativos e prática hands-on </p> <p class="text-xs"> © 2025 Mrebi. Todos os direitos reservados. </p> </div> </div> </div> <!-- Social Links --> <div class="mt-8 pt-6 border-t border-gray-800 text-center"> <div class="flex justify-center gap-6 flex-wrap"> <a href="https://www.linkedin.com/in/mr-ebi/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="LinkedIn" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/> </svg> </a> <a href="https://www.youtube.com/@mrebi-com" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="YouTube" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/> </svg> </a> <a href="https://www.instagram.com/mrebicom/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="Instagram" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.148 3.227-1.691 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.148-4.771-1.691-4.919-4.919-.058-1.265-.069-1.645-.069-4.849 0-3.205.012-3.584.069-4.849.149-3.227 1.691-4.771 4.919-4.919 1.266-.058 1.644-.07 4.849-.07zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.667.072 4.947.2 4.36 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.667-.014 4.947-.072 4.358-.2 6.78-2.618 6.98-6.98.059-1.281.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.2-4.36-2.618-6.78-6.98-6.98-1.281-.058-1.689-.072-4.948-.072zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/> </svg> </a> <a href="#" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="TikTok" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 0 1-5.2 1.74 2.89 2.89 0 0 1 2.31-4.55 2.89 2.89 0 0 1 .88.13V9.65a6.34 6.34 0 0 0-1-.09A6.34 6.34 0 0 0 3 16a6.34 6.34 0 0 0 11.13 4.13 6.34 6.34 0 0 0 1.81-4.55V8.52a8.28 8.28 0 0 0 4.85 1.56V6.69z"/> </svg> </a> <a href="https://x.com/mrebicom" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="X" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/> </svg> </a> <a href="https://www.facebook.com/mrebicom/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="Facebook" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M22.675 0H1.325C.593 0 0 .593 0 1.325v21.351C0 23.407.593 24 1.325 24H12.82v-9.294H9.692v-3.622h3.128V8.413c0-3.1 1.893-4.788 4.659-4.788 1.325 0 2.463.099 2.795.143v3.24l-1.918.001c-1.504 0-1.795.715-1.795 1.763v2.313h3.587l-.467 3.622h-3.12V24h6.116c.73 0 1.323-.593 1.323-1.325V1.325C24 .593 23.407 0 22.675 0z"/> </svg> </a> </div> <p class="text-xs text-gray-500 mt-4"> Join our community and start your programming journey today! </p> </div> </div> </div> </footer> <script> // Handle Coming Soon links in footer document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.coming-soon-link').forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); const courseName = this.getAttribute('data-course') || 'default'; if (typeof window.showComingSoonModal === 'function') { window.showComingSoonModal(courseName); } }); }); }); </script> <!-- Prism.js for Syntax Highlighting --> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-html.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-css.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-python.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-php.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-sql.min.js"></script> <!-- Theme Switcher --> <script src="/static/js/theme-switcher.6107c7dde403.js"></script> <!-- Custom JavaScript --> <script src="/static/js/code-editor.744452e3251a.js"></script> <script src="/static/js/code-runner.0ff7847dbd6e.js"></script> <script src="/static/js/mobile-menu.b685f211e4ca.js"></script> <script> // Mobile menu toggle function toggleMobileMenu() { const menu = document.getElementById('mobile-menu'); menu.classList.toggle('hidden'); } // Enhanced language switcher function changeLanguage(languageCode) { const changeUrl = `/pt/change-language/?language=${languageCode}`; if (typeof htmx !== 'undefined') { htmx.ajax('GET', changeUrl, { headers: { 'HX-Request': 'true' } }).then(function(response) { if (response.redirect) { window.location.href = response.redirect; } }); } else { window.location.href = changeUrl; } } // HTMX event listeners document.body.addEventListener('htmx:beforeRequest', function(evt) { document.getElementById('loading-indicator').style.display = 'block'; }); document.body.addEventListener('htmx:afterRequest', function(evt) { document.getElementById('loading-indicator').style.display = 'none'; }); document.body.addEventListener('htmx:afterSwap', function(evt) { // Reinitialize Prism.js highlighting if (typeof Prism !== 'undefined') { Prism.highlightAll(); } // Close mobile menu const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenu && !mobileMenu.classList.contains('hidden')) { mobileMenu.classList.add('hidden'); } // Scroll to top for new content window.scrollTo({ top: 0, behavior: 'smooth' }); }); // Smooth scroll for anchor links document.addEventListener('click', function(e) { if (e.target.matches('a[href^="#"]')) { const href = e.target.getAttribute('href'); // Skip if just # if (href === '#') { return; } e.preventDefault(); const target = document.querySelector(href); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } }); // Coming Soon Modal functionality function initComingSoonModal() { const modal = document.getElementById('coming-soon-modal'); const closeBtn = document.getElementById('close-coming-soon-modal'); const backdrop = modal.querySelector('.coming-soon-backdrop'); const notifyForm = document.getElementById('notify-form'); // Course mapping for dynamic content const courseInfo = { 'python': { name: 'Python Programming', description: 'Aprenda Python desde o básico até conceitos avançados incluindo desenvolvimento web, ciência de dados e automação.' }, 'java': { name: 'Java Programming', description: 'Domine a programação Java para aplicações empresariais, desenvolvimento Android e programação do lado do servidor.' }, 'nodejs': { name: 'Node.js Development', description: 'Construa aplicações escaláveis do lado do servidor com Node.js e framework Express.' }, 'react': { name: 'React Development', description: 'Crie interfaces de usuário modernas com React, hooks e gerenciamento de estado.' }, 'typescript': { name: 'TypeScript Guide', description: 'Escreva JavaScript mais seguro com verificação de tipo estática e recursos modernos da linguagem.' }, 'vue': { name: 'Vue.js Framework', description: 'Construa aplicações web progressivas com Vue.js e seu ecossistema.' }, 'angular': { name: 'Angular Framework', description: 'Desenvolva aplicações de página única de nível empresarial com Angular.' }, 'tailwind': { name: 'Tailwind CSS', description: 'Crie designs modernos rapidamente com framework CSS utility-first.' }, 'django': { name: 'Django Framework', description: 'Construa aplicações web robustas com o framework Django baterias incluídas.' }, 'express': { name: 'Express.js Framework', description: 'Crie aplicações web rápidas e minimalistas com Express.js.' }, 'spring': { name: 'Spring Boot', description: 'Desenvolva aplicações Java empresariais com framework Spring Boot.' }, 'php': { name: 'PHP Programming', description: 'Aprenda scripting do lado do servidor com PHP para desenvolvimento web dinâmico.' }, 'laravel': { name: 'Laravel Framework', description: 'Construa aplicações web elegantes com a sintaxe expressiva do Laravel.' }, 'sql': { name: 'SQL Tutorial', description: 'Domine consultas de banco de dados e manipulação de dados com SQL.' }, 'mysql': { name: 'MySQL Tutorial', description: 'Aprenda o banco de dados relacional de código aberto mais popular do mundo.' }, 'postgresql': { name: 'PostgreSQL Tutorial', description: 'Domine recursos avançados do sistema de banco de dados PostgreSQL.' }, 'mongodb': { name: 'MongoDB Tutorial', description: 'Trabalhe com banco de dados de documentos NoSQL flexível para aplicações modernas.' }, 'flutter': { name: 'Flutter Tutorial', description: 'Construa aplicativos móveis nativos bonitos para iOS e Android com uma única base de código.' }, 'react-native': { name: 'React Native Tutorial', description: 'Crie aplicações móveis nativas usando React e JavaScript.' }, 'swift': { name: 'iOS Swift Tutorial', description: 'Desenvolva aplicações iOS nativas com a linguagem de programação Swift.' }, 'kotlin': { name: 'Android Kotlin', description: 'Construa aplicações Android modernas com a linguagem de programação Kotlin.' }, 'docker': { name: 'Docker', description: 'Containerize aplicações para implantação consistente em diferentes ambientes.' }, 'git': { name: 'Git', description: 'Domine controle de versão e fluxos de trabalho colaborativos com Git.' }, 'aws': { name: 'AWS', description: 'Implante e escale aplicações na plataforma de nuvem Amazon Web Services.' }, 'kubernetes': { name: 'Kubernetes', description: 'Orquestre aplicações containerizadas em escala com Kubernetes.' }, 'go': { name: 'Go Programming', description: 'Construa software rápido, confiável e eficiente com a linguagem Go.' }, 'rust': { name: 'Rust Programming', description: 'Aprenda programação de sistemas com segurança de memória e abstrações de custo zero.' }, 'csharp': { name: 'C# Programming', description: 'Desenvolva aplicações modernas com C# e ecossistema .NET.' }, 'cpp': { name: 'C++ Programming', description: 'Domine programação de sistemas e aplicações de alto desempenho com C++.' }, 'bootstrap': { name: 'Bootstrap Framework', description: 'Construa sites responsivos rapidamente com framework CSS Bootstrap.' }, 'jquery': { name: 'jQuery Library', description: 'Simplifique a programação JavaScript com biblioteca jQuery para manipulação DOM.' }, 'sass': { name: 'Sass & SCSS', description: 'Escreva CSS mais sustentável com pré-processador Sass e recursos avançados.' }, 'graphql': { name: 'GraphQL Tutorial', description: 'Construa APIs eficientes com linguagem de consulta GraphQL e definição de schema.' }, 'nextjs': { name: 'Next.js', description: 'Crie aplicações React full-stack com framework Next.js.' }, 'nuxtjs': { name: 'Nuxt.js', description: 'Construa aplicações Vue.js universais com framework Nuxt.js.' }, 'redis': { name: 'Redis Tutorial', description: 'Aprenda armazenamento de estrutura de dados em memória para cache e aplicações em tempo real.' }, 'firebase': { name: 'Firebase Tutorial', description: 'Construa aplicações web e móveis com serviços de backend Google Firebase.' }, 'elasticsearch': { name: 'Elasticsearch Tutorial', description: 'Implemente busca e análise poderosas com motor Elasticsearch.' }, 'c': { name: 'C Programming', description: 'Aprenda a base da programação de sistemas com linguagem C.' }, 'ruby': { name: 'Ruby Programming', description: 'Escreva código elegante com linguagem de programação Ruby e framework Rails.' }, 'scala': { name: 'Scala Programming', description: 'Combine programação orientada a objetos e funcional com Scala.' }, 'r': { name: 'R Programming', description: 'Execute computação estatística e análise de dados com linguagem R.' }, 'matlab': { name: 'MATLAB Programming', description: 'Resolva problemas de engenharia e científicos com programação MATLAB.' }, 'perl': { name: 'Perl Programming', description: 'Domine processamento de texto e administração de sistemas com Perl.' }, 'assembly': { name: 'Assembly Language', description: 'Entenda programação de baixo nível e arquitetura de computador com Assembly.' }, 'lua': { name: 'Lua Programming', description: 'Aprenda linguagem de script leve para sistemas embarcados e jogos.' }, 'xamarin': { name: 'Xamarin Tutorial', description: 'Construa aplicativos móveis multiplataforma com Xamarin e C#.' }, 'ionic': { name: 'Ionic Framework', description: 'Crie aplicações móveis híbridas com Ionic e tecnologias web.' }, 'phonegap': { name: 'PhoneGap Tutorial', description: 'Construa aplicativos móveis usando tecnologias web com plataforma PhoneGap.' }, 'pwa': { name: 'Progressive Web Apps', description: 'Crie experiências semelhantes a aplicativos na web com tecnologias Progressive Web App.' }, 'mobile-ui': { name: 'Mobile UI Design', description: 'Design interfaces de usuário bonitas e intuitivas para aplicações móveis.' }, 'data-structures': { name: 'Data Structures', description: 'Domine estruturas de dados fundamentais para implementação eficiente de algoritmos.' }, 'algorithms': { name: 'Algorithms Tutorial', description: 'Aprenda pensamento algorítmico e técnicas de resolução de problemas.' }, 'oop': { name: 'Object Oriented Programming', description: 'Entenda conceitos de programação orientada a objetos e princípios de design.' }, 'design-patterns': { name: 'Design Patterns', description: 'Aplique padrões de design de software comprovados para resolver problemas comuns de programação.' }, 'api-development': { name: 'API Development', description: 'Projete e construa APIs robustas para aplicações web e móveis.' }, 'rest-api': { name: 'REST API Tutorial', description: 'Crie serviços web RESTful seguindo melhores práticas e padrões.' }, 'microservices': { name: 'Microservices', description: 'Arquitete aplicações escaláveis usando padrões de design de microsserviços.' }, 'machine-learning': { name: 'Machine Learning', description: 'Construa sistemas inteligentes com algoritmos e técnicas de aprendizado de máquina.' }, 'ai': { name: 'Artificial Intelligence', description: 'Explore conceitos de IA e construa aplicações inteligentes com frameworks modernos.' }, 'blockchain': { name: 'Blockchain Programming', description: 'Desenvolva aplicações descentralizadas e contratos inteligentes em plataformas blockchain.' }, 'game-dev': { name: 'Game Development', description: 'Crie jogos envolventes usando motores de jogos modernos e técnicas de programação.' }, 'webcomponents': { name: 'Web Components', description: 'Construa elementos personalizados reutilizáveis com padrões Web Components.' }, 'database-design': { name: 'Database Design', description: 'Projete esquemas de banco de dados eficientes e escaláveis e relacionamentos.' }, 'sqlserver': { name: 'SQL Server Tutorial', description: 'Trabalhe com sistema de gerenciamento de banco de dados Microsoft SQL Server.' }, 'oracle': { name: 'Oracle Database', description: 'Domine técnicas de administração e desenvolvimento de banco de dados Oracle.' }, 'mariadb': { name: 'MariaDB Tutorial', description: 'Aprenda recursos e administração do banco de dados MariaDB.' }, 'dotnet': { name: 'ASP.NET Core', description: 'Construa aplicações web modernas com framework ASP.NET Core.' }, 'flask': { name: 'Flask Framework', description: 'Crie aplicações web leves com microframework Python Flask.' }, 'android-java': { name: 'Android Java', description: 'Desenvolva aplicações Android usando linguagem de programação Java.' }, 'swiftui': { name: 'SwiftUI Tutorial', description: 'Construa interfaces iOS modernas com framework declarativo SwiftUI.' }, 'prompt-engineering': { name: 'AI Prompt Engineering', description: 'Domine a arte de se comunicar efetivamente com sistemas de IA e modelos de linguagem.' }, 'default': { name: 'Novo Curso', description: 'Este curso abrangente está sendo desenvolvido com os mais recentes padrões da indústria e melhores práticas.' } }; // Show modal function function showModal(courseName = 'default') { const info = courseInfo[courseName] || courseInfo['default']; const courseNameElement = document.getElementById('course-name'); const courseDescElement = modal.querySelector('.course-description'); if (courseNameElement) courseNameElement.textContent = info.name; if (courseDescElement) courseDescElement.textContent = info.description; modal.classList.remove('hidden'); modal.classList.add('active'); document.body.style.overflow = 'hidden'; } // Hide modal function function hideModal() { modal.classList.remove('active'); modal.classList.add('hidden'); document.body.style.overflow = 'auto'; // Reset form if (notifyForm) { notifyForm.reset(); } } // Event listeners if (closeBtn) { closeBtn.addEventListener('click', hideModal); } if (backdrop) { backdrop.addEventListener('click', hideModal); } // Escape key document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && modal.classList.contains('active')) { hideModal(); } }); // Handle notify form submission if (notifyForm) { notifyForm.addEventListener('submit', function(e) { e.preventDefault(); const email = document.getElementById('notify-email').value; if (email) { // Here you would typically send the email to your backend console.log('Notify email:', email); // Show success message alert('Thank you! We will notify you when this course becomes available.'); hideModal(); } }); } // Detect clicks on # links and show modal document.addEventListener('click', function(e) { if (e.target.matches('a[href="#"]') || e.target.closest('a[href="#"]')) { e.preventDefault(); // Try to extract course name from link text or data attribute const link = e.target.matches('a') ? e.target : e.target.closest('a'); const linkText = link.textContent.toLowerCase(); let courseName = 'default'; if (linkText.includes('python')) courseName = 'python'; else if (linkText.includes('java') && !linkText.includes('javascript')) courseName = 'java'; else if (linkText.includes('node')) courseName = 'nodejs'; else if (linkText.includes('react')) courseName = 'react'; else if (linkText.includes('typescript')) courseName = 'typescript'; else if (linkText.includes('vue')) courseName = 'vue'; else if (linkText.includes('angular')) courseName = 'angular'; else if (linkText.includes('tailwind')) courseName = 'tailwind'; else if (linkText.includes('django')) courseName = 'django'; else if (linkText.includes('express')) courseName = 'express'; else if (linkText.includes('spring')) courseName = 'spring'; else if (linkText.includes('php')) courseName = 'php'; else if (linkText.includes('laravel')) courseName = 'laravel'; else if (linkText.includes('sql') && !linkText.includes('mysql') && !linkText.includes('postgresql')) courseName = 'sql'; else if (linkText.includes('mysql')) courseName = 'mysql'; else if (linkText.includes('postgresql')) courseName = 'postgresql'; else if (linkText.includes('mongodb')) courseName = 'mongodb'; else if (linkText.includes('flutter')) courseName = 'flutter'; else if (linkText.includes('react native')) courseName = 'react-native'; else if (linkText.includes('swift')) courseName = 'swift'; else if (linkText.includes('kotlin')) courseName = 'kotlin'; else if (linkText.includes('docker')) courseName = 'docker'; else if (linkText.includes('git')) courseName = 'git'; else if (linkText.includes('aws')) courseName = 'aws'; else if (linkText.includes('kubernetes')) courseName = 'kubernetes'; else if (linkText.includes('go')) courseName = 'go'; else if (linkText.includes('rust')) courseName = 'rust'; else if (linkText.includes('c#')) courseName = 'csharp'; else if (linkText.includes('c++')) courseName = 'cpp'; else if (linkText.includes('bootstrap')) courseName = 'bootstrap'; else if (linkText.includes('jquery')) courseName = 'jquery'; else if (linkText.includes('sass')) courseName = 'sass'; else if (linkText.includes('graphql')) courseName = 'graphql'; else if (linkText.includes('next')) courseName = 'nextjs'; else if (linkText.includes('nuxt')) courseName = 'nuxtjs'; else if (linkText.includes('redis')) courseName = 'redis'; else if (linkText.includes('firebase')) courseName = 'firebase'; else if (linkText.includes('elasticsearch')) courseName = 'elasticsearch'; else if (linkText.includes('c programming')) courseName = 'c'; else if (linkText.includes('ruby')) courseName = 'ruby'; else if (linkText.includes('scala')) courseName = 'scala'; else if (linkText.includes('r programming')) courseName = 'r'; else if (linkText.includes('matlab')) courseName = 'matlab'; else if (linkText.includes('perl')) courseName = 'perl'; else if (linkText.includes('assembly')) courseName = 'assembly'; else if (linkText.includes('lua')) courseName = 'lua'; else if (linkText.includes('xamarin')) courseName = 'xamarin'; else if (linkText.includes('ionic')) courseName = 'ionic'; else if (linkText.includes('phonegap')) courseName = 'phonegap'; else if (linkText.includes('progressive web')) courseName = 'pwa'; else if (linkText.includes('mobile ui')) courseName = 'mobile-ui'; else if (linkText.includes('data structures')) courseName = 'data-structures'; else if (linkText.includes('algorithms')) courseName = 'algorithms'; else if (linkText.includes('object oriented')) courseName = 'oop'; else if (linkText.includes('design patterns')) courseName = 'design-patterns'; else if (linkText.includes('api development')) courseName = 'api-development'; else if (linkText.includes('rest api')) courseName = 'rest-api'; else if (linkText.includes('microservices')) courseName = 'microservices'; else if (linkText.includes('machine learning')) courseName = 'machine-learning'; else if (linkText.includes('artificial intelligence')) courseName = 'ai'; else if (linkText.includes('blockchain')) courseName = 'blockchain'; else if (linkText.includes('game development')) courseName = 'game-dev'; else if (linkText.includes('web components')) courseName = 'webcomponents'; else if (linkText.includes('database design')) courseName = 'database-design'; else if (linkText.includes('sql server')) courseName = 'sqlserver'; else if (linkText.includes('oracle')) courseName = 'oracle'; else if (linkText.includes('mariadb')) courseName = 'mariadb'; else if (linkText.includes('asp.net') || linkText.includes('dotnet')) courseName = 'dotnet'; else if (linkText.includes('flask')) courseName = 'flask'; else if (linkText.includes('android java')) courseName = 'android-java'; else if (linkText.includes('swiftui')) courseName = 'swiftui'; else if (linkText.includes('prompt engineering') || linkText.includes('ai prompt')) courseName = 'prompt-engineering'; showModal(courseName); } }); // Make showModal globally available window.showComingSoonModal = showModal; } // Initialize on page load document.addEventListener('DOMContentLoaded', function() { // Initialize Prism.js if (typeof Prism !== 'undefined') { Prism.highlightAll(); } // Hide loading indicator document.getElementById('loading-indicator').style.display = 'none'; // RTL adjustments if (window.siteConfig.isRTL) { document.body.classList.add('rtl'); } // Initialize Coming Soon Modal initComingSoonModal(); }); </script> <!-- Block for additional JavaScript --> <!-- Analytics (add your tracking code here) --> <!-- Add Google Analytics, Plausible, or other analytics scripts here --> </body> </html>