made navbar ssr

This commit is contained in:
2025-12-27 19:47:13 +01:00
parent bc74aa8116
commit 4bca41f6a2
21 changed files with 232 additions and 1001 deletions

View File

@@ -1,5 +1,5 @@
const providerSelector = document.getElementById('provider-selector');
const searchInput = document.getElementById('main-search-input');
const searchInput = document.getElementById('search-input');
const resultsContainer = document.getElementById('gallery-results');
let currentPage = 1;

View File

@@ -2,91 +2,145 @@ import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import * as fs from 'fs';
import * as path from 'path';
let cachedNavbar: string | null = null;
function getNavbarHTML(activePage: string, showSearch: boolean = true): string {
if (!cachedNavbar) {
const navbarPath = path.join(__dirname, '..', '..', 'views', 'components', 'navbar.html');
cachedNavbar = fs.readFileSync(navbarPath, 'utf-8');
}
let navbar = cachedNavbar;
const pages = ['anime', 'books', 'gallery', 'schedule', 'my-list', 'marketplace'];
pages.forEach(page => {
const regex = new RegExp(`(<button class="nav-button[^"]*)"\\s+data-page="${page}"`, 'g');
if (page === activePage) {
navbar = navbar.replace(regex, `$1 active" data-page="${page}"`);
}
});
if (!showSearch) {
navbar = navbar.replace(
'<div class="search-wrapper">',
'<div class="search-wrapper" style="visibility: hidden;">'
);
}
return navbar;
}
function injectNavbar(htmlContent: string, activePage: string, showSearch: boolean = true): string {
const navbar = getNavbarHTML(activePage, showSearch);
return htmlContent.replace(/<body[^>]*>/, `$&\n${navbar}`);
}
async function viewsRoutes(fastify: FastifyInstance) {
fastify.get('/', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'users.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'users.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
reply.type('text/html').send(html);
});
fastify.get('/anime', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'anime', 'animes.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'anime', 'animes.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
const htmlWithNavbar = injectNavbar(html, 'anime', true);
reply.type('text/html').send(htmlWithNavbar);
});
fastify.get('/my-list', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'list.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'list.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
const htmlWithNavbar = injectNavbar(html, 'my-list', false);
reply.type('text/html').send(htmlWithNavbar);
});
fastify.get('/books', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'books', 'books.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'books', 'books.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
const htmlWithNavbar = injectNavbar(html, 'books', true);
reply.type('text/html').send(htmlWithNavbar);
});
fastify.get('/schedule', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'schedule.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'schedule.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
const htmlWithNavbar = injectNavbar(html, 'schedule', false);
reply.type('text/html').send(htmlWithNavbar);
});
fastify.get('/gallery', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'gallery', 'gallery.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'gallery', 'gallery.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
const htmlWithNavbar = injectNavbar(html, 'gallery', true);
reply.type('text/html').send(htmlWithNavbar);
});
fastify.get('/marketplace', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'marketplace.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'marketplace.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
const htmlWithNavbar = injectNavbar(html, 'marketplace', false);
reply.type('text/html').send(htmlWithNavbar);
});
fastify.get('/gallery/:extension/*', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'gallery', 'image.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'gallery', 'image.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
const htmlWithNavbar = injectNavbar(html, 'gallery', true);
reply.type('text/html').send(htmlWithNavbar);
});
fastify.get('/gallery/favorites/*', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'gallery', 'image.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'gallery', 'image.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
const htmlWithNavbar = injectNavbar(html, 'gallery', true);
reply.type('text/html').send(htmlWithNavbar);
});
fastify.get('/anime/:id', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'anime', 'anime.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'anime', 'anime.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
reply.type('text/html').send(html);
});
fastify.get('/anime/:extension/*', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'anime', 'anime.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'anime', 'anime.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
reply.type('text/html').send(html);
});
fastify.get('/watch/:id/:episode', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'anime', 'watch.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'anime', 'watch.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
reply.type('text/html').send(html);
});
fastify.get('/book/:id', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'books', 'book.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'books', 'book.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
reply.type('text/html').send(html);
});
fastify.get('/book/:extension/*', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'books', 'book.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'books', 'book.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
reply.type('text/html').send(html);
});
fastify.get('/read/:provider/:chapter/*', (req: FastifyRequest, reply: FastifyReply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', 'books', 'read.html'));
reply.type('text/html').send(stream);
const htmlPath = path.join(__dirname, '..', '..', 'views', 'books', 'read.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
reply.type('text/html').send(html);
});
fastify.setNotFoundHandler((req, reply) => {
const stream = fs.createReadStream(path.join(__dirname, '..', '..', 'views', '404.html'));
reply
.code(404)
.type('text/html')
.send(stream)
})
const htmlPath = path.join(__dirname, '..', '..', 'views', '404.html');
const html = fs.readFileSync(htmlPath, 'utf-8');
reply.code(404).type('text/html').send(html);
});
}
export default viewsRoutes;

View File

@@ -45,18 +45,6 @@
</head>
<body>
<div id="titlebar">
<div class="title-left">
<img class="app-icon" src="/public/assets/waifuboards.ico" alt=""/>
<span class="app-title">WaifuBoard</span>
</div>
<div class="title-right">
<button class="min"></button>
<button class="max">🗖</button>
<button class="close"></button>
</div>
</div>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">

View File

@@ -13,76 +13,6 @@
<link rel="icon" href="/public/assets/waifuboards.ico" type="image/x-icon">
</head>
<body>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">
<img src="/public/assets/waifuboards.ico" alt="WF Logo">
</div>
WaifuBoard
</a>
<div class="nav-center">
<button class="nav-button active">Anime</button>
<button class="nav-button" onclick="window.location.href='/books'">Books</button>
<button class="nav-button" onclick="window.location.href='/gallery'">Gallery</button>
<button class="nav-button" onclick="window.location.href='/schedule'">Schedule</button>
<button class="nav-button" onclick="window.location.href='/my-list'">My List</button>
<button class="nav-button" onclick="window.location.href='/marketplace'">Marketplace</button>
</div>
<div class="nav-right">
<div class="search-wrapper">
<svg class="search-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</svg>
<input type="text" class="search-input" id="search-input" placeholder="Search anime..." autocomplete="off">
<div class="search-results" id="search-results"></div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
<img id="nav-avatar" src="/public/assets/waifuboards.ico" alt="avatar">
<div class="online-indicator"></div>
</div>
<div class="nav-dropdown" id="nav-dropdown">
<div class="dropdown-header">
<img id="dropdown-avatar" src="/public/assets/waifuboards.ico" alt="avatar" class="dropdown-avatar">
<div class="dropdown-user-info">
<div class="dropdown-username" id="nav-username"></div>
</div>
</div>
<button class="dropdown-item" id="nav-settings">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06A1.65 1.65 0 0 0 15 19.4a1.65 1.65 0 0 0-1 .6 1.65 1.65 0 0 0-.33 1.82V22a2 2 0 1 1-4 0v-.18a1.65 1.65 0 0 0-.33-1.82 1.65 1.65 0 0 0-1-.6 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-.6-1 1.65 1.65 0 0 0-1.82-.33H2a2 2 0 1 1 0-4h.18a1.65 1.65 0 0 0 1.82-.33 1.65 1.65 0 0 0 .6-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6c.37 0 .72-.14 1-.6A1.65 1.65 0 0 0 10.33 2.18V2a2 2 0 1 1 4 0v.18a1.65 1.65 0 0 0 .33 1.82c.28.46.63.6 1 .6a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9c0 .37.14.72.6 1 .46.28.6.63.6 1z"/>
</svg>
<span>Settings</span>
</button>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17 21 17 13 7 13 7 21"/>
<polyline points="7 3 7 8 15 8"/>
</svg>
<span>My List</span>
</a>
<button class="dropdown-item logout-item" id="nav-logout">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
<span>Logout</span>
</button>
</div>
</div>
</div>
</nav>
<div class="hero-wrapper">
<div class="hero-background">
<img id="hero-bg-media" alt="">

View File

@@ -12,67 +12,6 @@
<link rel="icon" href="/public/assets/waifuboards.ico" type="image/x-icon">
</head>
<body>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">
<img src="/public/assets/waifuboards.ico" alt="WF Logo">
</div>
WaifuBoard
</a>
<div class="nav-center">
<button class="nav-button" onclick="window.location.href='/anime'">Anime</button>
<button class="nav-button active">Books</button>
<button class="nav-button" onclick="window.location.href='/gallery'">Gallery</button>
<button class="nav-button" onclick="window.location.href='/schedule'">Schedule</button>
<button class="nav-button" onclick="window.location.href='/my-list'">My List</button>
<button class="nav-button" onclick="window.location.href='/marketplace'">Marketplace</button>
</div>
<div class="nav-right">
<div class="search-wrapper">
<svg class="search-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
<input type="text" class="search-input" id="search-input" placeholder="Search books..." autocomplete="off">
<div class="search-results" id="search-results"></div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
<img id="nav-avatar" src="/public/assets/waifuboards.ico" alt="avatar">
<div class="online-indicator"></div>
</div>
<div class="nav-dropdown" id="nav-dropdown">
<div class="dropdown-header">
<img id="dropdown-avatar" src="/public/assets/waifuboards.ico" alt="avatar" class="dropdown-avatar">
<div class="dropdown-user-info">
<div class="dropdown-username" id="nav-username"></div>
</div>
</div>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17 21 17 13 7 13 7 21"/>
<polyline points="7 3 7 8 15 8"/>
</svg>
<span>My List</span>
</a>
<button class="dropdown-item logout-item" id="nav-logout">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
<span>Logout</span>
</button>
</div>
</div>
</div>
</nav>
<div class="hero-wrapper">
<div class="hero-background">
<img id="hero-bg-media" src="" alt="">

View File

@@ -6,25 +6,24 @@
WaifuBoard
</a>
<nav class="navbar">
<div class="nav-center">
<a href="/anime" class="nav-button {{anime}}">Anime</a>
<a href="/books" class="nav-button {{books}}">Books</a>
<a href="/gallery" class="nav-button {{gallery}}">Gallery</a>
<a href="/schedule" class="nav-button {{schedule}}">Schedule</a>
<a href="/my-list" class="nav-button {{myList}}">My List</a>
<a href="/marketplace" class="nav-button {{marketplace}}">Marketplace</a>
</div>
<div class="nav-center">
<button class="nav-button" data-page="anime" onclick="window.location.href='/anime'">Anime</button>
<button class="nav-button" data-page="books" onclick="window.location.href='/books'">Books</button>
<button class="nav-button" data-page="gallery" onclick="window.location.href='/gallery'">Gallery</button>
<button class="nav-button" data-page="schedule" onclick="window.location.href='/schedule'">Schedule</button>
<button class="nav-button" data-page="my-list" onclick="window.location.href='/my-list'">My List</button>
<button class="nav-button" data-page="marketplace" onclick="window.location.href='/marketplace'">Marketplace</button>
</div>
<div class="nav-right">
<div class="search-wrapper {{hideSearch}}">
<div class="search-wrapper">
<svg class="search-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</svg>
<input type="text" class="search-input" id="search-input" placeholder="Search anime..." autocomplete="off">
<div class="search-results" id="search-results"></div>
</div>
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</svg>
<input type="text" class="search-input" id="search-input" placeholder="Search..." autocomplete="off">
<div class="search-results" id="search-results"></div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
@@ -40,6 +39,14 @@
</div>
</div>
<button class="dropdown-item" id="nav-settings">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06A1.65 1.65 0 0 0 15 19.4a1.65 1.65 0 0 0-1 .6 1.65 1.65 0 0 0-.33 1.82V22a2 2 0 1 1-4 0v-.18a1.65 1.65 0 0 0-.33-1.82 1.65 1.65 0 0 0-1-.6 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-.6-1 1.65 1.65 0 0 0-1.82-.33H2a2 2 0 1 1 0-4h.18a1.65 1.65 0 0 0 1.82-.33 1.65 1.65 0 0 0 .6-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6c.37 0 .72-.14 1-.6A1.65 1.65 0 0 0 10.33 2.18V2a2 2 0 1 1 4 0v.18a1.65 1.65 0 0 0 .33 1.82c.28.46.63.6 1 .6a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9c0 .37.14.72.6 1 .46.28.6.63.6 1z"/>
</svg>
<span>Settings</span>
</button>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>

View File

@@ -15,70 +15,6 @@
</head>
<body>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">
<img src="/public/assets/waifuboards.ico" alt="WF Logo">
</div>
WaifuBoard
</a>
<div class="nav-center">
<button class="nav-button" onclick="window.location.href='/anime'">Anime</button>
<button class="nav-button" onclick="window.location.href='/books'">Books</button>
<button class="nav-button active">Gallery</button>
<button class="nav-button" onclick="window.location.href='/schedule'">Schedule</button>
<button class="nav-button" onclick="window.location.href='/my-list'">My List</button>
<button class="nav-button" onclick="window.location.href='/marketplace'">Marketplace</button>
</div>
<!-- Mejorado el contenedor de usuario con dropdown más completo -->
<div class="nav-right">
<div class="search-wrapper">
<input type="text" id="main-search-input" class="search-input" placeholder="Search in gallery..." autocomplete="off">
<div class="search-results">
<button id="favorites-toggle-nav" class="fav-toggle-btn" title="Mostrar favoritos" style="margin: 10px; width: auto; font-size: 0.85rem;">
<i class="far fa-heart"></i>
<span class="fav-text">Favorites Mode</span>
</button>
</div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
<img id="nav-avatar" src="/placeholder.svg" alt="avatar">
<div class="online-indicator"></div>
</div>
<div class="nav-dropdown" id="nav-dropdown">
<div class="dropdown-header">
<img id="dropdown-avatar" src="/placeholder.svg" alt="avatar" class="dropdown-avatar">
<div class="dropdown-user-info">
<div class="dropdown-username" id="nav-username"></div>
</div>
</div>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17 21 17 13 7 13 7 21"/>
<polyline points="7 3 7 8 15 8"/>
</svg>
<span>My List</span>
</a>
<button class="dropdown-item logout-item" id="nav-logout">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
<span>Logout</span>
</button>
</div>
</div>
</div>
</nav>
<main class="gallery-main">
<div class="gallery-hero-placeholder"></div>

View File

@@ -14,65 +14,6 @@
</head>
<body>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">
<img src="/public/assets/waifuboards.ico" alt="WF Logo">
</div>
WaifuBoard
</a>
<div class="nav-center">
<button class="nav-button">Anime</button>
<button class="nav-button" onclick="window.location.href='/books'">Books</button>
<button class="nav-button active" onclick="window.location.href='/gallery'">Gallery</button>
<button class="nav-button" onclick="window.location.href='/schedule'">Schedule</button>
<button class="nav-button" onclick="window.location.href='/my-list'">My List</button>
<button class="nav-button" onclick="window.location.href='/marketplace'">Marketplace</button>
</div>
<!-- Mejorado el contenedor de usuario con dropdown más completo -->
<div class="nav-right">
<div class="search-wrapper" id="global-search-wrapper" style="visibility: hidden;width: 250px;">
<svg class="search-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
<input type="text" class="search-input" placeholder="Search site..." autocomplete="off">
<div class="search-results"></div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
<img id="nav-avatar" src="/placeholder.svg" alt="avatar">
<div class="online-indicator"></div>
</div>
<div class="nav-dropdown" id="nav-dropdown">
<div class="dropdown-header">
<img id="dropdown-avatar" src="/placeholder.svg" alt="avatar" class="dropdown-avatar">
<div class="dropdown-user-info">
<div class="dropdown-username" id="nav-username"></div>
</div>
</div>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17 21 17 13 7 13 7 21"/>
<polyline points="7 3 7 8 15 8"/>
</svg>
<span>My List</span>
</a>
<button class="dropdown-item logout-item" id="nav-logout">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
<span>Logout</span>
</button>
</div>
</div>
</div>
</nav>
<a href="/gallery" class="back-btn">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path d="M15 19l-7-7 7-7"/></svg>
Back to Gallery

View File

@@ -13,68 +13,6 @@
</head>
<body>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">
<img src="/public/assets/waifuboards.ico" alt="WF Logo">
</div>
WaifuBoard
</a>
<div class="nav-center">
<button class="nav-button" onclick="window.location.href='/anime'">Anime</button>
<button class="nav-button" onclick="window.location.href='/books'">Books</button>
<button class="nav-button" onclick="window.location.href='/gallery'">Gallery</button>
<button class="nav-button" onclick="window.location.href='/schedule'">Schedule</button>
<button class="nav-button active">My List</button>
<button class="nav-button" onclick="window.location.href='/marketplace'">Marketplace</button>
</div>
<div class="nav-right">
<div class="search-wrapper" style="visibility: hidden;">
<svg class="search-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</svg>
<input type="text" class="search-input" id="search-input" placeholder="Search anime..." autocomplete="off">
<div class="search-results" id="search-results"></div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
<img id="nav-avatar" src="/public/assets/waifuboards.ico" alt="avatar">
<div class="online-indicator"></div>
</div>
<div class="nav-dropdown" id="nav-dropdown">
<div class="dropdown-header">
<img id="dropdown-avatar" src="/public/assets/waifuboards.ico" alt="avatar" class="dropdown-avatar">
<div class="dropdown-user-info">
<div class="dropdown-username" id="nav-username"></div>
</div>
</div>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17 21 17 13 7 13 7 21"/>
<polyline points="7 3 7 8 15 8"/>
</svg>
<span>My List</span>
</a>
<button class="dropdown-item logout-item" id="nav-logout">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
<span>Logout</span>
</button>
</div>
</div>
</div>
</nav>
<div class="container">
<div class="header-section">
<h1 class="page-title">My List</h1>

View File

@@ -12,68 +12,6 @@
</head>
<body>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">
<img src="/public/assets/waifuboards.ico" alt="WF Logo">
</div>
WaifuBoard
</a>
<div class="nav-center">
<button class="nav-button" onclick="window.location.href='/anime'">Anime</button>
<button class="nav-button" onclick="window.location.href='/books'">Books</button>
<button class="nav-button" onclick="window.location.href='/gallery'">Gallery</button>
<button class="nav-button" onclick="window.location.href='/schedule.html'">Schedule</button>
<button class="nav-button" onclick="window.location.href='/my-list'">My List</button>
<button class="nav-button">Marketplace</button>
</div>
<div class="nav-right">
<div class="search-wrapper" style="visibility: hidden;">
<svg class="search-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</svg>
<input type="text" class="search-input" id="search-input" placeholder="Search anime..." autocomplete="off">
<div class="search-results" id="search-results"></div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
<img id="nav-avatar" src="/public/assets/waifuboards.ico" alt="avatar">
<div class="online-indicator"></div>
</div>
<div class="nav-dropdown" id="nav-dropdown">
<div class="dropdown-header">
<img id="dropdown-avatar" src="/public/assets/waifuboards.ico" alt="avatar" class="dropdown-avatar">
<div class="dropdown-user-info">
<div class="dropdown-username" id="nav-username"></div>
</div>
</div>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17 21 17 13 7 13 7 21"/>
<polyline points="7 3 7 8 15 8"/>
</svg>
<span>My List</span>
</a>
<button class="dropdown-item logout-item" id="nav-logout">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
<span>Logout</span>
</button>
</div>
</div>
</div>
</nav>
<div class="hero-spacer"></div>
<main>

View File

@@ -16,68 +16,6 @@
<body>
<div class="ambient-bg" id="ambientBg"></div>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">
<img src="/public/assets/waifuboards.ico" alt="WF Logo">
</div>
WaifuBoard
</a>
<div class="nav-center">
<button class="nav-button" onclick="window.location.href='/anime'">Anime</button>
<button class="nav-button" onclick="window.location.href='/books'">Books</button>
<button class="nav-button" onclick="window.location.href='/gallery'">Gallery</button>
<button class="nav-button active">Schedule</button>
<button class="nav-button" onclick="window.location.href='/my-list'">My List</button>
<button class="nav-button" onclick="window.location.href='/marketplace'">Marketplace</button>
</div>
<div class="nav-right">
<div class="search-wrapper" style="visibility: hidden;">
<svg class="search-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</svg>
<input type="text" class="search-input" id="search-input" placeholder="Search anime..." autocomplete="off">
<div class="search-results" id="search-results"></div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
<img id="nav-avatar" src="/public/assets/waifuboards.ico" alt="avatar">
<div class="online-indicator"></div>
</div>
<div class="nav-dropdown" id="nav-dropdown">
<div class="dropdown-header">
<img id="dropdown-avatar" src="/public/assets/waifuboards.ico" alt="avatar" class="dropdown-avatar">
<div class="dropdown-user-info">
<div class="dropdown-username" id="nav-username"></div>
</div>
</div>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17 21 17 13 7 13 7 21"/>
<polyline points="7 3 7 8 15 8"/>
</svg>
<span>My List</span>
</a>
<button class="dropdown-item logout-item" id="nav-logout">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
<span>Logout</span>
</button>
</div>
</div>
</div>
</nav>
<div class="calendar-wrapper">
<div class="calendar-controls">
<div class="month-selector">