Add web templates and handlers for home, embed card, and admin pages
This commit is contained in:
156
internal/web/templates/admin/index.html
Normal file
156
internal/web/templates/admin/index.html
Normal file
@@ -0,0 +1,156 @@
|
||||
{{ define "admin/index.html" }}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media Approval</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
background-color: #f9f9f9;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.card {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
max-width: 300px;
|
||||
position: relative;
|
||||
}
|
||||
.card img {
|
||||
max-width: 100%;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
button {
|
||||
margin: 5px;
|
||||
padding: 10px 15px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
}
|
||||
.approve { background-color: #4CAF50; }
|
||||
.reject { background-color: #f44336; }
|
||||
.message {
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #4CAF50;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="card" id="media-card">
|
||||
<div class="message" id="status-msg"></div>
|
||||
<img id="preview" src="" alt="Media Preview" onerror="loadRemote()" />
|
||||
<div>
|
||||
<button class="approve" onclick="sendAction('approve')">Approve</button>
|
||||
<button class="reject" onclick="sendAction('reject')">Reject</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let currentMedia = null;
|
||||
let nextMedia = null;
|
||||
let preloadedImage = new Image();
|
||||
|
||||
window.onload = async () => {
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
alert("No token found. Please login first.");
|
||||
window.location.href = "login";
|
||||
return;
|
||||
}
|
||||
|
||||
currentMedia = await fetchMedia(token);
|
||||
showMedia(currentMedia);
|
||||
preloadNextMedia(token);
|
||||
};
|
||||
|
||||
function getToken() {
|
||||
const match = document.cookie.match(/(^| )token=([^;]+)/);
|
||||
return match ? match[2] : null;
|
||||
}
|
||||
|
||||
function showMedia(media) {
|
||||
const preview = document.getElementById('preview');
|
||||
preview.src = media.preview_url;
|
||||
}
|
||||
|
||||
function loadRemote() {
|
||||
if (currentMedia?.remote_url) {
|
||||
document.getElementById('preview').src = currentMedia.remote_url;
|
||||
}
|
||||
}
|
||||
|
||||
async function sendAction(action) {
|
||||
if (!currentMedia?.id) return;
|
||||
|
||||
const token = getToken();
|
||||
const endpoint = `admin/api/${action}`;
|
||||
await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ' + token
|
||||
},
|
||||
body: JSON.stringify({ mediaId: currentMedia.id })
|
||||
});
|
||||
|
||||
showMessage(action.charAt(0).toUpperCase() + action.slice(1) + " successful");
|
||||
|
||||
// Show next media
|
||||
if (nextMedia) {
|
||||
currentMedia = nextMedia;
|
||||
showMedia(currentMedia);
|
||||
preloadNextMedia(token);
|
||||
} else {
|
||||
document.getElementById('media-card').innerHTML = 'No more media.';
|
||||
}
|
||||
}
|
||||
|
||||
function showMessage(text) {
|
||||
const msgDiv = document.getElementById('status-msg');
|
||||
msgDiv.innerText = text;
|
||||
msgDiv.style.display = 'block';
|
||||
setTimeout(() => {
|
||||
msgDiv.style.display = 'none';
|
||||
}, 500);
|
||||
}
|
||||
|
||||
async function fetchMedia(token) {
|
||||
const res = await fetch('admin/api/getmedia', {
|
||||
method: 'GET',
|
||||
headers: { 'Authorization': 'Bearer ' + token }
|
||||
});
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
async function preloadNextMedia(token) {
|
||||
try {
|
||||
nextMedia = await fetchMedia(token);
|
||||
preloadedImage.src = nextMedia.preview_url;
|
||||
preloadedImage.onerror = () => {
|
||||
preloadedImage.src = nextMedia.remote_url;
|
||||
};
|
||||
} catch (err) {
|
||||
console.error("Failed to preload next media:", err);
|
||||
nextMedia = null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
Reference in New Issue
Block a user