Super Tela
tailwind.config = {
darkMode: ‘class’,
theme: {
extend: {
colors: {
netflix: ‘#E50914’,
darkBg: ‘#141414’,
cardBg: ‘#1f1f1f’
}
}
}
}
.sidebar-transition {
transition: transform 0.3s ease-in-out, width 0.3s ease-in-out;
}
/* Scrollbar customizada sem margens laterais desnecessárias */
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
SUPERTELA
Lançamentos
let isSidebarOpen = false;
let isProfileMenuOpen = false;
let authMode = ‘login’;
let currentUser = null;
let currentItem = null;
let currentEpIndex = 0;
let currentSeasonIndex = 0;
const defaultContent = [
{
id: “1”,
title: “Exemplo Filme Ação”,
type: “Filme”,
genre: “Ação”,
year: “2026”,
synopsis: “Um filme repleto de adrenalina e efeitos visuais impressionantes mapeado diretamente da web.”,
poster: “https://images.unsplash.com/photo-1536440136628-849c177e76a1?q=80&w=600&auto=format&fit=crop”,
link: “https://www.youtube.com/watch?v=dQw4w9WgXcQ”
},
{
id: “2”,
title: “Exemplo Série Drama”,
type: “Série”,
genre: “Drama”,
year: “2025”,
synopsis: “Uma série dramática envolvente com várias temporadas e episódios automáticos.”,
poster: “https://images.unsplash.com/photo-1489599849927-2ee91cede3ba?q=80&w=600&auto=format&fit=crop”,
seasons: [
{
name: “Temporada 1”,
episodes: [
{ title: “Episódio 1: O Início”, link: “https://www.w3schools.com/html/mov_bbb.mp4” },
{ title: “Episódio 2: Consequências”, link: “https://www.w3schools.com/html/mov_bbb.mp4″ }
]
}
]
}
];
// — SISTEMA DE AUTENTICAÇÃO E PERFIL —
function loadUserSession() {
const savedUser = localStorage.getItem(‘st_logged_user’);
if (savedUser) {
currentUser = JSON.parse(savedUser);
}
updateProfileUI();
}
function toggleProfileMenu(forceState) {
const dropdown = document.getElementById(‘profile-dropdown’);
const overlay = document.getElementById(‘profile-overlay’);
if (forceState !== undefined) {
isProfileMenuOpen = forceState;
} else {
isProfileMenuOpen = !isProfileMenuOpen;
}
if (isProfileMenuOpen) {
dropdown.classList.remove(‘hidden’);
dropdown.classList.add(‘flex’);
overlay.classList.remove(‘hidden’);
} else {
dropdown.classList.add(‘hidden’);
dropdown.classList.remove(‘flex’);
overlay.classList.add(‘hidden’);
}
}
function updateProfileUI() {
const loggedOutView = document.getElementById(‘dropdown-logged-out’);
const loggedInView = document.getElementById(‘dropdown-logged-in’);
const statusDot = document.getElementById(‘user-status-dot’);
const profileBtn = document.getElementById(‘profile-btn’);
if (currentUser) {
loggedOutView.classList.add(‘hidden’);
loggedInView.classList.remove(‘hidden’);
statusDot.classList.remove(‘bg-zinc-500’);
statusDot.classList.add(‘bg-emerald-500’);
document.getElementById(‘user-display-name’).innerText = currentUser.name || ‘Usuário’;
document.getElementById(‘user-display-email’).innerText = currentUser.email;
document.getElementById(‘user-avatar-initial’).innerText = (currentUser.name || currentUser.email).charAt(0).toUpperCase();
profileBtn.classList.add(‘border-netflix’);
} else {
loggedOutView.classList.remove(‘hidden’);
loggedInView.classList.add(‘hidden’);
statusDot.classList.remove(‘bg-emerald-500’);
statusDot.classList.add(‘bg-zinc-500’);
profileBtn.classList.remove(‘border-netflix’);
}
}
function openAuthModal(mode) {
authMode = mode;
toggleProfileMenu(false);
const modal = document.getElementById(‘auth-modal’);
modal.classList.remove(‘hidden’);
modal.classList.add(‘flex’);
updateAuthModalFields();
}
function closeAuthModal() {
const modal = document.getElementById(‘auth-modal’);
modal.classList.add(‘hidden’);
modal.classList.remove(‘flex’);
document.getElementById(‘auth-error-msg’).classList.add(‘hidden’);
}
function toggleAuthMode() {
authMode = authMode === ‘login’ ? ‘register’ : ‘login’;
updateAuthModalFields();
}
function updateAuthModalFields() {
const title = document.getElementById(‘auth-modal-title’);
const subtitle = document.getElementById(‘auth-modal-subtitle’);
const nameContainer = document.getElementById(‘field-name-container’);
const submitBtn = document.getElementById(‘auth-submit-btn’);
const toggleText = document.getElementById(‘auth-toggle-text’);
const toggleBtn = document.getElementById(‘auth-toggle-btn’);
if (authMode === ‘register’) {
title.innerText = ‘Criar Conta Gratuita’;
subtitle.innerText = ‘Crie sua conta para acessar em qualquer dispositivo’;
nameContainer.classList.remove(‘hidden’);
submitBtn.innerText = ‘Cadastrar Conta’;
toggleText.innerText = ‘Já possui uma conta?’;
toggleBtn.innerText = ‘Entrar agora’;
} else {
title.innerText = ‘Entrar no Super Tela’;
subtitle.innerText = ‘Insira seus dados de acesso’;
nameContainer.classList.add(‘hidden’);
submitBtn.innerText = ‘Entrar’;
toggleText.innerText = ‘Ainda não possui uma conta?’;
toggleBtn.innerText = ‘Criar conta gratuita’;
}
}
function handleAuthSubmit(e) {
e.preventDefault();
const email = document.getElementById(‘auth-email’).value.trim();
const password = document.getElementById(‘auth-password’).value;
const name = document.getElementById(‘auth-name’).value.trim();
const errorMsg = document.getElementById(‘auth-error-msg’);
errorMsg.classList.add(‘hidden’);
if (authMode === ‘register’) {
let users = JSON.parse(localStorage.getItem(‘st_registered_users’)) || [];
if (users.some(u => u.email === email)) {
errorMsg.innerText = ‘Este e-mail já está cadastrado!’;
errorMsg.classList.remove(‘hidden’);
return;
}
const newUser = { id: Date.now().toString(), name: name || ‘Usuário’, email, password };
users.push(newUser);
localStorage.setItem(‘st_registered_users’, JSON.stringify(users));
currentUser = newUser;
localStorage.setItem(‘st_logged_user’, JSON.stringify(currentUser));
} else {
let users = JSON.parse(localStorage.getItem(‘st_registered_users’)) || [];
const userFound = users.find(u => u.email === email && u.password === password);
if (!userFound) {
if (users.length === 0) {
currentUser = { id: ‘1’, name: email.split(‘@’)[0], email, password };
localStorage.setItem(‘st_logged_user’, JSON.stringify(currentUser));
} else {
errorMsg.innerText = ‘E-mail ou senha incorretos!’;
errorMsg.classList.remove(‘hidden’);
return;
}
} else {
currentUser = userFound;
localStorage.setItem(‘st_logged_user’, JSON.stringify(currentUser));
}
}
updateProfileUI();
closeAuthModal();
const reqUser = document.getElementById(‘req-user’);
if (reqUser && currentUser) reqUser.value = currentUser.name;
}
function logoutUser() {
currentUser = null;
localStorage.removeItem(‘st_logged_user’);
updateProfileUI();
toggleProfileMenu(false);
}
// — SISTEMA NAVEGAÇÃO E SIDEBAR —
function toggleSidebar() {
const sidebar = document.getElementById(‘sidebar’);
const overlay = document.getElementById(‘sidebar-overlay’);
isSidebarOpen = !isSidebarOpen;
if (isSidebarOpen) {
sidebar.classList.remove(‘-translate-x-full’);
overlay.classList.remove(‘hidden’);
} else {
sidebar.classList.add(‘-translate-x-full’);
overlay.classList.add(‘hidden’);
}
}
function getContent() {
return JSON.parse(localStorage.getItem(‘st_content’)) || defaultContent;
}
function getFavorites() {
return JSON.parse(localStorage.getItem(‘st_favorites_guest’)) || [];
}
function saveFavorites(favs) {
localStorage.setItem(‘st_favorites_guest’, JSON.stringify(favs));
}
function initApp() {
loadUserSession();
renderHome();
renderCatalog();
}
function showSection(secName) {
[‘home’, ‘movies’, ‘series’, ‘favorites’, ‘request’, ‘player’].forEach(s => {
document.getElementById(`sec-${s}`).classList.add(‘hidden’);
const navBtn = document.getElementById(`nav-${s}`);
if (navBtn) {
navBtn.classList.remove(‘bg-netflix/20’, ‘text-white’);
navBtn.classList.add(‘text-zinc-400’);
const icon = navBtn.querySelector(‘i’);
if (icon) icon.classList.remove(‘text-netflix’);
}
});
document.getElementById(`sec-${secName}`).classList.remove(‘hidden’);
const activeBtn = document.getElementById(`nav-${secName}`);
if (activeBtn) {
activeBtn.classList.add(‘bg-netflix/20’, ‘text-white’);
activeBtn.classList.remove(‘text-zinc-400’);
const icon = activeBtn.querySelector(‘i’);
if (icon) icon.classList.add(‘text-netflix’);
}
if (isSidebarOpen) toggleSidebar();
if (isProfileMenuOpen) toggleProfileMenu(false);
window.scrollTo(0, 0);
if (secName === ‘favorites’) renderFavorites();
if (secName === ‘request’ && currentUser) {
document.getElementById(‘req-user’).value = currentUser.name || ”;
}
}
function renderHome() {
const content = getContent();
if (content.length === 0) return;
const hero = content[0];
document.getElementById(‘hero-title’).innerText = hero.title;
document.getElementById(‘hero-desc’).innerText = hero.synopsis;
document.getElementById(‘hero-banner’).style.backgroundImage = `linear-gradient(to top, #141414, transparent), url(‘${hero.poster}’)`;
document.getElementById(‘hero-play-btn’).onclick = () => openPlayer(hero);
document.getElementById(‘hero-fav-btn’).onclick = () => {
currentItem = hero;
toggleCurrentFavorite();
};
const releasesEl = document.getElementById(‘releases-list’);
releasesEl.innerHTML = content.slice(0, 6).map(item => cardTemplate(item)).join(”);
const genresMap = {};
content.forEach(item => {
if (!genresMap[item.genre]) genresMap[item.genre] = [];
genresMap[item.genre].push(item);
});
const genresContainer = document.getElementById(‘genres-container’);
genresContainer.innerHTML = Object.keys(genresMap).map(genre => `
${genre}
`).join(”);
renderContinueWatching();
}
function renderCatalog() {
const content = getContent();
document.getElementById(‘movies-grid’).innerHTML = content.filter(i => i.type === ‘Filme’).map(i => cardTemplate(i)).join(”);
document.getElementById(‘series-grid’).innerHTML = content.filter(i => i.type === ‘Série’).map(i => cardTemplate(i)).join(”);
}
function renderFavorites() {
const favs = getFavorites();
const content = getContent();
const favItems = content.filter(i => favs.includes(i.id));
const grid = document.getElementById(‘favorites-grid’);
if (favItems.length === 0) {
grid.innerHTML = `
Sua lista de favoritos está vazia.
`;
} else {
grid.innerHTML = favItems.map(i => cardTemplate(i)).join(”);
}
}
function cardTemplate(item) {
return `
${item.title}
${item.genre} • ${item.year}
`;
}
function openPlayerById(id) {
const content = getContent();
const item = content.find(i => i.id === id);
if (item) openPlayer(item);
}
function openPlayer(item, sIndex = 0, eIndex = 0) {
currentItem = item;
currentSeasonIndex = sIndex;
currentEpIndex = eIndex;
document.getElementById(‘player-title’).innerText = item.title;
document.getElementById(‘player-year’).innerText = item.year;
document.getElementById(‘player-genre’).innerText = item.genre;
document.getElementById(‘player-desc’).innerText = item.synopsis;
updateFavoriteButtonState();
setupVideoSource();
if (item.type === ‘Série’ && item.seasons) {
document.getElementById(‘seasons-wrapper’).classList.remove(‘hidden’);
renderSeasons(item);
} else {
document.getElementById(‘seasons-wrapper’).classList.add(‘hidden’);
}
showSection(‘player’);
saveContinueWatching(item);
}
function setupVideoSource() {
let link = “”;
if (currentItem.type === ‘Série’ && currentItem.seasons) {
link = currentItem.seasons[currentSeasonIndex].episodes[currentEpIndex].link;
} else {
link = currentItem.link;
}
const container = document.getElementById(‘player-container’);
container.innerHTML = parseVideoLink(link);
}
function parseVideoLink(url) {
if (!url) return `
`;
if (url.includes(‘youtube.com’) || url.includes(‘youtu.be’)) {
let videoId = ”;
if (url.includes(‘youtu.be/’)) videoId = url.split(‘youtu.be/’)[1].split(‘?’)[0];
else if (url.includes(‘watch?v=’)) videoId = url.split(‘watch?v=’)[1].split(‘&’)[0];
return `
}
if (url.includes(‘drive.google.com’) || url.includes(‘mega.nz’) || url.includes(‘terabox.com’) || url.includes(‘<iframe')) {
if (url.startsWith('<iframe')) return url;
return “;
}
return ``;
}
function handleVideoEnded() {
if (currentItem.type === ‘Série’ && currentItem.seasons) {
const season = currentItem.seasons[currentSeasonIndex];
if (currentEpIndex + 1 < season.episodes.length) {
currentEpIndex++;
setupVideoSource();
} else if (currentSeasonIndex + 1 `
`).join(”);
const epsEl = document.getElementById(‘episodes-list’);
const currentSeason = item.seasons[currentSeasonIndex];
epsEl.innerHTML = currentSeason.episodes.map((ep, eIdx) => `
${ep.title}
`).join(”);
}
function changeSeason(sIdx) {
currentSeasonIndex = sIdx;
currentEpIndex = 0;
setupVideoSource();
renderSeasons(currentItem);
}
function changeEpisode(sIdx, eIdx) {
currentSeasonIndex = sIdx;
currentEpIndex = eIdx;
setupVideoSource();
renderSeasons(currentItem);
}
function toggleCurrentFavorite() {
if (!currentItem) return;
let favs = getFavorites();
if (favs.includes(currentItem.id)) {
favs = favs.filter(id => id !== currentItem.id);
} else {
favs.push(currentItem.id);
}
saveFavorites(favs);
updateFavoriteButtonState();
}
function updateFavoriteButtonState() {
if (!currentItem) return;
const favs = getFavorites();
const isFav = favs.includes(currentItem.id);
const btn = document.getElementById(‘player-fav-btn’);
btn.innerHTML = isFav ? ` Na Lista` : ` Favorito`;
}
function saveContinueWatching(item) {
let userHistory = JSON.parse(localStorage.getItem(‘st_history_guest’)) || [];
userHistory = userHistory.filter(i => i.id !== item.id);
userHistory.unshift(item);
localStorage.setItem(‘st_history_guest’, JSON.stringify(userHistory));
renderContinueWatching();
}
function renderContinueWatching() {
let userHistory = JSON.parse(localStorage.getItem(‘st_history_guest’)) || [];
const wrapper = document.getElementById(‘continue-watching-wrapper’);
const list = document.getElementById(‘continue-list’);
if (userHistory.length === 0) {
wrapper.classList.add(‘hidden’);
return;
}
wrapper.classList.remove(‘hidden’);
list.innerHTML = userHistory.map(item => `
${item.title}
`).join(”);
}
function handleRequestSubmit(e) {
e.preventDefault();
const user = document.getElementById(‘req-user’).value.trim() || (currentUser ? currentUser.name : ‘Usuário Anônimo’);
const title = document.getElementById(‘req-title’).value;
const type = document.getElementById(‘req-type’).value;
const obs = document.getElementById(‘req-obs’).value;
let requests = JSON.parse(localStorage.getItem(‘st_requests’)) || [];
requests.unshift({
id: Date.now().toString(),
user,
title,
type,
obs,
date: new Date().toLocaleDateString(‘pt-BR’)
});
localStorage.setItem(‘st_requests’, JSON.stringify(requests));
alert(“Pedido enviado com sucesso para a administração!”);
document.getElementById(‘req-title’).value = ”;
document.getElementById(‘req-obs’).value = ”;
showSection(‘home’);
}
function goBack() {
showSection(‘home’);
}
window.onload = initApp;