Adding final project to dev branch

This commit is contained in:
2025-12-19 18:53:21 -06:00
commit fd2ab3e14c
62 changed files with 4730 additions and 0 deletions

View File

@@ -0,0 +1,230 @@

using SQLite;
using WguApp.Models;
namespace WguApp.Services;
public static class DatabaseService
{
private static SQLiteAsyncConnection? _db;
public static async Task Init()
{
if (_db is not null) return;
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "WguApp.db");
_db = new SQLiteAsyncConnection(databasePath);
try
{
await _db.CreateTablesAsync<Term, Course, Assessment>();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
// -- Add Methods -- //
#region Add methods
public static async Task<bool> AddTerm(Term term)
{
await Init();
var result = await _db?.InsertAsync(term)!;
return !(result <= 0);
}
public static async Task<bool> AddCourse(Course course)
{
await Init();
var result = await _db?.InsertAsync(course)!;
return !(result <= 0);
}
public static async Task<bool> AddAssessment(Assessment assessment)
{
await Init();
var result = await _db?.InsertAsync(assessment)!;
return !(result <= 0);
}
#endregion
// -- Get Methods -- //
#region Get Methods
public static async Task<List<Term>> GetAllTerms()
{
await Init();
var allTerms = await _db?.Table<Term>().ToListAsync()!;
return allTerms ?? [];
}
public static async Task<List<Course>> GetAllCourses()
{
await Init();
var allCourses = await _db?.Table<Course>().ToListAsync()!;
return allCourses ?? [];
}
public static async Task<List<Assessment>> GetAllAssessments()
{
await Init();
var allAssessments = await _db?.Table<Assessment>().ToListAsync()!;
return allAssessments ?? [];
}
public static async Task<List<Assessment>> GetAssessmentsByCourseId(int courseId)
{
await Init();
var query = $"SELECT * FROM Assessments WHERE CourseId = {courseId}";
var result = await _db?.QueryAsync<Assessment>(query)!;
return result.ToList() ?? [];
}
public static async Task<List<Course>> GetCoursesByTermId(int termId)
{
await Init();
var query = $"SELECT * FROM Courses WHERE TermId = {termId}";
var result = await _db?.QueryAsync<Course>(query)!;
return result.ToList() ?? [];
}
#endregion
// -- Update Methods
#region Update Methods
public static async Task<bool> UpdateTerm(Term term)
{
await Init();
return await _db?.UpdateAsync(term)! != 0;
}
public static async Task<bool> UpdateCourse(Course course)
{
await Init();
return await _db?.UpdateAsync(course)! != 0;
}
public static async Task<bool> UpdateAssessment(Assessment assessment)
{
await Init();
return await _db?.UpdateAsync(assessment)! != 0;
}
#endregion
// -- Delete Methods
#region Delete Methods
public static async Task<bool> DeleteTerm(Term term)
{
await Init();
return await _db?.DeleteAsync(term)! != 0;
}
public static async Task<bool> DeleteTerm(int termId)
{
await Init();
return await _db?.DeleteAsync<Term>(termId)! != 0;
}
public static async Task<bool> DeleteCourse(Course course)
{
await Init();
return await _db?.DeleteAsync(course)! != 0;
}
public static async Task<bool> DeleteCourse(int courseId)
{
await Init();
return await _db?.DeleteAsync<Course>(courseId)! != 0;
}
public static async Task<bool> DeleteAssessment(Assessment assessment)
{
await Init();
return await _db?.DeleteAsync(assessment)! != 0;
}
public static async Task<bool> DeleteAssessment(int assessmentId)
{
await Init();
return await _db?.DeleteAsync<Assessment>(assessmentId)! != 0;
}
#endregion
// -- Sample Data -- //
public static async Task LoadSampleData()
{
await ClearDbData();
var term1 = new Term()
{
Name = "Term 1",
StartDate = DateTime.Today,
EndDate = DateTime.Today.AddDays(30)
};
await AddTerm(term1);
var course1 = new Course()
{
TermId = term1.Id,
Name = "Course 1",
StartDate = DateTime.Today,
EndDate = DateTime.Today.AddDays(30),
InstructorName = "Anika Patel",
InstructorEmail = "anika.patel@strimeuniversity.edu",
InstructorPhone = "555-123-4567",
StartNotifCheck = false,
EndNotifCheck = false,
Status = CourseStatus.InProgress,
Notes = "Some notes"
};
await AddCourse(course1);
var assessment1 = new Assessment()
{
CourseId = course1.Id,
Name = "Performance Assessment",
Type = AssessmentType.Performance,
StartDate = DateTime.Today,
EndDate = DateTime.Today.AddDays(30),
StartNotifCheck = false,
EndNotifCheck = false
};
await AddAssessment(assessment1);
var assessment2 = new Assessment()
{
CourseId = course1.Id,
Name = "Objective Assessment",
Type = AssessmentType.Objective,
StartDate = DateTime.Today,
EndDate = DateTime.Today.AddDays(30),
StartNotifCheck = false,
EndNotifCheck = false
};
await AddAssessment(assessment2);
}
public static async Task ClearDbData()
{
await Init();
await _db?.DeleteAllAsync<Assessment>()!;
await _db?.DeleteAllAsync<Course>()!;
await _db?.DeleteAllAsync<Term>()!;
_db = null;
}
}

View File

@@ -0,0 +1,114 @@
using Plugin.LocalNotification;
namespace WguApp.Services;
public static class LocalNotificationService
{
private static readonly Random Rng = new();
public static async Task<int?> ScheduleNotification(string title, string description, DateTime time)
{
var permCheck = await PermissionsService.CheckNotificationPermissions();
if (!permCheck)
{
LoggerService.LogToFile("Notification Service: Notification Permission Not Granted");
return null;
}
var newId = Rng.Next();
var notif = new NotificationRequest
{
NotificationId = newId,
Title = title,
Description = description,
Schedule =
{
NotifyTime = time,
RepeatType = NotificationRepeat.No
}
};
try
{
await LocalNotificationCenter.Current.Show(notif);
LoggerService.LogToFile($"Notification Service: {notif.NotificationId}:{notif.Title} set");
}
catch (Exception e)
{
LoggerService.LogToFile($"Notification Service: {e.Message}");
throw;
}
return notif.NotificationId;
}
public static async Task<int> ScheduleNotification(NotificationRequest notif)
{
try
{
await LocalNotificationCenter.Current.Show(notif);
}
catch (Exception e)
{
LoggerService.LogToFile(e.Message);
throw;
}
return notif.NotificationId;
}
public static async Task<bool> UpdateNotification(int notificationId, string? title = null, string? description = null, DateTime? time = null)
{
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
var notif = pendingNotifs.FirstOrDefault(n => n.NotificationId == notificationId);
if (notif is null) return false;
await CancelNotification(notif);
notif.Title = title ?? notif.Title;
notif.Description = description ?? notif.Description;
notif.Schedule = new NotificationRequestSchedule()
{
NotifyTime = time ?? notif.Schedule.NotifyTime,
RepeatType = NotificationRepeat.No
};
await ScheduleNotification(notif);
return true;
}
public static async Task<bool> CancelNotification(int notificationId)
{
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
var match = pendingNotifs.FirstOrDefault(n => n.NotificationId == notificationId);
if (match is null) return false;
LocalNotificationCenter.Current.Cancel(notificationId);
return true;
}
public static async Task<bool> CancelNotification(NotificationRequest notif)
{
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
if (pendingNotifs.Contains(notif))
{
notif.Cancel();
}
return true;
}
public static async Task<bool> DoesNotificationAlreadyExist(int notificationId)
{
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
var match = pendingNotifs.FirstOrDefault(n => n.NotificationId == notificationId);
return match is not null;
}
}

View File

@@ -0,0 +1,11 @@
namespace WguApp.Services;
public class LoggerService
{
public static void LogToFile(string text)
{
var logFilePath = Path.Combine(FileSystem.AppDataDirectory, "log.txt");
File.AppendAllText(logFilePath, $"{DateTime.UtcNow} : {text}\n");
}
}

View File

@@ -0,0 +1,21 @@
using Plugin.LocalNotification;
namespace WguApp.Services;
public static class PermissionsService
{
public static async Task<bool> CheckNotificationPermissions()
{
if (await LocalNotificationCenter.Current.AreNotificationsEnabled()) return true;
try
{
return await LocalNotificationCenter.Current.RequestNotificationPermission();
}
catch (Exception e)
{
LoggerService.LogToFile(e.Message);
return false;
}
}
}