Add Impressum and QR code management templates
- Created a new Impressum page with legal information and contact details. - Developed admin link page for linking QR codes to events with form functionality. - Implemented QR code dashboard for managing QR code sets, including creation and quick actions. - Added detailed view for QR code sets, allowing addition of QR codes and management actions. - Introduced static file serving for favicon and related images. - Established views for static content pages (about, contact, privacy, terms). - Implemented translation management scripts for compiling and updating translations.
This commit is contained in:
@@ -1,23 +1,61 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">About LeagueLedger</h1>
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">{{ _("About LeagueLedger") }}</h1>
|
||||
<p class="mb-4">
|
||||
{% if locale == "de" %}
|
||||
LeagueLedger ist Ihr ultimativer Begleiter für die Verfolgung von Pub-Quiz-Team-Erfolgen. Wir möchten eine unterhaltsame und ansprechende Plattform für Quiz-Enthusiasten bieten, um sich zu vernetzen, zu wetteifern und ihr Wissen zu feiern.
|
||||
{% else %}
|
||||
LeagueLedger is your ultimate companion for tracking pub quiz team achievements. We aim to provide a fun and engaging platform for quiz enthusiasts to connect, compete, and celebrate their knowledge.
|
||||
{% endif %}
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
{% if locale == "de" %}
|
||||
Als Pub-Quiz-Meister können Sie QR-Codes für Ihre bestplatzierten Teams generieren, diese verteilen und Teams diese auf unserer Website für Punkte einlösen lassen.
|
||||
{% else %}
|
||||
As a pub quiz master, you can generate printout QR codes for your top-ranking teams, distribute them, and let teams redeem them for points on our website.
|
||||
{% endif %}
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
{% if locale == "de" %}
|
||||
Als Pub-Quiz-Teammitglied können Sie QR-Codes einlösen, einen Teamnamen erstellen, andere Mitglieder einladen und Social-Logins für einen einfachen Zugang nutzen.
|
||||
{% else %}
|
||||
As a pub quiz team member, you can redeem QR codes, create a team name, invite other members, and use social logins for easy access.
|
||||
{% endif %}
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Our Mission</h2>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">
|
||||
{% if locale == "de" %}Unsere Mission{% else %}Our Mission{% endif %}
|
||||
</h2>
|
||||
<p class="mb-4">
|
||||
{% if locale == "de" %}
|
||||
Die Pub-Quiz-Erfahrung zu verbessern, indem wir eine nahtlose und intuitive Plattform für die Verfolgung des Teamfortschritts bieten, freundlichen Wettbewerb fördern und den Geist des Quiz feiern.
|
||||
{% else %}
|
||||
To enhance the pub quiz experience by providing a seamless and intuitive platform for tracking team progress, fostering friendly competition, and celebrating the spirit of trivia.
|
||||
{% endif %}
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Our Team</h2>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">
|
||||
{% if locale == "de" %}Unser Team{% else %}Our Team{% endif %}
|
||||
</h2>
|
||||
<p class="mb-4">
|
||||
LeagueLedger is an Open-Source initiative and part of the KaufDeinQuiz platform. It is brought to you by Christian Louis IT Beratung und Medienproduktion, a team of dedicated quiz enthusiasts and software developers passionate about creating innovative solutions for the pub quiz community.
|
||||
{% if locale == "de" %}
|
||||
LeagueLedger ist eine Open-Source-Initiative und Teil der KaufDeinQuiz-Plattform. Es wird von Christian Louis IT Beratung und Medienproduktion entwickelt, unter der Leitung von Christian Krakau-Louis, einem Team von engagierten Quiz-Enthusiasten und Softwareentwicklern, die leidenschaftlich daran arbeiten, innovative Lösungen für die Pub-Quiz-Community zu schaffen.
|
||||
{% else %}
|
||||
LeagueLedger is an Open-Source initiative and part of the KaufDeinQuiz platform. It is brought to you by Christian Louis IT Beratung und Medienproduktion, led by Christian Krakau-Louis, a team of dedicated quiz enthusiasts and software developers passionate about creating innovative solutions for the pub quiz community.
|
||||
{% endif %}
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">
|
||||
{% if locale == "de" %}Lizenz{% else %}License{% endif %}
|
||||
</h2>
|
||||
<p class="mb-4">
|
||||
{% if locale == "de" %}
|
||||
LeagueLedger ist unter der Apache License 2.0 lizenziert. Die vollständige Lizenz finden Sie in unserer GitHub-Repository oder auf Anfrage.
|
||||
{% else %}
|
||||
LeagueLedger is licensed under the Apache License 2.0. You can find the full license in our GitHub repository or upon request.
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
<p class="mt-8 text-sm text-gray-600">
|
||||
{% if locale == "de" %}Letzte Aktualisierung: April 2025{% else %}Last updated: April 2025{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -22,7 +22,10 @@
|
||||
|
||||
<div class="mt-10 pt-6 border-t border-gray-200">
|
||||
<h2 class="text-xl font-bold text-irish-green mb-4">Quick Actions</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<a href="/qr" class="bg-white border border-irish-green text-irish-green hover:bg-irish-green hover:text-white px-4 py-3 rounded-md transition flex items-center">
|
||||
<i class="fas fa-qrcode mr-2"></i> QR Code Dashboard
|
||||
</a>
|
||||
<a href="/qr/generate/10" class="bg-white border border-irish-green text-irish-green hover:bg-irish-green hover:text-white px-4 py-3 rounded-md transition flex items-center">
|
||||
<i class="fas fa-qrcode mr-2"></i> Generate QR Code (10 points)
|
||||
</a>
|
||||
|
||||
+249
-144
@@ -1,151 +1,256 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="h-full">
|
||||
<html lang="{{ locale }}">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>LeagueLedger</title>
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=EB+Garamond:wght@400;600;700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<!-- Font Awesome Icons -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
'irish-green': '#006837',
|
||||
'golden-ale': '#FFB400',
|
||||
'cream-white': '#F5F0E1',
|
||||
'black-stout': '#1A1A1A',
|
||||
'guinness-red': '#B22222',
|
||||
},
|
||||
fontFamily: {
|
||||
'garamond': ['"EB Garamond"', 'serif'],
|
||||
'inter': ['"Inter"', 'sans-serif'],
|
||||
}
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}LeagueLedger - Pub Quiz Tracking{% endblock %}</title>
|
||||
|
||||
<!-- Favicon -->
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/images/favicon/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/images/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/images/favicon/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/images/favicon/site.webmanifest">
|
||||
|
||||
|
||||
<!-- Font Awesome for icons -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
'irish-green': '#006837',
|
||||
'golden-ale': '#FFB400',
|
||||
'cream-white': '#F5F0E1',
|
||||
'black-stout': '#1A1A1A',
|
||||
'guinness-red': '#B22222',
|
||||
},
|
||||
fontFamily: {
|
||||
'garamond': ['Garamond', 'Georgia', 'serif'],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: 'EB Garamond', serif;
|
||||
}
|
||||
</style>
|
||||
</script>
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', path='css/styles.css') }}">
|
||||
|
||||
<!-- HTML5 QR Code Scanner library -->
|
||||
<script src="https://unpkg.com/html5-qrcode"></script>
|
||||
|
||||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
<body class="flex flex-col min-h-screen bg-cream-white text-black-stout">
|
||||
<header class="bg-irish-green text-cream-white shadow-md">
|
||||
<div class="container mx-auto px-4">
|
||||
<!-- Desktop Navigation -->
|
||||
<div class="flex justify-between items-center py-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<img src="https://picsum.photos/40" alt="LeagueLedger Logo" class="h-10 w-10">
|
||||
<h1 class="text-2xl font-bold font-garamond">LeagueLedger</h1>
|
||||
<body class="bg-gray-100 min-h-screen flex flex-col">
|
||||
<!-- Navigation -->
|
||||
<nav class="bg-irish-green text-white shadow-md">
|
||||
<div class="container mx-auto px-4 py-3">
|
||||
<div class="flex justify-between items-center">
|
||||
<!-- Logo and site name -->
|
||||
<div class="flex items-center space-x-2">
|
||||
<a href="/" class="flex items-center">
|
||||
<img src="{{ url_for('static', path='images/logos/monogram.png') }}" alt="LeagueLedger Logo" class="h-12">
|
||||
<span class="ml-2 text-xl font-bold">LeagueLedger</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation -->
|
||||
<div class="hidden md:flex space-x-6 items-center">
|
||||
<a href="/" class="hover:text-golden-ale transition">{{ _("Home") }}</a>
|
||||
<a href="/teams" class="hover:text-golden-ale transition">{{ _("Teams") }}</a>
|
||||
<a href="/leaderboard" class="hover:text-golden-ale transition">{{ _("Leaderboard") }}</a>
|
||||
<a href="/scan" class="hover:text-golden-ale transition">{{ _("Scan QR Code") }}</a>
|
||||
|
||||
<!-- Language Selector -->
|
||||
<div class="relative dropdown">
|
||||
<button class="dropdown-toggle flex items-center space-x-1 hover:text-golden-ale transition">
|
||||
<i class="fas fa-globe text-lg"></i>
|
||||
<span>{{ SUPPORTED_LANGUAGES[locale] }}</span>
|
||||
<i class="fas fa-chevron-down text-xs"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-50">
|
||||
{% for code, name in SUPPORTED_LANGUAGES.items() %}
|
||||
<a href="/set-language/{{ code }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 {% if locale == code %}font-bold{% endif %}">
|
||||
{{ name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if user %}
|
||||
<div class="relative dropdown">
|
||||
<button class="dropdown-toggle flex items-center space-x-1 hover:text-golden-ale transition">
|
||||
<i class="fas fa-user-circle text-lg"></i>
|
||||
<span>{{ user.username }}</span>
|
||||
<i class="fas fa-chevron-down text-xs"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-50">
|
||||
<a href="/profile" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
|
||||
<i class="fas fa-user mr-2"></i> {{ _("Profile") }}
|
||||
</a>
|
||||
<a href="/dashboard" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
|
||||
<i class="fas fa-tachometer-alt mr-2"></i> {{ _("Dashboard") }}
|
||||
</a>
|
||||
{% if user.is_admin %}
|
||||
<a href="/admin" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
|
||||
<i class="fas fa-cog mr-2"></i> {{ _("Admin") }}
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="border-t border-gray-100 my-1"></div>
|
||||
<a href="/logout" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
|
||||
<i class="fas fa-sign-out-alt mr-2"></i> {{ _("Logout") }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<a href="/login" class="bg-golden-ale hover:bg-opacity-90 text-black-stout px-4 py-2 rounded-md transition">{{ _("Sign In") }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Mobile menu button -->
|
||||
<div class="md:hidden flex items-center space-x-4">
|
||||
<!-- Mobile Language Selector -->
|
||||
<div class="relative dropdown">
|
||||
<button class="dropdown-toggle flex items-center hover:text-golden-ale transition">
|
||||
<i class="fas fa-globe text-lg"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu hidden absolute right-0 mt-2 w-32 bg-white rounded-md shadow-lg py-1 z-50">
|
||||
{% for code, name in SUPPORTED_LANGUAGES.items() %}
|
||||
<a href="/set-language/{{ code }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 {% if locale == code %}font-bold{% endif %}">
|
||||
{{ name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="mobile-menu-button" class="text-white hover:text-golden-ale transition">
|
||||
<i class="fas fa-bars text-2xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Navigation -->
|
||||
<div id="mobile-menu" class="hidden md:hidden mt-3 pb-3 border-t border-irish-green border-opacity-30">
|
||||
<div class="flex flex-col space-y-2 mt-3">
|
||||
<a href="/" class="hover:text-golden-ale transition py-2">{{ _("Home") }}</a>
|
||||
<a href="/teams" class="hover:text-golden-ale transition py-2">{{ _("Teams") }}</a>
|
||||
<a href="/leaderboard" class="hover:text-golden-ale transition py-2">{{ _("Leaderboard") }}</a>
|
||||
<a href="/scan" class="hover:text-golden-ale transition py-2">{{ _("Scan QR Code") }}</a>
|
||||
{% if user %}
|
||||
<a href="/profile" class="hover:text-golden-ale transition py-2">{{ _("Profile") }}</a>
|
||||
<a href="/dashboard" class="hover:text-golden-ale transition py-2">{{ _("Dashboard") }}</a>
|
||||
{% if user.is_admin %}
|
||||
<a href="/admin" class="hover:text-golden-ale transition py-2">{{ _("Admin") }}</a>
|
||||
{% endif %}
|
||||
<a href="/logout" class="hover:text-golden-ale transition py-2">{{ _("Logout") }}</a>
|
||||
{% else %}
|
||||
<a href="/login" class="bg-golden-ale hover:bg-opacity-90 text-black-stout px-4 py-2 rounded-md transition text-center">{{ _("Sign In") }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation Links -->
|
||||
<nav class="hidden md:flex items-center space-x-6">
|
||||
<a href="/" class="hover:text-golden-ale transition-colors duration-200">
|
||||
<i class="fas fa-home"></i> Home
|
||||
</a>
|
||||
<a href="/teams/" class="hover:text-golden-ale transition-colors duration-200">
|
||||
<i class="fas fa-users"></i> Teams
|
||||
</a>
|
||||
<a href="/leaderboard" class="hover:text-golden-ale transition-colors duration-200">
|
||||
<i class="fas fa-trophy"></i> Leaderboard
|
||||
</a>
|
||||
<a href="/dashboard" class="hover:text-golden-ale transition-colors duration-200">
|
||||
<i class="fas fa-tachometer-alt"></i> Dashboard
|
||||
</a>
|
||||
<a href="/admin/" class="hover:text-golden-ale transition-colors duration-200">
|
||||
<i class="fas fa-lock"></i> Admin
|
||||
</a>
|
||||
<a href="/about" class="hover:text-golden-ale transition-colors duration-200">
|
||||
About
|
||||
</a>
|
||||
<a href="/contact" class="hover:text-golden-ale transition-colors duration-200">
|
||||
Contact
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<!-- Mobile Menu Button -->
|
||||
<button id="mobile-menu-button" class="md:hidden text-cream-white focus:outline-none">
|
||||
<i class="fas fa-bars text-2xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Navigation Menu -->
|
||||
<div id="mobile-menu" class="md:hidden hidden pb-4">
|
||||
<nav class="flex flex-col space-y-3">
|
||||
<a href="/" class="hover:bg-green-800 py-2 px-3 rounded-md transition-colors duration-200">
|
||||
<i class="fas fa-home"></i> Home
|
||||
</a>
|
||||
<a href="/teams/" class="hover:bg-green-800 py-2 px-3 rounded-md transition-colors duration-200">
|
||||
<i class="fas fa-users"></i> Teams
|
||||
</a>
|
||||
<a href="/leaderboard" class="hover:bg-green-800 py-2 px-3 rounded-md transition-colors duration-200">
|
||||
<i class="fas fa-trophy"></i> Leaderboard
|
||||
</a>
|
||||
<a href="/dashboard" class="hover:bg-green-800 py-2 px-3 rounded-md transition-colors duration-200">
|
||||
<i class="fas fa-tachometer-alt"></i> Dashboard
|
||||
</a>
|
||||
<a href="/admin/" class="hover:bg-green-800 py-2 px-3 rounded-md transition-colors duration-200">
|
||||
<i class="fas fa-lock"></i> Admin
|
||||
</a>
|
||||
<a href="/about" class="hover:bg-green-800 py-2 px-3 rounded-md transition-colors duration-200">
|
||||
About
|
||||
</a>
|
||||
<a href="/contact" class="hover:bg-green-800 py-2 px-3 rounded-md transition-colors duration-200">
|
||||
Contact
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="flex-grow container mx-auto px-4 py-6">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="bg-black-stout text-cream-white mt-auto">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row justify-between items-center">
|
||||
<div class="mb-4 md:mb-0">
|
||||
<h3 class="text-xl font-garamond">LeagueLedger</h3>
|
||||
<p class="text-sm text-cream-white opacity-70">Track Your Triumphs. Celebrate the Quiz.</p>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="flex-grow py-6">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="bg-black-stout text-cream-white py-8 mt-auto">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="flex flex-col md:flex-row justify-between">
|
||||
<div class="mb-6 md:mb-0">
|
||||
<div class="flex items-center mb-4">
|
||||
<img src="{{ url_for('static', path='images/logos/monogram.png') }}" alt="LeagueLedger Logo" class="h-12">
|
||||
<span class="ml-2 text-xl font-bold">LeagueLedger</span>
|
||||
</div>
|
||||
<p class="text-sm">{{ _("Track your pub quiz team's progress.") }}<br>{{ _("Scan QR codes to earn points.") }}</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-8">
|
||||
<div>
|
||||
<h3 class="text-golden-ale font-bold mb-4">{{ _("Navigation") }}</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="/" class="hover:text-golden-ale transition">{{ _("Home") }}</a></li>
|
||||
<li><a href="/teams" class="hover:text-golden-ale transition">{{ _("Teams") }}</a></li>
|
||||
<li><a href="/leaderboard" class="hover:text-golden-ale transition">{{ _("Leaderboard") }}</a></li>
|
||||
<li><a href="/scan" class="hover:text-golden-ale transition">{{ _("Scan QR Code") }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="text-golden-ale font-bold mb-4">{{ _("Account") }}</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="/login" class="hover:text-golden-ale transition">{{ _("Sign In") }}</a></li>
|
||||
<li><a href="/register" class="hover:text-golden-ale transition">{{ _("Register") }}</a></li>
|
||||
<li><a href="/profile" class="hover:text-golden-ale transition">{{ _("Profile") }}</a></li>
|
||||
<li><a href="/dashboard" class="hover:text-golden-ale transition">{{ _("Dashboard") }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="text-golden-ale font-bold mb-4">{{ _("Legal") }}</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="/about" class="hover:text-golden-ale transition">{{ _("About") }}</a></li>
|
||||
<li><a href="/contact" class="hover:text-golden-ale transition">{{ _("Contact") }}</a></li>
|
||||
<li><a href="/terms" class="hover:text-golden-ale transition">{{ _("Terms of Service") }}</a></li>
|
||||
<li><a href="/privacy" class="hover:text-golden-ale transition">{{ _("Privacy Policy") }}</a></li>
|
||||
<li><a href="/cookies" class="hover:text-golden-ale transition">{{ _("Cookie Policy") }}</a></li>
|
||||
<li><a href="/impressum" class="hover:text-golden-ale transition">{{ _("Imprint") }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-800 mt-8 pt-8 flex flex-col md:flex-row justify-between items-center">
|
||||
<div class="flex items-center space-x-4">
|
||||
<p class="text-sm">© 2025 LeagueLedger. {{ _("Licensed under Apache License 2.0") }}</p>
|
||||
</div>
|
||||
<div class="flex space-x-4 mt-4 md:mt-0">
|
||||
{% for code, name in SUPPORTED_LANGUAGES.items() %}
|
||||
<a href="/set-language/{{ code }}" class="hover:text-golden-ale transition {% if locale == code %}font-bold{% endif %}">
|
||||
{{ name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-links">
|
||||
<a href="/about" class="text-cream-white hover:text-golden-ale transition-colors duration-200">About</a>
|
||||
<a href="/contact" class="text-cream-white hover:text-golden-ale transition-colors duration-200">Contact</a>
|
||||
<a href="/privacy" class="text-cream-white hover:text-golden-ale transition-colors duration-200">Privacy</a>
|
||||
<a href="/terms" class="text-cream-white hover:text-golden-ale transition-colors duration-200">Terms</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-gray-700 mt-6 pt-6 text-center text-sm text-cream-white opacity-70">
|
||||
© {{ now().year }} LeagueLedger. All rights reserved.
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// Mobile menu toggle
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const menuButton = document.getElementById('mobile-menu-button');
|
||||
const mobileMenu = document.getElementById('mobile-menu');
|
||||
|
||||
menuButton.addEventListener('click', function() {
|
||||
mobileMenu.classList.toggle('hidden');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</footer>
|
||||
<!-- Custom JavaScript -->
|
||||
<script src="{{ url_for('static', path='js/main.js') }}"></script>
|
||||
<!-- Mobile menu toggle script -->
|
||||
<script>
|
||||
document.getElementById('mobile-menu-button').addEventListener('click', function() {
|
||||
const menu = document.getElementById('mobile-menu');
|
||||
menu.classList.toggle('hidden');
|
||||
});
|
||||
</script>
|
||||
<!-- Email Protection Script -->
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Decrypt email addresses
|
||||
const emailElements = document.querySelectorAll('.email-protection');
|
||||
emailElements.forEach(function(element) {
|
||||
const email = element.dataset.email;
|
||||
// Create clickable email link
|
||||
const link = document.createElement('a');
|
||||
link.href = 'mailto:' + email;
|
||||
link.textContent = email;
|
||||
link.className = element.className;
|
||||
// Replace placeholder with actual email link
|
||||
element.parentNode.replaceChild(link, element);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% block extra_scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,23 +1,48 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Contact Us</h1>
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Kontakt</h1>
|
||||
<p class="mb-4">
|
||||
Have questions, suggestions, or feedback? We'd love to hear from you!
|
||||
Haben Sie Fragen, Anregungen oder Feedback? Wir freuen uns, von Ihnen zu hören!
|
||||
</p>
|
||||
<div class="mb-6">
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Contact Information</h2>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Kontaktinformationen</h2>
|
||||
<p><strong>Christian Louis IT Beratung</strong></p>
|
||||
<p>Alter Steinweg 3</p>
|
||||
<p>20459 Hamburg</p>
|
||||
<p>Deutschland</p>
|
||||
<p><strong>Phone:</strong> +49 179 5183732</p>
|
||||
<p><strong>Email:</strong> <a href="mailto:quizarium@kaufdeinquiz.com">quizarium@kaufdeinquiz.com</a></p>
|
||||
<p><strong>Telefon:</strong> +49 179 5183732</p>
|
||||
<p><strong>E-Mail:</strong> <span class="email-protection" data-email="leagueledger@kaufdeinquiz.com">leagueledger [at] kaufdeinquiz.com</span></p>
|
||||
<p><strong>Fax:</strong> +49 40 97074609</p>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Connect With Us</h2>
|
||||
<p>This project is part of the KaufDeinQuiz platform and is operated as an Open-Source initiative. All rights reserved.</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Verbinden Sie sich mit uns</h2>
|
||||
<p>Dieses Projekt ist Teil der KaufDeinQuiz-Plattform und wird als Open-Source-Initiative betrieben. Lizenziert unter der Apache License 2.0.</p>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="text-xl font-semibold text-irish-green mb-2">Verantwortlicher gemäß § 5 TMG</h2>
|
||||
<p>Christian Krakau-Louis</p>
|
||||
<p>Christian Louis IT Beratung und Medienproduktion</p>
|
||||
<p>Alter Steinweg 3</p>
|
||||
<p>20459 Hamburg</p>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="text-xl font-semibold text-irish-green mb-2">Umsatzsteuer-ID</h2>
|
||||
<p>Umsatzsteuer-Identifikationsnummer gemäß §27a Umsatzsteuergesetz:</p>
|
||||
<p>DE202899017</p>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="text-xl font-semibold text-irish-green mb-2">Steuernummer</h2>
|
||||
<p>48/148/00526</p>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="text-xl font-semibold text-irish-green mb-2">Streitschlichtung</h2>
|
||||
<p>Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: <a href="https://ec.europa.eu/consumers/odr/" target="_blank" class="text-irish-green hover:underline">https://ec.europa.eu/consumers/odr/</a></p>
|
||||
<p>Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.</p>
|
||||
</div>
|
||||
|
||||
<p class="mt-8 text-sm text-gray-600">
|
||||
Letzte Aktualisierung: April 2025
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Cookie-Richtlinie</h1>
|
||||
<p class="mb-4">
|
||||
Diese Cookie-Richtlinie erläutert, wie LeagueLedger Cookies und ähnliche Technologien verwendet.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Was sind Cookies?</h2>
|
||||
<p class="mb-4">
|
||||
Cookies sind kleine Textdateien, die auf Ihrem Gerät gespeichert werden, wenn Sie eine Website besuchen. Sie werden weithin verwendet, um Websites funktionsfähig zu machen oder effizienter zu arbeiten, sowie um Informationen für die Website-Betreiber bereitzustellen.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Welche Cookies wir verwenden</h2>
|
||||
<p class="mb-4">
|
||||
Wir verwenden die folgenden Arten von Cookies:
|
||||
</p>
|
||||
<ul class="list-disc ml-6 mb-4">
|
||||
<li><strong>Notwendige Cookies:</strong> Diese sind für die Grundfunktionen der Website erforderlich und können nicht deaktiviert werden.</li>
|
||||
<li><strong>Funktionscookies:</strong> Diese ermöglichen erweiterte Funktionen und Personalisierung.</li>
|
||||
<li><strong>Analyse-Cookies:</strong> Diese helfen uns zu verstehen, wie Besucher mit unserer Website interagieren.</li>
|
||||
</ul>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Cookie-Verwaltung</h2>
|
||||
<p class="mb-4">
|
||||
Sie können Ihre Cookie-Einstellungen jederzeit ändern, indem Sie die Einstellungen Ihres Browsers anpassen. Beachten Sie, dass das Blockieren einiger Cookies die Funktionalität unserer Website beeinträchtigen kann.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Detaillierte Cookie-Liste</h2>
|
||||
<table class="min-w-full bg-white border border-gray-300 mt-4">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="py-2 px-4 border-b">Name</th>
|
||||
<th class="py-2 px-4 border-b">Zweck</th>
|
||||
<th class="py-2 px-4 border-b">Ablaufzeit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="py-2 px-4 border-b">session</td>
|
||||
<td class="py-2 px-4 border-b">Speichert Ihre Sitzungsinformationen</td>
|
||||
<td class="py-2 px-4 border-b">Sitzung</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-4 border-b">auth_token</td>
|
||||
<td class="py-2 px-4 border-b">Authentifizierung</td>
|
||||
<td class="py-2 px-4 border-b">30 Tage</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-4 border-b">cookie_consent</td>
|
||||
<td class="py-2 px-4 border-b">Speichert Ihre Cookie-Präferenzen</td>
|
||||
<td class="py-2 px-4 border-b">1 Jahr</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Änderungen dieser Cookie-Richtlinie</h2>
|
||||
<p class="mb-4">
|
||||
Wir behalten uns das Recht vor, diese Cookie-Richtlinie jederzeit zu ändern. Die aktuelle Version ist stets auf dieser Seite verfügbar.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Kontakt</h2>
|
||||
<p class="mb-4">
|
||||
Wenn Sie Fragen zu unserer Cookie-Richtlinie haben, kontaktieren Sie uns bitte unter <span class="email-protection" data-email="leagueledger@kaufdeinquiz.com">leagueledger [at] kaufdeinquiz.com</span>.
|
||||
</p>
|
||||
<p class="mt-8 text-sm text-gray-600">
|
||||
Letzte Aktualisierung: April 2025
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,64 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Impressum</h1>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Angaben gemäß § 5 TMG</h2>
|
||||
<p>Christian Louis IT Beratung</p>
|
||||
<p>Alter Steinweg 3</p>
|
||||
<p>20459 Hamburg</p>
|
||||
<p>Deutschland</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Vertreten durch</h2>
|
||||
<p>Christian Krakau-Louis</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Kontakt</h2>
|
||||
<p>Telefon: +49 179 5183732</p>
|
||||
<p>E-Mail: <span class="email-protection" data-email="leagueledger@kaufdeinquiz.com">leagueledger [at] kaufdeinquiz.com</span></p>
|
||||
<p>Fax: +49 40 97074609</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Umsatzsteuer-ID</h2>
|
||||
<p>Umsatzsteuer-Identifikationsnummer gemäß §27a Umsatzsteuergesetz:</p>
|
||||
<p>DE202899017</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Steuernummer</h2>
|
||||
<p>48/148/00526</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV</h2>
|
||||
<p>Christian Krakau-Louis</p>
|
||||
<p>Alter Steinweg 3</p>
|
||||
<p>20459 Hamburg</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Streitschlichtung</h2>
|
||||
<p>Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: <a href="https://ec.europa.eu/consumers/odr/" target="_blank" class="text-irish-green hover:underline">https://ec.europa.eu/consumers/odr/</a>.</p>
|
||||
<p>Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Haftung für Inhalte</h2>
|
||||
<p class="mb-4">
|
||||
Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.
|
||||
</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Haftung für Links</h2>
|
||||
<p class="mb-4">
|
||||
Unser Angebot enthält Links zu externen Websites Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.
|
||||
</p>
|
||||
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Urheberrecht</h2>
|
||||
<p class="mb-4">
|
||||
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Dieses Projekt ist Teil der Plattform KaufDeinQuiz und wird als Open-Source-Initiative betrieben. Der Quellcode dieser Anwendung ist unter der Apache License 2.0 lizenziert. Details finden Sie in der LICENSE-Datei im Repository.
|
||||
</p>
|
||||
|
||||
<p class="mt-8 text-sm text-gray-600">
|
||||
Letzte Aktualisierung: April 2025
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
+46
-17
@@ -1,32 +1,61 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Privacy Policy</h1>
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Datenschutzerklärung</h1>
|
||||
<p class="mb-4">
|
||||
Your privacy is important to us. This Privacy Policy outlines how LeagueLedger collects, uses, and protects your information.
|
||||
Der Schutz Ihrer Daten ist uns wichtig. Diese Datenschutzerklärung erläutert, wie LeagueLedger Ihre Informationen sammelt, verwendet und schützt.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Information We Collect</h2>
|
||||
<ul class="list-disc ml-6 mb-4">
|
||||
<li>Email addresses</li>
|
||||
<li>Usernames</li>
|
||||
<li>Team names</li>
|
||||
<li>Quiz scores and points</li>
|
||||
</ul>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">How We Use Your Information</h2>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Verantwortlicher im Sinne der DSGVO</h2>
|
||||
<p class="mb-4">
|
||||
We use your information to:
|
||||
Christian Krakau-Louis<br>
|
||||
Christian Louis IT Beratung und Medienproduktion<br>
|
||||
Alter Steinweg 3<br>
|
||||
20459 Hamburg<br>
|
||||
Deutschland<br>
|
||||
E-Mail: <span class="email-protection" data-email="leagueledger@kaufdeinquiz.com">leagueledger [at] kaufdeinquiz.com</span>
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Welche Daten wir sammeln</h2>
|
||||
<ul class="list-disc ml-6 mb-4">
|
||||
<li>E-Mail-Adressen</li>
|
||||
<li>Benutzernamen</li>
|
||||
<li>Team-Namen</li>
|
||||
<li>Quiz-Ergebnisse und Punkte</li>
|
||||
</ul>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Wie wir Ihre Daten verwenden</h2>
|
||||
<p class="mb-4">
|
||||
Wir verwenden Ihre Daten für folgende Zwecke:
|
||||
</p>
|
||||
<ul class="list-disc ml-6 mb-4">
|
||||
<li>Track leaderboard rankings</li>
|
||||
<li>Send notifications about team activities</li>
|
||||
<li>Improve our services and user experience</li>
|
||||
<li>Führen der Bestenliste</li>
|
||||
<li>Senden von Benachrichtigungen über Team-Aktivitäten</li>
|
||||
<li>Verbesserung unserer Dienste und Nutzererfahrung</li>
|
||||
</ul>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Data Sharing</h2>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Rechtsgrundlage für die Verarbeitung</h2>
|
||||
<p class="mb-4">
|
||||
We do not share your personal information with third parties except as required by law.
|
||||
Die Verarbeitung Ihrer personenbezogenen Daten erfolgt auf Grundlage Ihrer Einwilligung (Art. 6 Abs. 1 lit. a DSGVO) sowie zur Erfüllung des Vertrages (Art. 6 Abs. 1 lit. b DSGVO).
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Datenweitergabe</h2>
|
||||
<p class="mb-4">
|
||||
Wir geben Ihre personenbezogenen Daten nicht an Dritte weiter, außer wenn dies gesetzlich erforderlich ist.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Ihre Rechte</h2>
|
||||
<p class="mb-4">
|
||||
Sie haben das Recht auf Auskunft, Berichtigung, Löschung, Einschränkung der Verarbeitung, Datenübertragbarkeit und Widerspruch gemäß der DSGVO.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Speicherdauer</h2>
|
||||
<p class="mb-4">
|
||||
Wir speichern Ihre personenbezogenen Daten nur so lange, wie es für die Zwecke, für die sie erhoben wurden, erforderlich ist oder gesetzlich vorgeschrieben ist.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Beschwerderecht</h2>
|
||||
<p class="mb-4">
|
||||
Sie haben das Recht, sich bei einer Aufsichtsbehörde zu beschweren, wenn Sie der Ansicht sind, dass die Verarbeitung Ihrer personenbezogenen Daten gegen die DSGVO verstößt.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
Christian Louis IT Beratung und Medienproduktion, as the operator of this platform, takes data privacy seriously and implements measures to protect your personal information.
|
||||
Christian Louis IT Beratung und Medienproduktion als Betreiber dieser Plattform nimmt den Datenschutz ernst und implementiert Maßnahmen zum Schutz Ihrer personenbezogenen Daten.
|
||||
</p>
|
||||
|
||||
<p class="mt-8 text-sm text-gray-600">
|
||||
Letzte Aktualisierung: April 2025
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="max-w-md mx-auto p-4">
|
||||
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
|
||||
<div class="text-center mb-6">
|
||||
<i class="fas fa-link text-irish-green text-4xl mb-4"></i>
|
||||
<h1 class="text-2xl font-bold text-irish-green">Link QR Codes to Event</h1>
|
||||
<p class="text-gray-600">Administrator Access</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-irish-green bg-opacity-10 border border-irish-green rounded-md p-4 mb-6">
|
||||
<h3 class="font-bold text-irish-green mb-1">QR Set: {{ qr_set.name }}</h3>
|
||||
<p class="text-sm">You are about to link all QR codes in this set to an event.</p>
|
||||
</div>
|
||||
|
||||
<form action="/qr/admin-link/{{ admin_code }}" method="post" class="space-y-6">
|
||||
<!-- Select Existing Event -->
|
||||
<div>
|
||||
<label for="event_id" class="block text-sm font-medium text-gray-700 mb-2">Select Existing Event</label>
|
||||
<select name="event_id" id="event_id"
|
||||
class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-irish-green"
|
||||
onchange="toggleNewEventInput()">
|
||||
<option value="">-- Select an event --</option>
|
||||
{% for event in events %}
|
||||
<option value="{{ event.id }}">{{ event.name }} ({{ event.event_date.strftime('%Y-%m-%d') }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- OR Divider -->
|
||||
<div class="relative">
|
||||
<div class="absolute inset-0 flex items-center">
|
||||
<div class="w-full border-t border-gray-300"></div>
|
||||
</div>
|
||||
<div class="relative flex justify-center text-sm">
|
||||
<span class="px-2 bg-white text-gray-500">OR</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create New Event -->
|
||||
<div>
|
||||
<label for="new_event_name" class="block text-sm font-medium text-gray-700 mb-2">Create New Event</label>
|
||||
<input type="text" name="new_event_name" id="new_event_name"
|
||||
placeholder="e.g., Irish Rover Quiz Night 2025-04-17"
|
||||
class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-irish-green">
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button type="submit"
|
||||
class="w-full bg-irish-green hover:bg-opacity-90 text-white font-bold py-3 px-4 rounded-md transition">
|
||||
<i class="fas fa-link mr-2"></i> Link QR Codes to Event
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Information Box -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6">
|
||||
<h2 class="text-lg font-semibold text-irish-green mb-4">What This Does</h2>
|
||||
<div class="space-y-4 text-sm">
|
||||
<p>
|
||||
By linking QR codes to an event, you'll be able to track which achievements and points were earned
|
||||
during specific quiz nights or events.
|
||||
</p>
|
||||
<p>
|
||||
This helps with reporting and allows teams to see which events they've participated in and what
|
||||
awards they've received at each event.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Note:</strong> This action only affects QR codes that haven't been redeemed yet.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleNewEventInput() {
|
||||
const eventSelect = document.getElementById('event_id');
|
||||
const newEventInput = document.getElementById('new_event_name');
|
||||
|
||||
if (eventSelect.value) {
|
||||
newEventInput.disabled = true;
|
||||
newEventInput.classList.add('bg-gray-100');
|
||||
} else {
|
||||
newEventInput.disabled = false;
|
||||
newEventInput.classList.remove('bg-gray-100');
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
toggleNewEventInput();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,209 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="max-w-6xl mx-auto p-4">
|
||||
<div class="mb-8">
|
||||
<h1 class="text-3xl font-bold text-irish-green mb-2">QR Code Management</h1>
|
||||
<p class="text-gray-600">Create and manage QR code sets for your pub quiz events</p>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
<!-- QR Set Creation -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6">
|
||||
<h2 class="text-xl font-bold text-irish-green mb-4">Create QR Set</h2>
|
||||
<p class="text-sm text-gray-500 mb-4">
|
||||
Create a new set of QR codes for your pub quiz event with points and achievements.
|
||||
</p>
|
||||
|
||||
<form id="qrSetForm" action="/qr/sets" method="post" class="space-y-4">
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-gray-700">Set Name</label>
|
||||
<input type="text" name="name" id="name" required
|
||||
class="mt-1 block w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-irish-green"
|
||||
placeholder="e.g., Irish Rover Quiz Night">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700">Description (Optional)</label>
|
||||
<textarea name="description" id="description"
|
||||
class="mt-1 block w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-irish-green"
|
||||
placeholder="Weekly quiz with 1st, 2nd, and 3rd place prizes" rows="3"></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit"
|
||||
class="w-full bg-irish-green hover:bg-opacity-90 text-white font-bold py-2 px-4 rounded transition">
|
||||
Create QR Set
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- QR Set Examples -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6">
|
||||
<h2 class="text-xl font-bold text-irish-green mb-4">Common Templates</h2>
|
||||
<p class="text-sm text-gray-500 mb-4">
|
||||
Quickly create QR code sets using these pre-defined templates
|
||||
</p>
|
||||
|
||||
<div class="space-y-3">
|
||||
<div class="border rounded-md p-3 hover:bg-gray-50 cursor-pointer"
|
||||
onclick="useTemplate('Standard Pub Quiz',
|
||||
'Contains QR codes for 1st place (25 points), 2nd place (15 points), 3rd place (10 points), and 4th place (5 points)')">
|
||||
<h3 class="font-medium">Standard Pub Quiz</h3>
|
||||
<p class="text-xs text-gray-500">1st, 2nd, 3rd and 4th place</p>
|
||||
</div>
|
||||
|
||||
<div class="border rounded-md p-3 hover:bg-gray-50 cursor-pointer"
|
||||
onclick="useTemplate('Trivia Night',
|
||||
'Special trivia night with QR codes for winners and achievement codes for trivia categories')">
|
||||
<h3 class="font-medium">Trivia Night</h3>
|
||||
<p class="text-xs text-gray-500">With category achievements</p>
|
||||
</div>
|
||||
|
||||
<div class="border rounded-md p-3 hover:bg-gray-50 cursor-pointer"
|
||||
onclick="useTemplate('Weekly League',
|
||||
'Complete set for tracking weekly league progress with placements and special achievements')">
|
||||
<h3 class="font-medium">Weekly League</h3>
|
||||
<p class="text-xs text-gray-500">For ongoing competitions</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<p class="text-xs text-gray-500">
|
||||
Click a template to pre-fill the form. You can customize it before creating.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6">
|
||||
<h2 class="text-xl font-bold text-irish-green mb-4">Quick Actions</h2>
|
||||
<p class="text-sm text-gray-500 mb-4">
|
||||
Generate individual QR codes or access your created sets
|
||||
</p>
|
||||
|
||||
<div class="space-y-3">
|
||||
<a href="#"
|
||||
class="block border border-dashed border-gray-300 rounded-md p-4 hover:bg-gray-50 text-center"
|
||||
id="quickQrBtn">
|
||||
<i class="fas fa-qrcode text-irish-green text-2xl mb-2"></i>
|
||||
<p class="font-medium">Generate Quick QR</p>
|
||||
<p class="text-xs text-gray-500">Create a single QR code</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Quick QR Modal (hidden by default) -->
|
||||
<div id="quickQrModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center">
|
||||
<div class="bg-white rounded-lg p-6 max-w-md w-full">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="text-lg font-bold">Generate Quick QR Code</h3>
|
||||
<button id="closeModal" class="text-gray-500 hover:text-gray-700">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form id="quickQrForm" class="space-y-4">
|
||||
<div>
|
||||
<label for="qr-points" class="block text-sm font-medium text-gray-700">Points</label>
|
||||
<input type="number" id="qr-points" name="points" min="0" value="10"
|
||||
class="mt-1 block w-full border border-gray-300 rounded-md px-3 py-2">
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<button type="submit" class="bg-irish-green text-white px-4 py-2 rounded-md">
|
||||
Generate
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="qr-result" class="hidden mt-4 text-center">
|
||||
<div id="qr-image" class="mx-auto mb-2"></div>
|
||||
<p class="text-sm">Right-click to save the QR code</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Existing QR Sets -->
|
||||
<div class="mt-10">
|
||||
<h2 class="text-2xl font-bold text-irish-green mb-4">Your QR Sets</h2>
|
||||
|
||||
{% if qr_sets %}
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
{% for qr_set in qr_sets %}
|
||||
<div class="bg-white rounded-lg shadow hover:shadow-lg transition-shadow overflow-hidden">
|
||||
<div class="border-b px-6 py-4">
|
||||
<h3 class="font-bold">{{ qr_set.name }}</h3>
|
||||
{% if qr_set.description %}
|
||||
<p class="text-sm text-gray-600 mt-1">{{ qr_set.description }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="px-6 py-4">
|
||||
<div class="text-sm text-gray-500">
|
||||
<p>Created: {{ qr_set.created_at.strftime('%Y-%m-%d') }}</p>
|
||||
<p>QR Codes: {% if qr_set.qr_codes %}{{ qr_set.qr_codes | length }}{% else %}0{% endif %}</p>
|
||||
</div>
|
||||
<div class="mt-4 flex justify-between">
|
||||
<a href="/qr/sets/{{ qr_set.id }}" class="text-irish-green hover:underline">
|
||||
<i class="fas fa-eye mr-1"></i> View
|
||||
</a>
|
||||
<a href="/qr/sets/{{ qr_set.id }}/pdf" class="text-irish-green hover:underline">
|
||||
<i class="fas fa-file-pdf mr-1"></i> Generate PDF
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="bg-gray-50 border border-gray-200 rounded-md p-6 text-center">
|
||||
<i class="fas fa-info-circle text-gray-400 text-3xl mb-3"></i>
|
||||
<p class="text-gray-600">You haven't created any QR sets yet. Create your first set using the form above.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Template selection
|
||||
function useTemplate(name, description) {
|
||||
document.getElementById('name').value = name;
|
||||
document.getElementById('description').value = description;
|
||||
}
|
||||
|
||||
// Quick QR Modal
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const quickQrBtn = document.getElementById('quickQrBtn');
|
||||
const quickQrModal = document.getElementById('quickQrModal');
|
||||
const closeModal = document.getElementById('closeModal');
|
||||
const quickQrForm = document.getElementById('quickQrForm');
|
||||
const qrResult = document.getElementById('qr-result');
|
||||
const qrImage = document.getElementById('qr-image');
|
||||
|
||||
quickQrBtn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
quickQrModal.classList.remove('hidden');
|
||||
});
|
||||
|
||||
closeModal.addEventListener('click', function() {
|
||||
quickQrModal.classList.add('hidden');
|
||||
qrResult.classList.add('hidden');
|
||||
});
|
||||
|
||||
// Close modal when clicking outside
|
||||
quickQrModal.addEventListener('click', function(e) {
|
||||
if (e.target === quickQrModal) {
|
||||
quickQrModal.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
quickQrForm.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const points = document.getElementById('qr-points').value;
|
||||
|
||||
// Generate QR code
|
||||
qrImage.innerHTML = '<img src="/qr/generate/' + points + '" alt="QR Code" class="mx-auto" />';
|
||||
qrResult.classList.remove('hidden');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,273 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="max-w-6xl mx-auto p-4">
|
||||
<div class="mb-8">
|
||||
<div class="flex items-center">
|
||||
<a href="/qr" class="text-irish-green hover:underline mr-4">
|
||||
<i class="fas fa-arrow-left"></i> Back to Dashboard
|
||||
</a>
|
||||
<h1 class="text-3xl font-bold text-irish-green">{{ qr_set.name }}</h1>
|
||||
</div>
|
||||
{% if qr_set.description %}
|
||||
<p class="text-gray-600 mt-2">{{ qr_set.description }}</p>
|
||||
{% endif %}
|
||||
<p class="text-sm text-gray-500 mt-1">Created on {{ qr_set.created_at.strftime('%Y-%m-%d') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
<!-- QR Code Creation -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6">
|
||||
<h2 class="text-xl font-bold text-irish-green mb-4">Add QR Code</h2>
|
||||
<p class="text-sm text-gray-500 mb-4">
|
||||
Create QR codes for points and achievements in this set
|
||||
</p>
|
||||
|
||||
<form id="qrCodeForm" action="/qr/sets/{{ qr_set.id }}/codes" method="post" class="space-y-4">
|
||||
<div>
|
||||
<label for="title" class="block text-sm font-medium text-gray-700">Title</label>
|
||||
<input type="text" name="title" id="title" required
|
||||
class="mt-1 block w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-irish-green"
|
||||
placeholder="e.g., 1st Place, Most Creative, etc.">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="points" class="block text-sm font-medium text-gray-700">Points</label>
|
||||
<input type="number" name="points" id="points" step="0.1" min="0" value="10"
|
||||
class="mt-1 block w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-irish-green">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="achievement_name" class="block text-sm font-medium text-gray-700">Achievement (Optional)</label>
|
||||
<input type="text" name="achievement_name" id="achievement_name"
|
||||
class="mt-1 block w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-irish-green"
|
||||
placeholder="e.g., Quiz Champion, Top Scorer">
|
||||
</div>
|
||||
|
||||
<div class="flex items-center">
|
||||
<input type="checkbox" name="is_achievement_only" id="is_achievement_only" class="h-4 w-4 text-irish-green focus:ring-irish-green border-gray-300 rounded">
|
||||
<label for="is_achievement_only" class="ml-2 block text-sm text-gray-700">
|
||||
Achievement only (no points)
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700">Description (Optional)</label>
|
||||
<textarea name="description" id="description"
|
||||
class="mt-1 block w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-irish-green"
|
||||
placeholder="Description of this QR code" rows="2"></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit"
|
||||
class="w-full bg-irish-green hover:bg-opacity-90 text-white font-bold py-2 px-4 rounded transition">
|
||||
Add QR Code
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Common QR Code Templates -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6">
|
||||
<h2 class="text-xl font-bold text-irish-green mb-4">Quick Templates</h2>
|
||||
<p class="text-sm text-gray-500 mb-4">
|
||||
Click to quickly add common QR code types to this set
|
||||
</p>
|
||||
|
||||
<div class="space-y-3">
|
||||
<button class="w-full border border-gray-200 rounded-md p-3 hover:bg-gray-50 text-left"
|
||||
onclick="useQRTemplate('1st Place', 25, 'First Place Winner', false, 'First place award (25 points)')">
|
||||
<div class="flex items-center">
|
||||
<div class="bg-yellow-500 rounded-full h-6 w-6 flex items-center justify-center mr-3">
|
||||
<i class="fas fa-trophy text-white text-xs"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-medium">1st Place (25 points)</h3>
|
||||
<p class="text-xs text-gray-500">Top winner award</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button class="w-full border border-gray-200 rounded-md p-3 hover:bg-gray-50 text-left"
|
||||
onclick="useQRTemplate('2nd Place', 15, 'Second Place Winner', false, 'Second place award (15 points)')">
|
||||
<div class="flex items-center">
|
||||
<div class="bg-gray-400 rounded-full h-6 w-6 flex items-center justify-center mr-3">
|
||||
<i class="fas fa-medal text-white text-xs"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-medium">2nd Place (15 points)</h3>
|
||||
<p class="text-xs text-gray-500">Runner-up award</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button class="w-full border border-gray-200 rounded-md p-3 hover:bg-gray-50 text-left"
|
||||
onclick="useQRTemplate('3rd Place', 10, 'Third Place Winner', false, 'Third place award (10 points)')">
|
||||
<div class="flex items-center">
|
||||
<div class="bg-amber-700 rounded-full h-6 w-6 flex items-center justify-center mr-3">
|
||||
<i class="fas fa-award text-white text-xs"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-medium">3rd Place (10 points)</h3>
|
||||
<p class="text-xs text-gray-500">Third place award</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button class="w-full border border-gray-200 rounded-md p-3 hover:bg-gray-50 text-left"
|
||||
onclick="useQRTemplate('Estimate Winner', 0, 'Closest Guess Award', true, 'Achievement for closest estimate')">
|
||||
<div class="flex items-center">
|
||||
<div class="bg-blue-500 rounded-full h-6 w-6 flex items-center justify-center mr-3">
|
||||
<i class="fas fa-bullseye text-white text-xs"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-medium">Estimate Winner</h3>
|
||||
<p class="text-xs text-gray-500">Achievement only (no points)</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- QR Set Actions -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6">
|
||||
<h2 class="text-xl font-bold text-irish-green mb-4">QR Set Actions</h2>
|
||||
<p class="text-sm text-gray-500 mb-4">
|
||||
Create printable PDFs and admin codes for this set
|
||||
</p>
|
||||
|
||||
<div class="space-y-4">
|
||||
<a href="/qr/sets/{{ qr_set.id }}/pdf" class="block bg-irish-green text-white text-center font-bold py-3 px-4 rounded hover:opacity-90 transition">
|
||||
<i class="fas fa-file-pdf mr-2"></i> Generate PDF
|
||||
</a>
|
||||
|
||||
<div class="border rounded-md p-4">
|
||||
<h3 class="font-medium mb-2">Admin QR Code</h3>
|
||||
<p class="text-xs text-gray-500 mb-3">
|
||||
Use this special QR code to link all codes in this set to an event. Print this on each page.
|
||||
</p>
|
||||
<div class="text-center">
|
||||
<img src="/qr/sets/{{ qr_set.id }}/generate-admin" alt="Admin QR Code" class="mx-auto h-32">
|
||||
</div>
|
||||
<p class="text-xs text-center mt-2">Scan to link all QR codes to an event</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 pt-6 border-t">
|
||||
<h3 class="font-medium text-red-600">Danger Zone</h3>
|
||||
<p class="text-xs text-gray-500 mt-1 mb-3">These actions cannot be undone</p>
|
||||
<button id="deleteSetBtn" class="text-red-600 border border-red-600 rounded px-3 py-1 text-sm hover:bg-red-50">
|
||||
<i class="fas fa-trash-alt mr-1"></i> Delete Set
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- QR Codes List -->
|
||||
<div class="mt-10">
|
||||
<h2 class="text-2xl font-bold text-irish-green mb-4">QR Codes in this Set</h2>
|
||||
|
||||
{% if qr_codes %}
|
||||
<div class="bg-white shadow overflow-hidden rounded-lg">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
QR Code
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Details
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Points
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Achievement
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Status
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
{% for qr_code in qr_codes %}
|
||||
<tr>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<img src="/qr/code/{{ qr_code.code }}" alt="QR Code" class="h-16 w-16">
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="text-sm font-medium text-gray-900">{{ qr_code.title or "Untitled" }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">
|
||||
Code: {{ qr_code.code[:10] }}...
|
||||
</div>
|
||||
{% if qr_code.description %}
|
||||
<div class="text-xs text-gray-500 mt-1">{{ qr_code.description }}</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<span class="px-2 inline-flex text-sm leading-5 font-semibold rounded-full {{ 'bg-green-100 text-green-800' if qr_code.points > 0 else 'bg-gray-100 text-gray-800' }}">
|
||||
{{ qr_code.points }} pts
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{% if qr_code.achievement_name %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
||||
<i class="fas fa-award mr-1"></i>
|
||||
{{ qr_code.achievement_name }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="text-gray-400">None</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
{% if qr_code.used %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
|
||||
Redeemed
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
||||
Available
|
||||
</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||
<a href="{{ base_url }}/redeem/{{ qr_code.code }}" target="_blank" class="text-irish-green hover:underline">
|
||||
<i class="fas fa-external-link-alt mr-1"></i> View
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="bg-gray-50 border border-gray-200 rounded-md p-6 text-center">
|
||||
<i class="fas fa-qrcode text-gray-400 text-3xl mb-3"></i>
|
||||
<p class="text-gray-600">No QR codes in this set yet. Add your first QR code using the form.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// QR Code template function
|
||||
function useQRTemplate(title, points, achievement, isAchievementOnly, description) {
|
||||
document.getElementById('title').value = title;
|
||||
document.getElementById('points').value = points;
|
||||
document.getElementById('achievement_name').value = achievement;
|
||||
document.getElementById('is_achievement_only').checked = isAchievementOnly;
|
||||
document.getElementById('description').value = description;
|
||||
|
||||
// Scroll to the form
|
||||
document.getElementById('qrCodeForm').scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
|
||||
// Delete Set confirmation
|
||||
document.getElementById('deleteSetBtn').addEventListener('click', function() {
|
||||
if (confirm('Are you sure you want to delete this entire set? This action cannot be undone.')) {
|
||||
// Send delete request - this would need an endpoint implementation
|
||||
alert('Delete functionality will be implemented in a future update');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -1,42 +1,104 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="max-w-lg mx-auto">
|
||||
<div class="bg-white rounded-lg shadow-md p-6 mb-8 text-center">
|
||||
<!-- Success Card -->
|
||||
<div class="bg-white rounded-lg shadow-md p-8 mb-6 text-center">
|
||||
<div class="mb-6">
|
||||
<div class="inline-block p-4 rounded-full bg-green-100">
|
||||
<i class="fas fa-check-circle text-irish-green text-5xl"></i>
|
||||
<div class="inline-flex items-center justify-center w-20 h-20 rounded-full bg-green-100 mb-6">
|
||||
<i class="fas fa-check text-green-600 text-5xl"></i>
|
||||
</div>
|
||||
<h1 class="text-2xl font-bold text-irish-green">Success!</h1>
|
||||
|
||||
{% if achievement %}
|
||||
<p class="text-gray-600 mt-2">Your team has earned an achievement and points!</p>
|
||||
{% else %}
|
||||
<p class="text-gray-600 mt-2">Your team has earned points!</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Success!</h1>
|
||||
<p class="text-xl mb-2">You've earned <span class="font-bold">{{ points }}</span> points</p>
|
||||
<p class="text-gray-600 mb-6">Points have been added to <span class="font-semibold">{{ team.name }}</span></p>
|
||||
|
||||
<div class="p-4 bg-irish-green bg-opacity-10 rounded-lg border border-irish-green text-left mb-6">
|
||||
<h3 class="font-bold text-irish-green mb-2">What's next?</h3>
|
||||
<ul class="list-disc ml-5 text-gray-700">
|
||||
<li>Check your team's position on the <a href="/leaderboard" class="text-irish-green hover:underline">leaderboard</a></li>
|
||||
<li>Scan another QR code to earn more points</li>
|
||||
<li>Invite friends to your team</li>
|
||||
</ul>
|
||||
<div class="space-y-4">
|
||||
<div class="p-4 bg-irish-green bg-opacity-10 rounded-lg border border-irish-green">
|
||||
<p class="font-bold text-irish-green mb-1">Points Earned:</p>
|
||||
<p class="text-3xl">{{ points }}</p>
|
||||
</div>
|
||||
|
||||
{% if achievement %}
|
||||
<div class="p-4 bg-blue-50 rounded-lg border border-blue-200">
|
||||
<p class="font-bold text-blue-800 mb-1">Achievement Unlocked:</p>
|
||||
<div class="flex items-center justify-center">
|
||||
<i class="fas fa-award text-amber-500 text-xl mr-2"></i>
|
||||
<p class="text-2xl text-blue-800">{{ achievement }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="p-4 bg-gray-50 rounded-lg">
|
||||
<p class="font-bold mb-1">Team:</p>
|
||||
<p>{{ team.name }}</p>
|
||||
</div>
|
||||
|
||||
{% if event %}
|
||||
<div class="p-4 bg-purple-50 rounded-lg border border-purple-100">
|
||||
<p class="font-bold text-purple-800 mb-1">Event:</p>
|
||||
<p>{{ event.name }}</p>
|
||||
<p class="text-sm text-gray-500">{{ event.event_date.strftime('%Y-%m-%d') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row justify-center space-y-3 sm:space-y-0 sm:space-x-4">
|
||||
<a href="/dashboard" class="bg-irish-green hover:bg-opacity-90 text-white font-medium py-2 px-4 rounded-md transition">
|
||||
Go to Dashboard
|
||||
</div>
|
||||
|
||||
<!-- Next Steps -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6">
|
||||
<h3 class="text-xl font-semibold text-irish-green mb-4">What's Next?</h3>
|
||||
<div class="space-y-4">
|
||||
<a href="/teams/{{ team.id }}" class="flex items-start hover:bg-gray-50 p-3 rounded-md cursor-pointer">
|
||||
<div class="bg-cream-white p-2 rounded-full mr-3">
|
||||
<i class="fas fa-users text-irish-green"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-medium">View Team Profile</p>
|
||||
<p class="text-gray-600 text-sm">Check your team's achievements and points.</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="/dashboard/scan" class="bg-cream-white border border-irish-green text-irish-green font-medium py-2 px-4 rounded-md hover:bg-irish-green hover:text-white transition">
|
||||
Scan Another Code
|
||||
|
||||
<a href="/leaderboard" class="flex items-start hover:bg-gray-50 p-3 rounded-md cursor-pointer">
|
||||
<div class="bg-cream-white p-2 rounded-full mr-3">
|
||||
<i class="fas fa-trophy text-irish-green"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-medium">View Leaderboard</p>
|
||||
<p class="text-gray-600 text-sm">See how your team ranks compared to others.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/scan" class="flex items-start hover:bg-gray-50 p-3 rounded-md cursor-pointer">
|
||||
<div class="bg-cream-white p-2 rounded-full mr-3">
|
||||
<i class="fas fa-qrcode text-irish-green"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-medium">Scan Another QR Code</p>
|
||||
<p class="text-gray-600 text-sm">Got more codes to redeem? Scan them now.</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center text-gray-600">
|
||||
<p>Share your achievement!</p>
|
||||
<div class="flex justify-center space-x-4 mt-2">
|
||||
<a href="#" class="text-blue-600 hover:text-opacity-80"><i class="fab fa-facebook fa-lg"></i></a>
|
||||
<a href="#" class="text-blue-400 hover:text-opacity-80"><i class="fab fa-twitter fa-lg"></i></a>
|
||||
<a href="#" class="text-green-600 hover:text-opacity-80"><i class="fab fa-whatsapp fa-lg"></i></a>
|
||||
<!-- Share -->
|
||||
<div class="mt-6 text-center">
|
||||
<p class="text-gray-500 mb-3">Share your achievement</p>
|
||||
<div class="flex justify-center space-x-4">
|
||||
<a href="https://twitter.com/intent/tweet?text=I just earned {{ points }} points{% if achievement %} and the '{{ achievement }}' achievement{% endif %} at {{ base_url }}!"
|
||||
target="_blank" class="text-blue-400 hover:text-blue-500">
|
||||
<i class="fab fa-twitter text-2xl"></i>
|
||||
</a>
|
||||
<a href="https://www.facebook.com/sharer/sharer.php?u={{ base_url }}"
|
||||
target="_blank" class="text-blue-600 hover:text-blue-700">
|
||||
<i class="fab fa-facebook text-2xl"></i>
|
||||
</a>
|
||||
<a href="https://api.whatsapp.com/send?text=I just earned {{ points }} points{% if achievement %} and the '{{ achievement }}' achievement{% endif %} at {{ base_url }}!"
|
||||
target="_blank" class="text-green-500 hover:text-green-600">
|
||||
<i class="fab fa-whatsapp text-2xl"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+24
-12
@@ -1,27 +1,39 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Terms of Service</h1>
|
||||
<h1 class="text-2xl font-bold text-irish-green mb-4">Nutzungsbedingungen</h1>
|
||||
<p class="mb-4">
|
||||
Welcome to LeagueLedger! By using our platform, you agree to comply with the following terms and conditions.
|
||||
Willkommen bei LeagueLedger! Mit der Nutzung unserer Plattform erklären Sie sich mit den folgenden Bedingungen einverstanden.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Acceptable Use</h2>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Nutzungsregeln</h2>
|
||||
<ul class="list-disc ml-6 mb-4">
|
||||
<li>No cheating or unfair practices</li>
|
||||
<li>Respectful communication with other users</li>
|
||||
<li>Compliance with all applicable laws and regulations</li>
|
||||
<li>Kein Betrug oder unfaire Praktiken</li>
|
||||
<li>Respektvolle Kommunikation mit anderen Nutzern</li>
|
||||
<li>Einhaltung aller anwendbaren Gesetze und Vorschriften</li>
|
||||
</ul>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Liability Disclaimer</h2>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Haftungsausschluss</h2>
|
||||
<p class="mb-4">
|
||||
LeagueLedger is provided "as is" without any warranties. We are not liable for any damages arising from your use of the platform.
|
||||
LeagueLedger wird "wie besehen" ohne jegliche Garantie bereitgestellt. Wir haften nicht für Schäden, die aus Ihrer Nutzung der Plattform entstehen.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Governing Law</h2>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Geltendes Recht</h2>
|
||||
<p class="mb-4">
|
||||
These terms shall be governed by and construed in accordance with the laws of Germany.
|
||||
Diese Bedingungen unterliegen dem deutschen Recht und werden in Übereinstimmung mit diesem ausgelegt.
|
||||
</p>
|
||||
<p class="mb-4">
|
||||
This project is part of the KaufDeinQuiz platform and is operated as an Open-Source initiative. All rights reserved.
|
||||
Dieses Projekt ist Teil der KaufDeinQuiz-Plattform und wird als Open-Source-Initiative betrieben. Lizenziert unter der Apache License 2.0.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Widerrufsbelehrung</h2>
|
||||
<p class="mb-4">
|
||||
Sie haben das Recht, binnen vierzehn Tagen ohne Angabe von Gründen diesen Vertrag zu widerrufen. Die Widerrufsfrist beträgt vierzehn Tage ab dem Tag des Vertragsabschlusses.
|
||||
</p>
|
||||
<h2 class="text-xl font-semibold text-irish-green mt-6 mb-2">Änderungen der Nutzungsbedingungen</h2>
|
||||
<p class="mb-4">
|
||||
Wir behalten uns das Recht vor, diese Nutzungsbedingungen jederzeit zu ändern. Die aktuelle Version ist stets auf dieser Seite verfügbar.
|
||||
</p>
|
||||
<p>Christian Louis IT Beratung und Medienproduktion ist verantwortlich für den Betrieb dieser Plattform.</p>
|
||||
|
||||
<p class="mt-8 text-sm text-gray-600">
|
||||
Letzte Aktualisierung: April 2025
|
||||
</p>
|
||||
<p>Christian Louis IT Beratung und Medienproduktion is responsible for the operation of this platform.</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user