199 lines
9.3 KiB
Python
199 lines
9.3 KiB
Python
|
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 student_main_page(page: ft.Page):
|
||
|
page.clean()
|
||
|
page.theme_mode = ft.ThemeMode.LIGHT # Set the theme to light
|
||
|
page.title = "Room Information"
|
||
|
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)
|
||
|
|
||
|
# Buttons
|
||
|
test_button = ft.TextButton(
|
||
|
text="Auch Räume an anderen Tagen anzeigen",
|
||
|
on_click=lambda e: page.go("/all_rooms"),
|
||
|
style=ft.ButtonStyle(padding=20),
|
||
|
visible=False, # Initially hidden
|
||
|
)
|
||
|
|
||
|
join_more_rooms_button = ft.TextButton(
|
||
|
text="Tritt noch mehr Räume bei",
|
||
|
on_click=lambda e: page.go("/join"),
|
||
|
style=ft.ButtonStyle(padding=25),
|
||
|
)
|
||
|
def leave_current_room(e=None, unique_id=None):
|
||
|
if not unique_id:
|
||
|
page.snack_bar = ft.SnackBar(ft.Text("No room selected to leave."))
|
||
|
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 e:
|
||
|
page.snack_bar = ft.SnackBar(ft.Text(f"Left Room {unique_id}"))
|
||
|
page.snack_bar.open = True
|
||
|
page.update()
|
||
|
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 "Something went wrong."
|
||
|
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.Text(
|
||
|
"Für heute hast du noch keine Räume ausgewählt!",
|
||
|
size=50,
|
||
|
weight="bold",
|
||
|
text_align="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)]
|
||
|
test_button.visible = bool(other_date_rooms) # Show button if there are rooms on other dates
|
||
|
|
||
|
if today_lessons:
|
||
|
for lesson in today_lessons:
|
||
|
# Create lesson card
|
||
|
room_card = ft.Card(
|
||
|
content=ft.Container(
|
||
|
content=ft.Row(
|
||
|
[
|
||
|
# Room details
|
||
|
ft.Column(
|
||
|
[
|
||
|
# Top line: room_number, info, location
|
||
|
ft.Row(
|
||
|
[
|
||
|
ft.Text(
|
||
|
f"{lesson['room_number']} {lesson['info']}",
|
||
|
size=20,
|
||
|
weight="bold",
|
||
|
),
|
||
|
ft.Text(
|
||
|
f"| {lesson['location']}",
|
||
|
size=20,
|
||
|
weight="bold",
|
||
|
),
|
||
|
],
|
||
|
spacing=5,
|
||
|
),
|
||
|
# Second line: first_name and last_name
|
||
|
ft.Text(
|
||
|
f"Teacher: {lesson['first_name']} {lesson['last_name']}",
|
||
|
size=16,
|
||
|
),
|
||
|
# Third line: lesson_time
|
||
|
ft.Text(
|
||
|
f"Time: {lesson['lesson_time']}",
|
||
|
size=16,
|
||
|
),
|
||
|
],
|
||
|
expand=True,
|
||
|
alignment=ft.MainAxisAlignment.CENTER,
|
||
|
),
|
||
|
# IconButton on the right
|
||
|
ft.IconButton(
|
||
|
icon=ft.icons.EXIT_TO_APP,
|
||
|
on_click=lambda e, lesson_id=lesson['unique_id']: leave_current_room(e, lesson_id),
|
||
|
tooltip="View Room Details",
|
||
|
),
|
||
|
],
|
||
|
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
|
||
|
),
|
||
|
padding=20, # Add padding inside the card
|
||
|
),
|
||
|
margin=10,
|
||
|
elevation=5, # Add shadow for better visual appeal
|
||
|
)
|
||
|
lessons_container.controls.append(room_card)
|
||
|
else:
|
||
|
# Show "No Rooms for Today" message
|
||
|
lessons_container.controls.append(
|
||
|
ft.Text(
|
||
|
"No Rooms for Today",
|
||
|
size=50,
|
||
|
weight="bold",
|
||
|
text_align="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()
|
||
|
|
||
|
# Add components to page
|
||
|
page.add(
|
||
|
ft.Column(
|
||
|
[
|
||
|
# Lessons container (centered)
|
||
|
ft.Column(
|
||
|
[lessons_container],
|
||
|
alignment=ft.MainAxisAlignment.CENTER,
|
||
|
expand=True,
|
||
|
),
|
||
|
# Buttons in one row at the bottom
|
||
|
ft.Row(
|
||
|
[test_button, join_more_rooms_button],
|
||
|
alignment=ft.MainAxisAlignment.CENTER,
|
||
|
spacing=20, # Add spacing between buttons
|
||
|
),
|
||
|
],
|
||
|
expand=True,
|
||
|
)
|
||
|
)
|