fixed website

This commit is contained in:
2025-05-20 15:59:09 +02:00
parent 1c5b8e2298
commit 8330b73cd1
12 changed files with 701 additions and 37 deletions

View File

@@ -45,7 +45,7 @@ class Password(db.Model):
value : Mapped[str] = mapped_column(String(60))
expires_at: Mapped[Optional[datetime]] = mapped_column(UTCDateTime()) # Optional expiration
decks : Mapped[List[Deck]] = relationship("Deck", secondary=deck_password, back_populates='passwords', cascade="all")
decks : Mapped[List[Deck]] = relationship("Deck", secondary=deck_password, back_populates='passwords')
def __init__(self, value: str, expires_at: datetime|None) -> None:
self.value = value
@@ -67,8 +67,8 @@ class Deck(db.Model):
deck : Mapped[str] = mapped_column(String(60), unique=True, nullable=False)
description : Mapped[str] = mapped_column(String(60))
passwords : Mapped[List[Password]] = relationship("Password", secondary=deck_password, back_populates='decks', cascade="all")
tokens : Mapped[List[Token]] = relationship("Token", secondary=deck_token, back_populates='decks', cascade="all")
passwords : Mapped[List[Password]] = relationship("Password", secondary=deck_password, back_populates='decks')
tokens : Mapped[List[Token]] = relationship("Token", secondary=deck_token, back_populates='decks')
def __init__(self, name: str, deck: str, description: str = "") -> None:
self.name = name
@@ -82,7 +82,7 @@ class Token(db.Model):
__tablename__ = "token"
id : Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(60), unique=True, nullable=False)
decks : Mapped[List[Deck]]= relationship("Deck", secondary=deck_token, back_populates='tokens', cascade="all")
decks : Mapped[List[Deck]]= relationship("Deck", secondary=deck_token, back_populates='tokens')
def __init__(self, name: str) -> None:
self.name = name

View File

@@ -215,7 +215,8 @@ def serve_deck(deck, path='index.html'):
def admin():
deck_form = DeckForm()
password_form = PasswordForm()
password_form.value.data = generate_password()
if request.method == 'GET':
password_form.value.data = generate_password()
deck_form.deck.choices = get_available_decks(current_app)
decks = db.session.scalars(db.select(Deck).order_by(Deck.name)).all()
passwords = db.session.scalars(db.select(Password)).all()

View File

@@ -33,12 +33,29 @@
<link href="https://cdn.jsdelivr.net/npm/flowbite@3.1.2/dist/flowbite.min.css" rel="stylesheet">
</head>
<body class="bg-background text-text min-h-screen font-sans">
<div class="container mx-auto px-6 py-10 space-y-12">
<!-- Admin Title -->
<h1 class="text-3xl font-bold text-center mb-8">Deck & Password Admin</h1>
<nav class="bg-white border-gray-200 dark:bg-gray-900">
<div class="max-w-screen-xl flex flex-wrap items-center x-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="w-auto" id="navbar-default">
<ul class="font-medium p-0 py-2 border border-gray-100 rounded-lg bg-gray-50 flex flex-row space-x-8 rtl:space-x-reverse mt-0 border-0 bg-white dark:bg-gray-800 dark:bg-gray-900 dark:border-gray-700 justify-between">
<li>
<a href="{{url_for('main.admin')}}" class="rounded-sm bg-transparent text-blue-700 p-0 dark:text-blue-500" aria-current="page">Deck Admin</a>
</li>
<li>
<a href="{{url_for('main.banner')}}" class="text-grey-900 dark:hover:text-blue-500 hover:text-blue-700 rounded-sm bg-transparent dark:text-white">Banner</a>
</li>
<li>
<a href="{{url_for('main.confused_notifications')}}" class="text-grey-900 dark:hover:text-blue-500 hover:text-blue-700 rounded-sm bg-transparent p-0 dark:text-white">Confused</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container mx-auto px-6 py-10 space-y-12">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-10">
<!-- Deck Form + Decks -->

View File

@@ -32,12 +32,36 @@
<body class="bg-background text-text min-h-screen font-sans">
<!-- Header -->
<header class="bg-surface border-b border-border shadow-sm">
<div class="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between">
<div class="text-lg font-semibold">Info Banner</div>
<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('main.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('main.banner')}}"
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">
Banner
</a>
</li>
<li>
<a href="{{url_for('main.confused_notifications')}}"
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">
Confused
</a>
</li>
</ul>
</div>
</header>
</div>
</nav>
<!-- Main Content -->
<main class="max-w-5xl mx-auto px-6 py-10 space-y-12">

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="dark">
<head>
<meta charset="utf-8">
<title>Live Confusion Alerts</title>
@@ -8,11 +8,61 @@
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.1/socket.io.min.js"></script>
<!-- Tailwind Config (Dark Mode + Theme Colors) -->
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
background: '#121418', // dark slate with blue/gray tone
surface: '#1e2127', // a bit lighter for containers/cards
border: '#2a2d34', // visible but subtle borders
primary: '#4f8cff', // soft blue that pops but is not neon
text: '#e4e4e7', // light gray for high contrast
muted: '#a0a0ad', // for subdued text
},
},
}
};
</script>
</head>
<body class="bg-gray-100 min-h-screen">
<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('main.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('main.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('main.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>
</div>
</nav>
<div class="max-w-3xl mx-auto mt-12 px-4">
<h1 class="text-3xl font-bold mb-6">Live Confusion Alerts</h1>
<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>

View File

@@ -41,25 +41,34 @@
<!-- Header -->
<header class="bg-surface border-b border-border shadow-sm">
<div class="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between relative">
<!-- Editable Username Form -->
<form method="POST" action="/retrieve-token" class="flex items-center space-x-2">
<input
type="text"
name="user_name"
value="{{ user_name }}"
class="bg-transparent text-muted text-sm font-medium px-2 py-1 rounded-md border border-transparent focus:border-primary focus:outline-none focus:bg-background"
size = "{{ user_name|length }}"
disabled
id="usernameInput"
/>
<div
class="max-w-7xl mx-auto px-6 py-4
grid grid-cols-2 items-center gap-4"
>
<!-- 1) form in column 1 -->
<form
method="POST"
action="/retrieve-token"
class="relative z-10 flex flex-col space-y-2"
>
<input
type="text"
name="user_name"
value="{{ user_name }}"
class="bg-transparent text-muted text-sm font-medium w-auto min-w-max whitespace-nowrap px-2 py-1 rounded-md border border-transparent focus:border-primary focus:outline-none focus:bg-background"
size="{{ user_name|length }}"
disabled
id="usernameInput"
/>
<div class="w-auto min-w-max whitespace-nowrap">
<button
type="button"
onclick="enableUsernameEdit()"
class="text-sm text-white bg-primary px-3 py-1 rounded-md hover:bg-blue-700"
id="editBtn"
>
Username ändern
Username ändern
</button>
<button
type="submit"
@@ -68,18 +77,24 @@
>
Save
</button>
</form>
<div class="absolute inset-0 flex items-center justify-center pointer-events-none">GRNVS Tutorium</div>
</div>
</form>
<!-- 2) admin button in column 2 -->
<div class="flex justify-end">
<a href="/admin">
<button class="bg-primary hover:bg-blue-700 text-white px-3 py-1 rounded-md transition">
Admin
</button>
</a>
</div>
</header>
</div>
</header>
<!-- Main Content -->
<main class="max-w-5xl mx-auto px-6 py-10 space-y-12">
<h3 class="text-3xl font-bold text-center mb-8">GRNVS Tutorium SS 25</h3>
{% if active_banner %}
<section class="flex justify-center">

View File

@@ -30,7 +30,7 @@ def generate_username() -> str:
def generate_password() -> str:
return cast(str, xkcd_password.generate_xkcdpassword(wordlist=words, numwords=5, delimiter="-"))
return cast(str, xkcd_password.generate_xkcdpassword(wordlist=words, numwords=2, delimiter="-"))
def generate_token() -> Token:
max_tries = 100