Add recent grades card
This commit is contained in:
parent
438ee1b3ce
commit
a1a0a6212d
4 changed files with 175 additions and 135 deletions
|
@ -37,6 +37,7 @@ def sync():
|
||||||
|
|
||||||
except NoLoggedInException:
|
except NoLoggedInException:
|
||||||
print("NoLoggedInException, or in other words, vulcan shitted itself.")
|
print("NoLoggedInException, or in other words, vulcan shitted itself.")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
|
||||||
students = interface.get_students()
|
students = interface.get_students()
|
||||||
|
|
|
@ -1,53 +1,46 @@
|
||||||
import flet as ft
|
import flet as ft
|
||||||
from i18n import *
|
from i18n import _
|
||||||
from constants import *
|
from constants import *
|
||||||
|
from test import RecentGradesColumn # Import the function from your new file
|
||||||
|
|
||||||
def HomePage():
|
def HomePage():
|
||||||
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.Row([
|
ft.Row([
|
||||||
ft.Container( # Timetable Card
|
ft.Container( # Timetable Card
|
||||||
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"),
|
||||||
ft.Text((_("Timetable")), size=24, font_family="Roboto", weight="bold")
|
ft.Text((_("Timetable")), size=24, font_family="Roboto", weight="bold")
|
||||||
]),
|
|
||||||
ft.ListView(
|
|
||||||
controls=[
|
|
||||||
ft.Placeholder()
|
|
||||||
],
|
|
||||||
expand=True,
|
|
||||||
spacing=10,
|
|
||||||
padding=10,
|
|
||||||
auto_scroll=False
|
|
||||||
)
|
|
||||||
]),
|
]),
|
||||||
margin=20,
|
ft.ListView(
|
||||||
padding=10,
|
controls=[
|
||||||
alignment=ft.alignment.top_left,
|
ft.Placeholder()
|
||||||
bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST,
|
],
|
||||||
width=420,
|
expand=True,
|
||||||
height=270,
|
spacing=10,
|
||||||
border_radius=10,
|
padding=10,
|
||||||
),
|
auto_scroll=False
|
||||||
|
)
|
||||||
ft.Container( # Recent Grades Card
|
]),
|
||||||
content=ft.Column([
|
margin=20,
|
||||||
ft.Row([
|
padding=10,
|
||||||
ft.Icon(ft.Icons.LOOKS_6_OUTLINED, size=32, color="#FFFFFF"),
|
alignment=ft.alignment.top_left,
|
||||||
ft.Text((_("Recent Grades")), size=24, font_family="Roboto", weight="bold")
|
bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST,
|
||||||
]),
|
width=420,
|
||||||
|
height=270,
|
||||||
ft.Placeholder()
|
border_radius=10,
|
||||||
]),
|
),
|
||||||
margin=20,
|
ft.Container( # Recent Grades Card
|
||||||
padding=10,
|
content=RecentGradesColumn(), # Use the imported function here
|
||||||
alignment=ft.alignment.top_left,
|
margin=20,
|
||||||
bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST,
|
padding=10,
|
||||||
width=420,
|
alignment=ft.alignment.top_left,
|
||||||
height=270,
|
bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST,
|
||||||
border_radius=10,
|
width=420,
|
||||||
)
|
height=270,
|
||||||
])
|
border_radius=10,
|
||||||
|
)
|
||||||
])
|
])
|
||||||
|
])
|
|
@ -81,58 +81,9 @@ def create_grades_database(grades_list, db_path="grades.db"):
|
||||||
print(f"Database created successfully with data from {len(list(re.finditer(pattern, grades_str)))} grades")
|
print(f"Database created successfully with data from {len(list(re.finditer(pattern, grades_str)))} grades")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_recent_grades(days=7, db_path="grades.db"):
|
def get_current_week_grades(db_path="grades.db"):
|
||||||
"""
|
"""
|
||||||
Retrieve grades from the database from the last specified number of days.
|
Get all grades from the current week (Monday to Sunday).
|
||||||
|
|
||||||
Args:
|
|
||||||
days (int): Number of days to look back
|
|
||||||
db_path (str): Path to the SQLite database file
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: List of dictionaries containing the grade records
|
|
||||||
"""
|
|
||||||
# Connect to SQLite database
|
|
||||||
conn = sqlite3.connect(db_path)
|
|
||||||
|
|
||||||
# Configure connection to return datetime objects for timestamp fields
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
# Calculate the date from which to retrieve grades
|
|
||||||
cutoff_date = datetime.datetime.now() - timedelta(days=days)
|
|
||||||
|
|
||||||
# Query recent grades
|
|
||||||
cursor.execute('''
|
|
||||||
SELECT * FROM grades
|
|
||||||
WHERE created_at >= ?
|
|
||||||
ORDER BY created_at DESC
|
|
||||||
''', (cutoff_date,))
|
|
||||||
|
|
||||||
# Fetch all results
|
|
||||||
results = cursor.fetchall()
|
|
||||||
|
|
||||||
# Convert results to a list of dictionaries for easier access
|
|
||||||
grades = []
|
|
||||||
for row in results:
|
|
||||||
grade_dict = dict(row)
|
|
||||||
grades.append(grade_dict)
|
|
||||||
|
|
||||||
# Close connection
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
return grades
|
|
||||||
|
|
||||||
def get_grades_by_subject(subject, db_path="grades.db"):
|
|
||||||
"""
|
|
||||||
Retrieve grades for a specific subject from the database.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
subject (str): The subject name to filter by
|
|
||||||
db_path (str): Path to the SQLite database file
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: List of dictionaries containing the grade records
|
|
||||||
"""
|
"""
|
||||||
# Connect to SQLite database
|
# Connect to SQLite database
|
||||||
conn = sqlite3.connect(db_path)
|
conn = sqlite3.connect(db_path)
|
||||||
|
@ -141,46 +92,24 @@ def get_grades_by_subject(subject, db_path="grades.db"):
|
||||||
conn.row_factory = sqlite3.Row
|
conn.row_factory = sqlite3.Row
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
# Query grades by subject
|
# Calculate the start and end of the current week
|
||||||
|
today = datetime.datetime.now()
|
||||||
|
start_of_week = today - timedelta(days=today.weekday())
|
||||||
|
start_of_week = start_of_week.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
|
end_of_week = start_of_week + timedelta(days=6, hours=23, minutes=59, seconds=59)
|
||||||
|
|
||||||
|
# Query to get grades from the current week
|
||||||
cursor.execute('''
|
cursor.execute('''
|
||||||
SELECT * FROM grades
|
SELECT id, subject, name, value, is_point, point_numerator, point_denominator, created_at
|
||||||
WHERE subject = ?
|
FROM grades
|
||||||
ORDER BY created_at DESC
|
WHERE created_at BETWEEN ? AND ?
|
||||||
''', (subject,))
|
ORDER BY subject, created_at
|
||||||
|
''', (start_of_week, end_of_week))
|
||||||
|
|
||||||
# Fetch all results
|
# Convert cursor results to dictionaries
|
||||||
results = cursor.fetchall()
|
grades = [dict(row) for row in cursor.fetchall()]
|
||||||
|
|
||||||
# Convert results to a list of dictionaries for easier access
|
# Close the connection
|
||||||
grades = []
|
|
||||||
for row in results:
|
|
||||||
grade_dict = dict(row)
|
|
||||||
grades.append(grade_dict)
|
|
||||||
|
|
||||||
# Close connection
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
return grades
|
return grades
|
||||||
|
|
||||||
def display_grades(grades):
|
|
||||||
"""
|
|
||||||
Helper function to display grades in a readable format.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
grades (list): List of grade dictionaries
|
|
||||||
"""
|
|
||||||
if not grades:
|
|
||||||
print("No grades found.")
|
|
||||||
return
|
|
||||||
|
|
||||||
for grade in grades:
|
|
||||||
created_at = grade['created_at']
|
|
||||||
if isinstance(created_at, str):
|
|
||||||
created_at = datetime.datetime.fromisoformat(created_at)
|
|
||||||
|
|
||||||
print(f"Subject: {grade['subject']}")
|
|
||||||
print(f"Value: {grade['value']} (Weight: {grade['weight']})")
|
|
||||||
print(f"Name: {grade['name']}")
|
|
||||||
print(f"Created at: {created_at}")
|
|
||||||
print(f"Creator: {grade['creator']}")
|
|
||||||
print("-" * 50)
|
|
117
src/test.py
Normal file
117
src/test.py
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
import flet as ft
|
||||||
|
import sqlite3
|
||||||
|
import datetime
|
||||||
|
from datetime import timedelta
|
||||||
|
from collections import defaultdict
|
||||||
|
from sqlite_handler import get_current_week_grades
|
||||||
|
from i18n import _
|
||||||
|
|
||||||
|
def format_grade(grade):
|
||||||
|
"""
|
||||||
|
Format a single grade into a readable string.
|
||||||
|
"""
|
||||||
|
# For simple grade display
|
||||||
|
return str(grade['value'])
|
||||||
|
|
||||||
|
def RecentGradesColumn(db_path="grades.db"):
|
||||||
|
"""
|
||||||
|
Create a column containing the recent grades content styled like the image.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_path (str): Path to the SQLite database file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
ft.Column: A column widget containing the recent grades UI
|
||||||
|
"""
|
||||||
|
# Create a function to load grades
|
||||||
|
def load_grades(e=None):
|
||||||
|
try:
|
||||||
|
# Get grades from the current week
|
||||||
|
grades_list = get_current_week_grades(db_path)
|
||||||
|
|
||||||
|
# Group by subject
|
||||||
|
grades_by_subject = defaultdict(list)
|
||||||
|
for grade in grades_list:
|
||||||
|
subject = grade['subject']
|
||||||
|
grades_by_subject[subject].append(grade)
|
||||||
|
|
||||||
|
# Prepare the list of controls
|
||||||
|
grade_controls = []
|
||||||
|
|
||||||
|
if not grades_list:
|
||||||
|
# No grades found
|
||||||
|
grade_controls.append(
|
||||||
|
ft.Text(_("No grades found for this week."),
|
||||||
|
color="#AAAAAA")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Add each subject with its grades
|
||||||
|
for subject, grades in grades_by_subject.items():
|
||||||
|
# Format grades as a space-separated string
|
||||||
|
formatted_grades = [format_grade(grade) for grade in grades]
|
||||||
|
grades_str = " ".join(formatted_grades)
|
||||||
|
|
||||||
|
# Create a row for each subject
|
||||||
|
subject_row = ft.Row([
|
||||||
|
ft.Text(
|
||||||
|
subject,
|
||||||
|
color="#FFFFFF",
|
||||||
|
size=16,
|
||||||
|
expand=True,
|
||||||
|
no_wrap=False
|
||||||
|
),
|
||||||
|
*[
|
||||||
|
ft.Container(
|
||||||
|
content=ft.Text(grade_val,color="#FFFFFF",size=16,text_align=ft.TextAlign.CENTER,width=30),
|
||||||
|
expand=False,
|
||||||
|
bgcolor=ft.Colors.with_opacity(0.3, ft.Colors.BLACK),
|
||||||
|
width=30,
|
||||||
|
height=30,
|
||||||
|
border_radius=1000,
|
||||||
|
alignment=ft.alignment.center,
|
||||||
|
)
|
||||||
|
for grade_val in formatted_grades
|
||||||
|
]
|
||||||
|
])
|
||||||
|
grade_controls.append(subject_row)
|
||||||
|
|
||||||
|
return grade_controls
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# Return an error message
|
||||||
|
return [
|
||||||
|
ft.Text(f"Error loading grades: {str(e)}",
|
||||||
|
color="#FF0000")
|
||||||
|
]
|
||||||
|
|
||||||
|
# Load the initial grades
|
||||||
|
initial_grades = load_grades()
|
||||||
|
|
||||||
|
# Create the grades ListView
|
||||||
|
grades_listview = ft.ListView(
|
||||||
|
controls=initial_grades,
|
||||||
|
expand=True,
|
||||||
|
spacing=8,
|
||||||
|
padding=ft.padding.only(left=10, right=10, top=10, bottom=16)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a refresh button function
|
||||||
|
def refresh_grades(e):
|
||||||
|
grades_listview.controls = load_grades()
|
||||||
|
grades_listview.update()
|
||||||
|
|
||||||
|
# Create the header section like in the image
|
||||||
|
header = ft.Row([
|
||||||
|
ft.Icon(ft.Icons.FILTER_6, size=32, color="#FFFFFF"),
|
||||||
|
ft.Text((_("Recent Grades")), size=24, font_family="Roboto", weight="bold")
|
||||||
|
], spacing=12, alignment=ft.MainAxisAlignment.START)
|
||||||
|
|
||||||
|
# Create the column with header and content
|
||||||
|
return ft.Container(
|
||||||
|
content=ft.Column([
|
||||||
|
header,
|
||||||
|
grades_listview
|
||||||
|
], spacing=5),
|
||||||
|
padding=ft.padding.only(left=5, right=5, top=5),
|
||||||
|
expand=True
|
||||||
|
)
|
Loading…
Add table
Reference in a new issue