001 / admin.html
flen-crypto's picture
fix broken links and embeds
3951d02 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin - Mr.FLEN</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<link rel="stylesheet" href="style.css">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#0B2D2F',
accent: '#FF914D',
magenta: '#C5427A',
paper: '#0A0F10'
}
}
}
}
</script>
</head>
<body class="bg-paper text-white min-h-screen flex flex-col">
<custom-navbar></custom-navbar>
<main class="flex-1 py-12 px-4">
<div class="max-w-6xl mx-auto">
<!-- Admin Header -->
<div class="text-center mb-12">
<h1 class="text-4xl md:text-5xl font-bold mb-4">
<span class="bg-gradient-to-r from-accent to-magenta bg-clip-text text-transparent">
EMBEDS MANAGER
</span>
</h1>
<p class="text-lg text-gray-400 max-w-2xl mx-auto">
Manage track embeds and export configuration
</p>
</div>
<!-- Security Check -->
<div id="securityCheck" class="max-w-md mx-auto bg-primary/20 rounded-2xl p-8 backdrop-blur-sm border border-accent/20">
<h3 class="text-xl font-semibold mb-4">Admin Access</h3>
<p class="text-gray-400 mb-4">Enter PIN to access embeds manager</p>
<input type="password" id="adminPin"
placeholder="Enter 6-digit PIN"
class="w-full bg-primary/10 border border-accent/20 rounded-full py-3 px-6 mb-4 focus:border-accent focus:outline-none transition-all duration-300">
<button onclick="checkAdminAccess()"
class="w-full bg-accent hover:bg-accent/80 text-paper font-bold py-3 px-8 rounded-full transition-all duration-300">
Access Admin
</button>
</div>
</div>
</div>
<!-- Embeds Manager (Hidden by default) -->
<div id="embedsManager" class="hidden">
<!-- Export Controls -->
<div class="flex justify-between items-center mb-8">
<h2 class="text-2xl font-bold">Track Embeds</h2>
<div class="flex gap-4">
<button onclick="exportAlbumData()"
class="flex items-center gap-2 bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded-full transition-all duration-300">
<i data-feather="download" class="w-4 h-4"></i>
Export JSON
</button>
<button onclick="resetAlbumData()"
class="flex items-center gap-2 bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded-full transition-all duration-300">
<i data-feather="refresh-cw" class="w-4 h-4"></i>
Reset Data
</button>
</div>
</div>
<!-- Tracks List -->
<div id="tracksAdminList" class="space-y-6">
<!-- Tracks will be populated by JavaScript -->
</div>
</div>
</div>
</main>
<custom-footer></custom-footer>
<script src="components/navbar.js"></script>
<script src="components/footer.js"></script>
<script src="script.js"></script>
<script>
feather.replace();
document.addEventListener('DOMContentLoaded', function() {
// Check if already authenticated
if (localStorage.getItem('mrflen_admin_auth') === 'true') {
showEmbedsManager();
}
});
function checkAdminAccess() {
const pinInput = document.getElementById('adminPin');
const enteredPin = pinInput.value;
// For MVP, use a simple PIN (in production, use environment variable)
const adminPin = '123456'; // Should be from environment variable
if (enteredPin === adminPin) {
localStorage.setItem('mrflen_admin_auth', 'true');
showEmbedsManager();
} else {
alert('Invalid PIN. Please try again.');
}
}
function showEmbedsManager() {
document.getElementById('securityCheck').classList.add('hidden');
document.getElementById('embedsManager').classList.remove('hidden');
loadAdminTracks();
}
function loadAdminTracks() {
const container = document.getElementById('tracksAdminList');
if (!container) return;
container.innerHTML = albumData.tracks.map(track => `
<div class="bg-primary/20 rounded-2xl p-6 backdrop-blur-sm border border-accent/20">
<div class="flex items-start justify-between mb-4">
<h3 class="text-xl font-semibold">${track.no}. ${track.title}</h3>
<span class="text-sm ${track.embeds && track.embeds.length > 0 ? 'text-green-400' : 'text-red-400'}">
${track.embeds && track.embeds.length > 0 ? `${track.embeds.length} embed(s)` : 'No embeds'}</span>
</div>
<!-- Embeds List for this track -->
<div id="embeds-${track.slug}" class="space-y-4 mb-4">
${track.embeds ? track.embeds.map((embed, index) => `
<div class="bg-primary/10 rounded-xl p-4">
<div class="flex items-center gap-4 mb-2">
<select class="provider-select bg-primary/20 border border-accent/20 rounded-full py-2 px-4 focus:border-accent focus:outline-none transition-all duration-300"
onchange="updateEmbedProvider('${track.slug}', ${index}, this.value)">
<option value="soundcloud" ${embed.provider === 'soundcloud' ? 'selected' : ''}>SoundCloud</option>
<option value="spotify" ${embed.provider === 'spotify' ? 'selected' : ''}>Spotify</option>
<option value="youtube" ${embed.provider === 'youtube' ? 'selected' : ''}>YouTube</option>
<option value="bandcamp" ${embed.provider === 'bandcamp' ? 'selected' : ''}>Bandcamp</option>
</select>
<input type="text"
value="${embed.url}"
placeholder="Embed URL"
class="flex-1 bg-primary/20 border border-accent/20 rounded-full py-2 px-4 focus:border-accent focus:outline-none transition-all duration-300"
oninput="updateEmbedUrl('${track.slug}', ${index}, this.value)"
class="w-full">
</div>
<div class="aspect-video rounded-lg bg-primary/10 border border-accent/20">
<iframe src="${embed.url}" class="w-full h-full rounded-lg" loading="lazy" allow="autoplay"></iframe>
</div>
`).join('') : '<p class="text-gray-400 text-sm">No embeds configured</p>'}
</div>
<!-- Add New Embed Button -->
<button onclick="addNewEmbed('${track.slug}')"
class="w-full border border-dashed border-accent/30 hover:border-accent/50 text-accent font-medium py-3 rounded-xl transition-all duration-300">
<i data-feather="plus" class="w-4 h-4 inline mr-2"></i>
Add Embed
</button>
</div>
</div>
`).join('');
feather.replace();
}
function updateEmbedProvider(trackSlug, embedIndex, newProvider) {
const track = albumData.tracks.find(t => t.slug === trackSlug);
if (track && track.embeds[embedIndex]) {
track.embeds[embedIndex].provider = newProvider;
saveAlbumData();
loadAdminTracks(); // Refresh to show updated preview
}
function updateEmbedUrl(trackSlug, embedIndex, newUrl) {
const track = albumData.tracks.find(t => t.slug === trackSlug);
if (track && track.embeds[embedIndex]) {
track.embeds[embedIndex].url = newUrl;
saveAlbumData();
loadAdminTracks(); // Refresh to show updated preview
}
function addNewEmbed(trackSlug) {
const track = albumData.tracks.find(t => t.slug === trackSlug);
if (track) {
if (!track.embeds) track.embeds = [];
track.embeds.push({
provider: 'soundcloud',
url: ''
});
saveAlbumData();
loadAdminTracks();
}
}
function resetAlbumData() {
if (confirm('Are you sure you want to reset all album data? This cannot be undone.')) {
localStorage.removeItem('mrflen_album_data');
window.location.reload();
}
}
</script>
</body>
</html>