using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WguApp.Controls; using WguApp.Models; using WguApp.Services; namespace WguApp.Views; public partial class CoursePage : ContentPage { private Course _course; private Assessment? _oa = null; private Assessment? _pa = null; public CoursePage(Course course) { InitializeComponent(); _course = course; Title = _course.Name; StatusPicker.ItemsSource = Enum.GetValues(); TitleEntry.Text = _course.Name; StartDatePicker.Date = _course.StartDate; EndDatePicker.Date = _course.EndDate; StatusPicker.SelectedItem = _course.Status; InstructorNameEntry.Text = _course.InstructorName; InstructorEmailEntry.Text = _course.InstructorEmail; InstructorPhoneEntry.Text = _course.InstructorPhone; NotesEditor.Text = _course.Notes; StartNotifCheck.IsChecked = _course.StartNotifCheck; EndNotifCheck.IsChecked = _course.EndNotifCheck; StartNotifCheck.CheckedChanged += async (sender, e) => { await ToggleStartNotification(); }; EndNotifCheck.CheckedChanged += async (sender, e) => { await ToggleEndNotification(); }; } private async Task ToggleStartNotification() { if (StartNotifCheck.IsChecked) { var id = await LocalNotificationService.ScheduleNotification($"{_course.Name} Start Reminder", $"Your course '{_course.Id} starts in 12 hours'", _course.StartDate.Subtract(TimeSpan.FromHours(12))); _course.StartNotifId = id ?? 0; LoggerService.LogToFile($"{_course.Id}:{_course.Name} set start notification {_course.StartNotifId}"); } else { var res = await LocalNotificationService.CancelNotification(_course.StartNotifId); LoggerService.LogToFile($"{_course.Id}:{_course.Name} canceled start notification {_course.StartNotifId}"); _course.StartNotifId = 0; } _course.StartNotifCheck = StartNotifCheck.IsChecked; } private async Task ToggleEndNotification() { if (EndNotifCheck.IsChecked) { var id = await LocalNotificationService.ScheduleNotification($"{_course.Name} End Reminder", $"Your course '{_course.Id} ends in 12 hours'", _course.EndDate.Subtract(TimeSpan.FromHours(12))); _course.EndNotifId = id ?? 0; LoggerService.LogToFile($"{_course.Id}:{_course.Name} set end notification {_course.EndNotifId}"); } else { var res = await LocalNotificationService.CancelNotification(_course.EndNotifId); LoggerService.LogToFile($"{_course.Id}:{_course.Name} canceled end notification {_course.EndNotifId}"); _course.EndNotifId = 0; } _course.EndNotifCheck = EndNotifCheck.IsChecked; } private (string msg, bool result) ValidateFields() { var message = string.Empty; if (string.IsNullOrWhiteSpace(TitleEntry.Text)) message += "Title cannot be blank\n"; if (StartDatePicker.Date > EndDatePicker.Date) message += "Start Date cannot be after the End Date\n"; if (string.IsNullOrWhiteSpace(InstructorNameEntry.Text)) message += "Instructor Name cannot be blank\n"; if (string.IsNullOrWhiteSpace(InstructorPhoneEntry.Text)) message += "Instructor Phone cannot be blank\n"; if (string.IsNullOrWhiteSpace(InstructorEmailEntry.Text)) message += "Instructor Email cannot be blank\n"; return string.IsNullOrWhiteSpace(message) ? (message, true) : (message, false); } private async void SaveButton_OnClicked(object? sender, EventArgs e) { await Save(); } private async Task Save() { var validationResult = ValidateFields(); if (!validationResult.result) { await DisplayAlert("Validation Error", validationResult.msg, "Ok"); return false; } _course.Name = TitleEntry.Text; _course.StartDate = StartDatePicker.Date; _course.EndDate = EndDatePicker.Date; _course.InstructorName = InstructorNameEntry.Text; _course.InstructorPhone = InstructorPhoneEntry.Text; _course.InstructorEmail = InstructorEmailEntry.Text; _course.Notes = NotesEditor.Text; _course.StartNotifCheck = StartNotifCheck.IsChecked; _course.EndNotifCheck = EndNotifCheck.IsChecked; var updateResult = await DatabaseService.UpdateCourse(_course); if (updateResult) { await DisplayAlert("Info", $"{_course.Name} Saved!", "Ok"); } else { await DisplayAlert("Error", "Could not save term", "Ok"); } Title = _course.Name; if (_course.StartNotifId != 0) { await LocalNotificationService.UpdateNotification(_course.StartNotifId, $"{_course.Name} Start Reminder", $"Your course '{_course.Id} starts in 12 hours'", _course.StartDate.Subtract(TimeSpan.FromHours(12))); } if (_course.EndNotifId != 0) { await LocalNotificationService.UpdateNotification(_course.EndNotifId, $"{_course.Name} End Reminder", $"Your course '{_course.Id} ends in 12 hours'", _course.EndDate.Subtract(TimeSpan.FromHours(12))); } return true; } private async void DeleteButton_OnClicked(object? sender, EventArgs e) { var result = await DisplayAlert("Delete Course", $"Do you really want to delete '{_course.Name}'? This action cannot be undone.", "Delete", "Cancel"); if (!result) return; await DatabaseService.DeleteCourse(_course); await Navigation.PopAsync(); } private async void ShareNotesButton_OnClicked(object? sender, EventArgs e) { if (string.IsNullOrWhiteSpace(NotesEditor.Text)) { await DisplayAlert("Info", "Failed to share: Notes are empty", "Ok"); } await Share.Default.RequestAsync(new ShareTextRequest { Title = "Share course notes", Text = $"-- Course notes for {_course.Name} --\n{NotesEditor.Text}" }); } private async Task RefreshAssessmentsList() { AssessmentButtonStack.Children.Clear(); var allAssessments = await DatabaseService.GetAssessmentsByCourseId(_course.Id); _oa = allAssessments.FirstOrDefault(a => a.Type == AssessmentType.Objective); _pa = allAssessments.FirstOrDefault(a => a.Type == AssessmentType.Performance); if (_oa is not null) { var oaBtn = new CustomButton() { Text = _oa.Name, DateText = $"{DateOnly.FromDateTime(_oa.StartDate).ToString()} - {DateOnly.FromDateTime(_oa.EndDate).ToString()}" }; AssessmentButtonStack.Add(oaBtn); oaBtn.Clicked += async (sender, e) => { await HandleAssessmentButtonClick(_oa); }; } if (_pa is not null) { var paBtn = new CustomButton() { Text = _pa.Name, DateText = $"{DateOnly.FromDateTime(_pa.StartDate).ToString()} - {DateOnly.FromDateTime(_pa.EndDate).ToString()}" }; AssessmentButtonStack.Add(paBtn); paBtn.Clicked += async (sender, e) => { await HandleAssessmentButtonClick(_pa); }; } } protected async override void OnNavigatedTo(NavigatedToEventArgs args) { await RefreshAssessmentsList(); } private async Task HandleAssessmentButtonClick(Assessment assessment) { await Navigation.PushAsync(new AssessmentPage(assessment)); } private async void AddAssessmentButton_OnClicked(object? sender, EventArgs e) { if (_oa is not null && _pa is not null) { await DisplayAlert("Info", "Cannot add any more assessments", "Ok"); return; } var action = await DisplayActionSheet("Which type of lesson do you want to add?", "Cancel", null, "Performance", "Objective"); if (action is null or "Cancel") return; var assessment = new Assessment { CourseId = _course.Id, StartDate = DateTime.Now, EndDate = DateTime.Today.AddDays(30), StartNotifCheck = false, EndNotifCheck = false }; switch (action) { case "Objective": if (_oa is not null) { await DisplayAlert("Info", "Cannot add any more objective assessments", "Ok"); break; } assessment.Type = AssessmentType.Objective; assessment.Name = "Objective Assessment"; break; case "Performance": if (_pa is not null) { await DisplayAlert("Info", "Cannot add any more performance assessments", "Ok"); break; } assessment.Type = AssessmentType.Performance; assessment.Name = "Performance Assessment"; break; } await DatabaseService.AddAssessment(assessment); await RefreshAssessmentsList(); } }