webclient / app /templates /video_comments.html
ariansyahdedy's picture
Add UI
b0f2d3d
{% extends "base.html" %}
{% block title %}
Moderate Comments - {{ video.title }}
{% endblock %}
{% block content %}
<div class="container mx-auto px-4 py-8">
<!-- Outer container with card styling -->
<div class="bg-white shadow-xl rounded-lg overflow-visible">
<!-- Header section with video title and controls -->
<div class="bg-gradient-to-r from-blue-500 to-purple-600 p-6">
<div class="flex justify-between items-center">
<h1 class="text-3xl font-bold text-white flex items-center">
<i class="fab fa-youtube mr-4 text-red-500"></i>
{{ video.title }}
</h1>
<div class="flex space-x-4">
<button id="refreshCommentsBtn" class="bg-white text-blue-600 px-4 py-2 rounded-lg hover:bg-blue-50 transition duration-300 flex items-center shadow-md">
<i class="fas fa-sync mr-2"></i>Refresh Comments
</button>
<div x-data="{ showSettings: false, saveSettings() {
// Add your save logic here, e.g., update a model or call an API
alert('Settings saved!');
this.showSettings = false; // Optionally hide the settings box after saving
} }" class="relative">
<button @click="showSettings = !showSettings" class="bg-white text-purple-600 px-4 py-2 rounded-lg hover:bg-purple-50 transition duration-300 flex items-center shadow-md">
<i class="fas fa-cog mr-2"></i>Moderation Settings
</button>
<div x-show="showSettings" x-transition class="absolute right-0 mt-2 w-72 bg-white rounded-lg shadow-2xl p-6 z-20 border border-gray-100">
<h3 class="text-xl font-semibold mb-4 text-gray-800">Moderation Settings</h3>
<div class="space-y-4">
<div class="flex items-center">
<input type="checkbox" id="auto-delete" class="mr-3 rounded text-blue-500 focus:ring-blue-400">
<label for="auto-delete" class="text-gray-700">Auto-delete flagged comments</label>
</div>
<div>
<label class="block mb-2 text-gray-700">Gambling Confidence Threshold</label>
<input type="range" min="0" max="1" step="0.05" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer" x-model="threshold" value="0.55">
</div>
<button @click="saveSettings" class="w-full bg-gradient-to-r from-blue-500 to-purple-600 text-white py-2 rounded-lg hover:opacity-90 transition duration-300">
Save Settings
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Comments Section -->
<div class="grid md:grid-cols-2 gap-6 p-6">
<!-- Safe Comments Column -->
<div>
<h2 class="text-2xl font-semibold mb-4 flex items-center text-green-600">
<i class="fas fa-check-circle mr-3"></i>Safe Comments
<span class="text-sm text-gray-500 ml-2">({{ safe_comments|length }})</span>
</h2>
<div class="space-y-4">
{% for comment in safe_comments %}
<div class="bg-white p-4 rounded-lg shadow-md border border-gray-100">
<p class="mb-2 text-gray-800">{{ comment.text }}</p>
<div class="text-sm text-gray-600 flex justify-between items-center">
<span class="font-medium">{{ comment.author }}</span>
<span class="text-xs text-green-600">Safe</span>
</div>
</div>
{% endfor %}
</div>
</div>
<!-- Flagged Comments Column -->
<div>
<h2 class="text-2xl font-semibold mb-4 flex items-center text-red-600">
<i class="fas fa-exclamation-triangle mr-3"></i>Flagged Comments
<span id="flaggedCount" class="text-sm text-gray-500 ml-2">({{ flagged_comments|length }})</span>
</h2>
<div class="space-y-4">
{% for comment in flagged_comments %}
<div class="comment-card bg-red-50 p-4 rounded-lg shadow-md border border-red-200 relative">
<p class="mb-2 text-gray-800">{{ comment.text }}</p>
<div class="text-sm text-gray-600 flex justify-between items-center">
<span class="font-medium">{{ comment.author }}</span>
<div class="flex space-x-2">
<button data-comment-id="{{ comment.id }}" data-video-id="{{ video.id }}" class="delete-comment-btn bg-red-500 text-white px-3 py-1 rounded hover:bg-red-600 transition duration-300">
Delete
</button>
<button data-comment-id="{{ comment.id }}" data-video-id="{{ video.id }}"class="keep-comment-btn bg-green-500 text-white px-3 py-1 rounded hover:bg-green-600 transition duration-300">
Keep
</button>
</div>
</div>
<div class="mt-2 text-xs text-gray-500">
<strong>Gambling Confidence:</strong> {{ comment.metrics.confidence_score }}
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Delete Comment Functionality
document.querySelectorAll('.delete-comment-btn').forEach(button => {
button.addEventListener('click', async function(e) {
e.stopPropagation(); // Ensure this click doesn't affect other handlers
const commentId = this.getAttribute('data-comment-id');
const videoId = this.getAttribute('data-video-id');
const commentCard = this.closest('.comment-card');
try {
const response = await fetch(`/api/comments/${commentId}?video_id=${videoId}`, {
method: 'DELETE'
});
const data = await response.json();
if (data.success) {
// Remove the comment from the DOM
commentCard.remove();
// Optionally, update the flagged comments count
const flaggedCommentsCount = document.querySelector('h2 span');
const currentCount = parseInt(flaggedCommentsCount.textContent.replace(/[()]/g, ''));
flaggedCommentsCount.textContent = `(${currentCount - 1})`;
} else {
alert("Failed to delete comment. Please refresh and try again.");
}
} catch (err) {
console.error(err);
alert("Error deleting comment.");
}
});
});
// Keep Comment Functionality with added debug logging
document.querySelectorAll('.keep-comment-btn').forEach(button => {
button.addEventListener('click', async function(e) {
e.stopPropagation();
const commentId = this.getAttribute('data-comment-id');
const videoId = this.getAttribute('data-video-id');
const commentCard = this.closest('.comment-card');
console.log(`Keep button clicked for commentId: ${commentId}, videoId: ${videoId}`);
try {
// Make the API call to keep the comment on YouTube
const response = await fetch(`/api/comments/keep/${commentId}?video_id=${videoId}`, {
method: 'POST'
});
console.log("Response received from API:", response);
const data = await response.json();
console.log("Parsed response data:", data);
if (data.success) {
// If successful, remove from DOM and update the flagged count
commentCard.remove();
const flaggedCommentsCount = document.querySelector('#flaggedCount');
const currentCount = parseInt(flaggedCommentsCount.textContent);
flaggedCommentsCount.textContent = currentCount - 1;
console.log(`Comment ${commentId} removed, flagged count updated to ${currentCount - 1}`);
} else {
console.error(`API reported error for comment ${commentId}:`, data.error);
alert("Failed to keep comment: " + (data.error || 'Unknown error'));
}
} catch (err) {
console.error(`Error keeping comment ${commentId}:`, err);
alert("Error keeping comment.");
}
});
});
// Refresh Comments Functionality
document.getElementById('refreshCommentsBtn').addEventListener('click', function(e) {
e.stopPropagation(); // Prevent any unwanted event bubbling
const videoId = "{{ video.id }}";
window.location.href = `/video/${videoId}`;
});
});
</script>
{% endblock %}