Files
schoolplanner/frontend/pages/main_page.py

272 lines
10 KiB
Python
Raw Normal View History

2025-01-19 00:04:08 +01:00
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
from pages.student_main_page import student_main_page
def main_page(page: ft.Page):
page.clean()
page.theme_mode = ft.ThemeMode.LIGHT
session = page.session.get("access_token")
if not session:
page.go("/login") # Redirect to login if no session
def is_student():
url = 'http://awesom-o.org:8000/check_role'
headers = {
'accept': 'application/json',
'Content-Type': 'application/json'
}
session_id = page.session.get("access_token")
if not session_id:
return None
data = {'session_id': session_id}
try:
response = requests.post(url, json=data, headers=headers)
response.raise_for_status()
role = response.json()
if role and 'role' in role and 'role' in role['role']:
if role['role']['role'] == "student":
role = "s"
return role
elif role['role']['role'] == "teacher":
role = "t"
return role
print("Unexpected response structure:", role)
return None
except requests.exceptions.RequestExceptin as error:
print("Error during role check:", error)
return None
page.title = "Room Information"
page.vertical_alignment = ft.MainAxisAlignment.START # Align all content to the top
if is_student() == "s":
student_main_page(page)
elif is_student() == "t":
async def fetch_room_data(session_id: str, update_room_list):
uri = "ws://localhost:8000/ws/teacher/open_rooms"
headers = {"session-id": session_id} # Add session ID to headers
async with websockets.connect(uri, extra_headers=headers) as websocket:
print("WebSocket connected")
try:
while True:
# Receive data from the WebSocket
data = await websocket.recv()
room_data = json.loads(data)
open_rooms = room_data.get("open_rooms", [])
# Update the room list
update_room_list(open_rooms)
except websockets.ConnectionClosed:
print("WebSocket connection closed")
except Exception as e:
print(f"WebSocket error: {e}")
# Function to fetch students in a room
def fetch_students_in_room(unique_id: str, session_id: str):
url = f"http://awesom-o.org:8000/teacher/room_students/?unique_id={unique_id}"
headers = {"accept": "application/json", "Content-Type": "application/json"}
data = {"session_id": session_id}
try:
response = requests.post(url, json=data, headers=headers)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print(f"Error fetching students: {e}")
return None
# Function to delete a room
def delete_room(unique_id: str, session_id: str):
url = f"http://awesom-o.org:8000/teacher/delete_room/?unique_id={unique_id}"
headers = {"accept": "application/json", "Content-Type": "application/json"}
data = {"session_id": session_id}
try:
response = requests.delete(url, json=data, headers=headers)
response.raise_for_status()
return True
except requests.RequestException as e:
print(f"Error deleting room: {e}")
return False
# Main Flet app
page.title = "Room Management"
page.vertical_alignment = ft.MainAxisAlignment.START # Align content to the top
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
page.padding = 20
page.scroll = "adaptive"
# Check if the user is logged in
session_id = page.session.get("access_token")
if not session_id:
page.go("/login") # Redirect to login if no session
# Search field
search_field = ft.TextField(label="Search", expand=True)
# Icon button to navigate to "/create" page
create_button = ft.IconButton(
icon=ft.icons.ADD,
on_click=lambda _: page.go("/create"),
)
# Container for the room list
room_container = ft.Column(scroll=ft.ScrollMode.AUTO, expand=True)
# Function to update the room list
def update_room_list(rooms):
room_container.controls.clear()
for room in rooms:
room_name = room.get("room_name", "Unknown Room")
room_info = room.get("info", "")
location = room.get("location", "")
teacher_name = room.get("teacher_name", "")
max_students = room.get("max_students", 0)
current_students = room.get("current_students", 0)
unique_id = room.get("unique_id", "")
# Create a clickable room card
room_card = ft.GestureDetector(
content=ft.Card(
content=ft.Container(
content=ft.Column(
[
# Top line: room_name, room_info, location
ft.Row(
[
ft.Text(f"{room_name}", size=20),
ft.Text(f"{room_info}", size=16),
ft.Text(f"| {location}", size=16),
],
spacing=5,
),
# Teacher line
ft.Text(f"Teacher: {teacher_name}", size=16),
# Capacity line
ft.Text(f"Capacity: {current_students}/{max_students}", size=16),
],
spacing=10,
),
padding=20,
),
margin=10,
elevation=5,
),
on_tap=lambda e, unique_id=unique_id: open_room_dialog(unique_id),
)
room_container.controls.append(room_card)
if not rooms:
room_container.controls.append(ft.Text("No open rooms available.", size=18))
page.update()
# Function to open the room dialog
def open_room_dialog(unique_id: str):
# Fetch students in the room
students_data = fetch_students_in_room(unique_id, session_id)
if not students_data:
page.snack_bar = ft.SnackBar(ft.Text("Failed to fetch students."))
page.snack_bar.open = True
page.update()
return
students = students_data.get("students", [])
if students != None:
students_list = ft.Column(
[ft.Text(f"Student: {student}") for student in students],
scroll=ft.ScrollMode.AUTO,
expand=True,
)
else:
students_list = ft.Column(ft.Text(f"There are no students who joined your Room"),
scroll=ft.ScrollMode.AUTO,
expand=True,
)
# Confirmation dialog for deleting the room
def open_delete_confirmation_dialog():
page.close(dialog)
def confirm_delete(e):
if delete_room(unique_id, session_id):
page.snack_bar = ft.SnackBar(ft.Text("Room deleted successfully."))
page.snack_bar.open = True
page.update()
page.close(confirm_dialog)
page.update()
else:
page.snack_bar = ft.SnackBar(ft.Text("Failed to delete room."))
page.snack_bar.open = True
page.update()
confirm_dialog = ft.AlertDialog(
title=ft.Text("Are you sure you want to delete this room?"),
actions=[
ft.TextButton("No", on_click=lambda e: page.close(confirm_dialog)),
ft.TextButton("Yes", on_click=confirm_delete),
],
)
page.dialog = confirm_dialog
confirm_dialog.open = True
page.update()
# Room dialog
dialog = ft.AlertDialog(
title=ft.Text("Room Details"),
content=students_list,
actions=[
ft.TextButton("Close", on_click=lambda e: page.close(dialog)),
ft.TextButton("Delete Room", on_click=lambda e: open_delete_confirmation_dialog()),
],
)
page.dialog = dialog
dialog.open = True
page.update()
# WebSocket listener for real-time updates
async def listen_for_updates():
while True:
try:
await fetch_room_data(session_id, update_room_list)
except Exception as e:
print(f"WebSocket connection error: {e}. Reconnecting in 5 seconds...")
await asyncio.sleep(5) # Wait before reconnecting
# Top bar layout
top_bar = ft.Row(
[
search_field,
create_button,
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
vertical_alignment=ft.CrossAxisAlignment.CENTER,
)
# Add components to the page
page.add(
top_bar,
room_container,
)
# Start the WebSocket listener
page.run_task(listen_for_updates)
else:
page.go("/login")