umsortierung.

This commit is contained in:
Daniel Nagel 2026-03-31 12:04:08 +00:00
parent a7e3dfffcb
commit 20123348a7
11 changed files with 128 additions and 115 deletions

View File

Binary file not shown.

Binary file not shown.

2
data/data_api.py Normal file
View File

@ -0,0 +1,2 @@
import sqlite3
from data.database import DB_NAME

View File

@ -29,7 +29,6 @@ def initialize_db():
''') ''')
# Optional: Ein paar Test-ats anlegen, falls die Tabelle leer ist # Optional: Ein paar Test-ats anlegen, falls die Tabelle leer ist
# (Damit du direkt was im Dropdown siehst)
cursor.execute("SELECT count(*) FROM ats") cursor.execute("SELECT count(*) FROM ats")
if cursor.fetchone()[0] == 0: if cursor.fetchone()[0] == 0:
ats_liste = [("Tim Grubmüller",), ("Phil Langer",), ("Max Hämmerle",)] ats_liste = [("Tim Grubmüller",), ("Phil Langer",), ("Max Hämmerle",)]

9
gui/gui_admin.py Normal file
View File

@ -0,0 +1,9 @@
from nicegui import ui
from data import database
from gui import gui_style
def setup_route():
@ui.page("/")
def admin_page():
ui.label("kasdlkfs")

22
gui/gui_style.py Normal file
View File

@ -0,0 +1,22 @@
from nicegui import ui
# Funktion die jede GUI Seite am Anfang aufrufen kann. Dann haben alle die gleichen Farbeinstellungen. Und, wenn man was ändert,
# muss man es nur hier ändern!
def apply_design():
ui.add_css('body { background-color: #171721; }')
# 1. Dark Mode aktivieren
ui.dark_mode(True)
ui.colors(
primary='#e30013', # Hauptfarbe (z.B. für Standard-Buttons) Wenn keine Farbe angegeben wird, ist es diese Farbe
secondary='#FF3333', # Zweitfarbe
accent='#2078D4', # Akzentfarbe
positive='#188C42', # Farbe für Erfolg (Grün)
negative='#E31919', # Farbe für Fehler/Abbruch (Rot)
info='#939393', # Info-Farbe
warning='#f59e0b', # Warn-Farbe (Orange)
# Farben für Texte
normaltext="#F7F7F7",
accenttext="#2078D4",
infotext="#A8A8A8"
)

View File

@ -1,39 +1,32 @@
from nicegui import ui from nicegui import ui
from datetime import datetime from datetime import datetime
import database from data import database
from gui import gui_style, gui_admin
def build_ui():
ui.colors(primary='#e30013')
# 1. HAUPT-CONTAINER:
# Spalte die exakt so hoch ist wie der Bildschirm (h-screen). def setup_route():
# 'items-stretch' sorgt dafür, dass die Kinder (Header, Mitte, Footer) die volle Breite nutzen. @ui.page("/")
def main_page():
with ui.column().classes('w-full h-screen no-wrap gap-0 items-stretch'): with ui.column().classes('w-full h-screen no-wrap gap-0 items-stretch'):
# --------------------------------------------------------- # ---------------------------------------------------------
# BEREICH OBEN (Header) - Feste Höhe (h-25) # Header
# --------------------------------------------------------- # ---------------------------------------------------------
with ui.card().classes("h-25 rounded-none").style("background-color: #e30013"): with ui.card().classes("h-25 rounded-none").style("background-color: #e30013"):
# Hinweis: rounded-none entfernt die abgerundeten Ecken, damit es nahtlos aussieht # Hinweis: rounded-none entfernt die abgerundeten Ecken, damit es nahtlos aussieht
ui.image('gui/logo.png').classes('absolute top-4 right-4 w-55') ui.image('gui/logo.png').classes('absolute top-4 right-4 w-55')
# --------------------------------------------------------- # ---------------------------------------------------------
# BEREICH MITTE (Inhalt) - Variable Höhe (flex-1) # MITTE
# --------------------------------------------------------- # ---------------------------------------------------------
# 'flex-1' ist hier entscheidend. Es sagt: "Nimm allen Platz zwischen Header und Footer".
# 'overflow-hidden' verhindert, dass das ganze Fenster scrollt -> wir wollen nur die Tabelle scrollen.
with ui.row().classes("w-full flex-1 p-4 gap-4 no-wrap overflow-hidden"): with ui.row().classes("w-full flex-1 p-4 gap-4 no-wrap overflow-hidden"):
with ui.column(): with ui.column():
# --- Linke Karte: Eingabemaske --- # --- Linke Karte: Eingabemaske ---
# 'overflow-y-auto': Falls das Formular zu lang für kleine Bildschirme wird, bekommt nur diese Karte einen Scrollbalken.
with ui.card().classes('overflow-y-auto'): with ui.card().classes('overflow-y-auto'):
traeger = database.get_ats_names() traeger = database.get_ats_names()
input_name = ui.select(label="ATS Träger Name", options=traeger, with_input=True).classes('w-full') input_name = ui.select(label="ATS Träger Name", options=traeger, with_input=True).classes('w-full')
input_location = ui.input(label='Einsatzort', placeholder='Adresse, oder Beschreibung').classes("w-full") input_location = ui.input(label='Einsatzort', placeholder='Adresse, oder Beschreibung').classes("w-full")
with ui.row().classes('gap-10'): with ui.row().classes('gap-10'):
today = datetime.now().strftime("%Y-%m-%d") today = datetime.now().strftime("%Y-%m-%d")
with ui.input('Datum', value=today).classes('flex-1') as date_input: with ui.input('Datum', value=today).classes('flex-1') as date_input:
@ -44,11 +37,19 @@ def build_ui():
input_date = ui.date().bind_value(date_input) input_date = ui.date().bind_value(date_input)
input_time = ui.number(label="Dauer (Min)", value=0).classes('flex-1') input_time = ui.number(label="Dauer (Min)", value=0).classes('flex-1')
with ui.row().classes("gap-10 w-full items-center"): with ui.row().classes("gap-10 w-full items-center"):
input_type = ui.toggle(["Einsatz", "Übung"]).classes('flex-1 center') input_type = ui.toggle(["Einsatz", "Übung"]).classes('flex-1 center')
input_device = ui.select(["ATS Gerät 1", "ATS Gerät 2"], label="ATS Gerät auswählen").classes('flex-1') input_device = ui.select(["ATS Gerät 1", "ATS Gerät 2"], label="ATS Gerät auswählen").classes('flex-1')
def ClearForm():
input_name.value = ""
input_location.value = ""
input_date.value = today
input_time.value = 0
input_type.value = "Einsatz" # Achtung: Value sollte zum Toggle passen (String, nicht 0)
input_device.value = None # Select resetten
ui.notify("Gelöscht.")
def InputDataToTable(): def InputDataToTable():
name = input_name.value name = input_name.value
location = input_location.value location = input_location.value
@ -58,20 +59,12 @@ def build_ui():
device = input_device.value device = input_device.value
# Hinweis: database Aufruf ist hier korrekt, sofern importiert # Hinweis: database Aufruf ist hier korrekt, sofern importiert
database.add_data_to_einsaetze(name, location, date, time, etype, device) database.add_data_to_einsaetze(name, location, date, time, etype, device)
einsaetze_table.rows = database.get_einsaetze() einsaetze_table.rows = database.get_einsaetze()
einsaetze_table.update() einsaetze_table.update()
ui.notify("Eintrag in Datenbank erstellt.") ui.notify("Eintrag in Datenbank erstellt.")
ClearForm()
def ClearForm():
input_name.value = ""
input_location.value = ""
input_date.value = today
input_time.value = 0
input_type.value = "Einsatz" # Achtung: Value sollte zum Toggle passen (String, nicht 0)
input_device.value = None # Select resetten
ui.notify("Gelöscht.")
ui.notify(admin_login.value)
ui.separator() ui.separator()
ui.space() # Drückt die Buttons nach unten (innerhalb der Formular-Karte) ui.space() # Drückt die Buttons nach unten (innerhalb der Formular-Karte)
@ -80,24 +73,14 @@ def build_ui():
ui.space() ui.space()
ui.button(text="Eintragen", on_click=InputDataToTable) ui.button(text="Eintragen", on_click=InputDataToTable)
admin_container = ui.column().classes("w-full")
with ui.card().classes("w-full"): with ui.card().classes("w-full"):
# 1. Das Passwort-Feld # 1. Das Passwort-Feld
pw_input = ui.input("Passwort", password=True) pw_input = ui.input("Passwort", password=True)
# Das Admin-Panel wird nur angezeigt, wenn der Wert vom Input '1234' ist.
# lambda v: v == '1234' ist die Prüf-Logik (True/False).
with ui.card().bind_visibility_from(pw_input, 'value', backward=lambda v: v == '1234').classes("w-full"): with ui.card().bind_visibility_from(pw_input, 'value', backward=lambda v: v == '1234').classes("w-full"):
ui.label("Admin Panel") ui.button(text="Admin Seite", on_click=lambda:ui.navigate.to("/admin"))
with ui.row().classes('w-full'):
ui.input(label="Neuer ATS Träger").classes('flex-1')
ui.button(text="Hinzufügen")
# --- Rechte Karte: Tabelle --- # --- Rechte Karte: Tabelle ---
# 'flex-1': Diese Karte nimmt die restliche Breite der Reihe ein.
# 'h-full': Diese Karte nutzt die volle Höhe des mittleren Bereichs.
with ui.card().classes('flex-1 h-full p-0'): with ui.card().classes('flex-1 h-full p-0'):
collums = [ collums = [
{'name': 'date', 'label': 'Datum', 'field': 'date', 'sortable': True, 'align': 'left'}, {'name': 'date', 'label': 'Datum', 'field': 'date', 'sortable': True, 'align': 'left'},
@ -115,10 +98,8 @@ def build_ui():
).classes("w-full h-full") ).classes("w-full h-full")
# --------------------------------------------------------- # ---------------------------------------------------------
# BEREICH UNTEN (Footer) - Automatische Höhe # Footer
# --------------------------------------------------------- # ---------------------------------------------------------
# Hier landet dein Switch. Durch 'flex-1' im mittleren Bereich wird dieser Teil
# immer an den unteren Bildschirmrand geschoben.
with ui.row().classes("p-2 pb-6 items-center"): with ui.row().classes("p-2 pb-6 items-center"):
dark = ui.dark_mode(True) dark = ui.dark_mode(True)

View File

@ -1,10 +1,10 @@
from gui import main_gui from gui import main_gui
from nicegui import ui from nicegui import ui
import database from data import database
database.initialize_db() database.initialize_db()
main_gui.build_ui() main_gui.setup_route()
main_gui.ui.run( main_gui.ui.run(
title="ATS Träger Dokumentation", title="ATS Träger Dokumentation",