2026-02-25 15:26:24 +01:00
|
|
|
import os
|
|
|
|
|
import urllib.parse
|
|
|
|
|
import requests
|
|
|
|
|
from nicegui import ui, app
|
|
|
|
|
|
|
|
|
|
# NEU: Wir importieren unsere eigene Datenbank-Datei
|
|
|
|
|
import database
|
|
|
|
|
|
|
|
|
|
def setup_routes():
|
|
|
|
|
client_id = os.getenv("DISCORD_CLIENT_ID")
|
|
|
|
|
client_secret = os.getenv("DISCORD_CLIENT_SECRET")
|
|
|
|
|
app_url = os.getenv("APP_URL")
|
|
|
|
|
|
|
|
|
|
redirect_uri = f"{app_url}/login/discord"
|
|
|
|
|
encoded_redirect_uri = urllib.parse.quote(redirect_uri, safe="")
|
|
|
|
|
|
|
|
|
|
discord_auth_url = f"https://discord.com/api/oauth2/authorize?client_id={client_id}&redirect_uri={encoded_redirect_uri}&response_type=code&scope=identify"
|
|
|
|
|
|
|
|
|
|
# --- HOME PAGE ---
|
|
|
|
|
@ui.page('/')
|
|
|
|
|
|
|
|
|
|
def home_page():
|
|
|
|
|
ui.dark_mode(True)
|
|
|
|
|
|
2026-02-27 10:26:40 +01:00
|
|
|
# --- Profil Block Oben ---
|
2026-02-26 16:20:05 +01:00
|
|
|
with ui.card().classes('w-full items-center mt-10'):
|
2026-02-25 15:26:24 +01:00
|
|
|
if app.storage.user.get('authenticated', False):
|
2026-02-27 10:26:40 +01:00
|
|
|
with ui.row():
|
|
|
|
|
discord_name = app.storage.user.get('discord_name')
|
|
|
|
|
db_id = app.storage.user.get('db_id')
|
2026-02-25 15:26:24 +01:00
|
|
|
|
2026-02-27 10:26:40 +01:00
|
|
|
ui.label(f'Welcome back, {discord_name}!').classes('text-green-500 font-bold')
|
|
|
|
|
ui.button('Enter Match', on_click=lambda: ui.navigate.to('/add-match')).classes('mt-4 bg-blue-500 text-white')
|
2026-02-25 15:26:24 +01:00
|
|
|
|
2026-02-26 16:20:05 +01:00
|
|
|
|
|
|
|
|
|
2026-02-25 15:26:24 +01:00
|
|
|
def logout():
|
|
|
|
|
app.storage.user.clear()
|
|
|
|
|
ui.navigate.to('/')
|
|
|
|
|
|
|
|
|
|
ui.button('Logout', on_click=logout).classes('mt-4 bg-red-500 text-white')
|
|
|
|
|
else:
|
|
|
|
|
ui.button('Login with Discord', on_click=lambda: ui.navigate.to(discord_auth_url))
|
2026-02-26 16:20:05 +01:00
|
|
|
|
|
|
|
|
if app.storage.user.get('authenticated', False):
|
|
|
|
|
with ui.card().classes("w-full"):
|
|
|
|
|
# 1. Die Row muss wissen, dass sie die volle Breite nutzen darf (w-full)
|
|
|
|
|
# und wir geben ihr einen kleinen Abstand zwischen den Karten (gap-4)
|
|
|
|
|
with ui.row().classes("w-full h-30 gap-4 items-center"):
|
|
|
|
|
|
|
|
|
|
with ui.card().classes("flex-1 h-full items-center"):
|
|
|
|
|
ui.label(text="40k")
|
|
|
|
|
|
|
|
|
|
with ui.card().classes("flex-1 h-full items-center"):
|
|
|
|
|
ui.label(text="AoS")
|
|
|
|
|
|
|
|
|
|
with ui.card().classes("flex-1 h-full items-center"):
|
|
|
|
|
ui.label(text="Spearhead")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-25 15:26:24 +01:00
|
|
|
# --- DISCORD CALLBACK PAGE ---
|
|
|
|
|
@ui.page('/login/discord')
|
|
|
|
|
def discord_callback(code: str = None):
|
|
|
|
|
if not code:
|
|
|
|
|
ui.label('Fehler: Kein Code erhalten.').classes('text-red-500')
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
token_data = {
|
|
|
|
|
'client_id': client_id,
|
|
|
|
|
'client_secret': client_secret,
|
|
|
|
|
'grant_type': 'authorization_code',
|
|
|
|
|
'code': code,
|
|
|
|
|
'redirect_uri': redirect_uri
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
token_response = requests.post('https://discord.com/api/oauth2/token', data=token_data)
|
|
|
|
|
token_json = token_response.json()
|
|
|
|
|
|
|
|
|
|
if 'access_token' in token_json:
|
|
|
|
|
access_token = token_json['access_token']
|
|
|
|
|
|
|
|
|
|
user_headers = {
|
|
|
|
|
'Authorization': f"Bearer {access_token}"
|
|
|
|
|
}
|
|
|
|
|
user_response = requests.get('https://discord.com/api/users/@me', headers=user_headers)
|
|
|
|
|
user_json = user_response.json()
|
|
|
|
|
|
|
|
|
|
# --- NEU: DATENBANK INTEGRATION ---
|
|
|
|
|
discord_id = user_json['id']
|
|
|
|
|
discord_name = user_json['username']
|
|
|
|
|
|
|
|
|
|
# 1. Spieler in der DB suchen oder neu anlegen
|
|
|
|
|
player = database.get_or_create_player(discord_id, discord_name)
|
|
|
|
|
|
|
|
|
|
# 2. Session-Daten aktualisieren
|
|
|
|
|
app.storage.user['authenticated'] = True
|
|
|
|
|
app.storage.user['discord_id'] = discord_id
|
|
|
|
|
app.storage.user['discord_name'] = discord_name
|
|
|
|
|
|
|
|
|
|
# player ist ein Tuple aus der DB, z.B.: (1, "123456", "Daniel", 1000, 0, 0)
|
|
|
|
|
# player[0] ist die interne Datenbank-ID. Diese merken wir uns in der Session!
|
|
|
|
|
app.storage.user['db_id'] = player[0]
|
|
|
|
|
|
|
|
|
|
ui.navigate.to('/')
|
|
|
|
|
else:
|
|
|
|
|
ui.label('Fehler beim Login!').classes('text-red-500')
|
|
|
|
|
ui.label(str(token_json))
|