/* WA Dev Tools — Shared JS (sidebar, theme, tailwind config, categories) */
/* Tailwind config */
if (typeof tailwind !== 'undefined') {
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
fontFamily: {
mono: ['JetBrains Mono', 'monospace'],
sans: ['Manrope', 'sans-serif'],
},
colors: {
surface: { 900: '#060c18', 800: '#091020', 700: '#0d1828', 600: '#162040' },
accent: { DEFAULT: '#0054e6', dim: '#0043b8', bright: '#6b9fff' },
warn: '#ffd600',
danger: '#ff5252',
}
}
}
};
}
/* Categories */
const WA_CATEGORIES = [
{ id: 'images', title: 'Изображения', description: 'Сжатие, редактирование и генерация', icon: '', tools: ['compress', 'placeholder', 'svgeditor', 'editor', 'video'] },
{ id: 'code', title: 'Код', description: 'Форматирование, очистка и конвертация', icon: '', tools: ['formatter', 'sanitizer', 'converter'] },
{ id: 'web', title: 'Веб', description: 'HTTP-клиент, парсер и анализ', icon: '', tools: ['parser', 'httpclient', 'redirects'] },
{ id: 'utils', title: 'Утилиты', description: 'Пароли, Markdown и другие', icon: '', tools: ['password', 'md'] },
];
/* Sidebar tools definition */
const WA_TOOLS = [
{ id: 'home', path: '/dashboard', title: 'Главная', category: null, icon: '' },
// Изображения
{ id: 'compress', path: '/compress', title: 'Сжатие', category: 'images', icon: '' },
{ id: 'placeholder', path: '/placeholder', title: 'Placeholder', category: 'images', icon: '' },
{ id: 'svgeditor', path: '/svgeditor', title: 'SVG', category: 'images', icon: '' },
{ id: 'editor', path: '/editor', title: 'Фото', category: 'images', icon: '' },
{ id: 'video', path: '/video', title: 'Видео', category: 'images', icon: '' },
// Код
{ id: 'formatter', path: '/formatter', title: 'Formatter', category: 'code', icon: '' },
{ id: 'sanitizer', path: '/sanitizer', title: 'Sanitizer', category: 'code', icon: '' },
{ id: 'converter', path: '/converter', title: 'Converter', category: 'code', icon: '' },
// Веб
{ id: 'parser', path: '/parser', title: 'Parser', category: 'web', icon: '' },
{ id: 'httpclient', path: '/httpclient', title: 'HTTP', category: 'web', icon: '' },
{ id: 'redirects', path: '/redirects', title: 'Redirects', category: 'web', icon: '' },
// Утилиты
{ id: 'password', path: '/password', title: 'Пароли', category: 'utils', icon: '' },
{ id: 'md', path: '/md', title: 'Markdown', category: 'utils', icon: '' },
// Admin (only visible in sidebar for admins — hidden by default, shown via JS)
{ id: 'admin', path: '/admin', title: 'Админ', category: null, adminOnly: true, icon: '' },
];
/* Build sidebar SVG icon */
function _svgIcon(innerPath) {
return ``;
}
/* Inject sidebar into the page */
function initSidebar(activeId) {
if (!activeId) {
const path = window.location.pathname;
const match = WA_TOOLS.find(t => t.path !== '/dashboard' && path.startsWith(t.path));
activeId = match ? match.id : 'home';
}
// Build links grouped by category
let linksHtml = '';
let lastCategory = '__none__';
for (const t of WA_TOOLS) {
// Add category divider
if (t.category !== lastCategory && t.category !== null && lastCategory !== '__none__') {
linksHtml += '
';
}
lastCategory = t.category;
const isActive = t.id === activeId ? ' active' : '';
const adminClass = t.adminOnly ? ' sidebar-admin-link' : '';
const hidden = t.adminOnly ? ' style="display:none"' : '';
linksHtml += `\n`;
}
const nav = document.createElement('nav');
nav.className = 'sidebar';
nav.innerHTML = `
`;
document.body.prepend(nav);
_updateThemeIcons();
_loadUser();
}
/* Load user info for sidebar avatar */
async function _loadUser() {
try {
const res = await fetch('/auth/me');
if (!res.ok) return;
const user = await res.json();
const avatar = document.getElementById('sidebarAvatar');
const container = document.getElementById('sidebarUser');
if (!avatar || !container) return;
const initials = (user.name || user.email || '?').charAt(0).toUpperCase();
avatar.textContent = initials;
avatar.title = user.name || user.email;
container.style.display = 'block';
avatar.addEventListener('click', () => {
if (confirm('Выйти из аккаунта?')) {
window.location.href = '/auth/logout';
}
});
// Show admin links for admin users
if (user.role === 'admin') {
document.querySelectorAll('.sidebar-admin-link').forEach(el => {
el.style.display = '';
});
}
} catch {}
}
/* Theme management */
function initTheme() {
const html = document.documentElement;
const saved = localStorage.getItem('theme');
if (saved === 'dark') {
html.classList.add('dark');
} else {
html.classList.remove('dark');
}
document.addEventListener('click', (e) => {
const toggle = e.target.closest('#themeToggle');
if (!toggle) return;
const isDark = html.classList.toggle('dark');
localStorage.setItem('theme', isDark ? 'dark' : '');
_updateThemeIcons();
});
}
function _updateThemeIcons() {
const isDark = document.documentElement.classList.contains('dark');
document.querySelectorAll('.wa-sun-icon').forEach(el => el.style.display = isDark ? 'none' : 'block');
document.querySelectorAll('.wa-moon-icon').forEach(el => el.style.display = isDark ? 'block' : 'none');
}
/* Auto-init on DOM ready */
document.addEventListener('DOMContentLoaded', () => {
initSidebar(window.WA_TOOL_ID);
});
/* Init theme immediately (before DOM ready to prevent flash) */
initTheme();