206 lines
9.9 KiB
HTML
206 lines
9.9 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Content Library - DigiServer v2{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="container">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||
<h1>Content Library</h1>
|
||
<a href="{{ url_for('content.upload_content') }}" class="btn btn-success">+ Upload Content</a>
|
||
</div>
|
||
|
||
{% if content_list %}
|
||
<div class="card">
|
||
<div style="margin-bottom: 15px; padding: 15px; background: #f8f9fa; border-radius: 5px;">
|
||
<strong>Total Files:</strong> {{ content_list|length }} |
|
||
<strong>Total Assignments:</strong> {% set total = namespace(count=0) %}{% for item in content_list %}{% set total.count = total.count + item.player_count %}{% endfor %}{{ total.count }}
|
||
</div>
|
||
|
||
<table style="width: 100%; border-collapse: collapse;">
|
||
<thead>
|
||
<tr style="background: #f8f9fa; text-align: left;">
|
||
<th style="padding: 12px; border-bottom: 2px solid #dee2e6;">File Name</th>
|
||
<th style="padding: 12px; border-bottom: 2px solid #dee2e6;">Type</th>
|
||
<th style="padding: 12px; border-bottom: 2px solid #dee2e6;">Duration</th>
|
||
<th style="padding: 12px; border-bottom: 2px solid #dee2e6;">Size</th>
|
||
<th style="padding: 12px; border-bottom: 2px solid #dee2e6;">Assigned To</th>
|
||
<th style="padding: 12px; border-bottom: 2px solid #dee2e6;">Uploaded</th>
|
||
<th style="padding: 12px; border-bottom: 2px solid #dee2e6;">Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for item in content_list %}
|
||
<tr style="border-bottom: 1px solid #dee2e6;">
|
||
<td style="padding: 12px;">
|
||
<strong>{{ item.filename }}</strong>
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
{% if item.content_type == 'image' %}
|
||
<span style="background: #28a745; color: white; padding: 3px 8px; border-radius: 3px; font-size: 12px;">📷 Image</span>
|
||
{% elif item.content_type == 'video' %}
|
||
<span style="background: #007bff; color: white; padding: 3px 8px; border-radius: 3px; font-size: 12px;">🎬 Video</span>
|
||
{% elif item.content_type == 'pdf' %}
|
||
<span style="background: #dc3545; color: white; padding: 3px 8px; border-radius: 3px; font-size: 12px;">📄 PDF</span>
|
||
{% elif item.content_type == 'presentation' %}
|
||
<span style="background: #ffc107; color: black; padding: 3px 8px; border-radius: 3px; font-size: 12px;">📊 PPT</span>
|
||
{% else %}
|
||
<span style="background: #6c757d; color: white; padding: 3px 8px; border-radius: 3px; font-size: 12px;">📁 Other</span>
|
||
{% endif %}
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
{{ item.duration }}s
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
{{ item.file_size }} MB
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
{% if item.player_count == 0 %}
|
||
<span style="color: #6c757d; font-style: italic;">Not assigned</span>
|
||
{% else %}
|
||
<div style="max-height: 100px; overflow-y: auto;">
|
||
{% for player in item.players %}
|
||
<div style="margin-bottom: 5px;">
|
||
<strong>{{ player.name }}</strong>
|
||
{% if player.group %}
|
||
<span style="color: #6c757d; font-size: 12px;">({{ player.group }})</span>
|
||
{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
<div style="margin-top: 5px;">
|
||
<span style="background: #007bff; color: white; padding: 2px 6px; border-radius: 3px; font-size: 11px;">
|
||
{{ item.player_count }} player{% if item.player_count != 1 %}s{% endif %}
|
||
</span>
|
||
</div>
|
||
{% endif %}
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
<small style="color: #6c757d;">{{ item.uploaded_at | localtime }}</small>
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
{% if item.player_count > 0 %}
|
||
{% set first_player = item.players[0] %}
|
||
<a href="{{ url_for('players.player_page', player_id=first_player.id) }}"
|
||
class="btn btn-primary btn-sm"
|
||
title="Manage Playlist for {{ first_player.name }}"
|
||
style="margin-bottom: 5px;">
|
||
📝 Manage Playlist
|
||
</a>
|
||
{% if item.player_count > 1 %}
|
||
<button onclick="showAllPlayers('{{ item.filename|replace("'", "\\'") }}', {{ item.players|tojson }})"
|
||
class="btn btn-info btn-sm"
|
||
title="View all players with this content">
|
||
👥 View All ({{ item.player_count }})
|
||
</button>
|
||
{% endif %}
|
||
{% endif %}
|
||
<button onclick="deleteContent('{{ item.filename|replace("'", "\\'") }}')"
|
||
class="btn btn-danger btn-sm"
|
||
title="Delete this content from all playlists"
|
||
style="margin-top: 5px;">
|
||
🗑️ Delete
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{% else %}
|
||
<div style="background: #d1ecf1; border: 1px solid #bee5eb; color: #0c5460; padding: 15px; border-radius: 5px;">
|
||
ℹ️ No content uploaded yet. <a href="{{ url_for('content.upload_content') }}" style="color: #0c5460; text-decoration: underline;">Upload your first content</a>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<!-- Modal for viewing all players -->
|
||
<div id="playersModal" class="modal" style="display: none;">
|
||
<div class="modal-content" style="max-width: 600px; margin: 100px auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
|
||
<h2 id="modalTitle" style="margin-bottom: 20px; color: #2c3e50;">Players with this content</h2>
|
||
<div id="playersList" style="max-height: 400px; overflow-y: auto;"></div>
|
||
<div style="text-align: center; margin-top: 20px;">
|
||
<button type="button" class="btn" onclick="closePlayersModal()">Close</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
.modal {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
z-index: 9999;
|
||
overflow-y: auto;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
function showAllPlayers(filename, players) {
|
||
document.getElementById('modalTitle').textContent = 'Players with: ' + filename;
|
||
|
||
const playersList = document.getElementById('playersList');
|
||
playersList.innerHTML = '<table style="width: 100%; border-collapse: collapse;">';
|
||
playersList.innerHTML += '<thead><tr style="background: #f8f9fa;"><th style="padding: 10px; text-align: left;">Player Name</th><th style="padding: 10px; text-align: left;">Group</th><th style="padding: 10px; text-align: left;">Action</th></tr></thead><tbody>';
|
||
|
||
players.forEach(player => {
|
||
playersList.innerHTML += `
|
||
<tr style="border-bottom: 1px solid #dee2e6;">
|
||
<td style="padding: 10px;"><strong>${player.name}</strong></td>
|
||
<td style="padding: 10px;">${player.group || '-'}</td>
|
||
<td style="padding: 10px;">
|
||
<a href="/players/${player.id}" class="btn btn-sm" style="background: #007bff; color: white; padding: 5px 10px; text-decoration: none; border-radius: 3px;">
|
||
Manage Playlist
|
||
</a>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
});
|
||
|
||
playersList.innerHTML += '</tbody></table>';
|
||
|
||
document.getElementById('playersModal').style.display = 'block';
|
||
}
|
||
|
||
function closePlayersModal() {
|
||
document.getElementById('playersModal').style.display = 'none';
|
||
}
|
||
|
||
function deleteContent(filename) {
|
||
if (confirm(`Are you sure you want to delete "${filename}"?\n\nThis will remove it from ALL player playlists!`)) {
|
||
fetch('/content/delete-by-filename', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
filename: filename
|
||
})
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
alert(`Successfully deleted "${filename}" from ${data.deleted_count} playlist(s)`);
|
||
location.reload();
|
||
} else {
|
||
alert('Error deleting content: ' + data.message);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
alert('Error deleting content: ' + error);
|
||
});
|
||
}
|
||
}
|
||
|
||
// Close modal when clicking outside
|
||
window.onclick = function(event) {
|
||
const modal = document.getElementById('playersModal');
|
||
if (event.target == modal) {
|
||
closePlayersModal();
|
||
}
|
||
}
|
||
</script>
|
||
{% endblock %}
|