- admin.html: 14 sections (dashboard, posts, editor, tracks, settings, homepage editor, services, navigation, links, API keys, theme, SEO, contact settings, backups) - admin.js: 1554 lines, full AdminApp with CRUD for all sections - admin.css: 1972 lines, responsive mobile nav, all new section styles - app.py: 42 endpoints, new routes for homepage/services/nav/links/apikeys/theme/seo/contact/backups - 9 JSON data files for new settings - Contact form wired to POST /api/contact - 9 blog posts with full HUD metadata - .gitignore added
1050 lines
62 KiB
HTML
1050 lines
62 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>JAE // ADMIN HUD</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="css/admin.css">
|
||
</head>
|
||
<body>
|
||
|
||
<!-- ═══════════════════════════════════════════════════════ -->
|
||
<!-- LOGIN SCREEN -->
|
||
<!-- ═══════════════════════════════════════════════════════ -->
|
||
<div id="loginScreen" class="login-screen">
|
||
<div class="login-box">
|
||
<div class="login-logo">◈ JAE<span class="accent">SWIFT</span></div>
|
||
<div class="login-subtitle">OPERATOR AUTHENTICATION REQUIRED</div>
|
||
<div class="login-form">
|
||
<div class="login-field">
|
||
<label class="login-label">CALLSIGN</label>
|
||
<input type="text" id="loginUsername" class="login-input" placeholder="Enter username..." autocomplete="username">
|
||
</div>
|
||
<div class="login-field">
|
||
<label class="login-label">PASSPHRASE</label>
|
||
<input type="password" id="loginPassword" class="login-input" placeholder="Enter password..." autocomplete="current-password">
|
||
</div>
|
||
<button id="loginBtn" class="login-btn" onclick="AdminApp.login()">▶ AUTHENTICATE</button>
|
||
<div id="loginError" class="login-error"></div>
|
||
</div>
|
||
<div class="login-footer">SECURE CHANNEL // AES-256 ENCRYPTED</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ═══════════════════════════════════════════════════════ -->
|
||
<!-- ADMIN APPLICATION -->
|
||
<!-- ═══════════════════════════════════════════════════════ -->
|
||
<div id="adminApp" class="admin-app" style="display:none;">
|
||
|
||
<!-- ─── TOPBAR ─── -->
|
||
<div class="topbar">
|
||
<button id="mobileMenuBtn" class="mobile-menu-btn" onclick="AdminApp.toggleSidebar()" aria-label="Toggle menu">☰</button>
|
||
<div class="topbar-logo">◈ JAE<span class="accent">SWIFT</span> // HUD</div>
|
||
<div id="topbarTitle" class="topbar-title">DASHBOARD</div>
|
||
<div class="topbar-right">
|
||
<span class="topbar-user">▣ <span id="topbarUser">OPERATOR</span></span>
|
||
<button class="topbar-logout" onclick="AdminApp.logout()">⏻ LOGOUT</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ─── SIDEBAR ─── -->
|
||
<div id="sidebar" class="sidebar">
|
||
<div class="sidebar-header">
|
||
<span class="sidebar-brand">◈ ADMIN</span>
|
||
<button class="sidebar-close" onclick="AdminApp.toggleSidebar()" aria-label="Close menu">✕</button>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<a href="javascript:void(0)" class="sidebar-link active" data-section="dashboard" onclick="event.preventDefault(); AdminApp.showSection('dashboard')">
|
||
<span class="sidebar-icon">◈</span> Dashboard
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="posts" onclick="event.preventDefault(); AdminApp.showSection('posts')">
|
||
<span class="sidebar-icon">▤</span> Posts
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="editor" onclick="event.preventDefault(); AdminApp.showSection('editor')">
|
||
<span class="sidebar-icon">✎</span> Editor
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="tracks" onclick="event.preventDefault(); AdminApp.showSection('tracks')">
|
||
<span class="sidebar-icon">♫</span> Tracks
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="settings" onclick="event.preventDefault(); AdminApp.showSection('settings')">
|
||
<span class="sidebar-icon">⚙</span> Settings
|
||
</a>
|
||
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-section-label">CONTENT</div>
|
||
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="homepage" onclick="event.preventDefault(); AdminApp.showSection('homepage')">
|
||
<span class="sidebar-icon">⬡</span> Homepage
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="navigation" onclick="event.preventDefault(); AdminApp.showSection('navigation')">
|
||
<span class="sidebar-icon">◇</span> Navigation
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="links" onclick="event.preventDefault(); AdminApp.showSection('links')">
|
||
<span class="sidebar-icon">↗</span> Links
|
||
</a>
|
||
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-section-label">SYSTEM</div>
|
||
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="services" onclick="event.preventDefault(); AdminApp.showSection('services')">
|
||
<span class="sidebar-icon">⟐</span> Services
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="apikeys" onclick="event.preventDefault(); AdminApp.showSection('apikeys')">
|
||
<span class="sidebar-icon">⚿</span> API Keys
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="theme" onclick="event.preventDefault(); AdminApp.showSection('theme')">
|
||
<span class="sidebar-icon">◉</span> Theme
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="seo" onclick="event.preventDefault(); AdminApp.showSection('seo')">
|
||
<span class="sidebar-icon">⊛</span> SEO / Meta
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="contact" onclick="event.preventDefault(); AdminApp.showSection('contact')">
|
||
<span class="sidebar-icon">✉</span> Contact
|
||
</a>
|
||
<a href="javascript:void(0)" class="sidebar-link" data-section="backups" onclick="event.preventDefault(); AdminApp.showSection('backups')">
|
||
<span class="sidebar-icon">⛋</span> Backups
|
||
</a>
|
||
</nav>
|
||
<div class="sidebar-footer">
|
||
<span class="sidebar-version">v2.0 // EXPANDED HUD</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ─── SIDEBAR OVERLAY (mobile) ─── -->
|
||
<div id="sidebarOverlay" class="sidebar-overlay" onclick="AdminApp.toggleSidebar()"></div>
|
||
|
||
<!-- ═══════════════════════════════════════════════════════ -->
|
||
<!-- MAIN CONTENT -->
|
||
<!-- ═══════════════════════════════════════════════════════ -->
|
||
<div class="main-content">
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 1. DASHBOARD -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-dashboard" class="admin-section active">
|
||
<h2 class="section-heading">◈ SYSTEM DASHBOARD</h2>
|
||
|
||
<!-- Stats Cards -->
|
||
<div class="dash-grid">
|
||
<div class="dash-card">
|
||
<div class="dash-card-label">POSTS</div>
|
||
<div class="dash-card-value" id="statPosts">--</div>
|
||
</div>
|
||
<div class="dash-card">
|
||
<div class="dash-card-label">WORDS</div>
|
||
<div class="dash-card-value" id="statWords">--</div>
|
||
</div>
|
||
<div class="dash-card">
|
||
<div class="dash-card-label">TRACKS</div>
|
||
<div class="dash-card-value" id="statTracks">--</div>
|
||
</div>
|
||
<div class="dash-card">
|
||
<div class="dash-card-label">CPU</div>
|
||
<div class="dash-card-value" id="statCPU">--%</div>
|
||
</div>
|
||
<div class="dash-card">
|
||
<div class="dash-card-label">MEM</div>
|
||
<div class="dash-card-value" id="statMEM">--%</div>
|
||
</div>
|
||
<div class="dash-card">
|
||
<div class="dash-card-label">DISK</div>
|
||
<div class="dash-card-value" id="statDISK">--%</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Services Grid -->
|
||
<h3 class="section-subheading">⟐ SERVICES STATUS</h3>
|
||
<div id="servicesGrid" class="services-grid">
|
||
<!-- Populated by JS -->
|
||
</div>
|
||
|
||
<!-- Threat Feed -->
|
||
<h3 class="section-subheading">⚠ THREAT FEED</h3>
|
||
<div id="threatFeed" class="threat-feed">
|
||
<!-- Populated by JS -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 2. POSTS -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-posts" class="admin-section">
|
||
<h2 class="section-heading">▤ POSTS MANAGEMENT</h2>
|
||
<div class="section-toolbar">
|
||
<button class="action-btn accent" onclick="AdminApp.newPost()">+ NEW POST</button>
|
||
</div>
|
||
<div class="table-wrap">
|
||
<table class="admin-table" id="postsTable">
|
||
<thead>
|
||
<tr>
|
||
<th>TITLE</th>
|
||
<th>SLUG</th>
|
||
<th>DATE</th>
|
||
<th>WORDS</th>
|
||
<th>ACTIONS</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="postsTableBody">
|
||
<!-- Populated by JS -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 3. EDITOR -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-editor" class="admin-section">
|
||
<h2 class="section-heading">✎ POST EDITOR</h2>
|
||
|
||
<!-- Post Metadata -->
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="editorTitle">TITLE</label>
|
||
<input type="text" id="editorTitle" class="editor-input" placeholder="Post title...">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="editorSlug">SLUG</label>
|
||
<input type="text" id="editorSlug" class="editor-input" placeholder="post-slug">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="editorDate">DATE</label>
|
||
<input type="date" id="editorDate" class="editor-input">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="editorTime">TIME</label>
|
||
<input type="time" id="editorTime" class="editor-input">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="editorTags">TAGS</label>
|
||
<input type="text" id="editorTags" class="editor-input" placeholder="tag1, tag2, tag3">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="editorExcerpt">EXCERPT</label>
|
||
<textarea id="editorExcerpt" class="editor-input editor-textarea-sm" placeholder="Short description..."></textarea>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Markdown Toolbar -->
|
||
<div class="editor-toolbar">
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('bold')" title="Bold"><b>B</b></button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('italic')" title="Italic"><i>I</i></button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('strikethrough')" title="Strikethrough"><s>S</s></button>
|
||
<span class="toolbar-sep">│</span>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('h1')" title="Heading 1">H1</button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('h2')" title="Heading 2">H2</button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('h3')" title="Heading 3">H3</button>
|
||
<span class="toolbar-sep">│</span>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('link')" title="Link">🔗</button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('image')" title="Image">🖼</button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('code')" title="Code"></></button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('codeblock')" title="Code Block">▣</button>
|
||
<span class="toolbar-sep">│</span>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('ul')" title="Bullet List">• List</button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('ol')" title="Numbered List">1. List</button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('quote')" title="Blockquote">❝</button>
|
||
<button type="button" class="toolbar-btn" onclick="AdminApp.insertMarkdown('hr')" title="Horizontal Rule">―</button>
|
||
</div>
|
||
|
||
<!-- Markdown Editor + Preview -->
|
||
<div class="editor-split">
|
||
<div class="editor-pane">
|
||
<label class="editor-label">MARKDOWN</label>
|
||
<textarea id="editorContent" class="editor-input editor-textarea" placeholder="Write your post in markdown..."></textarea>
|
||
<div class="editor-meta-bar">
|
||
<span id="editorWordCount">0 words</span>
|
||
</div>
|
||
</div>
|
||
<div class="preview-pane">
|
||
<label class="editor-label">PREVIEW</label>
|
||
<div id="editorPreview" class="editor-preview"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ─── OPERATOR HUD ─── -->
|
||
<div class="operator-hud">
|
||
<h3 class="section-subheading">⬡ OPERATOR HUD</h3>
|
||
<div class="hud-grid">
|
||
<!-- Mood -->
|
||
<div class="hud-field">
|
||
<label class="editor-label" for="hudMood">MOOD</label>
|
||
<select id="hudMood" class="editor-input">
|
||
<option value="focused">focused</option>
|
||
<option value="creative">creative</option>
|
||
<option value="productive">productive</option>
|
||
<option value="tired">tired</option>
|
||
<option value="wired">wired</option>
|
||
<option value="chaotic">chaotic</option>
|
||
<option value="locked-in">locked-in</option>
|
||
<option value="zen">zen</option>
|
||
</select>
|
||
</div>
|
||
|
||
<!-- Energy -->
|
||
<div class="hud-field">
|
||
<label class="editor-label" for="hudEnergy">ENERGY <span id="hudEnergyVal" class="hud-val">3</span></label>
|
||
<input type="range" id="hudEnergy" class="editor-input hud-range" min="1" max="5" value="3">
|
||
</div>
|
||
|
||
<!-- Motivation -->
|
||
<div class="hud-field">
|
||
<label class="editor-label" for="hudMotivation">MOTIVATION <span id="hudMotivationVal" class="hud-val">3</span></label>
|
||
<input type="range" id="hudMotivation" class="editor-input hud-range" min="1" max="5" value="3">
|
||
</div>
|
||
|
||
<!-- Focus -->
|
||
<div class="hud-field">
|
||
<label class="editor-label" for="hudFocus">FOCUS <span id="hudFocusVal" class="hud-val">3</span></label>
|
||
<input type="range" id="hudFocus" class="editor-input hud-range" min="1" max="5" value="3">
|
||
</div>
|
||
|
||
<!-- Difficulty -->
|
||
<div class="hud-field">
|
||
<label class="editor-label" for="hudDifficulty">DIFFICULTY <span id="hudDifficultyVal" class="hud-val">3</span></label>
|
||
<input type="range" id="hudDifficulty" class="editor-input hud-range" min="1" max="5" value="3">
|
||
</div>
|
||
|
||
<!-- Coffee -->
|
||
<div class="hud-field">
|
||
<label class="editor-label" for="hudCoffee">COFFEE ☕ <span id="hudCoffeeVal" class="hud-val">0</span></label>
|
||
<input type="range" id="hudCoffee" class="editor-input hud-range" min="0" max="10" value="0">
|
||
</div>
|
||
|
||
<!-- BPM -->
|
||
<div class="hud-field">
|
||
<label class="editor-label" for="hudBPM">BPM ♡ <span id="hudBPMVal" class="hud-val">72</span></label>
|
||
<input type="range" id="hudBPM" class="editor-input hud-range" min="40" max="200" value="72">
|
||
</div>
|
||
|
||
<!-- Threat Level -->
|
||
<div class="hud-field">
|
||
<label class="editor-label" for="hudThreat">THREAT LEVEL</label>
|
||
<select id="hudThreat" class="editor-input">
|
||
<option value="low">low</option>
|
||
<option value="medium">medium</option>
|
||
<option value="high">high</option>
|
||
<option value="critical">critical</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Editor Actions -->
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.savePost()">⬡ SAVE POST</button>
|
||
<button class="action-btn" onclick="AdminApp.showSection('posts')">✕ CANCEL</button>
|
||
</div>
|
||
<input type="hidden" id="editorPostId" value="">
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 4. TRACKS -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-tracks" class="admin-section">
|
||
<h2 class="section-heading">♫ TRACKS LIBRARY</h2>
|
||
|
||
<!-- Add Track Form -->
|
||
<div class="tracks-add-form">
|
||
<h3 class="section-subheading">+ ADD TRACK</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="trackTitle">TITLE</label>
|
||
<input type="text" id="trackTitle" class="editor-input" placeholder="Track title...">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="trackArtist">ARTIST</label>
|
||
<input type="text" id="trackArtist" class="editor-input" placeholder="Artist name...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="trackAlbum">ALBUM</label>
|
||
<input type="text" id="trackAlbum" class="editor-input" placeholder="Album name...">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="trackGenre">GENRE</label>
|
||
<input type="text" id="trackGenre" class="editor-input" placeholder="Genre...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="trackURL">URL</label>
|
||
<input type="text" id="trackURL" class="editor-input" placeholder="https://...">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="trackCover">COVER URL</label>
|
||
<input type="text" id="trackCover" class="editor-input" placeholder="https://cover-image...">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent" onclick="AdminApp.addTrack()">+ ADD TRACK</button>
|
||
</div>
|
||
|
||
<!-- Tracks List -->
|
||
<div class="tracks-list" id="tracksList">
|
||
<!-- Populated by JS -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 5. SETTINGS -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-settings" class="admin-section">
|
||
<h2 class="section-heading">⚙ WIDGET SETTINGS</h2>
|
||
|
||
<div class="settings-grid">
|
||
<div class="setting-item">
|
||
<label class="editor-label">SCANLINES EFFECT</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="settingScanlines" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">PARTICLES</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="settingParticles" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">GLITCH TEXT</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="settingGlitch" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">TERMINAL</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="settingTerminal" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">TYPING ANIMATION</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="settingTyping" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">SCROLL REVEALS</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="settingScrollReveal" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">NOW PLAYING WIDGET</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="settingNowPlaying" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">GRID BACKGROUND</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="settingGridBg" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.saveSettings()">⬡ SAVE SETTINGS</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 6. HOMEPAGE EDITOR -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-homepage" class="admin-section">
|
||
<h2 class="section-heading">⬡ HOMEPAGE EDITOR</h2>
|
||
|
||
<!-- Hero Section -->
|
||
<h3 class="section-subheading">◈ HERO SECTION</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="heroTitle">HERO TITLE</label>
|
||
<input type="text" id="heroTitle" class="editor-input" placeholder="Main hero title...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="heroSubtitle">HERO SUBTITLE</label>
|
||
<input type="text" id="heroSubtitle" class="editor-input" placeholder="Subtitle text...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="heroTagline">TAGLINE</label>
|
||
<input type="text" id="heroTagline" class="editor-input" placeholder="Tagline / typing text...">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Section Toggles & Ordering -->
|
||
<h3 class="section-subheading">▤ SECTIONS VISIBILITY & ORDER</h3>
|
||
<div id="homepageSections" class="homepage-sections-list">
|
||
<div class="homepage-section-item" data-section-key="about">
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="hpSectionAbout" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
<span class="homepage-section-name">ABOUT</span>
|
||
<div class="homepage-section-controls">
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('about','up')" title="Move up">▲</button>
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('about','down')" title="Move down">▼</button>
|
||
</div>
|
||
</div>
|
||
<div class="homepage-section-item" data-section-key="blog">
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="hpSectionBlog" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
<span class="homepage-section-name">BLOG</span>
|
||
<div class="homepage-section-controls">
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('blog','up')" title="Move up">▲</button>
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('blog','down')" title="Move down">▼</button>
|
||
</div>
|
||
</div>
|
||
<div class="homepage-section-item" data-section-key="devcards">
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="hpSectionDevcards" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
<span class="homepage-section-name">DEV CARDS</span>
|
||
<div class="homepage-section-controls">
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('devcards','up')" title="Move up">▲</button>
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('devcards','down')" title="Move down">▼</button>
|
||
</div>
|
||
</div>
|
||
<div class="homepage-section-item" data-section-key="links">
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="hpSectionLinks" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
<span class="homepage-section-name">LINKS</span>
|
||
<div class="homepage-section-controls">
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('links','up')" title="Move up">▲</button>
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('links','down')" title="Move down">▼</button>
|
||
</div>
|
||
</div>
|
||
<div class="homepage-section-item" data-section-key="contact">
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="hpSectionContact" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
<span class="homepage-section-name">CONTACT</span>
|
||
<div class="homepage-section-controls">
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('contact','up')" title="Move up">▲</button>
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('contact','down')" title="Move down">▼</button>
|
||
</div>
|
||
</div>
|
||
<div class="homepage-section-item" data-section-key="terminal">
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="hpSectionTerminal" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
<span class="homepage-section-name">TERMINAL</span>
|
||
<div class="homepage-section-controls">
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('terminal','up')" title="Move up">▲</button>
|
||
<button class="action-btn sm" onclick="AdminApp.moveSection('terminal','down')" title="Move down">▼</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- About Text -->
|
||
<h3 class="section-subheading">✎ ABOUT TEXT</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="aboutText">ABOUT SECTION CONTENT (Markdown)</label>
|
||
<textarea id="aboutText" class="editor-input editor-textarea" placeholder="Write your about section content..."></textarea>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.saveHomepage()">⬡ SAVE HOMEPAGE</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 7. SERVICES MANAGER -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-services" class="admin-section">
|
||
<h2 class="section-heading">⟐ SERVICES MANAGER</h2>
|
||
|
||
<!-- Add Service Form -->
|
||
<h3 class="section-subheading">+ ADD SERVICE</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="serviceName">SERVICE NAME</label>
|
||
<input type="text" id="serviceName" class="editor-input" placeholder="e.g. Gitea">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="serviceURL">SERVICE URL</label>
|
||
<input type="text" id="serviceURL" class="editor-input" placeholder="https://git.example.com">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent" onclick="AdminApp.addService()">+ ADD SERVICE</button>
|
||
|
||
<!-- Services List -->
|
||
<h3 class="section-subheading">▤ MONITORED SERVICES</h3>
|
||
<div id="servicesList" class="services-manage-list">
|
||
<!-- Populated by JS -->
|
||
</div>
|
||
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.saveServices()">⬡ SAVE SERVICES</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 8. NAVIGATION EDITOR -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-navigation" class="admin-section">
|
||
<h2 class="section-heading">◇ NAVIGATION EDITOR</h2>
|
||
|
||
<!-- Add Nav Item -->
|
||
<h3 class="section-subheading">+ ADD NAV ITEM</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="navLabel">LABEL</label>
|
||
<input type="text" id="navLabel" class="editor-input" placeholder="e.g. Blog">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="navURL">URL</label>
|
||
<input type="text" id="navURL" class="editor-input" placeholder="/blog.html">
|
||
</div>
|
||
<div class="editor-field sm">
|
||
<label class="editor-label" for="navOrder">ORDER</label>
|
||
<input type="number" id="navOrder" class="editor-input" placeholder="0" min="0">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent" onclick="AdminApp.addNavItem()">+ ADD NAV ITEM</button>
|
||
|
||
<!-- Nav Items List -->
|
||
<h3 class="section-subheading">▤ MENU ITEMS</h3>
|
||
<div id="navList" class="nav-manage-list">
|
||
<!-- Populated by JS -->
|
||
</div>
|
||
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.saveNavigation()">⬡ SAVE NAVIGATION</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 9. LINKS MANAGER -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-links" class="admin-section">
|
||
<h2 class="section-heading">↗ LINKS MANAGER</h2>
|
||
|
||
<!-- Add Link Form -->
|
||
<h3 class="section-subheading">+ ADD LINK</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="linkName">NAME</label>
|
||
<input type="text" id="linkName" class="editor-input" placeholder="e.g. GitHub">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="linkURL">URL</label>
|
||
<input type="text" id="linkURL" class="editor-input" placeholder="https://github.com/...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="linkIcon">ICON (unicode/emoji)</label>
|
||
<input type="text" id="linkIcon" class="editor-input" placeholder="⬡ or 🐙">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="linkCategory">CATEGORY</label>
|
||
<input type="text" id="linkCategory" class="editor-input" placeholder="social / project / tool">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent" onclick="AdminApp.addLink()">+ ADD LINK</button>
|
||
|
||
<!-- Links List -->
|
||
<h3 class="section-subheading">▤ MANAGED LINKS</h3>
|
||
<div id="linksList" class="links-manage-list">
|
||
<!-- Populated by JS -->
|
||
</div>
|
||
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.saveLinks()">⬡ SAVE LINKS</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 10. API KEYS & INTEGRATIONS -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-apikeys" class="admin-section">
|
||
<h2 class="section-heading">⚿ API KEYS & INTEGRATIONS</h2>
|
||
|
||
<!-- Weather API -->
|
||
<div class="apikey-group">
|
||
<h3 class="section-subheading">☁ WEATHER API</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="apiWeatherKey">API KEY</label>
|
||
<input type="text" id="apiWeatherKey" class="editor-input" placeholder="Enter Weather API key...">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent sm" onclick="AdminApp.saveApiKey('weather')">⬡ SAVE</button>
|
||
</div>
|
||
|
||
<!-- Spotify / Music API -->
|
||
<div class="apikey-group">
|
||
<h3 class="section-subheading">♫ MUSIC / SPOTIFY API</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiSpotifyClientId">CLIENT ID</label>
|
||
<input type="text" id="apiSpotifyClientId" class="editor-input" placeholder="Enter Spotify Client ID...">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiSpotifyClientSecret">CLIENT SECRET</label>
|
||
<input type="password" id="apiSpotifyClientSecret" class="editor-input" placeholder="Enter Spotify Client Secret...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="apiSpotifyRefreshToken">REFRESH TOKEN</label>
|
||
<input type="text" id="apiSpotifyRefreshToken" class="editor-input" placeholder="Enter Spotify Refresh Token...">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent sm" onclick="AdminApp.saveApiKey('spotify')">⬡ SAVE</button>
|
||
</div>
|
||
|
||
<!-- Email SMTP -->
|
||
<div class="apikey-group">
|
||
<h3 class="section-subheading">✉ EMAIL SMTP</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiSmtpHost">SMTP HOST</label>
|
||
<input type="text" id="apiSmtpHost" class="editor-input" placeholder="smtp.example.com">
|
||
</div>
|
||
<div class="editor-field sm">
|
||
<label class="editor-label" for="apiSmtpPort">PORT</label>
|
||
<input type="number" id="apiSmtpPort" class="editor-input" placeholder="587">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiSmtpUser">USERNAME</label>
|
||
<input type="text" id="apiSmtpUser" class="editor-input" placeholder="user@example.com">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiSmtpPass">PASSWORD</label>
|
||
<input type="password" id="apiSmtpPass" class="editor-input" placeholder="Enter SMTP password...">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent sm" onclick="AdminApp.saveApiKey('smtp')">⬡ SAVE</button>
|
||
</div>
|
||
|
||
<!-- Discord Webhook -->
|
||
<div class="apikey-group">
|
||
<h3 class="section-subheading">◈ DISCORD WEBHOOK</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="apiDiscordWebhook">WEBHOOK URL</label>
|
||
<input type="text" id="apiDiscordWebhook" class="editor-input" placeholder="https://discord.com/api/webhooks/...">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent sm" onclick="AdminApp.saveApiKey('discord')">⬡ SAVE</button>
|
||
</div>
|
||
|
||
<!-- GitHub Token -->
|
||
<div class="apikey-group">
|
||
<h3 class="section-subheading">⬡ GITHUB TOKEN</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="apiGithubToken">PERSONAL ACCESS TOKEN</label>
|
||
<input type="password" id="apiGithubToken" class="editor-input" placeholder="Enter GitHub token...">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent sm" onclick="AdminApp.saveApiKey('github')">⬡ SAVE</button>
|
||
</div>
|
||
|
||
<!-- Custom API 1 -->
|
||
<div class="apikey-group">
|
||
<h3 class="section-subheading">⟐ CUSTOM API 1</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiCustom1Name">NAME</label>
|
||
<input type="text" id="apiCustom1Name" class="editor-input" placeholder="API name...">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiCustom1Key">API KEY</label>
|
||
<input type="password" id="apiCustom1Key" class="editor-input" placeholder="Enter API key...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="apiCustom1URL">BASE URL</label>
|
||
<input type="text" id="apiCustom1URL" class="editor-input" placeholder="https://api.example.com/v1">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent sm" onclick="AdminApp.saveApiKey('custom1')">⬡ SAVE</button>
|
||
</div>
|
||
|
||
<!-- Custom API 2 -->
|
||
<div class="apikey-group">
|
||
<h3 class="section-subheading">⟐ CUSTOM API 2</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiCustom2Name">NAME</label>
|
||
<input type="text" id="apiCustom2Name" class="editor-input" placeholder="API name...">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiCustom2Key">API KEY</label>
|
||
<input type="password" id="apiCustom2Key" class="editor-input" placeholder="Enter API key...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="apiCustom2URL">BASE URL</label>
|
||
<input type="text" id="apiCustom2URL" class="editor-input" placeholder="https://api.example.com/v1">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent sm" onclick="AdminApp.saveApiKey('custom2')">⬡ SAVE</button>
|
||
</div>
|
||
|
||
<!-- Custom API 3 -->
|
||
<div class="apikey-group">
|
||
<h3 class="section-subheading">⟐ CUSTOM API 3</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiCustom3Name">NAME</label>
|
||
<input type="text" id="apiCustom3Name" class="editor-input" placeholder="API name...">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="apiCustom3Key">API KEY</label>
|
||
<input type="password" id="apiCustom3Key" class="editor-input" placeholder="Enter API key...">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="apiCustom3URL">BASE URL</label>
|
||
<input type="text" id="apiCustom3URL" class="editor-input" placeholder="https://api.example.com/v1">
|
||
</div>
|
||
</div>
|
||
<button class="action-btn accent sm" onclick="AdminApp.saveApiKey('custom3')">⬡ SAVE</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 11. THEME / APPEARANCE -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-theme" class="admin-section">
|
||
<h2 class="section-heading">◉ THEME / APPEARANCE</h2>
|
||
|
||
<!-- Color Pickers -->
|
||
<h3 class="section-subheading">◈ COLOURS</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="themeAccentColor">ACCENT COLOUR</label>
|
||
<div class="color-picker-row">
|
||
<input type="color" id="themeAccentColor" class="editor-input color-input" value="#00ffc8">
|
||
<input type="text" id="themeAccentColorHex" class="editor-input color-hex" value="#00ffc8" placeholder="#00ffc8">
|
||
</div>
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="themeBgColor">BACKGROUND COLOUR</label>
|
||
<div class="color-picker-row">
|
||
<input type="color" id="themeBgColor" class="editor-input color-input" value="#0a0e17">
|
||
<input type="text" id="themeBgColorHex" class="editor-input color-hex" value="#0a0e17" placeholder="#0a0e17">
|
||
</div>
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="themeTextColor">TEXT COLOUR</label>
|
||
<div class="color-picker-row">
|
||
<input type="color" id="themeTextColor" class="editor-input color-input" value="#e0e0e0">
|
||
<input type="text" id="themeTextColorHex" class="editor-input color-hex" value="#e0e0e0" placeholder="#e0e0e0">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Effect Toggles -->
|
||
<h3 class="section-subheading">⚡ EFFECTS</h3>
|
||
<div class="settings-grid">
|
||
<div class="setting-item">
|
||
<label class="editor-label">SCANLINES</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="themeScanlines" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">PARTICLES</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="themeParticles" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">GLITCH EFFECT</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="themeGlitch" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="setting-item">
|
||
<label class="editor-label">GRID BACKGROUND</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="themeGridBg" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Font Size -->
|
||
<h3 class="section-subheading">Aa TYPOGRAPHY</h3>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="themeFontSize">BASE FONT SIZE <span id="themeFontSizeVal" class="hud-val">16px</span></label>
|
||
<input type="range" id="themeFontSize" class="editor-input hud-range" min="12" max="24" value="16">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.saveTheme()">⬡ SAVE THEME</button>
|
||
<button class="action-btn" onclick="AdminApp.resetTheme()">↺ RESET TO DEFAULTS</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 12. SEO / META -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-seo" class="admin-section">
|
||
<h2 class="section-heading">⊛ SEO / META</h2>
|
||
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="seoTitle">SITE TITLE</label>
|
||
<input type="text" id="seoTitle" class="editor-input" placeholder="JAE // SWIFT">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="seoDescription">META DESCRIPTION</label>
|
||
<textarea id="seoDescription" class="editor-input editor-textarea-sm" placeholder="A brief description of your site for search engines..."></textarea>
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="seoKeywords">KEYWORDS</label>
|
||
<input type="text" id="seoKeywords" class="editor-input" placeholder="cyberpunk, developer, portfolio, blog">
|
||
</div>
|
||
</div>
|
||
<div class="editor-row">
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="seoOgImage">OG IMAGE URL</label>
|
||
<input type="text" id="seoOgImage" class="editor-input" placeholder="https://jaeswift.xyz/assets/og-image.png">
|
||
</div>
|
||
<div class="editor-field">
|
||
<label class="editor-label" for="seoFavicon">FAVICON URL</label>
|
||
<input type="text" id="seoFavicon" class="editor-input" placeholder="/assets/favicon.ico">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.saveSEO()">⬡ SAVE SEO</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 13. CONTACT SETTINGS -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-contact" class="admin-section">
|
||
<h2 class="section-heading">✉ CONTACT SETTINGS</h2>
|
||
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="contactEmail">CONTACT EMAIL ADDRESS</label>
|
||
<input type="email" id="contactEmail" class="editor-input" placeholder="you@example.com">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-row">
|
||
<div class="setting-item">
|
||
<label class="editor-label">ENABLE CONTACT FORM</label>
|
||
<label class="toggle-switch">
|
||
<input type="checkbox" id="contactFormEnabled" checked>
|
||
<span class="toggle-slider"></span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-row">
|
||
<div class="editor-field full">
|
||
<label class="editor-label" for="contactAutoReply">AUTO-REPLY MESSAGE</label>
|
||
<textarea id="contactAutoReply" class="editor-input editor-textarea-sm" placeholder="Thanks for reaching out! I'll get back to you soon..."></textarea>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="editor-actions">
|
||
<button class="action-btn accent" onclick="AdminApp.saveContact()">⬡ SAVE CONTACT</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<!-- 14. BACKUPS -->
|
||
<!-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -->
|
||
<div id="section-backups" class="admin-section">
|
||
<h2 class="section-heading">⛋ BACKUPS & EXPORT</h2>
|
||
|
||
<div class="backup-grid">
|
||
<!-- Individual Downloads -->
|
||
<div class="backup-card">
|
||
<div class="backup-card-icon">▤</div>
|
||
<div class="backup-card-title">POSTS DATA</div>
|
||
<div class="backup-card-desc">Download posts.json</div>
|
||
<button class="action-btn accent" onclick="AdminApp.downloadBackup('posts')">⬡ DOWNLOAD</button>
|
||
</div>
|
||
<div class="backup-card">
|
||
<div class="backup-card-icon">♫</div>
|
||
<div class="backup-card-title">TRACKS DATA</div>
|
||
<div class="backup-card-desc">Download tracks.json</div>
|
||
<button class="action-btn accent" onclick="AdminApp.downloadBackup('tracks')">⬡ DOWNLOAD</button>
|
||
</div>
|
||
<div class="backup-card">
|
||
<div class="backup-card-icon">⚙</div>
|
||
<div class="backup-card-title">SETTINGS DATA</div>
|
||
<div class="backup-card-desc">Download settings.json</div>
|
||
<button class="action-btn accent" onclick="AdminApp.downloadBackup('settings')">⬡ DOWNLOAD</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Export All -->
|
||
<div class="backup-export">
|
||
<h3 class="section-subheading">⛋ FULL EXPORT</h3>
|
||
<p class="backup-desc">Download all site data (posts, tracks, settings) as a single ZIP archive.</p>
|
||
<button class="action-btn accent lg" onclick="AdminApp.downloadBackup('all')">⬡ EXPORT ALL DATA (ZIP)</button>
|
||
</div>
|
||
|
||
<!-- Backup Status -->
|
||
<div id="backupStatus" class="backup-status"></div>
|
||
</div>
|
||
|
||
</div><!-- /main-content -->
|
||
</div><!-- /adminApp -->
|
||
|
||
<!-- ═══════════════════════════════════════════════════════ -->
|
||
<!-- NOTIFICATION TOAST -->
|
||
<!-- ═══════════════════════════════════════════════════════ -->
|
||
<div id="notification" class="notification"></div>
|
||
|
||
<!-- Scripts -->
|
||
<script src="js/admin.js"></script>
|
||
</body>
|
||
</html>
|