initial commit
This commit is contained in:
343
frontend/pages/student_main_page.py
Normal file
343
frontend/pages/student_main_page.py
Normal file
@@ -0,0 +1,343 @@
|
||||
import flet as ft
|
||||
import requests
|
||||
import threading
|
||||
import asyncio
|
||||
import websockets
|
||||
from websockets import connect # Ensure this is imported
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
|
||||
def get_initials(user_name: str):
|
||||
if user_name:
|
||||
return user_name[0].capitalize()
|
||||
else:
|
||||
return "E" # or any default value you prefer
|
||||
|
||||
|
||||
def get_avatar_color(user_name: str):
|
||||
colors_lookup = [
|
||||
ft.colors.AMBER,
|
||||
ft.colors.BLUE,
|
||||
ft.colors.BROWN,
|
||||
ft.colors.CYAN,
|
||||
ft.colors.GREEN,
|
||||
ft.colors.INDIGO,
|
||||
ft.colors.LIME,
|
||||
ft.colors.ORANGE,
|
||||
ft.colors.PINK,
|
||||
ft.colors.PURPLE,
|
||||
ft.colors.RED,
|
||||
ft.colors.TEAL,
|
||||
]
|
||||
return colors_lookup[hash(user_name) % len(colors_lookup)]
|
||||
|
||||
|
||||
def student_main_page(page: ft.Page):
|
||||
page.clean()
|
||||
page.title = "Room Information"
|
||||
page.theme_mode = ft.ThemeMode.LIGHT
|
||||
|
||||
page.vertical_alignment = ft.MainAxisAlignment.START # Align all content to the top
|
||||
page.scroll = "adaptive"
|
||||
page.padding = 20
|
||||
|
||||
# Container for lessons
|
||||
lessons_container = ft.Column(
|
||||
alignment=ft.MainAxisAlignment.CENTER, spacing=20)
|
||||
|
||||
def test(e):
|
||||
print(e)
|
||||
page.go("/test")
|
||||
print("test")
|
||||
|
||||
def ausloggen(e=None):
|
||||
page.go("/login")
|
||||
print(page.session.get("access_token"))
|
||||
|
||||
def page_dialog_click(e, lesson_id):
|
||||
dialog_leave = ft.AlertDialog(
|
||||
modal=True,
|
||||
title=ft.Text("Bitte bestätige"),
|
||||
content=ft.Text("Möchtest du diesem Raum wirklich verlassen?"),
|
||||
actions=[
|
||||
ft.TextButton("Ja", on_click=lambda e: (page.close(
|
||||
dialog_leave), leave_current_room(e, lesson_id))),
|
||||
ft.TextButton(
|
||||
"Nein", on_click=lambda e: page.close(dialog_leave)),
|
||||
],
|
||||
actions_alignment=ft.MainAxisAlignment.END,
|
||||
)
|
||||
page.dialog = dialog_leave
|
||||
dialog_leave.open = True
|
||||
page.update()
|
||||
|
||||
def leave_current_room(e=None, unique_id=None):
|
||||
if not unique_id:
|
||||
page.snack_bar = ft.SnackBar(
|
||||
ft.Text("Kein Raum zum verlassen ausgewählt"))
|
||||
page.snack_bar.open = True
|
||||
page.update()
|
||||
return
|
||||
|
||||
url = f"http://awesom-o.org:8000/student/leave_room/?unique_id={
|
||||
unique_id}"
|
||||
headers = {"accept": "application/json",
|
||||
"Content-Type": "application/json"}
|
||||
data = {"session_id": page.session.get("access_token")}
|
||||
try:
|
||||
response = requests.post(url, json=data, headers=headers)
|
||||
response.raise_for_status()
|
||||
if response:
|
||||
get_rooms()
|
||||
page.snack_bar = ft.SnackBar(
|
||||
ft.Text("Raum erfolgreich verlassen"))
|
||||
page.snack_bar.open = True
|
||||
page.update()
|
||||
get_rooms()
|
||||
except requests.RequestException as error:
|
||||
# Handle all bad responses
|
||||
error_detail = "Something went wrong."
|
||||
if hasattr(error, "response") and error.response:
|
||||
try:
|
||||
error_detail = error.response.json().get("detail", "Something went wrong.")
|
||||
except json.JSONDecodeError:
|
||||
error_detail = error.response.text or "Etwas ist schiefgelaufen"
|
||||
page.snack_bar = ft.SnackBar(ft.Text(f"Error: {error_detail}"))
|
||||
page.snack_bar.open = True
|
||||
page.update()
|
||||
|
||||
async def get_rooms():
|
||||
uri = "ws://localhost:8000/ws/student/my_room"
|
||||
headers = {"session-id": page.session.get("access_token")}
|
||||
|
||||
try:
|
||||
async with websockets.connect(uri, extra_headers=headers) as websocket:
|
||||
while True:
|
||||
message = await websocket.recv()
|
||||
data = json.loads(message)
|
||||
# Clear previous lessons
|
||||
lessons_container.controls.clear()
|
||||
|
||||
if "error" in data:
|
||||
# Show "No Rooms for Today" message
|
||||
lessons_container.controls.append(
|
||||
ft.Container(
|
||||
content=ft.Text(
|
||||
"Für heute wurden noch keine Räume ausgewählt.",
|
||||
size=25,
|
||||
text_align="center",
|
||||
),
|
||||
border=ft.Border(
|
||||
top=ft.BorderSide(1, ft.colors.BLACK),
|
||||
bottom=ft.BorderSide(1, ft.colors.BLACK),
|
||||
left=ft.BorderSide(1, ft.colors.BLACK),
|
||||
right=ft.BorderSide(1, ft.colors.BLACK)
|
||||
),
|
||||
border_radius=20,
|
||||
padding=10,
|
||||
height=150,
|
||||
bgcolor=ft.colors.WHITE,
|
||||
alignment=ft.alignment.center,
|
||||
)
|
||||
)
|
||||
else:
|
||||
rooms = data.get("rooms", [])
|
||||
# Filter and sort lessons for today
|
||||
today = datetime.now().date()
|
||||
today_lessons = [
|
||||
room for room in rooms if room["lesson_date"] == str(today)]
|
||||
today_lessons.sort(key=lambda x: x["lesson_time"])
|
||||
|
||||
# Check if there are rooms on other dates
|
||||
other_date_rooms = [
|
||||
room for room in rooms if room["lesson_date"] != str(today)]
|
||||
if today_lessons:
|
||||
for lesson in today_lessons:
|
||||
if lesson['current_students'] == lesson['max_students']:
|
||||
BACKROUND_COLOR = "#f10d0c"
|
||||
TEXT_COLOR = ft.colors.WHITE
|
||||
else:
|
||||
BACKROUND_COLOR = "#729fcf"
|
||||
TEXT_COLOR = ft.colors.BLACK
|
||||
# Create lesson card
|
||||
room_card = ft.Card(
|
||||
content=ft.Container(
|
||||
content=ft.Row(
|
||||
[
|
||||
# Room details
|
||||
ft.Column(
|
||||
[
|
||||
# Top line:
|
||||
# room_number, info, location
|
||||
ft.Text(
|
||||
f"Heute, {
|
||||
lesson['lesson_time']} Uhr",
|
||||
size=16,
|
||||
color=TEXT_COLOR
|
||||
),
|
||||
|
||||
# Second line: first_name and last_name
|
||||
ft.Text(
|
||||
f"Lehrkraft: {lesson['first_name']} {
|
||||
lesson['last_name']} - {lesson['subjects']}",
|
||||
size=16,
|
||||
color=TEXT_COLOR
|
||||
),
|
||||
# Third line: lesson_time
|
||||
ft.Text(
|
||||
f"Raum {lesson['room_number']} {
|
||||
lesson['info']} | {lesson['location']}",
|
||||
size=16,
|
||||
color=TEXT_COLOR
|
||||
),
|
||||
|
||||
ft.Text(
|
||||
f"Belegte Plätze: {
|
||||
lesson['current_students']}/{lesson['max_students']}",
|
||||
size=16,
|
||||
color=TEXT_COLOR
|
||||
),
|
||||
],
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
),
|
||||
# IconButton on the right
|
||||
ft.Column(
|
||||
[
|
||||
ft.TextButton("Aus Raum abmelden", on_click=lambda e, lesson_id=lesson['unique_id']: page_dialog_click(e, lesson_id),
|
||||
style=ft.ButtonStyle(
|
||||
bgcolor=ft.colors.WHITE,
|
||||
color=ft.colors.BLACK,
|
||||
shape=ft.RoundedRectangleBorder(
|
||||
radius=5),
|
||||
padding=20,
|
||||
)
|
||||
),
|
||||
ft.Text("ACHTUNG: Hierdurch wird", size=12), ft.Text(
|
||||
"dein reservierter Platz für", size=12), ft.Text("jemand anderes freigegeben.", size=12),
|
||||
]
|
||||
)
|
||||
],
|
||||
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
|
||||
),
|
||||
padding=20, # Add padding inside the card
|
||||
),
|
||||
color=BACKROUND_COLOR,
|
||||
margin=10,
|
||||
)
|
||||
lessons_container.controls.append(room_card)
|
||||
else:
|
||||
# Show "No Rooms for Today" message
|
||||
lessons_container.controls.append(
|
||||
ft.Container(
|
||||
content=ft.Text(
|
||||
"Für heute wurden noch keine Räume ausgewählt.",
|
||||
size=25,
|
||||
text_align="center",
|
||||
),
|
||||
border=ft.Border(
|
||||
top=ft.BorderSide(1, ft.colors.BLACK),
|
||||
bottom=ft.BorderSide(
|
||||
1, ft.colors.BLACK),
|
||||
left=ft.BorderSide(1, ft.colors.BLACK),
|
||||
right=ft.BorderSide(1, ft.colors.BLACK)
|
||||
),
|
||||
border_radius=20,
|
||||
padding=10,
|
||||
height=150,
|
||||
bgcolor=ft.colors.WHITE,
|
||||
alignment=ft.alignment.center,
|
||||
)
|
||||
)
|
||||
|
||||
# Update page
|
||||
page.update()
|
||||
except Exception as e:
|
||||
lessons_container.controls.clear()
|
||||
lessons_container.controls.append(
|
||||
ft.Text(f"Error: {e}", size=50, weight="bold", text_align="center"))
|
||||
page.update()
|
||||
|
||||
def start_get_rooms():
|
||||
# Ensure a new event loop in the thread
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(get_rooms())
|
||||
|
||||
# Start the WebSocket client in a thread
|
||||
import threading
|
||||
threading.Thread(target=start_get_rooms, daemon=True).start()
|
||||
|
||||
join_more_rooms_button = ft.Container(
|
||||
content=ft.Text("Räume suchen", size=24, color=ft.colors.BLUE_900),
|
||||
on_click=lambda e: page.go("/join"),
|
||||
alignment=ft.alignment.center,
|
||||
width=200,
|
||||
height=60,
|
||||
bgcolor='transparent',
|
||||
ink=True,
|
||||
)
|
||||
|
||||
navigation_bar = ft.Row(
|
||||
[ft.Text("Home", size=23, weight=ft.FontWeight.BOLD,
|
||||
width=100), join_more_rooms_button],
|
||||
)
|
||||
|
||||
# Add components to page
|
||||
page.add(
|
||||
ft.Column(
|
||||
[
|
||||
ft.Row(
|
||||
[
|
||||
ft.Text(
|
||||
"Daltonraum-Buchungssystem der IGS Garbsen", size=30),
|
||||
ft.Column([
|
||||
ft.PopupMenuButton(
|
||||
items=[
|
||||
ft.PopupMenuItem(content=ft.Text(f"Eingeloggt als: {page.session.get("username")}", weight=ft.FontWeight.BOLD)),
|
||||
ft.PopupMenuItem(text="Profil anzeigen", on_click=test),
|
||||
ft.PopupMenuItem(text="Ausloggen", on_click=ausloggen),
|
||||
],
|
||||
content=ft.CircleAvatar(
|
||||
content=ft.Text(get_initials(
|
||||
page.session.get("username"))),
|
||||
color=ft.colors.WHITE,
|
||||
bgcolor=get_avatar_color(
|
||||
page.session.get("username")),
|
||||
),
|
||||
menu_position=ft.PopupMenuPosition.UNDER,
|
||||
tooltip="",
|
||||
|
||||
)
|
||||
|
||||
],
|
||||
# Align column content to the end (optional)
|
||||
alignment=ft.MainAxisAlignment.END,
|
||||
),
|
||||
],
|
||||
alignment=ft.MainAxisAlignment.SPACE_BETWEEN, # Space out the two elements
|
||||
vertical_alignment=ft.CrossAxisAlignment.CENTER, # Align items vertically
|
||||
),
|
||||
|
||||
navigation_bar,
|
||||
ft.Row( # Wrap the Text in a Row
|
||||
[
|
||||
ft.Text(
|
||||
"Du hast dich heute in folgende Daltonräume eingetragen:", size=25)
|
||||
],
|
||||
alignment=ft.MainAxisAlignment.CENTER # Center the Text horizontally
|
||||
),
|
||||
ft.Column(
|
||||
[
|
||||
lessons_container,
|
||||
],
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
expand=True, # Make it take available space vertically
|
||||
),
|
||||
],
|
||||
expand=True, # This makes the outer column take available space as well
|
||||
alignment=ft.MainAxisAlignment.CENTER, # Center the whole column vertically
|
||||
)
|
||||
)
|
Reference in New Issue
Block a user