Bilder auf Hauptseite. Spielerstatistik kann jetzt gesamte Match historie in eingener Unterseite. #12

Merged
daniel merged 2 commits from master into dev 2026-03-09 13:12:43 +01:00
18 changed files with 49 additions and 26 deletions
Showing only changes of commit 68a32bd03c - Show all commits

View File

@ -1 +1 @@
{"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":1,"display_name":"Daniel N.","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"}
{"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":1,"display_name":"Chaos Servitor","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"}

View File

@ -477,6 +477,26 @@ def get_leaderboard(system_name):
return result
def update_match_mmr_change(match_id, p1_change, p2_change):
"""Speichert die tatsächliche MMR-Änderung für das Log fest im Match ab."""
connection = sqlite3.connect(DB_PATH)
cursor = connection.cursor()
cursor.execute("""
UPDATE matches
SET player1_mmr_change = ?, player2_mmr_change = ?
WHERE id = ?
""", (p1_change, p2_change, match_id))
connection.commit()
connection.close()
# -----------------------------------------------------
# Matches Bestätigen, Löschen, Berechnen, ...
# -----------------------------------------------------
def get_unconfirmed_matches(player_id):
"""Holt alle offenen Matches, die der Spieler noch bestätigen muss."""
connection = sqlite3.connect(DB_PATH)
@ -537,7 +557,6 @@ def set_match_counted(match_id):
connection.close()
def get_submitted_matches(player_id):
"""Holt alle offenen Matches, die der Spieler selbst eingetragen hat, aber vom Gegner noch nicht bestätigt wurden."""
connection = sqlite3.connect(DB_PATH)

View File

@ -2,7 +2,7 @@ import sqlite3
import os
import json
dummy_is_in = False
dummy_is_in = True
# 1. Sucht den exakten, absoluten Pfad zu diesem Skript (z.B. /srv/Diceghost-Liga-System/data/)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
@ -10,6 +10,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DB_PATH = os.path.join(BASE_DIR, "league_database.db")
def init_db():
connection = sqlite3.connect(DB_PATH)
cursor = connection.cursor()

View File

@ -44,7 +44,7 @@ def setup_routes():
table_rows.append({
'rank': current_rank,
'trend': '', # Platzhalter für später
'name': f"{player['display_name']} aka {player['discord_name']}",
'name': f"{player['display_name']} 'aka' {player['discord_name']}",
'mmr': player['mmr']
})

View File

@ -238,25 +238,21 @@ def setup_routes(admin_discord_id):
# ---------------------------
with ui.card().classes("w-full"):
ui.label(text= "Meine letzten Spiele").classes("font-bold text-white text-xl")
# 1. Daten aus der DB holen
raw_matches = data_api.get_recent_matches_for_player(player_id)
# 1. Daten aus der DB holen ABER per [:5] hart auf die neuesten 5 Listen-Einträge abschneiden!
raw_matches = data_api.get_recent_matches_for_player(player_id)[:5]
# 2. Daten für die Tabelle aufbereiten
# 2. Daten für die Tabelle aufbereiten (Bleibt exakt gleich wie bei dir)
table_rows = []
for match in raw_matches:
# Bin ich Spieler 1 oder Spieler 2?
if match['player1_id'] == player_id:
# Ich bin Spieler 1, also ist Spieler 2 der Gegner
opponent_name = f"{match['p2_display']} aka {match['p2_discord']}"
my_score = match['score_player1']
opp_score = match['score_player2']
else:
# Ich bin Spieler 2, also ist Spieler 1 der Gegner
opponent_name = f"{match['p1_display']} aka {match['p1_discord']}"
my_score = match['score_player2']
opp_score = match['score_player1']
# Gewonnen oder Verloren?
if my_score > opp_score:
result_text = "Gewonnen"
elif my_score < opp_score:
@ -264,10 +260,8 @@ def setup_routes(admin_discord_id):
else:
result_text = "Unentschieden"
# Datum hübsch machen (schneidet die Millisekunden weg)
date_clean = str(match['played_at'])[:10]
# Eine fertige Zeile für unsere Tabelle bauen
table_rows.append({
'date': date_clean,
'system': match['gamesystem_name'],
@ -275,7 +269,6 @@ def setup_routes(admin_discord_id):
'result': f"{result_text} ({my_score} : {opp_score})"
})
# 3. Das Layout (Die Spalten) der Tabelle definieren
table_columns = [
{'name': 'date', 'label': 'Gespielt am', 'field': 'date', 'align': 'left'},
{'name': 'system', 'label': 'System', 'field': 'system', 'align': 'left'},
@ -283,15 +276,12 @@ def setup_routes(admin_discord_id):
{'name': 'result', 'label': 'Ergebnis', 'field': 'result', 'align': 'left'}
]
# 4. Die Tabelle zeichnen!
# 4. Die Tabelle zeichnen und den NEUEN BUTTON hinzufügen
if len(table_rows) > 0:
ui.table(columns=table_columns, rows=table_rows, row_key='date').classes('w-full bg-zinc-900 text-white')
# NEU: Der Button, der zur großen Log-Seite führt
ui.button("Komplette Historie & Log anzeigen", icon="history", on_click=lambda: ui.navigate.to('/matchhistory')).classes('w-full mt-4 bg-zinc-700 text-white hover:bg-zinc-600')
else:
ui.label("Noch keine Spiele absolviert.").classes("text-gray-500 italic")

View File

@ -37,7 +37,7 @@ def setup_routes():
for p in raw_players:
if p['player_id'] == my_id:
continue
dropdown_options[p['player_id']] = f"{p['display_name']} aka {p['discord_name']}"
dropdown_options[p['player_id']] = f"{p['display_name']} 'aka' {p['discord_name']}"
# ÄNDERUNG: .classes('w-full') hinzugefügt, damit der Slider sich anpasst
p1_points = ui.slider(min=0, max=100, value=10).props("label-always").classes('w-full')

View File

@ -1,7 +1,6 @@
from nicegui import ui, app
from data import data_api
# Falls du eine gui_style.py für Farben/Header hast, hier importieren!
# from gui import gui_style
from gui import gui_style
def setup_routes():
@ui.page('/matchhistory', dark=True)

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
gui/pictures/KT_Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,10 +1,9 @@
import os
from nicegui import app
from dotenv import load_dotenv
from nicegui import ui
from gui import main_gui, match_gui, discord_login, league_statistic, admin_gui, match_history_gui
from nicegui import app
from data import database
@ -17,6 +16,7 @@ app.add_static_files('/pictures', 'gui/pictures')
client_id = os.getenv("DISCORD_CLIENT_ID")
client_secret = os.getenv("DISCORD_CLIENT_SECRET")
admin_discord_id = os.getenv("ADMIN")
url = os.getenv("APP_URL")
database.check_db()

View File

@ -64,6 +64,20 @@ def calculate_match (match_id):
data_api.apply_match_to_player_statistic (winner_id, sys_id, mmr_change_winner, winner_score)
data_api.apply_match_to_player_statistic (looser_id, sys_id, mmr_change_looser, looser_score)
# Zuordnen: Welcher Change gehört zu P1 und welcher zu P2?
if winner_id == p1_id:
p1_change = mmr_change_winner
p2_change = mmr_change_looser
else:
# Wenn der Sieger nicht P1 ist, muss P1 der Verlierer sein (oder Draw, da ist es egal)
p1_change = mmr_change_looser
p2_change = mmr_change_winner
# Die Änderungen für das Log ins Match eintragen!
data_api.update_match_mmr_change(match_id, p1_change, p2_change)
# Das Match als Berechnet markieren
data_api.set_match_counted(match_id)