xenthra-inc / index.html
DevXen's picture
Add 1 files
5240316 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>V-Sysop Extreme: BBS Manager</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@keyframes terminal-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
@keyframes shake {
0% { transform: translateX(0); }
25% { transform: translateX(-5px); }
50% { transform: translateX(5px); }
75% { transform: translateX(-5px); }
100% { transform: translateX(0); }
}
.terminal {
background-color: #0f172a;
background-image:
linear-gradient(rgba(30, 41, 59, 0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(30, 41, 59, 0.1) 1px, transparent 1px);
background-size: 20px 20px;
font-family: 'Courier New', monospace;
}
.cursor {
animation: terminal-blink 1s infinite;
}
.bbs-header {
background: linear-gradient(90deg, #1e40af 0%, #7e22ce 100%);
}
.alert-shake {
animation: shake 0.5s;
}
.user-active {
box-shadow: 0 0 10px #10b981;
}
.user-idle {
box-shadow: 0 0 10px #f59e0b;
}
.user-new {
box-shadow: 0 0 10px #3b82f6;
}
</style>
</head>
<body class="bg-slate-900 text-slate-200 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header with BBS Info -->
<header class="mb-8 bbs-header rounded-lg p-4 text-white">
<div class="flex justify-between items-center">
<div>
<h1 class="text-3xl font-bold">V-Sysop <span class="text-yellow-300">Extreme</span></h1>
<div class="text-sm">Your BBS: <span class="font-mono">MEGABBS</span></div>
</div>
<div class="text-right">
<div class="text-xl">Nodes: <span id="node-count" class="font-bold">1</span>/4</div>
<div class="text-sm">Uptime: <span id="bbs-uptime">0d 0h 0m</span></div>
</div>
</div>
<div class="flex justify-between mt-4 text-xs">
<div>Sysop: <span class="font-mono">ADMIN</span></div>
<div>Callers Today: <span id="caller-count">0</span></div>
<div>Files: <span id="file-count">42</span></div>
<div>Messages: <span id="message-count">128</span></div>
</div>
</header>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Main Terminal -->
<div class="lg:col-span-2">
<div class="terminal rounded-lg border border-blue-500 p-4 h-full">
<div class="flex items-center mb-4">
<div class="w-3 h-3 rounded-full bg-red-500 mr-2"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500 mr-2"></div>
<div class="w-3 h-3 rounded-full bg-green-500"></div>
<div class="ml-auto text-sm text-slate-400">BBS MODE: ONLINE</div>
</div>
<div id="terminal-output" class="h-96 overflow-y-auto mb-4 font-mono space-y-2">
<p class="text-green-400">> Welcome to V-Sysop Extreme BBS Manager v2.0</p>
<p class="text-green-400">> BBS system initialized...</p>
<p class="text-green-400">> Loading node configuration...</p>
<p class="text-green-400">> Ready for commands.</p>
<p class="text-green-400">> Type 'help' for available commands</p>
</div>
<div class="flex items-center border-t border-slate-700 pt-2">
<span class="text-green-400 mr-2">></span>
<input id="command-input" type="text" class="flex-grow bg-transparent border-none outline-none font-mono" placeholder="Enter command..." autofocus>
<span class="cursor ml-1"></span>
</div>
</div>
</div>
<!-- BBS Dashboard -->
<div class="space-y-6">
<!-- Active Users -->
<div class="bg-slate-800 rounded-lg border border-slate-700 p-4">
<h2 class="text-xl font-bold mb-3 text-blue-400 flex items-center">
<i class="fas fa-users mr-2"></i> Active Callers
</h2>
<div id="active-users" class="space-y-2">
<div class="text-center py-4 text-slate-500">
<i class="fas fa-user-slash text-2xl mb-2"></i>
<p>No active callers</p>
</div>
</div>
</div>
<!-- BBS Statistics -->
<div class="bg-slate-800 rounded-lg border border-slate-700 p-4">
<h2 class="text-xl font-bold mb-3 text-blue-400 flex items-center">
<i class="fas fa-chart-bar mr-2"></i> BBS Stats
</h2>
<div class="grid grid-cols-2 gap-4">
<div class="bg-slate-700 rounded p-2 text-center">
<div class="text-2xl font-bold" id="daily-calls">0</div>
<div class="text-xs">Calls Today</div>
</div>
<div class="bg-slate-700 rounded p-2 text-center">
<div class="text-2xl font-bold" id="new-users">0</div>
<div class="text-xs">New Users</div>
</div>
<div class="bg-slate-700 rounded p-2 text-center">
<div class="text-2xl font-bold" id="uploads">0</div>
<div class="text-xs">Uploads</div>
</div>
<div class="bg-slate-700 rounded p-2 text-center">
<div class="text-2xl font-bold" id="downloads">0</div>
<div class="text-xs">Downloads</div>
</div>
</div>
</div>
<!-- Quick Commands -->
<div class="bg-slate-800 rounded-lg border border-slate-700 p-4">
<h2 class="text-xl font-bold mb-3 text-blue-400 flex items-center">
<i class="fas fa-bolt mr-2"></i> Quick Commands
</h2>
<div class="grid grid-cols-2 gap-2">
<button class="quick-command-btn bg-blue-600 hover:bg-blue-500 text-sm py-1 px-2 rounded" data-command="users">
<i class="fas fa-users mr-1"></i> Users
</button>
<button class="quick-command-btn bg-purple-600 hover:bg-purple-500 text-sm py-1 px-2 rounded" data-command="files">
<i class="fas fa-file-archive mr-1"></i> Files
</button>
<button class="quick-command-btn bg-green-600 hover:bg-green-500 text-sm py-1 px-2 rounded" data-command="messages">
<i class="fas fa-comments mr-1"></i> Messages
</button>
<button class="quick-command-btn bg-yellow-600 hover:bg-yellow-500 text-sm py-1 px-2 rounded" data-command="config">
<i class="fas fa-cog mr-1"></i> Config
</button>
<button class="quick-command-btn bg-red-600 hover:bg-red-500 text-sm py-1 px-2 rounded" data-command="restart">
<i class="fas fa-sync-alt mr-1"></i> Restart
</button>
<button class="quick-command-btn bg-pink-600 hover:bg-pink-500 text-sm py-1 px-2 rounded" data-command="sysop">
<i class="fas fa-user-secret mr-1"></i> Sysop
</button>
</div>
</div>
</div>
</div>
<!-- Alerts Section -->
<div id="alerts-container" class="fixed bottom-4 right-4 space-y-2 w-80"></div>
</div>
<script>
// BBS State
const bbsState = {
nodes: 1,
maxNodes: 4,
uptime: 0, // in minutes
callersToday: 0,
newUsersToday: 0,
uploadsToday: 0,
downloadsToday: 0,
files: 42,
messages: 128,
activeUsers: [],
achievements: [],
commandsExecuted: 0,
restarts: 0,
filesUploaded: 0,
messagesPosted: 0,
usersBanned: 0,
nodesAdded: 0
};
// Available Commands
const commands = {
'help': {
description: 'Show available commands',
execute: () => {
addTerminalOutput(`
Available commands:
<span class="text-yellow-400">help</span> - Show this help message
<span class="text-yellow-400">users</span> - List all users
<span class="text-yellow-400">callers</span> - Show active callers
<span class="text-yellow-400">files</span> - Manage file areas
<span class="text-yellow-400">messages</span> - Manage message areas
<span class="text-yellow-400">config</span> - Configure BBS settings
<span class="text-yellow-400">restart</span> - Restart BBS system
<span class="text-yellow-400">sysop</span> - Sysop utilities
<span class="text-yellow-400">stats</span> - Show BBS statistics
`);
}
},
'users': {
description: 'List all users',
execute: () => {
addTerminalOutput('<span class="text-blue-400">> Loading user database...</span>');
setTimeout(() => {
addTerminalOutput(`
User List:
<span class="text-green-400">ADMIN</span> - Sysop (Last call: Today)
<span class="text-blue-400">JOHNDOE</span> - User (Last call: Yesterday)
<span class="text-blue-400">JANEDOE</span> - User (Last call: 3 days ago)
<span class="text-blue-400">HACKER</span> - User (Last call: 1 week ago)
<span class="text-blue-400">NEWBIE</span> - New User (Last call: Today)
`);
addTerminalOutput('<span class="text-yellow-400">> Total users: 5</span>');
}, 1000);
}
},
'callers': {
description: 'Show active callers',
execute: () => {
if (bbsState.activeUsers.length === 0) {
addTerminalOutput('<span class="text-yellow-400">> No active callers</span>');
} else {
addTerminalOutput('<span class="text-blue-400">> Active callers:</span>');
bbsState.activeUsers.forEach(user => {
addTerminalOutput(`<span class="text-green-400">> ${user.name}</span> - ${user.status} (Node ${user.node})`);
});
}
}
},
'files': {
description: 'Manage file areas',
execute: (args) => {
if (args.length === 0) {
addTerminalOutput(`
File Area Management:
<span class="text-yellow-400">files list</span> - List file areas
<span class="text-yellow-400">files add [name]</span> - Add new file area
<span class="text-yellow-400">files del [name]</span> - Delete file area
<span class="text-yellow-400">files stats</span> - Show file statistics
`);
} else if (args[0] === 'list') {
addTerminalOutput(`
File Areas:
1. Public Files (${Math.floor(bbsState.files * 0.7)} files)
2. Games (${Math.floor(bbsState.files * 0.2)} files)
3. Utilities (${Math.floor(bbsState.files * 0.1)} files)
`);
} else if (args[0] === 'stats') {
addTerminalOutput(`
File Statistics:
Total files: ${bbsState.files}
Uploads today: ${bbsState.uploadsToday}
Downloads today: ${bbsState.downloadsToday}
`);
} else if (args[0] === 'add' && args[1]) {
addTerminalOutput(`<span class="text-blue-400">> Creating new file area: ${args[1]}</span>`);
setTimeout(() => {
addTerminalOutput(`<span class="text-green-400">> File area "${args[1]}" created successfully</span>`);
}, 1500);
} else if (args[0] === 'del' && args[1]) {
addTerminalOutput(`<span class="text-blue-400">> Deleting file area: ${args[1]}</span>`);
setTimeout(() => {
addTerminalOutput(`<span class="text-green-400">> File area "${args[1]}" deleted successfully</span>`);
}, 1500);
} else {
addTerminalOutput('<span class="text-red-400">> Error: Invalid files command</span>');
}
}
},
'messages': {
description: 'Manage message areas',
execute: (args) => {
if (args.length === 0) {
addTerminalOutput(`
Message Area Management:
<span class="text-yellow-400">messages list</span> - List message areas
<span class="text-yellow-400">messages read [area]</span> - Read messages
<span class="text-yellow-400">messages post [area]</span> - Post new message
<span class="text-yellow-400">messages stats</span> - Show message statistics
`);
} else if (args[0] === 'list') {
addTerminalOutput(`
Message Areas:
1. General Discussion (${Math.floor(bbsState.messages * 0.5)} messages)
2. Tech Talk (${Math.floor(bbsState.messages * 0.3)} messages)
3. Announcements (${Math.floor(bbsState.messages * 0.2)} messages)
`);
} else if (args[0] === 'stats') {
addTerminalOutput(`
Message Statistics:
Total messages: ${bbsState.messages}
New today: ${Math.floor(bbsState.messages * 0.1)}
`);
} else if (args[0] === 'read' && args[1]) {
addTerminalOutput(`<span class="text-blue-400">> Loading messages from area: ${args[1]}</span>`);
setTimeout(() => {
addTerminalOutput(`
Recent Messages:
1. ADMIN - Welcome to the BBS! (Today)
2. JOHNDOE - Testing the system (Today)
3. JANEDOE - Hello everyone! (Yesterday)
`);
}, 1500);
} else if (args[0] === 'post' && args[1]) {
addTerminalOutput(`<span class="text-blue-400">> Posting to area: ${args[1]}</span>`);
setTimeout(() => {
addTerminalOutput('<span class="text-green-400">> Message posted successfully</span>');
bbsState.messages++;
bbsState.messagesPosted++;
updateStats();
checkAchievements();
}, 1500);
} else {
addTerminalOutput('<span class="text-red-400">> Error: Invalid messages command</span>');
}
}
},
'config': {
description: 'Configure BBS settings',
execute: (args) => {
if (args.length === 0) {
addTerminalOutput(`
Configuration:
<span class="text-yellow-400">config show</span> - Show current configuration
<span class="text-yellow-400">config nodes [number]</span> - Set number of nodes
<span class="text-yellow-400">config name [name]</span> - Change BBS name
`);
} else if (args[0] === 'show') {
addTerminalOutput(`
Current Configuration:
BBS Name: MEGABBS
Nodes: ${bbsState.nodes}/${bbsState.maxNodes}
File Areas: 3
Message Areas: 3
`);
} else if (args[0] === 'nodes' && args[1]) {
const nodes = parseInt(args[1]);
if (nodes > 0 && nodes <= bbsState.maxNodes) {
addTerminalOutput(`<span class="text-blue-400">> Setting nodes to ${nodes}</span>`);
setTimeout(() => {
if (nodes > bbsState.nodes) {
bbsState.nodesAdded += (nodes - bbsState.nodes);
checkAchievements();
}
bbsState.nodes = nodes;
updateStats();
addTerminalOutput(`<span class="text-green-400">> Nodes set to ${nodes}</span>`);
}, 1500);
} else {
addTerminalOutput(`<span class="text-red-400">> Error: Nodes must be between 1 and ${bbsState.maxNodes}</span>`);
}
} else if (args[0] === 'name' && args[1]) {
addTerminalOutput(`<span class="text-blue-400">> Changing BBS name to ${args[1]}</span>`);
setTimeout(() => {
addTerminalOutput(`<span class="text-green-400">> BBS name changed to ${args[1]}</span>`);
document.querySelector('header h1').innerHTML = `V-Sysop <span class="text-yellow-300">Extreme</span>`;
document.querySelector('header .text-sm span').textContent = args[1];
}, 1500);
} else {
addTerminalOutput('<span class="text-red-400">> Error: Invalid config command</span>');
}
}
},
'restart': {
description: 'Restart BBS system',
execute: () => {
addTerminalOutput('<span class="text-red-400">> WARNING: This will disconnect all users</span>');
addTerminalOutput('<span class="text-yellow-400">> Type "restart confirm" to proceed</span>');
if (args && args[0] === 'confirm') {
addTerminalOutput('<span class="text-blue-400">> Restarting BBS system...</span>');
setTimeout(() => {
// Disconnect all users
bbsState.activeUsers = [];
updateActiveUsers();
// Increment uptime by 1 minute (simulating quick restart)
bbsState.uptime += 1;
updateStats();
bbsState.restarts++;
checkAchievements();
addTerminalOutput('<span class="text-green-400">> BBS restarted successfully</span>');
createAlert('System Restart', 'BBS has been restarted', 'yellow');
}, 2000);
}
}
},
'sysop': {
description: 'Sysop utilities',
execute: (args) => {
if (args.length === 0) {
addTerminalOutput(`
Sysop Utilities:
<span class="text-yellow-400">sysop ban [user]</span> - Ban a user
<span class="text-yellow-400">sysop promote [user]</span> - Promote user to co-sysop
<span class="text-yellow-400">sysop extreme</span> - Enable extreme mode
`);
} else if (args[0] === 'ban' && args[1]) {
addTerminalOutput(`<span class="text-red-400">> Banning user: ${args[1]}</span>`);
setTimeout(() => {
addTerminalOutput(`<span class="text-green-400">> User ${args[1]} banned successfully</span>`);
bbsState.usersBanned++;
checkAchievements();
createAlert('User Banned', `${args[1]} has been banned`, 'red');
}, 1500);
} else if (args[0] === 'promote' && args[1]) {
addTerminalOutput(`<span class="text-blue-400">> Promoting user: ${args[1]}</span>`);
setTimeout(() => {
addTerminalOutput(`<span class="text-green-400">> User ${args[1]} promoted to co-sysop</span>`);
createAlert('Promotion', `${args[1]} is now a co-sysop`, 'green');
}, 1500);
} else if (args[0] === 'extreme') {
addTerminalOutput('<span class="text-purple-400">> ACTIVATING EXTREME MODE</span>');
setTimeout(() => {
document.body.classList.add('bg-gradient-to-br', 'from-slate-900', 'to-purple-900');
addTerminalOutput('<span class="text-purple-400">> EXTREME MODE ENGAGED</span>');
addTerminalOutput('<span class="text-purple-400">> ALL NODES AT 200% CAPACITY</span>');
createAlert('Extreme Mode', 'All nodes operating at maximum capacity!', 'purple');
}, 1000);
} else {
addTerminalOutput('<span class="text-red-400">> Error: Invalid sysop command</span>');
}
}
},
'stats': {
description: 'Show BBS statistics',
execute: () => {
addTerminalOutput(`
BBS Statistics:
Uptime: ${Math.floor(bbsState.uptime / 1440)}d ${Math.floor((bbsState.uptime % 1440) / 60)}h ${bbsState.uptime % 60}m
Callers Today: ${bbsState.callersToday}
New Users Today: ${bbsState.newUsersToday}
Files: ${bbsState.files}
Messages: ${bbsState.messages}
Active Nodes: ${bbsState.nodes}/${bbsState.maxNodes}
`);
}
}
};
// Achievements
const achievements = [
{
id: 'first_command',
name: 'First Command',
description: 'Execute your first command',
icon: 'fa-terminal',
color: 'bg-blue-500',
check: () => bbsState.commandsExecuted >= 1
},
{
id: 'power_user',
name: 'Power User',
description: 'Execute 10 commands',
icon: 'fa-keyboard',
color: 'bg-green-500',
check: () => bbsState.commandsExecuted >= 10
},
{
id: 'sysop_tools',
name: 'Sysop Tools',
description: 'Use all sysop commands',
icon: 'fa-user-secret',
color: 'bg-purple-500',
check: () => bbsState.usersBanned >= 1 && bbsState.restarts >= 1
},
{
id: 'file_master',
name: 'File Master',
description: 'Upload 5 files',
icon: 'fa-file-upload',
color: 'bg-yellow-500',
check: () => bbsState.filesUploaded >= 5
},
{
id: 'message_king',
name: 'Message King',
description: 'Post 10 messages',
icon: 'fa-comment-alt',
color: 'bg-pink-500',
check: () => bbsState.messagesPosted >= 10
},
{
id: 'node_expander',
name: 'Node Expander',
description: 'Add a node',
icon: 'fa-server',
color: 'bg-red-500',
check: () => bbsState.nodesAdded >= 1
},
{
id: 'bbs_legend',
name: 'BBS Legend',
description: 'Reach 24 hours uptime',
icon: 'fa-trophy',
color: 'bg-indigo-500',
check: () => bbsState.uptime >= 1440
}
];
// DOM Elements
const terminalOutput = document.getElementById('terminal-output');
const commandInput = document.getElementById('command-input');
const activeUsersContainer = document.getElementById('active-users');
const alertsContainer = document.getElementById('alerts-container');
const quickCommandBtns = document.querySelectorAll('.quick-command-btn');
// Initialize the BBS
function init() {
// Set up event listeners
commandInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') executeCommand();
});
quickCommandBtns.forEach(btn => {
btn.addEventListener('click', function() {
commandInput.value = this.getAttribute('data-command');
commandInput.focus();
});
});
// Start uptime counter
setInterval(() => {
bbsState.uptime++;
updateStats();
// Check for achievements
checkAchievements();
// Random user activity
if (Math.random() < 0.1) simulateUserActivity();
}, 60000); // 1 minute = 1 minute uptime
// Initial stats update
updateStats();
// Simulate initial user activity
setTimeout(simulateUserActivity, 3000);
}
// Execute a command
function executeCommand() {
const input = commandInput.value.trim();
if (!input) return;
// Add command to terminal
addTerminalOutput(`<span class="text-blue-400">> ${input}</span>`);
// Parse command
const parts = input.split(' ');
const cmd = parts[0].toLowerCase();
const args = parts.slice(1);
// Execute command if found
if (commands[cmd]) {
commands[cmd].execute(args);
bbsState.commandsExecuted++;
checkAchievements();
} else {
addTerminalOutput(`<span class="text-red-400">> Error: Unknown command '${cmd}'</span>`);
}
// Clear input
commandInput.value = '';
}
// Add output to terminal
function addTerminalOutput(text) {
const line = document.createElement('p');
line.innerHTML = text;
terminalOutput.appendChild(line);
terminalOutput.scrollTop = terminalOutput.scrollHeight;
}
// Update stats display
function updateStats() {
// Update header stats
document.getElementById('node-count').textContent = `${bbsState.nodes}/${bbsState.maxNodes}`;
const days = Math.floor(bbsState.uptime / 1440);
const hours = Math.floor((bbsState.uptime % 1440) / 60);
const minutes = bbsState.uptime % 60;
document.getElementById('bbs-uptime').textContent = `${days}d ${hours}h ${minutes}m`;
document.getElementById('caller-count').textContent = bbsState.callersToday;
document.getElementById('file-count').textContent = bbsState.files;
document.getElementById('message-count').textContent = bbsState.messages;
// Update dashboard stats
document.getElementById('daily-calls').textContent = bbsState.callersToday;
document.getElementById('new-users').textContent = bbsState.newUsersToday;
document.getElementById('uploads').textContent = bbsState.uploadsToday;
document.getElementById('downloads').textContent = bbsState.downloadsToday;
}
// Update active users display
function updateActiveUsers() {
activeUsersContainer.innerHTML = '';
if (bbsState.activeUsers.length === 0) {
activeUsersContainer.innerHTML = `
<div class="text-center py-4 text-slate-500">
<i class="fas fa-user-slash text-2xl mb-2"></i>
<p>No active callers</p>
</div>
`;
} else {
bbsState.activeUsers.forEach(user => {
const userEl = document.createElement('div');
userEl.className = `flex items-center p-2 rounded ${user.status === 'Active' ? 'user-active' : user.status === 'New' ? 'user-new' : 'user-idle'}`;
userEl.innerHTML = `
<div class="w-10 h-10 rounded-full bg-slate-700 flex items-center justify-center mr-3">
<i class="fas fa-user"></i>
</div>
<div>
<div class="font-bold">${user.name}</div>
<div class="text-xs">${user.status} • Node ${user.node}</div>
</div>
<div class="ml-auto text-xs text-slate-400">
${user.time} min
</div>
`;
activeUsersContainer.appendChild(userEl);
});
}
}
// Simulate user activity
function simulateUserActivity() {
// Random chance of user connecting/disconnecting
if (bbsState.activeUsers.length === 0 || Math.random() < 0.3) {
// New user connects
if (bbsState.activeUsers.length < bbsState.nodes) {
const userTypes = [
{ name: 'JOHNDOE', status: 'Active' },
{ name: 'JANEDOE', status: 'Idle' },
{ name: 'NEWBIE', status: 'New' },
{ name: 'HACKER', status: 'Active' }
];
const user = userTypes[Math.floor(Math.random() * userTypes.length)];
user.node = bbsState.activeUsers.length + 1;
user.time = Math.floor(Math.random() * 30) + 1;
bbsState.activeUsers.push(user);
bbsState.callersToday++;
if (user.status === 'New') {
bbsState.newUsersToday++;
}
updateStats();
updateActiveUsers();
if (user.status === 'New') {
createAlert('New User', `${user.name} has joined the BBS!`, 'blue');
}
}
} else if (Math.random() < 0.2) {
// User disconnects
const index = Math.floor(Math.random() * bbsState.activeUsers.length);
const user = bbsState.activeUsers[index];
bbsState.activeUsers.splice(index, 1);
// Random file upload/download
if (Math.random() < 0.5) {
bbsState.uploadsToday++;
bbsState.files++;
bbsState.filesUploaded++;
} else {
bbsState.downloadsToday++;
}
updateStats();
updateActiveUsers();
checkAchievements();
} else {
// Update time for active users
bbsState.activeUsers.forEach(user => {
user.time += Math.floor(Math.random() * 5) + 1;
// Random chance to post message
if (Math.random() < 0.1) {
bbsState.messages++;
bbsState.messagesPosted++;
}
});
updateActiveUsers();
checkAchievements();
}
}
// Check for achievements
function checkAchievements() {
achievements.forEach(achievement => {
if (!bbsState.achievements.includes(achievement.id) && achievement.check()) {
// Unlock achievement
bbsState.achievements.push(achievement.id);
createAlert('Achievement Unlocked!', achievement.name, 'purple');
}
});
}
// Create an alert
function createAlert(title, message, color) {
const alertEl = document.createElement('div');
alertEl.className = `alert-shake bg-slate-800 border-l-4 border-${color}-500 p-3 rounded shadow-lg`;
alertEl.innerHTML = `
<div class="flex items-start">
<div class="flex-shrink-0">
<i class="fas ${getAlertIcon(color)} text-${color}-500"></i>
</div>
<div class="ml-3">
<h3 class="text-sm font-medium text-white">${title}</h3>
<div class="mt-1 text-sm text-slate-300">${message}</div>
<div class="mt-2">
<button class="close-alert-btn text-xs bg-slate-700 hover:bg-slate-600 px-2 py-1 rounded">
Dismiss
</button>
</div>
</div>
</div>
`;
alertsContainer.appendChild(alertEl);
// Auto-remove after 5 seconds
const timeout = setTimeout(() => {
alertEl.remove();
}, 5000);
// Add close button event
const closeBtn = alertEl.querySelector('.close-alert-btn');
closeBtn.addEventListener('click', () => {
clearTimeout(timeout);
alertEl.remove();
});
}
// Get icon for alert type
function getAlertIcon(color) {
switch(color) {
case 'red': return 'fa-exclamation-circle';
case 'green': return 'fa-check-circle';
case 'yellow': return 'fa-exclamation-triangle';
case 'blue': return 'fa-info-circle';
case 'purple': return 'fa-trophy';
default: return 'fa-bell';
}
}
// Initialize the BBS
window.addEventListener('DOMContentLoaded', init);
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=DevXen/xenthra-inc" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>