| <!DOCTYPE html> |
| <html lang="pt-BR"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Jornal Oliveira</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700&family=Open+Sans:wght@400;600;700&display=swap'); |
| |
| :root { |
| --primary: #4E653D; |
| --primary-light: #697E50; |
| --secondary: #A4B17B; |
| --background: #F5F7F0; |
| --text-dark: #20331B; |
| --text-light: #FFFFFF; |
| } |
| |
| body { |
| font-family: 'Open Sans', sans-serif; |
| background-color: var(--background); |
| color: var(--text-dark); |
| } |
| |
| .title-font { |
| font-family: 'Merriweather', serif; |
| } |
| |
| .card-shadow { |
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); |
| } |
| |
| .tab-animation { |
| transition: all 0.3s ease; |
| } |
| |
| .fade-in { |
| animation: fadeIn 0.5s ease-in; |
| } |
| |
| @keyframes fadeIn { |
| from { opacity: 0; } |
| to { opacity: 1; } |
| } |
| |
| |
| ::-webkit-scrollbar { |
| width: 8px; |
| } |
| ::-webkit-scrollbar-track { |
| background: #f1f1f1; |
| } |
| ::-webkit-scrollbar-thumb { |
| background: var(--primary-light); |
| border-radius: 4px; |
| } |
| ::-webkit-scrollbar-thumb:hover { |
| background: var(--primary); |
| } |
| </style> |
| </head> |
| <body class="min-h-screen flex flex-col"> |
| |
| <header class="bg-green-900 text-white py-4 px-6 shadow-md"> |
| <div class="container mx-auto"> |
| <h1 class="title-font text-3xl md:text-4xl font-bold mb-1">Jornal Oliveira</h1> |
| <p class="text-green-200 italic">Feito de alunos para alunos</p> |
| </div> |
| </header> |
|
|
| |
| <nav class="bg-green-800 text-white py-3 px-6 sticky top-0 z-10 shadow-sm"> |
| <div class="container mx-auto flex flex-wrap justify-center gap-2"> |
| <button data-tab="home" class="tab-animation px-4 py-2 rounded-md bg-green-700 hover:bg-green-600 font-medium flex items-center gap-2"> |
| <i class="fas fa-home"></i> Início |
| </button> |
| <button data-tab="enviar" class="tab-animation px-4 py-2 rounded-md bg-green-700 hover:bg-green-600 font-medium flex items-center gap-2 restricted hidden"> |
| <i class="fas fa-paper-plane"></i> Enviar |
| </button> |
| <button data-tab="avaliar" class="tab-animation px-4 py-2 rounded-md bg-green-700 hover:bg-green-600 font-medium flex items-center gap-2"> |
| <i class="fas fa-star"></i> Avaliar |
| </button> |
| <button data-tab="sugestoes" class="tab-animation px-4 py-2 rounded-md bg-green-700 hover:bg-green-600 font-medium flex items-center gap-2"> |
| <i class="fas fa-lightbulb"></i> Sugestões |
| </button> |
| <button id="loginBtn" class="tab-animation px-4 py-2 rounded-md bg-green-600 hover:bg-green-500 font-medium flex items-center gap-2"> |
| <i class="fas fa-sign-in-alt"></i> Login |
| </button> |
| </div> |
| </nav> |
|
|
| |
| <main class="flex-grow container mx-auto py-6 px-4"> |
| |
| <section id="home" class="fade-in"> |
| <div class="max-w-4xl mx-auto"> |
| <h2 class="title-font text-2xl md:text-3xl font-bold mb-6 text-green-900 border-b pb-2">Últimas Matérias</h2> |
| |
| <div id="articlesContainer" class="grid md:grid-cols-2 gap-6"> |
| |
| <div class="text-center py-10"> |
| <i class="fas fa-newspaper text-5xl text-green-700 mb-4"></i> |
| <p class="text-lg">Carregando matérias...</p> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="enviar" class="hidden max-w-2xl mx-auto"> |
| <div class="bg-white rounded-lg p-6 card-shadow"> |
| <h2 class="title-font text-2xl font-bold mb-6 text-green-900 flex items-center gap-3"> |
| <i class="fas fa-pen-fancy"></i> Enviar Matéria |
| </h2> |
| |
| <div class="space-y-4"> |
| <div> |
| <label for="artTitle" class="block text-sm font-medium text-gray-700 mb-1">Título</label> |
| <input id="artTitle" type="text" placeholder="Título da matéria" |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"> |
| </div> |
| |
| <div> |
| <label for="artAuthor" class="block text-sm font-medium text-gray-700 mb-1">Autor</label> |
| <input id="artAuthor" type="text" placeholder="Seu nome" |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"> |
| </div> |
| |
| <div> |
| <label for="artDate" class="block text-sm font-medium text-gray-700 mb-1">Data</label> |
| <input id="artDate" type="date" |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"> |
| </div> |
| |
| <div> |
| <label for="artCat" class="block text-sm font-medium text-gray-700 mb-1">Categoria</label> |
| <select id="artCat" |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"> |
| <option value="">Selecione uma categoria</option> |
| <option value="Cultura">Cultura</option> |
| <option value="Esportes">Esportes</option> |
| <option value="Opinião">Opinião</option> |
| <option value="Notícias">Notícias</option> |
| <option value="Entrevista">Entrevista</option> |
| </select> |
| </div> |
| |
| <div> |
| <label for="artContent" class="block text-sm font-medium text-gray-700 mb-1">Conteúdo</label> |
| <textarea id="artContent" rows="8" placeholder="Escreva sua matéria aqui..." |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"></textarea> |
| </div> |
| |
| <button id="btnSubmit" |
| class="w-full bg-green-700 hover:bg-green-600 text-white font-bold py-3 px-4 rounded-md transition duration-300 flex items-center justify-center gap-2"> |
| <i class="fas fa-paper-plane"></i> Enviar Matéria |
| </button> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="avaliar" class="hidden max-w-2xl mx-auto"> |
| <div class="bg-white rounded-lg p-6 card-shadow"> |
| <h2 class="title-font text-2xl font-bold mb-6 text-green-900 flex items-center gap-3"> |
| <i class="fas fa-star-half-alt"></i> Avalie o Jornal |
| </h2> |
| |
| <div class="space-y-4"> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-2">Sua avaliação</label> |
| <div class="flex justify-center space-x-2 mb-4"> |
| <i class="far fa-star text-3xl cursor-pointer text-yellow-400 hover:text-yellow-500 rating-star" data-value="1"></i> |
| <i class="far fa-star text-3xl cursor-pointer text-yellow-400 hover:text-yellow-500 rating-star" data-value="2"></i> |
| <i class="far fa-star text-3xl cursor-pointer text-yellow-400 hover:text-yellow-500 rating-star" data-value="3"></i> |
| <i class="far fa-star text-3xl cursor-pointer text-yellow-400 hover:text-yellow-500 rating-star" data-value="4"></i> |
| <i class="far fa-star text-3xl cursor-pointer text-yellow-400 hover:text-yellow-500 rating-star" data-value="5"></i> |
| </div> |
| </div> |
| |
| <div> |
| <label for="evalComment" class="block text-sm font-medium text-gray-700 mb-1">Comentário (opcional)</label> |
| <textarea id="evalComment" rows="4" placeholder="O que você achou do jornal?" |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"></textarea> |
| </div> |
| |
| <button id="btnEval" |
| class="w-full bg-green-700 hover:bg-green-600 text-white font-bold py-3 px-4 rounded-md transition duration-300 flex items-center justify-center gap-2"> |
| <i class="fas fa-check"></i> Enviar Avaliação |
| </button> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="sugestoes" class="hidden max-w-2xl mx-auto"> |
| <div class="bg-white rounded-lg p-6 card-shadow"> |
| <h2 class="title-font text-2xl font-bold mb-6 text-green-900 flex items-center gap-3"> |
| <i class="fas fa-lightbulb"></i> Envie uma Sugestão |
| </h2> |
| |
| <div class="space-y-4"> |
| <div> |
| <label for="suggestText" class="block text-sm font-medium text-gray-700 mb-1">Sua sugestão</label> |
| <textarea id="suggestText" rows="5" placeholder="O que podemos melhorar?" |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"></textarea> |
| </div> |
| |
| <button id="btnSuggest" |
| class="w-full bg-green-700 hover:bg-green-600 text-white font-bold py-3 px-4 rounded-md transition duration-300 flex items-center justify-center gap-2"> |
| <i class="fas fa-paper-plane"></i> Enviar Sugestão |
| </button> |
| </div> |
| </div> |
| </section> |
| </main> |
|
|
| |
| <div id="loginModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> |
| <div class="bg-white rounded-lg p-6 w-full max-w-md mx-4 card-shadow"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="title-font text-xl font-bold text-green-900"> |
| <i class="fas fa-sign-in-alt mr-2"></i> Login de Editor |
| </h3> |
| <button id="closeLoginModal" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <div class="space-y-4"> |
| <div> |
| <label for="loginName" class="block text-sm font-medium text-gray-700 mb-1">Nome</label> |
| <input id="loginName" type="text" placeholder="Seu nome" |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"> |
| </div> |
| |
| <div> |
| <label for="loginPass" class="block text-sm font-medium text-gray-700 mb-1">Senha</label> |
| <input id="loginPass" type="password" placeholder="Sua senha" |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-600 focus:border-green-600"> |
| </div> |
| |
| <button id="btnLogin" |
| class="w-full bg-green-700 hover:bg-green-600 text-white font-bold py-2 px-4 rounded-md transition duration-300"> |
| Entrar |
| </button> |
| |
| <p class="text-sm text-gray-600 text-center"> |
| Senha padrão: <span class="font-semibold">jornal Oliveira</span> |
| </p> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <footer class="bg-green-900 text-white py-4 px-6"> |
| <div class="container mx-auto text-center"> |
| <p class="text-green-200">Jornal Oliveira © <span id="currentYear"></span> - Todos os direitos reservados</p> |
| <div class="flex justify-center space-x-4 mt-2"> |
| <a href="#" class="text-green-200 hover:text-white"><i class="fab fa-facebook"></i></a> |
| <a href="#" class="text-green-200 hover:text-white"><i class="fab fa-instagram"></i></a> |
| <a href="#" class="text-green-200 hover:text-white"><i class="fab fa-twitter"></i></a> |
| </div> |
| </div> |
| </footer> |
|
|
| <script> |
| |
| let authUsers = JSON.parse(localStorage.getItem('jo_users')) || [ |
| { name: 'Mikael Silva', pass: 'Editor chefe 1' }, |
| { name: 'Lorena Rangel', pass: 'Editor chefe 2' } |
| ]; |
| localStorage.setItem('jo_users', JSON.stringify(authUsers)); |
| |
| let isLogged = false; |
| let currentRating = 0; |
| |
| |
| document.getElementById('currentYear').textContent = new Date().getFullYear(); |
| |
| |
| document.querySelectorAll('[data-tab]').forEach(tab => { |
| tab.addEventListener('click', () => { |
| const tabId = tab.getAttribute('data-tab'); |
| |
| |
| document.querySelectorAll('main > section').forEach(section => { |
| section.classList.add('hidden'); |
| }); |
| |
| |
| document.getElementById(tabId).classList.remove('hidden'); |
| document.getElementById(tabId).classList.add('fade-in'); |
| |
| |
| document.querySelectorAll('[data-tab]').forEach(t => { |
| t.classList.remove('bg-green-600'); |
| t.classList.add('bg-green-700'); |
| }); |
| tab.classList.remove('bg-green-700'); |
| tab.classList.add('bg-green-600'); |
| |
| |
| if (tabId === 'home') { |
| loadArticles(); |
| } |
| }); |
| }); |
| |
| |
| document.getElementById('loginBtn').addEventListener('click', () => { |
| document.getElementById('loginModal').classList.remove('hidden'); |
| }); |
| |
| document.getElementById('closeLoginModal').addEventListener('click', () => { |
| document.getElementById('loginModal').classList.add('hidden'); |
| }); |
| |
| |
| document.getElementById('btnLogin').addEventListener('click', () => { |
| const name = document.getElementById('loginName').value.trim(); |
| const pass = document.getElementById('loginPass').value.trim(); |
| |
| const user = authUsers.find(u => u.name === name && u.pass === pass); |
| |
| if (user || pass === 'jornal Oliveira') { |
| showToast('Login bem-sucedido!', 'success'); |
| isLogged = true; |
| document.getElementById('loginModal').classList.add('hidden'); |
| |
| |
| document.querySelectorAll('.restricted').forEach(tab => { |
| tab.classList.remove('hidden'); |
| }); |
| |
| |
| document.getElementById('loginName').value = ''; |
| document.getElementById('loginPass').value = ''; |
| } else { |
| showToast('Nome ou senha incorretos.', 'error'); |
| } |
| }); |
| |
| |
| document.getElementById('btnSubmit').addEventListener('click', () => { |
| if (!isLogged) { |
| showToast('Você precisa estar logado para enviar uma matéria!', 'error'); |
| return; |
| } |
| |
| const title = document.getElementById('artTitle').value.trim(); |
| const author = document.getElementById('artAuthor').value.trim(); |
| const date = document.getElementById('artDate').value; |
| const category = document.getElementById('artCat').value; |
| const content = document.getElementById('artContent').value.trim(); |
| |
| if (!title || !author || !date || !category || !content) { |
| showToast('Preencha todos os campos!', 'error'); |
| return; |
| } |
| |
| let pending = JSON.parse(localStorage.getItem('jo_pending')) || []; |
| pending.push({ |
| title, |
| author, |
| date: formatDate(date), |
| category, |
| content, |
| approved: false |
| }); |
| localStorage.setItem('jo_pending', JSON.stringify(pending)); |
| |
| showToast('Matéria enviada para aprovação!', 'success'); |
| |
| |
| document.getElementById('artTitle').value = ''; |
| document.getElementById('artAuthor').value = ''; |
| document.getElementById('artDate').value = ''; |
| document.getElementById('artCat').value = ''; |
| document.getElementById('artContent').value = ''; |
| }); |
| |
| |
| document.querySelectorAll('.rating-star').forEach(star => { |
| star.addEventListener('click', () => { |
| const value = parseInt(star.getAttribute('data-value')); |
| currentRating = value; |
| |
| document.querySelectorAll('.rating-star').forEach(s => { |
| if (parseInt(s.getAttribute('data-value')) <= value) { |
| s.classList.remove('far'); |
| s.classList.add('fas'); |
| } else { |
| s.classList.remove('fas'); |
| s.classList.add('far'); |
| } |
| }); |
| }); |
| }); |
| |
| |
| document.getElementById('btnEval').addEventListener('click', () => { |
| const comment = document.getElementById('evalComment').value.trim(); |
| |
| if (currentRating === 0) { |
| showToast('Por favor, selecione uma avaliação!', 'error'); |
| return; |
| } |
| |
| let evaluations = JSON.parse(localStorage.getItem('jo_evaluations')) || []; |
| evaluations.push({ |
| rating: currentRating, |
| comment, |
| date: new Date().toISOString() |
| }); |
| localStorage.setItem('jo_evaluations', JSON.stringify(evaluations)); |
| |
| showToast('Obrigado pela sua avaliação!', 'success'); |
| |
| |
| document.getElementById('evalComment').value = ''; |
| document.querySelectorAll('.rating-star').forEach(s => { |
| s.classList.remove('fas'); |
| s.classList.add('far'); |
| }); |
| currentRating = 0; |
| }); |
| |
| |
| document.getElementById('btnSuggest').addEventListener('click', () => { |
| const suggestion = document.getElementById('suggestText').value.trim(); |
| |
| if (!suggestion) { |
| showToast('Por favor, escreva sua sugestão!', 'error'); |
| return; |
| } |
| |
| let suggestions = JSON.parse(localStorage.getItem('jo_suggestions')) || []; |
| suggestions.push({ |
| text: suggestion, |
| date: new Date().toISOString() |
| }); |
| localStorage.setItem('jo_suggestions', JSON.stringify(suggestions)); |
| |
| showToast('Sugestão enviada com sucesso!', 'success'); |
| document.getElementById('suggestText').value = ''; |
| }); |
| |
| |
| function loadArticles() { |
| const articlesContainer = document.getElementById('articlesContainer'); |
| articlesContainer.innerHTML = '<div class="text-center py-10"><i class="fas fa-spinner fa-spin text-5xl text-green-700 mb-4"></i><p class="text-lg">Carregando matérias...</p></div>'; |
| |
| |
| setTimeout(() => { |
| const approvedArticles = JSON.parse(localStorage.getItem('jo_pending')) || []; |
| |
| if (approvedArticles.length === 0) { |
| articlesContainer.innerHTML = ` |
| <div class="col-span-full text-center py-10"> |
| <i class="fas fa-newspaper text-5xl text-green-700 mb-4"></i> |
| <p class="text-lg">Nenhuma matéria publicada ainda.</p> |
| <p class="text-gray-600 mt-2">Seja o primeiro a contribuir!</p> |
| </div> |
| `; |
| return; |
| } |
| |
| let html = ''; |
| approvedArticles.forEach(article => { |
| html += ` |
| <div class="bg-white rounded-lg overflow-hidden card-shadow hover:shadow-lg transition duration-300"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start mb-2"> |
| <span class="inline-block px-3 py-1 bg-green-100 text-green-800 text-xs font-semibold rounded-full"> |
| ${article.category} |
| </span> |
| <span class="text-sm text-gray-500">${article.date}</span> |
| </div> |
| <h3 class="title-font text-xl font-bold mb-2 text-green-900">${article.title}</h3> |
| <p class="text-gray-700 mb-4 line-clamp-3">${article.content}</p> |
| <div class="flex justify-between items-center"> |
| <span class="text-sm text-gray-600">Por: ${article.author}</span> |
| <button class="text-green-700 hover:text-green-600 font-medium text-sm"> |
| Ler mais <i class="fas fa-arrow-right ml-1"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| `; |
| }); |
| |
| articlesContainer.innerHTML = html; |
| }, 800); |
| } |
| |
| |
| function formatDate(dateString) { |
| if (!dateString) return ''; |
| const date = new Date(dateString); |
| return date.toLocaleDateString('pt-BR'); |
| } |
| |
| function showToast(message, type) { |
| const toast = document.createElement('div'); |
| toast.className = `fixed bottom-4 right-4 px-6 py-3 rounded-md shadow-lg text-white font-medium ${ |
| type === 'success' ? 'bg-green-600' : 'bg-red-600' |
| }`; |
| toast.innerHTML = ` |
| <div class="flex items-center gap-3"> |
| <i class="fas ${type === 'success' ? 'fa-check-circle' : 'fa-exclamation-circle'}"></i> |
| <span>${message}</span> |
| </div> |
| `; |
| document.body.appendChild(toast); |
| |
| setTimeout(() => { |
| toast.classList.add('opacity-0', 'transition-opacity', 'duration-300'); |
| setTimeout(() => { |
| toast.remove(); |
| }, 300); |
| }, 3000); |
| } |
| |
| |
| document.addEventListener('DOMContentLoaded', () => { |
| loadArticles(); |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Rwhehhehe/teste" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |