From dcf536f0c79cb6a27b9e85b73000d5ae56ea75e2 Mon Sep 17 00:00:00 2001 From: "mustafa.ahmed" Date: Tue, 10 Mar 2026 13:56:31 +0500 Subject: [PATCH] make the meal schedule page view only --- ViewModels/MealSchedulesViewModel.cs | 411 +++++++++++++++++---------- Views/MealSchedulesView.xaml | 239 ++++++++++++++-- 2 files changed, 475 insertions(+), 175 deletions(-) diff --git a/ViewModels/MealSchedulesViewModel.cs b/ViewModels/MealSchedulesViewModel.cs index f6d3adf..cc6add5 100644 --- a/ViewModels/MealSchedulesViewModel.cs +++ b/ViewModels/MealSchedulesViewModel.cs @@ -1,3 +1,244 @@ +//using System.Collections.ObjectModel; +//using System.Windows; +//using CommunityToolkit.Mvvm.ComponentModel; +//using CommunityToolkit.Mvvm.Input; +//using MySqlConnector; +//using UtopiaCanteenSystem.Models; +//using UtopiaCanteenSystem.Services; + +//namespace UtopiaCanteenSystem.ViewModels; + +///// +///// Admin CRUD for meal schedules in production (hrms.meal_schedule). No SQLite. Load all on open; optional Site filter (local). +///// +//public partial class MealSchedulesViewModel : ObservableObject +//{ +// private readonly IMealScheduleService _mealScheduleService; +// private readonly INavigationService _navigation; + +// [ObservableProperty] +// private ObservableCollection _schedules = new(); + +// /// Full list from production; Schedules is filtered by SelectedSiteFilter. +// private List _allSchedules = new(); + +// [ObservableProperty] +// private ObservableCollection _siteFilterChoices = new() { "All" }; + +// [ObservableProperty] +// private string _selectedSiteFilter = "All"; + +// [ObservableProperty] +// private MealSchedule? _selectedSchedule; + +// [ObservableProperty] +// private string _locationSiteId = string.Empty; + +// [ObservableProperty] +// private string _mealName = string.Empty; + +// [ObservableProperty] +// private string _startTime = "06:00:00"; + +// [ObservableProperty] +// private string _endTime = "09:00:00"; + +// [ObservableProperty] +// private string _message = string.Empty; + +// [ObservableProperty] +// private bool _isError; + +// [ObservableProperty] +// private bool _isLoading; + +// public MealSchedulesViewModel(IMealScheduleService mealScheduleService, INavigationService navigation) +// { +// _mealScheduleService = mealScheduleService; +// _navigation = navigation; +// _ = LoadSchedulesAsync(); +// } + +// partial void OnSelectedSiteFilterChanged(string value) +// { +// ApplyFilter(); +// } + +// partial void OnSelectedScheduleChanged(MealSchedule? value) +// { +// if (value == null) return; +// LocationSiteId = value.LocationSiteId ?? string.Empty; +// MealName = value.MealName ?? string.Empty; +// StartTime = value.StartTime ?? "00:00:00"; +// EndTime = value.EndTime ?? "23:59:59"; +// } + +// private void ApplyFilter() +// { +// if (string.IsNullOrEmpty(SelectedSiteFilter) || SelectedSiteFilter == "All") +// { +// Schedules = new ObservableCollection(_allSchedules); +// return; +// } +// var filtered = _allSchedules.Where(s => string.Equals(s.LocationSiteId?.Trim(), SelectedSiteFilter.Trim(), StringComparison.OrdinalIgnoreCase)).ToList(); +// Schedules = new ObservableCollection(filtered); +// } + +// private async Task LoadSchedulesAsync() +// { +// IsLoading = true; +// Message = string.Empty; +// IsError = false; +// try +// { +// var list = await _mealScheduleService.GetAllSchedulesAsync().ConfigureAwait(true); +// _allSchedules = list.ToList(); +// var siteIds = _allSchedules.Select(s => s.LocationSiteId?.Trim() ?? "").Where(s => !string.IsNullOrEmpty(s)).Distinct().OrderBy(s => s, StringComparer.Ordinal).ToList(); +// SiteFilterChoices = new ObservableCollection(new[] { "All" }.Concat(siteIds)); +// SelectedSiteFilter = "All"; +// ApplyFilter(); +// if (_allSchedules.Count == 0) +// Message = "No schedules in production. Add one below (HRMS MySQL must be configured)."; +// } +// catch (Exception ex) +// { +// IsError = true; +// var msg = ex is MySqlException mysql +// ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}" +// : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}"; +// Message = "Could not load schedules from production."; +// MessageBox.Show(msg, "Meal Schedules – Load Error", MessageBoxButton.OK, MessageBoxImage.Error); +// } +// finally +// { +// IsLoading = false; +// } +// } + +// [RelayCommand] +// private void AddNew() +// { +// SelectedSchedule = null; +// LocationSiteId = "02"; +// MealName = string.Empty; +// StartTime = "06:00:00"; +// EndTime = "09:00:00"; +// Message = string.Empty; +// } + +// [RelayCommand] +// private async Task Save() +// { +// Message = string.Empty; +// IsError = false; + +// if (!TimeSpan.TryParse(StartTime?.Trim(), out var start) || !TimeSpan.TryParse(EndTime?.Trim(), out var end)) +// { +// Message = "Start time and end time must be in HH:mm:ss format."; +// IsError = true; +// return; +// } +// if (start >= end) +// { +// Message = "Start time must be before end time."; +// IsError = true; +// return; +// } + +// var siteId = (LocationSiteId ?? string.Empty).Trim(); +// if (string.IsNullOrEmpty(siteId)) +// { +// Message = "Location site ID is required."; +// IsError = true; +// return; +// } + +// try +// { +// if (SelectedSchedule != null) +// { +// var dto = new MealSchedule +// { +// Id = SelectedSchedule.Id, +// MealName = (MealName ?? string.Empty).Trim(), +// LocationSiteId = siteId, +// StartTime = StartTime.Trim(), +// EndTime = EndTime.Trim() +// }; +// await _mealScheduleService.UpdateAsync(dto).ConfigureAwait(true); +// Message = "Schedule updated in production."; +// } +// else +// { +// var dto = new MealSchedule +// { +// MealName = (MealName ?? string.Empty).Trim(), +// LocationSiteId = siteId, +// StartTime = StartTime.Trim(), +// EndTime = EndTime.Trim() +// }; +// await _mealScheduleService.CreateAsync(dto).ConfigureAwait(true); +// Message = "Schedule added to production."; +// } +// await LoadSchedulesAsync().ConfigureAwait(true); +// } +// catch (Exception ex) +// { +// IsError = true; +// var msg = ex is MySqlException mysql +// ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}" +// : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}"; +// Message = "Failed to save to production."; +// MessageBox.Show(msg, "Meal Schedules – Save Error", MessageBoxButton.OK, MessageBoxImage.Error); +// } +// } + +// /// Selects a schedule for editing (used by Actions column Edit button). +// [RelayCommand] +// private void SelectSchedule(MealSchedule? schedule) +// { +// SelectedSchedule = schedule; +// } + +// [RelayCommand] +// private async Task Delete(MealSchedule? row) +// { +// var toDelete = row ?? SelectedSchedule; +// if (toDelete == null) +// { +// Message = "Select a schedule to delete."; +// IsError = true; +// return; +// } +// Message = string.Empty; +// IsError = false; +// try +// { +// await _mealScheduleService.DeleteAsync(toDelete.Id).ConfigureAwait(true); +// Message = "Schedule deleted from production."; +// SelectedSchedule = null; +// await LoadSchedulesAsync().ConfigureAwait(true); +// } +// catch (Exception ex) +// { +// IsError = true; +// var msg = ex is MySqlException mysql +// ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}" +// : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}"; +// Message = "Failed to delete."; +// MessageBox.Show(msg, "Meal Schedules – Delete Error", MessageBoxButton.OK, MessageBoxImage.Error); +// } +// } + +// [RelayCommand] +// private void Back() +// { +// _navigation.NavigateToSettings(); +// } +//} + + + using System.Collections.ObjectModel; using System.Windows; using CommunityToolkit.Mvvm.ComponentModel; @@ -9,7 +250,8 @@ using UtopiaCanteenSystem.Services; namespace UtopiaCanteenSystem.ViewModels; /// -/// Admin CRUD for meal schedules in production (hrms.meal_schedule). No SQLite. Load all on open; optional Site filter (local). +/// View-only display of meal schedules from production. +/// Loads all schedules on open; optional Site filter. /// public partial class MealSchedulesViewModel : ObservableObject { @@ -19,7 +261,6 @@ public partial class MealSchedulesViewModel : ObservableObject [ObservableProperty] private ObservableCollection _schedules = new(); - /// Full list from production; Schedules is filtered by SelectedSiteFilter. private List _allSchedules = new(); [ObservableProperty] @@ -31,18 +272,6 @@ public partial class MealSchedulesViewModel : ObservableObject [ObservableProperty] private MealSchedule? _selectedSchedule; - [ObservableProperty] - private string _locationSiteId = string.Empty; - - [ObservableProperty] - private string _mealName = string.Empty; - - [ObservableProperty] - private string _startTime = "06:00:00"; - - [ObservableProperty] - private string _endTime = "09:00:00"; - [ObservableProperty] private string _message = string.Empty; @@ -64,23 +293,21 @@ public partial class MealSchedulesViewModel : ObservableObject ApplyFilter(); } - partial void OnSelectedScheduleChanged(MealSchedule? value) - { - if (value == null) return; - LocationSiteId = value.LocationSiteId ?? string.Empty; - MealName = value.MealName ?? string.Empty; - StartTime = value.StartTime ?? "00:00:00"; - EndTime = value.EndTime ?? "23:59:59"; - } - private void ApplyFilter() { - if (string.IsNullOrEmpty(SelectedSiteFilter) || SelectedSiteFilter == "All") + if (string.IsNullOrWhiteSpace(SelectedSiteFilter) || SelectedSiteFilter == "All") { Schedules = new ObservableCollection(_allSchedules); return; } - var filtered = _allSchedules.Where(s => string.Equals(s.LocationSiteId?.Trim(), SelectedSiteFilter.Trim(), StringComparison.OrdinalIgnoreCase)).ToList(); + + var filtered = _allSchedules + .Where(s => string.Equals( + s.LocationSiteId?.Trim(), + SelectedSiteFilter.Trim(), + StringComparison.OrdinalIgnoreCase)) + .ToList(); + Schedules = new ObservableCollection(filtered); } @@ -89,24 +316,35 @@ public partial class MealSchedulesViewModel : ObservableObject IsLoading = true; Message = string.Empty; IsError = false; + try { var list = await _mealScheduleService.GetAllSchedulesAsync().ConfigureAwait(true); _allSchedules = list.ToList(); - var siteIds = _allSchedules.Select(s => s.LocationSiteId?.Trim() ?? "").Where(s => !string.IsNullOrEmpty(s)).Distinct().OrderBy(s => s, StringComparer.Ordinal).ToList(); + + var siteIds = _allSchedules + .Select(s => s.LocationSiteId?.Trim() ?? "") + .Where(s => !string.IsNullOrEmpty(s)) + .Distinct() + .OrderBy(s => s, StringComparer.Ordinal) + .ToList(); + SiteFilterChoices = new ObservableCollection(new[] { "All" }.Concat(siteIds)); SelectedSiteFilter = "All"; ApplyFilter(); + if (_allSchedules.Count == 0) - Message = "No schedules in production. Add one below (HRMS MySQL must be configured)."; + Message = "No schedules configured."; } catch (Exception ex) { IsError = true; + var msg = ex is MySqlException mysql ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}" : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}"; - Message = "Could not load schedules from production."; + + Message = "Could not load schedules."; MessageBox.Show(msg, "Meal Schedules – Load Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally @@ -115,124 +353,9 @@ public partial class MealSchedulesViewModel : ObservableObject } } - [RelayCommand] - private void AddNew() - { - SelectedSchedule = null; - LocationSiteId = "02"; - MealName = string.Empty; - StartTime = "06:00:00"; - EndTime = "09:00:00"; - Message = string.Empty; - } - - [RelayCommand] - private async Task Save() - { - Message = string.Empty; - IsError = false; - - if (!TimeSpan.TryParse(StartTime?.Trim(), out var start) || !TimeSpan.TryParse(EndTime?.Trim(), out var end)) - { - Message = "Start time and end time must be in HH:mm:ss format."; - IsError = true; - return; - } - if (start >= end) - { - Message = "Start time must be before end time."; - IsError = true; - return; - } - - var siteId = (LocationSiteId ?? string.Empty).Trim(); - if (string.IsNullOrEmpty(siteId)) - { - Message = "Location site ID is required."; - IsError = true; - return; - } - - try - { - if (SelectedSchedule != null) - { - var dto = new MealSchedule - { - Id = SelectedSchedule.Id, - MealName = (MealName ?? string.Empty).Trim(), - LocationSiteId = siteId, - StartTime = StartTime.Trim(), - EndTime = EndTime.Trim() - }; - await _mealScheduleService.UpdateAsync(dto).ConfigureAwait(true); - Message = "Schedule updated in production."; - } - else - { - var dto = new MealSchedule - { - MealName = (MealName ?? string.Empty).Trim(), - LocationSiteId = siteId, - StartTime = StartTime.Trim(), - EndTime = EndTime.Trim() - }; - await _mealScheduleService.CreateAsync(dto).ConfigureAwait(true); - Message = "Schedule added to production."; - } - await LoadSchedulesAsync().ConfigureAwait(true); - } - catch (Exception ex) - { - IsError = true; - var msg = ex is MySqlException mysql - ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}" - : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}"; - Message = "Failed to save to production."; - MessageBox.Show(msg, "Meal Schedules – Save Error", MessageBoxButton.OK, MessageBoxImage.Error); - } - } - - /// Selects a schedule for editing (used by Actions column Edit button). - [RelayCommand] - private void SelectSchedule(MealSchedule? schedule) - { - SelectedSchedule = schedule; - } - - [RelayCommand] - private async Task Delete(MealSchedule? row) - { - var toDelete = row ?? SelectedSchedule; - if (toDelete == null) - { - Message = "Select a schedule to delete."; - IsError = true; - return; - } - Message = string.Empty; - IsError = false; - try - { - await _mealScheduleService.DeleteAsync(toDelete.Id).ConfigureAwait(true); - Message = "Schedule deleted from production."; - SelectedSchedule = null; - await LoadSchedulesAsync().ConfigureAwait(true); - } - catch (Exception ex) - { - IsError = true; - var msg = ex is MySqlException mysql - ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}" - : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}"; - Message = "Failed to delete."; - MessageBox.Show(msg, "Meal Schedules – Delete Error", MessageBoxButton.OK, MessageBoxImage.Error); - } - } - [RelayCommand] private void Back() { _navigation.NavigateToSettings(); } -} +} \ No newline at end of file diff --git a/Views/MealSchedulesView.xaml b/Views/MealSchedulesView.xaml index 327424d..0039805 100644 --- a/Views/MealSchedulesView.xaml +++ b/Views/MealSchedulesView.xaml @@ -1,11 +1,11 @@ - - + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + Margin="0,2,0,0"/>--> + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +