Moviebox-api / index.html
darkvibe314's picture
Create index.html
e1551d6 verified
Raw
History Blame Contribute Delete
12.8 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TorchFlix API Dashboard</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
:root {
--bg-color: #0f172a;
--panel-bg: #1e293b;
--text-color: #f8fafc;
--accent-color: #3b82f6;
--accent-hover: #2563eb;
--border-color: #334155;
--success: #10b981;
--error: #ef4444;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
margin: 0;
padding: 20px;
line-height: 1.6;
}
.container {
max-width: 1200px;
margin: 0 auto;
display: grid;
grid-template-columns: 300px 1fr;
gap: 20px;
}
.header {
grid-column: 1 / -1;
display: flex;
align-items: center;
padding: 20px;
background: var(--panel-bg);
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.header h1 {
margin: 0;
font-size: 24px;
display: flex;
align-items: center;
gap: 10px;
}
.header h1 i {
color: var(--success);
}
.sidebar {
background: var(--panel-bg);
padding: 20px;
border-radius: 12px;
height: fit-content;
}
.api-key-section {
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid var(--border-color);
}
.api-key-input {
width: 100%;
padding: 10px;
margin-top: 10px;
background: var(--bg-color);
border: 1px solid var(--border-color);
color: var(--text-color);
border-radius: 6px;
box-sizing: border-box;
}
.endpoint-btn {
width: 100%;
padding: 12px 15px;
margin-bottom: 8px;
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-color);
border-radius: 8px;
cursor: pointer;
text-align: left;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 10px;
}
.endpoint-btn:hover, .endpoint-btn.active {
background: var(--accent-color);
border-color: var(--accent-color);
}
.main-content {
background: var(--panel-bg);
padding: 25px;
border-radius: 12px;
}
.request-config {
background: var(--bg-color);
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
}
.input-group {
margin-bottom: 15px;
}
.input-group label {
display: block;
margin-bottom: 5px;
color: #94a3b8;
font-size: 14px;
}
.input-group input, .input-group select {
width: 100%;
padding: 10px;
background: var(--panel-bg);
border: 1px solid var(--border-color);
color: var(--text-color);
border-radius: 6px;
box-sizing: border-box;
}
.execute-btn {
background: var(--success);
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
font-size: 16px;
display: flex;
align-items: center;
gap: 8px;
transition: background 0.2s;
}
.execute-btn:hover {
background: #059669;
}
.response-area {
background: #000;
border-radius: 8px;
overflow: hidden;
margin-top: 20px;
}
.response-header {
background: #1a1a1a;
padding: 10px 15px;
border-bottom: 1px solid #333;
display: flex;
justify-content: space-between;
align-items: center;
}
.status-badge {
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
}
.status-200 { background: #064e3b; color: #34d399; }
.status-error { background: #7f1d1d; color: #f87171; }
pre {
margin: 0;
padding: 15px;
overflow-x: auto;
color: #a78bfa;
font-size: 14px;
}
.hidden {
display: none !important;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1><i class="fas fa-server"></i> TorchFlix API Dashboard</h1>
</div>
<div class="sidebar">
<div class="api-key-section">
<label><i class="fas fa-key"></i> API Key</label>
<input type="password" id="apiKey" class="api-key-input" value="elijah2909_secret_key" placeholder="Enter API Key">
</div>
<h3>Movie APIs</h3>
<button class="endpoint-btn" onclick="selectEndpoint('search')">
<i class="fas fa-search"></i> Search Movies
</button>
<button class="endpoint-btn" onclick="selectEndpoint('trending')">
<i class="fas fa-fire"></i> Trending
</button>
<button class="endpoint-btn active" onclick="selectEndpoint('media-files')">
<i class="fas fa-film"></i> Media Files
</button>
<button class="endpoint-btn" onclick="selectEndpoint('homepage')">
<i class="fas fa-home"></i> Homepage
</button>
<button class="endpoint-btn" onclick="selectEndpoint('details')">
<i class="fas fa-info-circle"></i> Movie Details
</button>
<button class="endpoint-btn" onclick="selectEndpoint('recommend')">
<i class="fas fa-star"></i> Recommendations
</button>
<button class="endpoint-btn" onclick="selectEndpoint('popular')">
<i class="fas fa-chart-line"></i> Popular Searches
</button>
<button class="endpoint-btn" onclick="selectEndpoint('hot')">
<i class="fas fa-pepper-hot"></i> Hot Content
</button>
</div>
<div class="main-content">
<div class="request-config">
<h3 id="endpointTitle" style="margin-top: 0;">Configure Request</h3>
<div id="queryInput" class="input-group">
<label>Search Query / Title</label>
<input type="text" id="query" value="Avatar" placeholder="e.g. Iron Man">
</div>
<div id="typeInput" class="input-group">
<label>Content Type</label>
<select id="mediaType">
<option value="movie">Movie</option>
<option value="series">TV Series</option>
</select>
</div>
<div id="seriesInputs" class="hidden">
<div class="input-group">
<label>Season</label>
<input type="number" id="season" value="1" min="1">
</div>
<div class="input-group">
<label>Episode</label>
<input type="number" id="episode" value="1" min="1">
</div>
</div>
<button class="execute-btn" onclick="executeRequest()">
<i class="fas fa-play"></i> Execute Request
</button>
</div>
<div class="response-area">
<div class="response-header">
<span>Response</span>
<span id="statusBadge" class="status-badge hidden"></span>
</div>
<pre id="jsonOutput">// Response will appear here...</pre>
</div>
</div>
</div>
<script>
let currentEndpoint = 'media-files';
document.getElementById('mediaType').addEventListener('change', function(e) {
const seriesInputs = document.getElementById('seriesInputs');
if (e.target.value === 'series' && currentEndpoint === 'media-files') {
seriesInputs.classList.remove('hidden');
} else {
seriesInputs.classList.add('hidden');
}
});
function selectEndpoint(endpoint) {
currentEndpoint = endpoint;
document.querySelectorAll('.endpoint-btn').forEach(btn => btn.classList.remove('active'));
event.currentTarget.classList.add('active');
const queryInput = document.getElementById('queryInput');
const typeInput = document.getElementById('typeInput');
const seriesInputs = document.getElementById('seriesInputs');
// Reset visibility
queryInput.classList.remove('hidden');
typeInput.classList.add('hidden');
seriesInputs.classList.add('hidden');
const titles = {
'search': 'Search Query',
'media-files': 'Extract Stream URLs',
'details': 'Get Movie Metadata',
'recommend': 'Get Recommendations'
};
document.getElementById('endpointTitle').innerText = titles[endpoint] || 'No Parameters Required';
if (['trending', 'homepage', 'popular', 'hot'].includes(endpoint)) {
queryInput.classList.add('hidden');
}
if (['search', 'media-files', 'details', 'recommend'].includes(endpoint)) {
typeInput.classList.remove('hidden');
}
if (endpoint === 'media-files' && document.getElementById('mediaType').value === 'series') {
seriesInputs.classList.remove('hidden');
}
}
async function executeRequest() {
const btn = document.querySelector('.execute-btn');
const output = document.getElementById('jsonOutput');
const badge = document.getElementById('statusBadge');
const apiKey = document.getElementById('apiKey').value;
const query = encodeURIComponent(document.getElementById('query').value);
const type = document.getElementById('mediaType').value;
const season = document.getElementById('season').value;
const episode = document.getElementById('episode').value;
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Executing...';
output.innerText = 'Loading...';
badge.classList.add('hidden');
// Base URL relative to wherever it is hosted
let url = `/api/${currentEndpoint}?api_key=${apiKey}`;
if (['search', 'media-files', 'details', 'recommend'].includes(currentEndpoint)) {
url += `&query=${query}&type=${type}`;
}
if (currentEndpoint === 'media-files' && type === 'series') {
url += `&season=${season}&episode=${episode}`;
}
try {
// Ensure headers are sent properly
const response = await fetch(url, {
method: 'GET',
headers: {
'Accept': 'application/json',
'X-API-Key': apiKey
}
});
const data = await response.json();
badge.innerText = `Status: ${response.status}`;
badge.className = `status-badge ${response.ok ? 'status-200' : 'status-error'}`;
output.innerText = JSON.stringify(data, null, 2);
} catch (error) {
badge.innerText = 'Network Error';
badge.className = 'status-badge status-error';
output.innerText = error.toString();
} finally {
btn.innerHTML = '<i class="fas fa-play"></i> Execute Request';
}
}
// Initialize UI
selectEndpoint('media-files');
</script>
</body>
</html>