make the meal schedule page view only
parent
4d2433fa28
commit
dcf536f0c7
|
|
@ -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;
|
||||
|
||||
///// <summary>
|
||||
///// Admin CRUD for meal schedules in production (hrms.meal_schedule). No SQLite. Load all on open; optional Site filter (local).
|
||||
///// </summary>
|
||||
//public partial class MealSchedulesViewModel : ObservableObject
|
||||
//{
|
||||
// private readonly IMealScheduleService _mealScheduleService;
|
||||
// private readonly INavigationService _navigation;
|
||||
|
||||
// [ObservableProperty]
|
||||
// private ObservableCollection<MealSchedule> _schedules = new();
|
||||
|
||||
// /// <summary>Full list from production; Schedules is filtered by SelectedSiteFilter.</summary>
|
||||
// private List<MealSchedule> _allSchedules = new();
|
||||
|
||||
// [ObservableProperty]
|
||||
// private ObservableCollection<string> _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<MealSchedule>(_allSchedules);
|
||||
// return;
|
||||
// }
|
||||
// var filtered = _allSchedules.Where(s => string.Equals(s.LocationSiteId?.Trim(), SelectedSiteFilter.Trim(), StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
// Schedules = new ObservableCollection<MealSchedule>(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<string>(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);
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>Selects a schedule for editing (used by Actions column Edit button).</summary>
|
||||
// [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;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public partial class MealSchedulesViewModel : ObservableObject
|
||||
{
|
||||
|
|
@ -19,7 +261,6 @@ public partial class MealSchedulesViewModel : ObservableObject
|
|||
[ObservableProperty]
|
||||
private ObservableCollection<MealSchedule> _schedules = new();
|
||||
|
||||
/// <summary>Full list from production; Schedules is filtered by SelectedSiteFilter.</summary>
|
||||
private List<MealSchedule> _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<MealSchedule>(_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<MealSchedule>(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<string>(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,121 +353,6 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Selects a schedule for editing (used by Actions column Edit button).</summary>
|
||||
[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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<UserControl x:Class="UtopiaCanteenSystem.Views.MealSchedulesView"
|
||||
<!--<UserControl x:Class="UtopiaCanteenSystem.Views.MealSchedulesView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="clr-namespace:UtopiaCanteenSystem.Converters">
|
||||
<UserControl.Resources>
|
||||
<converters:MealSessionToNameConverter x:Key="MealSessionConverter"/>
|
||||
|
||||
<!-- Palette -->
|
||||
--><!-- Palette --><!--
|
||||
<SolidColorBrush x:Key="PrimaryText" Color="#1F2933"/>
|
||||
<SolidColorBrush x:Key="MutedText" Color="#718096"/>
|
||||
<SolidColorBrush x:Key="PrimaryAccent" Color="#5BA3A0"/>
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
<SolidColorBrush x:Key="ErrorBrush" Color="#E53E3E"/>
|
||||
<SolidColorBrush x:Key="CardBackground" Color="#FFFFFF"/>
|
||||
|
||||
<!-- Card style -->
|
||||
--><!-- Card style --><!--
|
||||
<Style x:Key="CardBorder" TargetType="Border">
|
||||
<Setter Property="Background" Value="{StaticResource CardBackground}"/>
|
||||
<Setter Property="CornerRadius" Value="16"/>
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Buttons -->
|
||||
--><!-- Buttons --><!--
|
||||
<Style x:Key="PrimaryButton" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Background" Value="{StaticResource PrimaryAccent}"/>
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
<Setter Property="Background" Value="#FFF5F5"/>
|
||||
</Style>
|
||||
|
||||
<!-- Back button: pill style with hover/pressed -->
|
||||
--><!-- Back button: pill style with hover/pressed --><!--
|
||||
<Style x:Key="BackButton" TargetType="Button" BasedOn="{StaticResource SecondaryButton}">
|
||||
<Setter Property="Padding" Value="18,10"/>
|
||||
<Setter Property="MinWidth" Value="100"/>
|
||||
|
|
@ -130,7 +130,7 @@
|
|||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Small icon action buttons for DataGrid Actions column -->
|
||||
--><!-- Small icon action buttons for DataGrid Actions column --><!--
|
||||
<Style x:Key="GridActionButton" TargetType="Button">
|
||||
<Setter Property="Width" Value="28"/>
|
||||
<Setter Property="Height" Value="28"/>
|
||||
|
|
@ -169,7 +169,7 @@
|
|||
<Setter Property="ToolTip" Value="Delete"/>
|
||||
</Style>
|
||||
|
||||
<!-- Inputs -->
|
||||
--><!-- Inputs --><!--
|
||||
<Style x:Key="ModernTextBox" TargetType="TextBox">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="10,8"/>
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<!-- DataGrid styling -->
|
||||
--><!-- DataGrid styling --><!--
|
||||
<Style x:Key="ModernDataGrid" TargetType="DataGrid">
|
||||
<Setter Property="AutoGenerateColumns" Value="False"/>
|
||||
<Setter Property="CanUserAddRows" Value="False"/>
|
||||
|
|
@ -276,7 +276,7 @@
|
|||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- HEADER BAR -->
|
||||
--><!-- HEADER BAR --><!--
|
||||
<Grid Grid.Row="0" Margin="24,20,24,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
|
|
@ -285,25 +285,25 @@
|
|||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Back -->
|
||||
--><!-- Back --><!--
|
||||
<Button Grid.Column="0"
|
||||
Command="{Binding BackCommand}"
|
||||
Style="{StaticResource BackButton}"
|
||||
Content="Back"/>
|
||||
|
||||
<!-- Title + subtitle -->
|
||||
--><!-- Title + subtitle --><!--
|
||||
<StackPanel Grid.Column="1" Margin="16,0,0,0" VerticalAlignment="Center">
|
||||
<TextBlock Text="Meal Schedules"
|
||||
FontSize="24"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{StaticResource PrimaryText}"/>
|
||||
<!--<TextBlock Text="(production hrms.meal_schedule)"
|
||||
--><!--<TextBlock Text="(production hrms.meal_schedule)"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource MutedText}"
|
||||
Margin="0,2,0,0"/>-->
|
||||
Margin="0,2,0,0"/>--><!--
|
||||
</StackPanel>
|
||||
|
||||
<!-- Site filter -->
|
||||
--><!-- Site filter --><!--
|
||||
<StackPanel Grid.Column="2"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right"
|
||||
|
|
@ -320,7 +320,7 @@
|
|||
Style="{StaticResource ModernComboBox}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Add New -->
|
||||
--><!-- Add New --><!--
|
||||
<Button Grid.Column="3"
|
||||
Command="{Binding AddNewCommand}"
|
||||
Style="{StaticResource PrimaryButton}">
|
||||
|
|
@ -331,12 +331,12 @@
|
|||
</Button>
|
||||
</Grid>
|
||||
|
||||
<!-- MAIN CONTENT -->
|
||||
--><!-- MAIN CONTENT --><!--
|
||||
<ScrollViewer Grid.Row="1"
|
||||
Margin="24,0,24,16"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<!-- Schedules card -->
|
||||
--><!-- Schedules card --><!--
|
||||
<Border Style="{StaticResource CardBorder}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
|
@ -344,7 +344,7 @@
|
|||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Card header -->
|
||||
--><!-- Card header --><!--
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,12">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Schedules"
|
||||
|
|
@ -357,7 +357,7 @@
|
|||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- DataGrid -->
|
||||
--><!-- DataGrid --><!--
|
||||
<DataGrid Grid.Row="1"
|
||||
Style="{StaticResource ModernDataGrid}"
|
||||
ItemsSource="{Binding Schedules}"
|
||||
|
|
@ -429,7 +429,7 @@
|
|||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Add / Edit card -->
|
||||
--><!-- Add / Edit card --><!--
|
||||
<Border Style="{StaticResource CardBorder}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
|
@ -438,7 +438,7 @@
|
|||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Card header -->
|
||||
--><!-- Card header --><!--
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,16">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Add or Edit Meal Schedule"
|
||||
|
|
@ -448,16 +448,16 @@
|
|||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Form -->
|
||||
--><!-- Form --><!--
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Left column -->
|
||||
--><!-- Left column --><!--
|
||||
<StackPanel Grid.Column="0" Margin="0,0,16,0">
|
||||
<!-- Location Site ID -->
|
||||
--><!-- Location Site ID --><!--
|
||||
<StackPanel Margin="0,0,0,12">
|
||||
<TextBlock Text="Location Site ID"
|
||||
FontSize="12"
|
||||
|
|
@ -467,7 +467,7 @@
|
|||
Style="{StaticResource ModernTextBox}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Meal Session -->
|
||||
--><!-- Meal Session --><!--
|
||||
<StackPanel Margin="0,0,0,12">
|
||||
<TextBlock Text="Meal Session"
|
||||
FontSize="12"
|
||||
|
|
@ -478,9 +478,9 @@
|
|||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Right column -->
|
||||
--><!-- Right column --><!--
|
||||
<StackPanel Grid.Column="1" Margin="0,0,0,0">
|
||||
<!-- Start time -->
|
||||
--><!-- Start time --><!--
|
||||
<StackPanel Margin="0,0,0,12">
|
||||
<TextBlock Text="Start (HH:mm:ss)"
|
||||
FontSize="12"
|
||||
|
|
@ -503,7 +503,7 @@
|
|||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<!-- End time -->
|
||||
--><!-- End time --><!--
|
||||
<StackPanel Margin="0,0,0,12">
|
||||
<TextBlock Text="End (HH:mm:ss)"
|
||||
FontSize="12"
|
||||
|
|
@ -528,7 +528,7 @@
|
|||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- Buttons -->
|
||||
--><!-- Buttons --><!--
|
||||
<StackPanel Grid.Row="2"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right"
|
||||
|
|
@ -550,7 +550,7 @@
|
|||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- Message -->
|
||||
--><!-- Message --><!--
|
||||
<Border Grid.Row="2"
|
||||
Margin="24,0,24,20"
|
||||
Background="Transparent">
|
||||
|
|
@ -572,4 +572,181 @@
|
|||
</TextBlock>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>-->
|
||||
|
||||
|
||||
<UserControl x:Class="UtopiaCanteenSystem.Views.MealSchedulesView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="clr-namespace:UtopiaCanteenSystem.Converters">
|
||||
<UserControl.Resources>
|
||||
<converters:MealSessionToNameConverter x:Key="MealSessionConverter"/>
|
||||
|
||||
<SolidColorBrush x:Key="PrimaryText" Color="#1F2933"/>
|
||||
<SolidColorBrush x:Key="MutedText" Color="#718096"/>
|
||||
<SolidColorBrush x:Key="PrimaryAccent" Color="#5BA3A0"/>
|
||||
<SolidColorBrush x:Key="PrimaryAccentLight" Color="#E3F5F4"/>
|
||||
<SolidColorBrush x:Key="BorderBrush" Color="#E2E8F0"/>
|
||||
<SolidColorBrush x:Key="ErrorBrush" Color="#E53E3E"/>
|
||||
<SolidColorBrush x:Key="CardBackground" Color="#FFFFFF"/>
|
||||
|
||||
<Style x:Key="CardBorder" TargetType="Border">
|
||||
<Setter Property="Background" Value="{StaticResource CardBackground}"/>
|
||||
<Setter Property="CornerRadius" Value="16"/>
|
||||
<Setter Property="Padding" Value="20"/>
|
||||
<Setter Property="Margin" Value="0,0,0,18"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SecondaryButton" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="{StaticResource PrimaryText}"/>
|
||||
<Setter Property="Background" Value="#FFFFFF"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Padding" Value="16,9"/>
|
||||
<Setter Property="MinHeight" Value="36"/>
|
||||
<Setter Property="MinWidth" Value="100"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="BackButton" TargetType="Button" BasedOn="{StaticResource SecondaryButton}">
|
||||
<Setter Property="Padding" Value="18,10"/>
|
||||
<Setter Property="MinWidth" Value="100"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ModernComboBox" TargetType="ComboBox">
|
||||
<Setter Property="Padding" Value="10,4"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="MinHeight" Value="34"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ModernDataGrid" TargetType="DataGrid">
|
||||
<Setter Property="AutoGenerateColumns" Value="False"/>
|
||||
<Setter Property="CanUserAddRows" Value="False"/>
|
||||
<Setter Property="CanUserDeleteRows" Value="False"/>
|
||||
<Setter Property="IsReadOnly" Value="True"/>
|
||||
<Setter Property="HeadersVisibility" Value="Column"/>
|
||||
<Setter Property="GridLinesVisibility" Value="None"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="RowBackground" Value="White"/>
|
||||
<Setter Property="AlternatingRowBackground" Value="#F7FAFC"/>
|
||||
<Setter Property="RowHeight" Value="44"/>
|
||||
<Setter Property="ColumnHeaderHeight" Value="44"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#F4F7FB">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header -->
|
||||
<Grid Grid.Row="0" Margin="24,20,24,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Column="0"
|
||||
Command="{Binding BackCommand}"
|
||||
Style="{StaticResource BackButton}"
|
||||
Content="← Back"/>
|
||||
|
||||
<StackPanel Grid.Column="1" Margin="16,0,0,0" VerticalAlignment="Center">
|
||||
<TextBlock Text="Meal Schedules"
|
||||
FontSize="24"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{StaticResource PrimaryText}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="2"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock Text="Site"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"
|
||||
Foreground="{StaticResource MutedText}"
|
||||
FontSize="13"/>
|
||||
<ComboBox ItemsSource="{Binding SiteFilterChoices}"
|
||||
SelectedItem="{Binding SelectedSiteFilter, Mode=TwoWay}"
|
||||
MinWidth="100"
|
||||
Style="{StaticResource ModernComboBox}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- Content -->
|
||||
<ScrollViewer Grid.Row="1"
|
||||
Margin="24,0,24,16"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<Border Style="{StaticResource CardBorder}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Margin="0,0,0,12">
|
||||
<TextBlock Text="Meal Schedules"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{StaticResource PrimaryText}"/>
|
||||
<TextBlock Text="View-only mode - configured meal windows per site"
|
||||
FontSize="12"
|
||||
Foreground="{StaticResource MutedText}"/>
|
||||
</StackPanel>
|
||||
|
||||
<DataGrid Grid.Row="1"
|
||||
Style="{StaticResource ModernDataGrid}"
|
||||
ItemsSource="{Binding Schedules}"
|
||||
SelectedItem="{Binding SelectedSchedule, Mode=TwoWay}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Site"
|
||||
Binding="{Binding LocationSiteId}"
|
||||
Width="*"/>
|
||||
<DataGridTextColumn Header="Session"
|
||||
Binding="{Binding MealName}"
|
||||
Width="*"/>
|
||||
<DataGridTextColumn Header="Start Time"
|
||||
Binding="{Binding StartTime}"
|
||||
Width="*"/>
|
||||
<DataGridTextColumn Header="End Time"
|
||||
Binding="{Binding EndTime}"
|
||||
Width="*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- Message -->
|
||||
<Border Grid.Row="2"
|
||||
Margin="24,0,24,20"
|
||||
Background="Transparent">
|
||||
<TextBlock Text="{Binding Message}" FontSize="14">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource PrimaryText}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsError}" Value="True">
|
||||
<Setter Property="Foreground" Value="{StaticResource ErrorBrush}"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Message}" Value="">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
Loading…
Reference in New Issue