1
0
Fork 0
forked from Fuji/Fuji

Compare commits

...

5 commits

Author SHA1 Message Date
2fe24aecf1 Fix timetable error when Room is null 2025-04-19 07:26:40 +00:00
437c5ec17b Add logging out 2025-04-19 07:26:40 +00:00
091d459574 Home: create bar with full name and class 2025-04-19 07:26:40 +00:00
c92f13d8ab Create exams page prototype 2025-04-19 07:26:40 +00:00
952fbed080 Update requirements.txt 2025-04-18 19:02:15 +00:00
8 changed files with 147 additions and 18 deletions

View file

@ -5,3 +5,4 @@ pydantic
pyOpenSSL pyOpenSSL
Requests Requests
keyring keyring
sqlmodel

View file

@ -18,4 +18,4 @@ usrconf = {
'fullName': '', 'fullName': '',
'grade': '', 'grade': '',
'semester': 1, 'semester': 1,
} }

View file

@ -73,7 +73,7 @@ def sync(page: ft.Page):
"/grades": GradesPage(page), "/grades": GradesPage(page),
"/timetable": TimetablePage(), "/timetable": TimetablePage(),
"/homework": HomeworkPage(), "/homework": HomeworkPage(),
"/exams": ExamsPage(), "/exams": ExamsPage(page),
"/attendance": AttendancePage(), "/attendance": AttendancePage(),
"/behaviour": BehaviourPage(), "/behaviour": BehaviourPage(),
"/settings": SettingsPage(page) "/settings": SettingsPage(page)
@ -117,7 +117,7 @@ def main(page: ft.Page):
"/grades": GradesPage(page), "/grades": GradesPage(page),
"/timetable": TimetablePage(), "/timetable": TimetablePage(),
"/homework": HomeworkPage(), "/homework": HomeworkPage(),
"/exams": ExamsPage(), "/exams": ExamsPage(page),
"/attendance": AttendancePage(), "/attendance": AttendancePage(),
"/behaviour": BehaviourPage(), "/behaviour": BehaviourPage(),
"/settings": SettingsPage(page) "/settings": SettingsPage(page)

View file

@ -2,10 +2,77 @@ import flet as ft
from i18n import _ from i18n import _
def ExamsPage(): def ExamsPage(page: ft.Page):
return ft.Column([ return ft.Column([
ft.Text((_("Exams")), size=30, weight="bold"), ft.Row([
ft.Placeholder() ft.Text((_("Exams")), size=30, weight="bold"),
]) ft.Row(
[
ft.IconButton(icon=ft.icons.ARROW_LEFT),
ft.Text("14.04-20.04", size=18, weight="bold"),
ft.IconButton(icon=ft.icons.ARROW_RIGHT),
],
alignment=ft.MainAxisAlignment.CENTER
)
], alignment=ft.MainAxisAlignment.SPACE_BETWEEN, spacing=10),
ft.Card(
content=ft.Container(
content=ft.Column(
[
ft.ListTile(
title=ft.Row([
ft.Text("Example subject" ,weight="bold"),
ft.Row(
[
ft.Text("14.04.2025"),
],
alignment=ft.MainAxisAlignment.CENTER
)
], alignment=ft.MainAxisAlignment.SPACE_BETWEEN, spacing=10),
subtitle=ft.Row([
ft.Text("Short test - Example description"),
ft.Row(
[
ft.Text("Example teacher"),
],
alignment=ft.MainAxisAlignment.CENTER
)
], alignment=ft.MainAxisAlignment.SPACE_BETWEEN, spacing=10),
)
]
),
padding=5,
)
),
ft.Card(
content=ft.Container(
content=ft.Column(
[
ft.ListTile(
title=ft.Row([
ft.Text("Example subject" ,weight="bold"),
ft.Row(
[
ft.Text("14.04.2025"),
],
alignment=ft.MainAxisAlignment.CENTER
)
], alignment=ft.MainAxisAlignment.SPACE_BETWEEN, spacing=10),
subtitle=ft.Row([
ft.Text("Short test - Example description"),
ft.Row(
[
ft.Text("Example teacher"),
],
alignment=ft.MainAxisAlignment.CENTER
)
], alignment=ft.MainAxisAlignment.SPACE_BETWEEN, spacing=10),
)
]
),
padding=5,
)
)
])

View file

@ -1,15 +1,39 @@
import flet as ft import flet as ft
import configparser
from i18n import _ from i18n import _
from constants import * from constants import *
from homeutils import RecentGradesColumn # Import the function from your new file from homeutils import RecentGradesColumn
from utils import getconfigpath, getinitials
def HomePage(): def HomePage():
config = configparser.ConfigParser()
config.read(f"{getconfigpath()}/config.ini")
studentFullName = config['User']['fullName']
studentClass = config['User']['grade']
return ft.Column([ return ft.Column([
ft.Text((_("Home")), size=30, weight="bold"), ft.Text((_("Home")), size=30, weight="bold"),
ft.Text("\n", size=30, weight="bold"), ft.Text("\n", size=30, weight="bold"),
ft.Card(
content=ft.Container(
content=ft.Column(
controls=[
ft.ListTile(
leading=ft.CircleAvatar(
content=ft.Text(getinitials(studentFullName)),
),
title=ft.Text(studentFullName),
subtitle=ft.Text(studentClass),
),
]
),
width=400,
padding=10
),
),
ft.Row([ ft.Row([
ft.Card( ft.Card(
content=ft.Container( # Timetable Card content=ft.Container(
content=ft.Column([ content=ft.Column([
ft.Row([ ft.Row([
ft.Icon(ft.Icons.BACKPACK_OUTLINED, size=32, color="#FFFFFF"), ft.Icon(ft.Icons.BACKPACK_OUTLINED, size=32, color="#FFFFFF"),
@ -34,8 +58,8 @@ def HomePage():
), ),
ft.Card( ft.Card(
content=ft.Container( # Recent Grades Card content=ft.Container(
content=RecentGradesColumn(), # Use the imported function here content=RecentGradesColumn(),
#margin=20, #margin=20,
padding=10, padding=10,
alignment=ft.alignment.top_left, alignment=ft.alignment.top_left,

View file

@ -1,13 +1,26 @@
import flet as ft import flet as ft
from constants import * from constants import *
from utils import setthemecolor, setlanguage, restart from utils import setthemecolor, setlanguage, restart, logout
from i18n import _, set_language from i18n import _, set_language
def SettingsPage(page): def SettingsPage(page):
# Create the main container to hold everything # Create the main container to hold everything
main_container = ft.Container() main_container = ft.Container()
# Create a custom notification that we'll show/hide def handle_logout(e):
logout()
restart(e.page)
logout_modal = ft.AlertDialog(
modal=True,
title=ft.Text(_("Logout")),
content=ft.Text(_("Do you want to logout?")),
actions=[
ft.TextButton("Yes", on_click=handle_logout),
ft.TextButton("No", on_click=lambda e: page.close(logout_modal)),
],
actions_alignment=ft.MainAxisAlignment.END,
)
notification = ft.Container( notification = ft.Container(
visible=False, visible=False,
bgcolor=ft.colors.AMBER_100, bgcolor=ft.colors.AMBER_100,
@ -103,6 +116,12 @@ def SettingsPage(page):
on_change=onthemechange on_change=onthemechange
) )
]), ]),
ft.Row([
ft.ElevatedButton(
_("Logout"),
on_click=lambda e: page.open(logout_modal)
),
]),
]), ]),
expand=True # Make this container expand to push the notification to the bottom expand=True # Make this container expand to push the notification to the bottom
), ),

View file

@ -32,7 +32,7 @@ class Lesson(BaseModel):
return Lesson( return Lesson(
position = data["TimeSlot"]["Position"], position = data["TimeSlot"]["Position"],
date = datetime.fromtimestamp(data["Date"]["Timestamp"] / 1000).date(), date = datetime.fromtimestamp(data["Date"]["Timestamp"] / 1000).date(),
room = data["Room"]["Code"], room = data["Room"]["Code"] if data.get("Room") else None,
start = datetime.strptime(data["TimeSlot"]["Start"], "%H:%M").time(), start = datetime.strptime(data["TimeSlot"]["Start"], "%H:%M").time(),
end = datetime.strptime(data["TimeSlot"]["End"], "%H:%M").time(), end = datetime.strptime(data["TimeSlot"]["End"], "%H:%M").time(),
subject = data["Subject"]["Name"] if data["Subject"] else data["Event"], subject = data["Subject"]["Name"] if data["Subject"] else data["Event"],

View file

@ -103,3 +103,21 @@ def get_current_month_dates():
end_date = next_month - timedelta(days=1) end_date = next_month - timedelta(days=1)
return start_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d") return start_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d")
def getinitials(full_name):
initials = ''.join([part[0].upper() for part in full_name.split()])
return initials
def logout():
config = configparser.ConfigParser()
config.read(f"{getconfigpath()}/config.ini")
config["Settings"]["islogged"] = "False"
config["User"]["fullname"] = ""
config["User"]["grade"] = ""
config["User"]["semester"] = "1"
if os.path.exists("database.db"):
os.remove("database.db")
with open(f"{getconfigpath()}/config.ini", "w") as file:
config.write(file)