Spaces:
Running
Running
Download index.html from Mochitik009/klein-server: direct link, hf CLI and curl.
- Browser
- Download file 53.7 kB
-
https://huggingface.co/spaces/Mochitik009/klein-server/resolve/main/index.html
- Command line
-
hf download hf://spaces/Mochitik009/klein-server/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Mochitik009/klein-server/resolve/main/index.html
53.7 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Kleinanzeigen Monitor - Server Management</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> | |
| /* Custom scrollbar */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #f1f1f1; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: #888; | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: #555; | |
| } | |
| /* Log window styling */ | |
| .log-entry { | |
| font-family: 'Courier New', monospace; | |
| font-size: 0.9rem; | |
| padding: 2px 0; | |
| border-bottom: 1px solid #eee; | |
| } | |
| .log-entry.info { color: #4a5568; } | |
| .log-entry.warning { color: #d69e2e; } | |
| .log-entry.error { color: #e53e3e; } | |
| .log-entry.success { color: #38a169; } | |
| /* Animation for server status */ | |
| @keyframes pulse { | |
| 0% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| 100% { opacity: 1; } | |
| } | |
| .status-pulse { | |
| animation: pulse 2s infinite; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100"> | |
| <!-- Login Modal --> | |
| <div id="loginModal" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50"> | |
| <div class="bg-white p-8 rounded-lg shadow-xl w-96"> | |
| <h2 class="text-2xl font-bold mb-6 text-center">Server Login</h2> | |
| <div class="mb-4"> | |
| <label class="block text-gray-700 text-sm font-bold mb-2" for="username">Username</label> | |
| <input id="username" type="text" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"> | |
| </div> | |
| <div class="mb-6"> | |
| <label class="block text-gray-700 text-sm font-bold mb-2" for="password">Password</label> | |
| <input id="password" type="password" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <button id="loginBtn" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full"> | |
| Login | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Dashboard (hidden until login) --> | |
| <div id="dashboard" class="hidden h-screen flex flex-col"> | |
| <!-- Top Navigation --> | |
| <nav class="bg-gray-800 text-white p-4 flex justify-between items-center"> | |
| <div class="flex items-center space-x-4"> | |
| <h1 class="text-xl font-bold">Kleinanzeigen Monitor</h1> | |
| <div id="serverStatus" class="flex items-center"> | |
| <span class="w-3 h-3 rounded-full bg-red-500 mr-2"></span> | |
| <span>Server Offline</span> | |
| </div> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <span id="currentUser" class="font-medium"></span> | |
| <button id="logoutBtn" class="bg-gray-700 hover:bg-gray-600 px-3 py-1 rounded"> | |
| <i class="fas fa-sign-out-alt mr-1"></i> Logout | |
| </button> | |
| </div> | |
| </nav> | |
| <div class="flex flex-1 overflow-hidden"> | |
| <!-- Sidebar --> | |
| <aside class="w-64 bg-gray-700 text-white p-4 overflow-y-auto"> | |
| <nav> | |
| <ul class="space-y-2"> | |
| <li> | |
| <a href="#" class="tab-link flex items-center p-2 rounded hover:bg-gray-600 active" data-tab="dashboard-tab"> | |
| <i class="fas fa-tachometer-alt mr-3"></i> Dashboard | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="tab-link flex items-center p-2 rounded hover:bg-gray-600" data-tab="database-tab"> | |
| <i class="fas fa-database mr-3"></i> Database | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="tab-link flex items-center p-2 rounded hover:bg-gray-600" data-tab="keywords-tab"> | |
| <i class="fas fa-key mr-3"></i> Keywords | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="tab-link flex items-center p-2 rounded hover:bg-gray-600" data-tab="logs-tab"> | |
| <i class="fas fa-clipboard-list mr-3"></i> Logs | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="tab-link flex items-center p-2 rounded hover:bg-gray-600" data-tab="settings-tab"> | |
| <i class="fas fa-cog mr-3"></i> Settings | |
| </a> | |
| </li> | |
| <li class="pt-4 mt-4 border-t border-gray-600"> | |
| <a href="#" class="tab-link flex items-center p-2 rounded hover:bg-gray-600" data-tab="admin-tab"> | |
| <i class="fas fa-user-shield mr-3"></i> Admin Panel | |
| </a> | |
| </li> | |
| </ul> | |
| </nav> | |
| </aside> | |
| <!-- Main Content --> | |
| <main class="flex-1 p-6 overflow-y-auto bg-gray-100"> | |
| <!-- Dashboard Tab --> | |
| <div id="dashboard-tab" class="tab-content"> | |
| <h2 class="text-2xl font-bold mb-6">Server Dashboard</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8"> | |
| <!-- Server Status Card --> | |
| <div class="bg-white p-6 rounded-lg shadow"> | |
| <h3 class="text-lg font-semibold mb-4">Server Control</h3> | |
| <div class="flex flex-col space-y-3"> | |
| <button id="startServer" class="bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded flex items-center justify-center"> | |
| <i class="fas fa-play mr-2"></i> Start Server | |
| </button> | |
| <button id="stopServer" class="bg-red-500 hover:bg-red-600 text-white py-2 px-4 rounded flex items-center justify-center" disabled> | |
| <i class="fas fa-stop mr-2"></i> Stop Server | |
| </button> | |
| <button id="restartServer" class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded flex items-center justify-center" disabled> | |
| <i class="fas fa-redo mr-2"></i> Restart Server | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Stats Card --> | |
| <div class="bg-white p-6 rounded-lg shadow"> | |
| <h3 class="text-lg font-semibold mb-4">Monitoring Stats</h3> | |
| <div class="space-y-3"> | |
| <div class="flex justify-between"> | |
| <span>Active Searches:</span> | |
| <span id="activeSearches" class="font-medium">0</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span>Items Found Today:</span> | |
| <span id="itemsFound" class="font-medium">0</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span>Telegram Notifications:</span> | |
| <span id="telegramNotifs" class="font-medium">0</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span>Uptime:</span> | |
| <span id="uptime" class="font-medium">00:00:00</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Recent Activity Card --> | |
| <div class="bg-white p-6 rounded-lg shadow"> | |
| <h3 class="text-lg font-semibold mb-4">Recent Activity</h3> | |
| <div class="space-y-2 max-h-48 overflow-y-auto"> | |
| <div class="text-sm p-2 bg-gray-50 rounded">No recent activity</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Quick Actions --> | |
| <div class="bg-white p-6 rounded-lg shadow mb-8"> | |
| <h3 class="text-lg font-semibold mb-4">Quick Actions</h3> | |
| <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> | |
| <button class="bg-indigo-100 hover:bg-indigo-200 text-indigo-800 py-2 px-4 rounded flex items-center justify-center"> | |
| <i class="fas fa-search mr-2"></i> Test Search | |
| </button> | |
| <button class="bg-indigo-100 hover:bg-indigo-200 text-indigo-800 py-2 px-4 rounded flex items-center justify-center"> | |
| <i class="fas fa-paper-plane mr-2"></i> Test Telegram | |
| </button> | |
| <button class="bg-indigo-100 hover:bg-indigo-200 text-indigo-800 py-2 px-4 rounded flex items-center justify-center"> | |
| <i class="fas fa-sync-alt mr-2"></i> Refresh Data | |
| </button> | |
| <button class="bg-indigo-100 hover:bg-indigo-200 text-indigo-800 py-2 px-4 rounded flex items-center justify-center"> | |
| <i class="fas fa-chart-line mr-2"></i> View Stats | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Database Tab --> | |
| <div id="database-tab" class="tab-content hidden"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-2xl font-bold">Database</h2> | |
| <div class="flex space-x-2"> | |
| <button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded flex items-center"> | |
| <i class="fas fa-plus mr-2"></i> Add Item | |
| </button> | |
| <button class="bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded flex items-center"> | |
| <i class="fas fa-sync-alt mr-2"></i> Refresh | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="p-4 border-b flex justify-between items-center"> | |
| <div class="flex items-center"> | |
| <input type="text" placeholder="Search items..." class="border rounded py-2 px-3 w-64"> | |
| </div> | |
| <div class="flex items-center space-x-2"> | |
| <span class="text-sm text-gray-600">Total items: <span id="totalItems">0</span></span> | |
| <select class="border rounded py-2 px-3"> | |
| <option>All</option> | |
| <option>Today</option> | |
| <option>Last 7 days</option> | |
| <option>Last 30 days</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="overflow-x-auto"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead class="bg-gray-50"> | |
| <tr> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">ID</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Title</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Price</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Location</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Link</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th> | |
| </tr> | |
| </thead> | |
| <tbody class="bg-white divide-y divide-gray-200"> | |
| <!-- Items will be loaded here --> | |
| <tr> | |
| <td colspan="7" class="px-6 py-4 text-center text-gray-500">No items found</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="p-4 border-t flex justify-between items-center"> | |
| <div class="text-sm text-gray-600"> | |
| Showing <span class="font-medium">0</span> to <span class="font-medium">0</span> of <span class="font-medium">0</span> entries | |
| </div> | |
| <div class="flex space-x-1"> | |
| <button class="px-3 py-1 border rounded disabled:opacity-50" disabled>Previous</button> | |
| <button class="px-3 py-1 border rounded bg-blue-500 text-white">1</button> | |
| <button class="px-3 py-1 border rounded">Next</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Keywords Tab --> | |
| <div id="keywords-tab" class="tab-content hidden"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-2xl font-bold">Search Keywords</h2> | |
| <div class="flex space-x-2"> | |
| <button id="addKeywordBtn" class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded flex items-center"> | |
| <i class="fas fa-plus mr-2"></i> Add Keyword | |
| </button> | |
| <button class="bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded flex items-center"> | |
| <i class="fas fa-sync-alt mr-2"></i> Refresh | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow overflow-hidden mb-6"> | |
| <div class="p-4 border-b"> | |
| <h3 class="font-medium">Active Search Keywords</h3> | |
| </div> | |
| <div class="p-4"> | |
| <div id="keywordsList" class="flex flex-wrap gap-2"> | |
| <!-- Keywords will be loaded here --> | |
| <div class="text-gray-500">No keywords added yet</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="p-4 border-b"> | |
| <h3 class="font-medium">Keyword Settings</h3> | |
| </div> | |
| <div class="p-4"> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Search Interval (minutes)</label> | |
| <input type="number" value="15" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Max Price (€)</label> | |
| <input type="number" placeholder="No limit" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Min Price (€)</label> | |
| <input type="number" placeholder="No limit" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Location Radius (km)</label> | |
| <input type="number" placeholder="No limit" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <label class="flex items-center"> | |
| <input type="checkbox" class="rounded text-blue-500"> | |
| <span class="ml-2">Enable exact match only</span> | |
| </label> | |
| <label class="flex items-center mt-2"> | |
| <input type="checkbox" class="rounded text-blue-500" checked> | |
| <span class="ml-2">Include similar results</span> | |
| </label> | |
| </div> | |
| <div class="mt-6"> | |
| <button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-6 rounded"> | |
| Save Settings | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Logs Tab --> | |
| <div id="logs-tab" class="tab-content hidden"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-2xl font-bold">Server Logs</h2> | |
| <div class="flex space-x-2"> | |
| <button id="clearLogsBtn" class="bg-red-500 hover:bg-red-600 text-white py-2 px-4 rounded flex items-center"> | |
| <i class="fas fa-trash mr-2"></i> Clear Logs | |
| </button> | |
| <button id="refreshLogsBtn" class="bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded flex items-center"> | |
| <i class="fas fa-sync-alt mr-2"></i> Refresh | |
| </button> | |
| <button id="exportLogsBtn" class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded flex items-center"> | |
| <i class="fas fa-download mr-2"></i> Export | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="p-4 border-b flex justify-between items-center"> | |
| <div class="flex items-center space-x-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Log Level</label> | |
| <select class="border rounded py-2 px-3"> | |
| <option>All</option> | |
| <option>Info</option> | |
| <option>Warnings</option> | |
| <option>Errors</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Time Range</label> | |
| <select class="border rounded py-2 px-3"> | |
| <option>Last hour</option> | |
| <option>Today</option> | |
| <option>Last 7 days</option> | |
| <option>All</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div> | |
| <input type="text" placeholder="Filter logs..." class="border rounded py-2 px-3 w-64"> | |
| </div> | |
| </div> | |
| <div id="logContainer" class="p-4 h-96 overflow-y-auto bg-gray-900 text-green-400 font-mono text-sm"> | |
| <div class="log-entry info">[2023-07-15 14:30:22] INFO: Server started successfully</div> | |
| <div class="log-entry info">[2023-07-15 14:30:25] INFO: Connected to database</div> | |
| <div class="log-entry info">[2023-07-15 14:30:28] INFO: Telegram bot initialized</div> | |
| <div class="log-entry info">[2023-07-15 14:35:10] INFO: Starting search for "iphone 13"</div> | |
| <div class="log-entry success">[2023-07-15 14:35:15] SUCCESS: Found 3 new items for "iphone 13"</div> | |
| <div class="log-entry info">[2023-07-15 14:35:16] INFO: Sent notifications to Telegram</div> | |
| <div class="log-entry warning">[2023-07-15 14:40:05] WARNING: Slow response from Kleinanzeigen API</div> | |
| <div class="log-entry error">[2023-07-15 14:45:30] ERROR: Failed to connect to Telegram (timeout)</div> | |
| <div class="log-entry info">[2023-07-15 14:45:35] INFO: Reconnecting to Telegram...</div> | |
| <div class="log-entry success">[2023-07-15 14:45:38] SUCCESS: Telegram connection restored</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Settings Tab --> | |
| <div id="settings-tab" class="tab-content hidden"> | |
| <h2 class="text-2xl font-bold mb-6">Settings</h2> | |
| <div class="bg-white rounded-lg shadow overflow-hidden mb-6"> | |
| <div class="p-4 border-b"> | |
| <h3 class="font-medium">Telegram Configuration</h3> | |
| </div> | |
| <div class="p-4"> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Bot Token</label> | |
| <input type="password" placeholder="Enter bot token" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Chat ID</label> | |
| <input type="text" placeholder="Enter chat ID" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Notification Template</label> | |
| <textarea class="border rounded w-full py-2 px-3 h-24" placeholder="Enter notification message template">New item found: {title} | |
| Price: {price}€ | |
| Location: {location} | |
| Link: {url}</textarea> | |
| </div> | |
| <div class="mt-6"> | |
| <button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-6 rounded"> | |
| Save Telegram Settings | |
| </button> | |
| <button class="ml-4 bg-gray-200 hover:bg-gray-300 text-gray-800 py-2 px-6 rounded"> | |
| Test Connection | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow overflow-hidden mb-6"> | |
| <div class="p-4 border-b"> | |
| <h3 class="font-medium">Database Settings</h3> | |
| </div> | |
| <div class="p-4"> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Database Host</label> | |
| <input type="text" value="localhost" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Database Port</label> | |
| <input type="number" value="3306" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Database Name</label> | |
| <input type="text" value="kleinanzeigen" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Database User</label> | |
| <input type="text" value="admin" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Database Password</label> | |
| <input type="password" placeholder="Enter password" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| </div> | |
| <div class="mt-6"> | |
| <button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-6 rounded"> | |
| Save Database Settings | |
| </button> | |
| <button class="ml-4 bg-gray-200 hover:bg-gray-300 text-gray-800 py-2 px-6 rounded"> | |
| Test Connection | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="p-4 border-b"> | |
| <h3 class="font-medium">Server Settings</h3> | |
| </div> | |
| <div class="p-4"> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Server Port</label> | |
| <input type="number" value="3000" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Log Level</label> | |
| <select class="border rounded w-full py-2 px-3"> | |
| <option>debug</option> | |
| <option selected>info</option> | |
| <option>warning</option> | |
| <option>error</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Max Log Files</label> | |
| <input type="number" value="10" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Log Retention (days)</label> | |
| <input type="number" value="30" class="border rounded w-full py-2 px-3"> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <label class="flex items-center"> | |
| <input type="checkbox" class="rounded text-blue-500" checked> | |
| <span class="ml-2">Enable auto-restart on crash</span> | |
| </label> | |
| <label class="flex items-center mt-2"> | |
| <input type="checkbox" class="rounded text-blue-500"> | |
| <span class="ml-2">Enable maintenance mode</span> | |
| </label> | |
| </div> | |
| <div class="mt-6"> | |
| <button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-6 rounded"> | |
| Save Server Settings | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Admin Tab --> | |
| <div id="admin-tab" class="tab-content hidden"> | |
| <h2 class="text-2xl font-bold mb-6">Administrator Panel</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6"> | |
| <!-- File Explorer --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="p-4 border-b flex justify-between items-center"> | |
| <h3 class="font-medium">File Explorer</h3> | |
| <div class="flex space-x-2"> | |
| <button class="text-gray-600 hover:text-gray-800"> | |
| <i class="fas fa-upload"></i> | |
| </button> | |
| <button class="text-gray-600 hover:text-gray-800"> | |
| <i class="fas fa-folder-plus"></i> | |
| </button> | |
| <button class="text-gray-600 hover:text-gray-800"> | |
| <i class="fas fa-sync-alt"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="p-4 h-64 overflow-y-auto"> | |
| <div class="space-y-1"> | |
| <div class="flex items-center p-2 hover:bg-gray-100 rounded cursor-pointer"> | |
| <i class="fas fa-folder text-yellow-500 mr-2"></i> | |
| <span>config</span> | |
| </div> | |
| <div class="flex items-center p-2 hover:bg-gray-100 rounded cursor-pointer"> | |
| <i class="fas fa-folder text-yellow-500 mr-2"></i> | |
| <span>logs</span> | |
| </div> | |
| <div class="flex items-center p-2 hover:bg-gray-100 rounded cursor-pointer"> | |
| <i class="fas fa-folder text-yellow-500 mr-2"></i> | |
| <span>database</span> | |
| </div> | |
| <div class="flex items-center p-2 hover:bg-gray-100 rounded cursor-pointer"> | |
| <i class="fas fa-file-code text-blue-500 mr-2"></i> | |
| <span>server.js</span> | |
| </div> | |
| <div class="flex items-center p-2 hover:bg-gray-100 rounded cursor-pointer"> | |
| <i class="fas fa-file-alt text-gray-500 mr-2"></i> | |
| <span>README.md</span> | |
| </div> | |
| <div class="flex items-center p-2 hover:bg-gray-100 rounded cursor-pointer"> | |
| <i class="fas fa-file-alt text-gray-500 mr-2"></i> | |
| <span>package.json</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="p-4 border-t"> | |
| <div class="flex justify-between"> | |
| <span class="text-sm text-gray-600">Selected: 0 items</span> | |
| <button class="text-red-500 hover:text-red-700 text-sm"> | |
| <i class="fas fa-trash mr-1"></i> Delete | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Admin Logs --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="p-4 border-b flex justify-between items-center"> | |
| <h3 class="font-medium">Admin Logs</h3> | |
| <div class="flex space-x-2"> | |
| <button class="text-gray-600 hover:text-gray-800"> | |
| <i class="fas fa-trash"></i> | |
| </button> | |
| <button class="text-gray-600 hover:text-gray-800"> | |
| <i class="fas fa-sync-alt"></i> | |
| </button> | |
| <button class="text-gray-600 hover:text-gray-800"> | |
| <i class="fas fa-download"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="p-4 h-64 overflow-y-auto bg-gray-900 text-green-400 font-mono text-sm"> | |
| <div class="log-entry info">[2023-07-15 10:15:22] ADMIN: User admin logged in</div> | |
| <div class="log-entry warning">[2023-07-15 10:20:05] ADMIN: Configuration changed by admin</div> | |
| <div class="log-entry info">[2023-07-15 10:25:18] ADMIN: Database backup initiated</div> | |
| <div class="log-entry success">[2023-07-15 10:25:25] ADMIN: Database backup completed successfully</div> | |
| <div class="log-entry error">[2023-07-15 10:30:42] ADMIN: Failed to clear cache (permission denied)</div> | |
| <div class="log-entry info">[2023-07-15 10:35:10] ADMIN: Server restarted by admin</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Admin Tools --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden mb-6"> | |
| <div class="p-4 border-b"> | |
| <h3 class="font-medium">Admin Tools</h3> | |
| </div> | |
| <div class="p-4"> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
| <button class="bg-red-500 hover:bg-red-600 text-white py-3 px-4 rounded flex flex-col items-center"> | |
| <i class="fas fa-power-off text-2xl mb-2"></i> | |
| <span>Full Server Restart</span> | |
| </button> | |
| <button class="bg-yellow-500 hover:bg-yellow-600 text-white py-3 px-4 rounded flex flex-col items-center"> | |
| <i class="fas fa-database text-2xl mb-2"></i> | |
| <span>Export Database</span> | |
| </button> | |
| <button class="bg-purple-500 hover:bg-purple-600 text-white py-3 px-4 rounded flex flex-col items-center"> | |
| <i class="fas fa-broom text-2xl mb-2"></i> | |
| <span>Clear Cache</span> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Admin Console --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="p-4 border-b"> | |
| <h3 class="font-medium">Admin Console</h3> | |
| </div> | |
| <div class="p-4"> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Command</label> | |
| <div class="flex"> | |
| <input type="text" placeholder="Enter command..." class="border rounded-l w-full py-2 px-3"> | |
| <button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-r"> | |
| Execute | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-gray-900 text-green-400 font-mono text-sm p-4 h-48 overflow-y-auto"> | |
| <div>Kleinanzeigen Monitor Admin Console v1.0.0</div> | |
| <div>Type 'help' for available commands</div> | |
| <div class="mt-2"> | |
| <span class="text-white">admin@server:~$</span> <span class="blinking-cursor">|</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| </div> | |
| <!-- Add Keyword Modal --> | |
| <div id="addKeywordModal" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50 hidden"> | |
| <div class="bg-white p-6 rounded-lg shadow-xl w-96"> | |
| <h2 class="text-xl font-bold mb-4">Add New Keyword</h2> | |
| <div class="mb-4"> | |
| <label class="block text-gray-700 text-sm font-bold mb-2" for="keyword">Keyword</label> | |
| <input id="keyword" type="text" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" placeholder="Enter keyword to monitor"> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-gray-700 text-sm font-bold mb-2" for="category">Category</label> | |
| <select id="category" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"> | |
| <option value="">All Categories</option> | |
| <option value="electronics">Electronics</option> | |
| <option value="fashion">Fashion</option> | |
| <option value="home">Home & Garden</option> | |
| <option value="sports">Sports & Leisure</option> | |
| <option value="vehicles">Vehicles</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-end space-x-2"> | |
| <button id="cancelAddKeyword" class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded"> | |
| Cancel | |
| </button> | |
| <button id="confirmAddKeyword" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> | |
| Add Keyword | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Login functionality | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Show login modal by default | |
| document.getElementById('loginModal').classList.remove('hidden'); | |
| // Login button click | |
| document.getElementById('loginBtn').addEventListener('click', function() { | |
| const username = document.getElementById('username').value; | |
| const password = document.getElementById('password').value; | |
| if (username && password) { | |
| // Simulate login | |
| document.getElementById('loginModal').classList.add('hidden'); | |
| document.getElementById('dashboard').classList.remove('hidden'); | |
| document.getElementById('currentUser').textContent = username; | |
| // Simulate server connection | |
| setTimeout(() => { | |
| updateServerStatus('online'); | |
| }, 1500); | |
| } else { | |
| alert('Please enter both username and password'); | |
| } | |
| }); | |
| // Logout button | |
| document.getElementById('logoutBtn').addEventListener('click', function() { | |
| document.getElementById('dashboard').classList.add('hidden'); | |
| document.getElementById('loginModal').classList.remove('hidden'); | |
| updateServerStatus('offline'); | |
| document.getElementById('username').value = ''; | |
| document.getElementById('password').value = ''; | |
| }); | |
| // Tab switching | |
| document.querySelectorAll('.tab-link').forEach(link => { | |
| link.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| // Remove active class from all tabs and links | |
| document.querySelectorAll('.tab-link').forEach(el => el.classList.remove('active')); | |
| document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden')); | |
| // Add active class to clicked link | |
| this.classList.add('active'); | |
| // Show corresponding tab | |
| const tabId = this.getAttribute('data-tab'); | |
| document.getElementById(tabId).classList.remove('hidden'); | |
| }); | |
| }); | |
| // Server control buttons | |
| document.getElementById('startServer').addEventListener('click', function() { | |
| updateServerStatus('starting'); | |
| setTimeout(() => { | |
| updateServerStatus('online'); | |
| document.getElementById('startServer').disabled = true; | |
| document.getElementById('stopServer').disabled = false; | |
| document.getElementById('restartServer').disabled = false; | |
| // Add log entry | |
| addLogEntry('Server started successfully', 'success'); | |
| }, 2000); | |
| }); | |
| document.getElementById('stopServer').addEventListener('click', function() { | |
| updateServerStatus('stopping'); | |
| setTimeout(() => { | |
| updateServerStatus('offline'); | |
| document.getElementById('startServer').disabled = false; | |
| document.getElementById('stopServer').disabled = true; | |
| document.getElementById('restartServer').disabled = true; | |
| // Add log entry | |
| addLogEntry('Server stopped', 'info'); | |
| }, 1000); | |
| }); | |
| document.getElementById('restartServer').addEventListener('click', function() { | |
| updateServerStatus('restarting'); | |
| setTimeout(() => { | |
| updateServerStatus('online'); | |
| // Add log entry | |
| addLogEntry('Server restarted successfully', 'success'); | |
| }, 3000); | |
| }); | |
| // Keyword management | |
| document.getElementById('addKeywordBtn').addEventListener('click', function() { | |
| document.getElementById('addKeywordModal').classList.remove('hidden'); | |
| }); | |
| document.getElementById('cancelAddKeyword').addEventListener('click', function() { | |
| document.getElementById('addKeywordModal').classList.add('hidden'); | |
| }); | |
| document.getElementById('confirmAddKeyword').addEventListener('click', function() { | |
| const keyword = document.getElementById('keyword').value; | |
| const category = document.getElementById('category').value; | |
| if (keyword) { | |
| addKeyword(keyword, category); | |
| document.getElementById('keyword').value = ''; | |
| document.getElementById('addKeywordModal').classList.add('hidden'); | |
| // Add log entry | |
| addLogEntry(`Added new keyword to monitor: "${keyword}"`, 'info'); | |
| } | |
| }); | |
| // Log management | |
| document.getElementById('clearLogsBtn').addEventListener('click', function() { | |
| if (confirm('Are you sure you want to clear all logs?')) { | |
| document.getElementById('logContainer').innerHTML = ''; | |
| addLogEntry('Logs cleared by admin', 'warning'); | |
| } | |
| }); | |
| document.getElementById('refreshLogsBtn').addEventListener('click', function() { | |
| // Simulate log refresh | |
| addLogEntry('Logs refreshed', 'info'); | |
| }); | |
| document.getElementById('exportLogsBtn').addEventListener('click', function() { | |
| alert('Logs exported successfully (simulated)'); | |
| addLogEntry('Logs exported by admin', 'info'); | |
| }); | |
| // Simulate some stats | |
| setInterval(() => { | |
| document.getElementById('activeSearches').textContent = Math.floor(Math.random() * 10); | |
| document.getElementById('itemsFound').textContent = Math.floor(Math.random() * 50); | |
| document.getElementById('telegramNotifs').textContent = Math.floor(Math.random() * 30); | |
| }, 3000); | |
| // Simulate uptime counter | |
| let seconds = 0; | |
| setInterval(() => { | |
| seconds++; | |
| const hours = Math.floor(seconds / 3600); | |
| const minutes = Math.floor((seconds % 3600) / 60); | |
| const secs = seconds % 60; | |
| document.getElementById('uptime').textContent = | |
| `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; | |
| }, 1000); | |
| }); | |
| function updateServerStatus(status) { | |
| const statusElement = document.getElementById('serverStatus'); | |
| const indicator = statusElement.querySelector('span:first-child'); | |
| const text = statusElement.querySelector('span:last-child'); | |
| indicator.classList.remove('bg-red-500', 'bg-green-500', 'bg-yellow-500', 'status-pulse'); | |
| switch(status) { | |
| case 'online': | |
| indicator.classList.add('bg-green-500', 'status-pulse'); | |
| text.textContent = 'Server Online'; | |
| break; | |
| case 'offline': | |
| indicator.classList.add('bg-red-500'); | |
| text.textContent = 'Server Offline'; | |
| break; | |
| case 'starting': | |
| indicator.classList.add('bg-yellow-500', 'status-pulse'); | |
| text.textContent = 'Server Starting...'; | |
| break; | |
| case 'stopping': | |
| indicator.classList.add('bg-yellow-500', 'status-pulse'); | |
| text.textContent = 'Server Stopping...'; | |
| break; | |
| case 'restarting': | |
| indicator.classList.add('bg-yellow-500', 'status-pulse'); | |
| text.textContent = 'Server Restarting...'; | |
| break; | |
| } | |
| } | |
| function addKeyword(keyword, category) { | |
| const keywordsList = document.getElementById('keywordsList'); | |
| if (keywordsList.textContent.includes('No keywords added yet')) { | |
| keywordsList.innerHTML = ''; | |
| } | |
| const keywordElement = document.createElement('div'); | |
| keywordElement.className = 'bg-blue-100 text-blue-800 px-3 py-1 rounded-full flex items-center'; | |
| keywordElement.innerHTML = ` | |
| <span>${keyword}</span> | |
| ${category ? `<span class="ml-2 text-xs bg-blue-200 px-2 py-0.5 rounded-full">${category}</span>` : ''} | |
| <button class="ml-2 text-blue-500 hover:text-blue-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| `; | |
| // Add delete functionality | |
| keywordElement.querySelector('button').addEventListener('click', function() { | |
| keywordElement.remove(); | |
| if (keywordsList.children.length === 0) { | |
| keywordsList.innerHTML = '<div class="text-gray-500">No keywords added yet</div>'; | |
| } | |
| // Add log entry | |
| addLogEntry(`Keyword removed: "${keyword}"`, 'warning'); | |
| }); | |
| keywordsList.appendChild(keywordElement); | |
| } | |
| function addLogEntry(message, type) { | |
| const logContainer = document.getElementById('logContainer'); | |
| const now = new Date(); | |
| const timestamp = now.toISOString().replace('T', ' ').substring(0, 19); | |
| const logEntry = document.createElement('div'); | |
| logEntry.className = `log-entry ${type}`; | |
| logEntry.textContent = `[${timestamp}] ${type.toUpperCase()}: ${message}`; | |
| logContainer.appendChild(logEntry); | |
| logContainer.scrollTop = logContainer.scrollHeight; | |
| } | |
| </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=Mochitik009/klein-server" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |