Spaces:
Paused
Paused
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Media Library</title> | |
<style> | |
body { | |
font-family: 'Roboto', sans-serif; | |
background: #0f0f0f; | |
color: #e0e0e0; | |
margin: 0; | |
padding: 0; | |
overflow-x: hidden; | |
} | |
.header { | |
background: linear-gradient(to right, #ff2c20, #ef8b81); | |
color: #fff; | |
padding: 40px 20px; | |
text-align: center; | |
border-bottom: 2px solid rgba(255, 255, 255, 0.2); | |
position: relative; | |
z-index: 1; | |
} | |
.header h1 { | |
margin: 0; | |
font-size: 48px; | |
font-weight: bold; | |
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7); | |
} | |
.content { | |
padding: 20px; | |
position: relative; | |
z-index: 1; | |
} | |
.section { | |
margin-bottom: 60px; | |
} | |
.section h2 { | |
margin-bottom: 20px; | |
font-size: 36px; | |
font-weight: bold; | |
color: #fff; | |
border-bottom: 2px solid #ff1e1e; | |
padding-bottom: 10px; | |
} | |
.section h2 a { | |
color: #f2629f; | |
text-decoration: none; | |
font-size: 16px; | |
} | |
.grid { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); | |
gap: 20px; | |
margin-top: 20px; | |
} | |
.card { | |
position: relative; | |
background: #222; | |
border-radius: 15px; | |
overflow: hidden; | |
text-align: center; | |
transition: transform 0.3s, box-shadow 0.3s; | |
cursor: pointer; | |
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.8); | |
} | |
.card:hover { | |
transform: scale(1.05); | |
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.9); | |
} | |
.card img { | |
width: 100%; | |
height: 330px; | |
object-fit: cover; | |
transition: opacity 0.3s; | |
} | |
.card h3 { | |
margin: 0; | |
padding: 10px; | |
font-size: 22px; | |
font-weight: bold; | |
background: rgba(0, 0, 0, 0.6); | |
} | |
.card::after { | |
content: ''; | |
display: block; | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.7) 100%); | |
opacity: 0; | |
transition: opacity 0.3s; | |
z-index: 1; | |
} | |
.card:hover::after { | |
opacity: 1; | |
} | |
.card p { | |
margin: 0; | |
padding: 10px; | |
font-size: 16px; | |
color: #ccc; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="header"> | |
<h1>Media Library</h1> | |
</div> | |
<div class="content"> | |
<div class="section" id="films"> | |
<h2>Films <a href="/films">View All</a></h2> | |
<div class="grid" id="films-grid"></div> | |
</div> | |
<div class="section" id="tv"> | |
<h2>TV Shows <a href="/tv">View All</a></h2> | |
<div class="grid" id="tv-grid"></div> | |
</div> | |
</div> | |
<script> | |
async function fetchData(endpoint) { | |
try { | |
const response = await fetch(endpoint); | |
if (!response.ok) throw new Error('Network response was not ok'); | |
return await response.json(); | |
} catch (error) { | |
console.error('Fetch error:', error); | |
return []; | |
} | |
} | |
async function fetchMetadata(title) { | |
try { | |
const response = await fetch(`/get_metadata?title=${encodeURIComponent(title)}`); | |
if (response.ok) { | |
const data = await response.json(); | |
if (data.data && data.data.length > 0) { | |
const thumbnailUrl = data.data[0].thumbnail; | |
return thumbnailUrl; | |
} | |
} | |
} catch (error) { | |
console.error('Metadata fetch error:', error); | |
} | |
return null; | |
} | |
function createCard(item, mediaType) { | |
const card = document.createElement('div'); | |
card.className = 'card'; | |
const title = item.path.split('/').pop(); | |
card.innerHTML = ` | |
<img src="https://via.placeholder.com/220x330.png" alt="${title}"> | |
<h3>${title}</h3> | |
`; | |
// Redirect to the appropriate page on card click | |
card.onclick = () => { | |
if (mediaType === 'movie') { | |
window.location.href = `/film/${encodeURIComponent(title)}`; | |
} else if (mediaType === 'series') { | |
window.location.href = `/tv/${encodeURIComponent(title)}`; | |
} | |
}; | |
fetchMetadata(title).then(thumbnailUrl => { | |
if (thumbnailUrl !== null) { | |
card.querySelector('img').src = thumbnailUrl; | |
} | |
}); | |
return card; | |
} | |
async function populateGrid(endpoint, gridId, mediaType, limit = 5) { | |
const grid = document.getElementById(gridId); | |
const data = await fetchData(endpoint); | |
data.slice(0, limit).forEach(item => { | |
grid.appendChild(createCard(item, mediaType)); | |
}); | |
} | |
populateGrid('/api/films', 'films-grid', 'movie'); | |
populateGrid('/api/tv', 'tv-grid', 'series'); | |
</script> | |
</body> | |
</html> | |