refactored templates

This commit is contained in:
2026-02-21 23:09:22 +01:00
parent 44b8e90448
commit 076293f80d
14 changed files with 694 additions and 699 deletions

View File

@@ -1,99 +1,60 @@
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="utf-8">
<title>Live Confusion Alerts</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/output.css') }}">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
{% extends "admin_base.html" %}
{% set active_page = 'confused' %}
{% set title = 'Live Confusion Alerts' %}
{% block head_extra %}
<script src="{{ url_for('static', filename='js/socket.io.min.js') }}"></script>
</head>
<body class="bg-background min-h-screen">
<nav class="bg-white border-gray-200 dark:bg-gray-900">
<div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4">
<a href="{{url_for('main.index')}}" class="flex items-center space-x-3 rtl:space-x-reverse">
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white">Tutortool</span>
</a>
<div class="hidden w-full md:block md:w-auto" id="navbar-default">
<ul class="font-medium flex flex-col justify-between md:justify-evenly p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 rtl:space-x-reverse md:mt-0 md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
<li>
<a href="{{url_for('admin.admin')}}"
class="block py-2 px-3 text-gray-900 rounded-sm hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">
Deck Admin
</a>
</li>
<li>
<a href="{{url_for('admin.banner')}}"
class="block py-2 px-3 text-gray-900 rounded-sm hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">
Banner
</a>
</li>
<li>
<a href="{{url_for('admin.confused_notifications')}}"
class="block py-2 px-3 text-white bg-blue-700 rounded-sm md:bg-transparent md:text-blue-700 md:p-0 dark:text-white md:dark:text-blue-500"
aria-current="page">
Confused
</a>
</li>
</ul>
</div>
{% endblock %}
{% block admin_content %}
<div class="max-w-3xl mx-auto mt-12 px-4">
<h1 class="text-3xl font-bold mb-6 dark:text-white">Live Confusion Alerts</h1>
<div id="notif-list" class="space-y-4 text-gray-700">
<p class="italic text-gray-500">Waiting for students to click "I'm confused…"</p>
</div>
</nav>
</div>
{% endblock admin_content %}
{% block scripts %}{% endblock %}{# No Flowbite needed #}
<div class="max-w-3xl mx-auto mt-12 px-4">
<h1 class="text-3xl font-bold mb-6 dark:text-white">Live Confusion Alerts</h1>
<div id="notif-list" class="space-y-4 text-gray-700">
<p class="italic text-gray-500">Waiting for students to click “Im confused…”</p>
</div>
</div>
{% block scripts_extra %}
<script>
const notifList = document.getElementById("notif-list");
const socket = io({ transports: ['websocket'] });
<!-- Socket.IO client (served by your Flask-SocketIO) -->
<script>
const notifList = document.getElementById("notif-list");
const socket = io({ transports: ['websocket'] });
socket.on("confused", data => {
if (notifList.children.length === 1 &&
notifList.children[0].classList.contains("italic")) {
notifList.innerHTML = "";
}
socket.on("confused", data => {
// Remove placeholder if its still there
if (notifList.children.length === 1 &&
notifList.children[0].classList.contains("italic")) {
notifList.innerHTML = "";
}
const box = document.createElement("div");
box.className = [
"flex items-start",
"bg-red-50 border border-red-400",
"text-red-800 px-4 py-3 rounded-lg shadow",
"relative"
].join(" ");
// Build a new alert box
const box = document.createElement("div");
box.className = [
"flex items-start",
"bg-red-50 border border-red-400",
"text-red-800 px-4 py-3 rounded-lg shadow",
"relative"
].join(" ");
const who = data.who || "Someone";
const now = new Date().toLocaleTimeString();
box.innerHTML = `
<div class="flex-1">
<strong class="font-semibold">Confused!</strong>
<p>${who} clicked "I'm confused." at ${now}</p>
</div>
`;
// Message text
const who = data.who || "Someone";
const now = new Date().toLocaleTimeString();
box.innerHTML = `
<div class="flex-1">
<strong class="font-semibold">Confused!</strong>
<p>${who} clicked “Im confused.” at ${now}</p>
</div>
`;
// Close button
const btn = document.createElement("button");
btn.className = "ml-4 text-red-600 hover:text-red-900 focus:outline-none";
btn.setAttribute("aria-label", "Dismiss");
btn.innerHTML = "&times;";
btn.onclick = () => box.remove();
box.appendChild(btn);
// Prepend new alert
notifList.prepend(box);
// Autoremove after 20 s
setTimeout(() => box.remove(), 20000);
});
</script>
</body>
</html>
const btn = document.createElement("button");
btn.className = "ml-4 text-red-600 hover:text-red-900 focus:outline-none";
btn.setAttribute("aria-label", "Dismiss");
btn.innerHTML = "&times;";
btn.onclick = () => box.remove();
box.appendChild(btn);
notifList.prepend(box);
setTimeout(() => box.remove(), 20000);
});
</script>
{% endblock %}