Ready For 1.1
This commit is contained in:
parent
c23f2f88e8
commit
7a221acb8e
11 changed files with 297 additions and 146 deletions
|
@ -8,6 +8,7 @@
|
|||
<meta name="theme-color" content="#212529">
|
||||
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
||||
<title>{{ _('Game Key Manager') }}</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<!-- Preload Bootstrap CSS for better LCP -->
|
||||
<link rel="preload" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"></noscript>
|
||||
|
@ -49,26 +50,34 @@
|
|||
<input class="form-control me-2" type="search" name="q" id="searchInput" placeholder="{{ _('Search') }}" value="{{ search_query }}">
|
||||
<button class="btn btn-outline-success" type="submit" aria-label="{{ _('Search') }}">🔍</button>
|
||||
</form>
|
||||
<ul class="navbar-nav ms-lg-3 mb-2 mb-lg-0">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="langDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<div class="dropdown ms-3">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{% if session.get('lang', 'en') == 'de' %} Deutsch {% elif session.get('lang', 'en') == 'en' %} English {% else %} Sprache {% endif %}
|
||||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="langDropdown">
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item {% if session.get('lang', 'en') == 'de' %}active{% endif %}" href="{{ url_for('set_lang', lang='de') }}">Deutsch</a></li>
|
||||
<li><a class="dropdown-item {% if session.get('lang', 'en') == 'en' %}active{% endif %}" href="{{ url_for('set_lang', lang='en') }}">English</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{% if current_user.is_authenticated %}
|
||||
{% if current_user.is_admin %}
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin_users') }}">⚙️ {{ _('Admin') }}</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin_audit_logs') }}">📜 {{ _('Audit Logs') }}</a></li>
|
||||
{% endif %}
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('change_password') }}">🔒 {{ _('Password') }}</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('logout') }}">🚪 {{ _('Logout') }}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class="dropdown ms-3">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{ _('Import/Export') }}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="{{ url_for('export_games') }}">⬇️ {{ _('Export CSV') }}</a></li>
|
||||
<li><a class="dropdown-item" href="{{ url_for('export_pdf') }}">⬇️ Export PDF (for sharing)</a></li>
|
||||
<li><a class="dropdown-item" href="{{ url_for('import_games') }}">⬆️ {{ _('Import CSV') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% if current_user.is_admin %}
|
||||
<a class="btn btn-outline-secondary ms-3" href="{{ url_for('admin_users') }}">⚙️ {{ _('Admin') }}</a>
|
||||
<a class="btn btn-outline-secondary ms-1" href="{{ url_for('admin_audit_logs') }}">📜 {{ _('Audit Logs') }}</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-outline-secondary ms-3" href="{{ url_for('change_password') }}">🔒 {{ _('Password') }}</a>
|
||||
<a class="btn btn-outline-danger ms-1" href="{{ url_for('logout') }}">🚪 {{ _('Logout') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container mt-4">
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>{{ _('My Games') }}</h1>
|
||||
<div>
|
||||
<a href="{{ url_for('export_games') }}" class="btn btn-outline-secondary">⬇️ {{ _('Export CSV') }}</a>
|
||||
<a href="{{ url_for('export_pdf') }}" class="btn btn-outline-secondary">⬇️ Export PDF (for sharing)</a>
|
||||
<a href="{{ url_for('import_games') }}" class="btn btn-outline-secondary">⬆️ {{ _('Import CSV') }}</a>
|
||||
<a href="{{ url_for('add_game') }}" class="btn btn-primary">+ {{ _('Add New Game') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="toggle-keys" class="btn btn-sm btn-outline-secondary mb-2">{{ _('Show/Hide Keys') }}</button>
|
||||
{% if games %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
|
@ -17,7 +8,7 @@
|
|||
<tr>
|
||||
<th>{{ _('Cover') }}</th>
|
||||
<th>{{ _('Name') }}</th>
|
||||
<th>{{ _('Key') }}</th>
|
||||
<th class="key-col d-md-table-cell">{{ _('Key') }}</th>
|
||||
<th>{{ _('Status') }}</th>
|
||||
<th>{{ _('Created') }}</th>
|
||||
<th>{{ _('Redeem by') }}</th>
|
||||
|
@ -33,15 +24,15 @@
|
|||
<a href="{{ url_for('game_details', game_id=game.id) }}" title="{{ _('Details') }}">
|
||||
{% if game.steam_appid %}
|
||||
<img src="https://cdn.cloudflare.steamstatic.com/steam/apps/{{ game.steam_appid }}/header.jpg"
|
||||
alt="Steam Header"
|
||||
alt="Steam Header"
|
||||
class="game-cover"
|
||||
{% if loop.first %}fetchpriority="high"{% endif %}
|
||||
width="368"
|
||||
width="368"
|
||||
height="172"
|
||||
loading="lazy">
|
||||
{% elif game.url and 'gog.com' in game.url %}
|
||||
<img src="{{ url_for('static', filename='gog_logo.webp') }}"
|
||||
alt="GOG Logo"
|
||||
alt="GOG Logo"
|
||||
class="game-cover"
|
||||
width="368"
|
||||
height="172"
|
||||
|
@ -50,7 +41,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>{{ game.name }}</td>
|
||||
<td class="font-monospace">{{ game.steam_key }}</td>
|
||||
<td class="font-monospace key-col d-none d-md-table-cell">{{ game.steam_key }}</td>
|
||||
<td>
|
||||
{% if game.status == 'nicht eingelöst' %}
|
||||
<span class="badge bg-warning text-dark">{{ _('Not redeemed') }}</span>
|
||||
|
@ -100,8 +91,8 @@
|
|||
</td>
|
||||
<td class="text-nowrap">
|
||||
{% if game.status == 'geschenkt' %}
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-success generate-redeem"
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-success generate-redeem"
|
||||
data-game-id="{{ game.id }}"
|
||||
title="{{ _('Generate redeem link') }}">
|
||||
🔗
|
||||
|
@ -122,7 +113,7 @@
|
|||
document.querySelectorAll('.generate-redeem').forEach(btn => {
|
||||
btn.addEventListener('click', async function() {
|
||||
const gameId = this.dataset.gameId;
|
||||
const flashContainer = document.querySelector('.flash-container');
|
||||
const flashContainer = document.querySelector('.flash-container')
|
||||
|
||||
try {
|
||||
const response = await fetch(`/generate_redeem/${gameId}`, {
|
||||
|
@ -134,22 +125,36 @@ document.querySelectorAll('.generate-redeem').forEach(btn => {
|
|||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || '{{ _("Unknown error") }}');
|
||||
}
|
||||
|
||||
if (data.url) {
|
||||
await navigator.clipboard.writeText(data.url);
|
||||
|
||||
// Erfolgsmeldung mit übersetztem Text
|
||||
flashContainer.innerHTML = `
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
{{ _("Link copied") }}: <a href="${data.url}" target="_blank">${data.url}</a>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
`;
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(data.url)
|
||||
.then(() => {
|
||||
// Succcess ?? maybe
|
||||
flashContainer.innerHTML = `
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
{{ _("Link copied") }}: <a href="${data.url}" target="_blank">${data.url}</a>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
`;
|
||||
})
|
||||
.catch(err => {
|
||||
flashContainer.innerHTML = `
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
{{ _("Clipboard error") }}: ${err.message}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
} else {
|
||||
alert("Clipboard API is not supported in your browser or context.");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
// Fehlermeldung mit übersetztem Text
|
||||
flashContainer.innerHTML = `
|
||||
|
@ -162,7 +167,26 @@ document.querySelectorAll('.generate-redeem').forEach(btn => {
|
|||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log("DOM ist geladen!"); // Überprüfe, ob DOMContentLoaded überhaupt ausgeführt wird
|
||||
const toggleKeysButton = document.getElementById('toggle-keys');
|
||||
if (toggleKeysButton) {
|
||||
console.log("Button with ID 'toggle-keys' found!");
|
||||
toggleKeysButton.addEventListener('click', function() {
|
||||
console.log("Button clicked!");
|
||||
const keyCols = document.querySelectorAll('.key-col');
|
||||
keyCols.forEach(function(el) {
|
||||
el.classList.toggle('hidden');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log("Button with ID 'toggle-keys' not found!");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% else %}
|
||||
<div class="alert alert-info">{{ _('No games yet') }}</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -16,11 +16,17 @@
|
|||
<h4>{{ _('Your Key:') }}</h4>
|
||||
<code class="fs-3">{{ game.steam_key }}</code>
|
||||
</div>
|
||||
{% if platform_link %}
|
||||
<a href="{{ platform_link }}{{ game.steam_key }}"
|
||||
class="btn btn-primary btn-lg mb-3"
|
||||
target="_blank">
|
||||
{{ _('Redeem now on') }} {{ platform_label }}
|
||||
class="btn btn-primary btn-lg mb-3"
|
||||
target="_blank">
|
||||
{{ _('Redeem now on') }} {{ platform_name }}
|
||||
</a>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
{{ _('Your key:') }} <code class="fs-3">{{ game.steam_key }}</code>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="mt-4 text-muted">
|
||||
<small>
|
||||
{{ _('This page will expire in') }}
|
||||
|
@ -28,9 +34,9 @@
|
|||
</small>
|
||||
<div class="progress mt-2" style="height: 8px;">
|
||||
<div id="expiry-bar"
|
||||
class="progress-bar bg-danger"
|
||||
role="progressbar"
|
||||
style="width: 100%">
|
||||
class="progress-bar bg-danger"
|
||||
role="progressbar"
|
||||
style="width: 100%">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue