From 1f90ad3a4fab98a8d6f0cca9ba48e4407cecea49 Mon Sep 17 00:00:00 2001 From: joeprogrammer88 Date: Tue, 31 Mar 2026 07:54:49 -0700 Subject: [PATCH 01/11] Initial features implemented --- SarahsDailyApp.slnx | 7 +- SarahsDailyApp/App.xaml | 14 + SarahsDailyApp/AppShell.xaml | 37 +- SarahsDailyApp/AppShell.xaml.cs | 13 +- .../BoolToStrikethroughConverter.cs | 16 + .../Converters/InverseBoolConverter.cs | 12 + SarahsDailyApp/Converters/ValueConverters.cs | 103 ++ SarahsDailyApp/MainPage.xaml | 36 - SarahsDailyApp/MainPage.xaml.cs | 24 - SarahsDailyApp/MauiProgram.cs | 58 +- SarahsDailyApp/Models/AppSettings.cs | 12 + SarahsDailyApp/Models/Category.cs | 12 + SarahsDailyApp/Models/FinanceItem.cs | 45 + SarahsDailyApp/Models/Habit.cs | 40 + SarahsDailyApp/Models/HabitLog.cs | 17 + SarahsDailyApp/Models/Note.cs | 18 + SarahsDailyApp/Models/Project.cs | 18 + SarahsDailyApp/Models/ShoppingItem.cs | 18 + SarahsDailyApp/Models/TaskItem.cs | 57 ++ SarahsDailyApp/Models/UserStats.cs | 16 + SarahsDailyApp/Models/WishItem.cs | 24 + SarahsDailyApp/Models/WishList.cs | 16 + SarahsDailyApp/SarahsDailyApp.csproj | 7 +- SarahsDailyApp/Services/CategoryService.cs | 61 ++ SarahsDailyApp/Services/DatabaseService.cs | 68 ++ .../Services/ExportImportService.cs | 146 +++ SarahsDailyApp/Services/FinanceService.cs | 50 + SarahsDailyApp/Services/HabitService.cs | 111 +++ SarahsDailyApp/Services/NoteService.cs | 42 + SarahsDailyApp/Services/ProjectService.cs | 44 + SarahsDailyApp/Services/ShoppingService.cs | 47 + SarahsDailyApp/Services/TaskService.cs | 122 +++ SarahsDailyApp/Services/UserStatsService.cs | 61 ++ SarahsDailyApp/Services/WishListService.cs | 98 ++ .../ViewModels/DashboardViewModel.cs | 177 ++++ .../ViewModels/FinanceDetailViewModel.cs | 118 +++ .../ViewModels/FinancesViewModel.cs | 94 ++ .../ViewModels/HabitDetailViewModel.cs | 132 +++ SarahsDailyApp/ViewModels/HabitsViewModel.cs | 83 ++ .../ViewModels/NoteDetailViewModel.cs | 66 ++ SarahsDailyApp/ViewModels/NotesViewModel.cs | 32 + .../ViewModels/ProjectDetailViewModel.cs | 75 ++ .../ViewModels/ProjectsViewModel.cs | 58 ++ .../ViewModels/SettingsViewModel.cs | 168 ++++ .../ViewModels/ShoppingItemDetailViewModel.cs | 67 ++ .../ViewModels/ShoppingListViewModel.cs | 50 + .../ViewModels/TaskDetailViewModel.cs | 172 ++++ SarahsDailyApp/ViewModels/TasksViewModel.cs | 145 +++ .../ViewModels/WishItemDetailViewModel.cs | 89 ++ .../ViewModels/WishListViewModel.cs | 123 +++ SarahsDailyApp/Views/DashboardPage.xaml | 132 +++ SarahsDailyApp/Views/DashboardPage.xaml.cs | 20 + SarahsDailyApp/Views/FinanceDetailPage.xaml | 44 + .../Views/FinanceDetailPage.xaml.cs | 20 + SarahsDailyApp/Views/FinancesPage.xaml | 133 +++ SarahsDailyApp/Views/FinancesPage.xaml.cs | 20 + SarahsDailyApp/Views/HabitDetailPage.xaml | 89 ++ SarahsDailyApp/Views/HabitDetailPage.xaml.cs | 28 + SarahsDailyApp/Views/HabitsPage.xaml | 61 ++ SarahsDailyApp/Views/HabitsPage.xaml.cs | 20 + SarahsDailyApp/Views/NoteDetailPage.xaml | 26 + SarahsDailyApp/Views/NoteDetailPage.xaml.cs | 20 + SarahsDailyApp/Views/NotesPage.xaml | 48 + SarahsDailyApp/Views/NotesPage.xaml.cs | 20 + SarahsDailyApp/Views/ProjectDetailPage.xaml | 34 + .../Views/ProjectDetailPage.xaml.cs | 20 + SarahsDailyApp/Views/ProjectsPage.xaml | 44 + SarahsDailyApp/Views/ProjectsPage.xaml.cs | 20 + SarahsDailyApp/Views/SettingsPage.xaml | 82 ++ SarahsDailyApp/Views/SettingsPage.xaml.cs | 20 + .../Views/ShoppingItemDetailPage.xaml | 28 + .../Views/ShoppingItemDetailPage.xaml.cs | 20 + SarahsDailyApp/Views/ShoppingListPage.xaml | 59 ++ SarahsDailyApp/Views/ShoppingListPage.xaml.cs | 20 + SarahsDailyApp/Views/TaskDetailPage.xaml | 84 ++ SarahsDailyApp/Views/TaskDetailPage.xaml.cs | 20 + SarahsDailyApp/Views/TasksPage.xaml | 102 ++ SarahsDailyApp/Views/TasksPage.xaml.cs | 20 + SarahsDailyApp/Views/WishItemDetailPage.xaml | 37 + .../Views/WishItemDetailPage.xaml.cs | 20 + SarahsDailyApp/Views/WishListPage.xaml | 84 ++ SarahsDailyApp/Views/WishListPage.xaml.cs | 28 + Spec.md | 886 ++++++++++++++++++ 83 files changed, 5357 insertions(+), 71 deletions(-) create mode 100644 SarahsDailyApp/Converters/BoolToStrikethroughConverter.cs create mode 100644 SarahsDailyApp/Converters/InverseBoolConverter.cs create mode 100644 SarahsDailyApp/Converters/ValueConverters.cs delete mode 100644 SarahsDailyApp/MainPage.xaml delete mode 100644 SarahsDailyApp/MainPage.xaml.cs create mode 100644 SarahsDailyApp/Models/AppSettings.cs create mode 100644 SarahsDailyApp/Models/Category.cs create mode 100644 SarahsDailyApp/Models/FinanceItem.cs create mode 100644 SarahsDailyApp/Models/Habit.cs create mode 100644 SarahsDailyApp/Models/HabitLog.cs create mode 100644 SarahsDailyApp/Models/Note.cs create mode 100644 SarahsDailyApp/Models/Project.cs create mode 100644 SarahsDailyApp/Models/ShoppingItem.cs create mode 100644 SarahsDailyApp/Models/TaskItem.cs create mode 100644 SarahsDailyApp/Models/UserStats.cs create mode 100644 SarahsDailyApp/Models/WishItem.cs create mode 100644 SarahsDailyApp/Models/WishList.cs create mode 100644 SarahsDailyApp/Services/CategoryService.cs create mode 100644 SarahsDailyApp/Services/DatabaseService.cs create mode 100644 SarahsDailyApp/Services/ExportImportService.cs create mode 100644 SarahsDailyApp/Services/FinanceService.cs create mode 100644 SarahsDailyApp/Services/HabitService.cs create mode 100644 SarahsDailyApp/Services/NoteService.cs create mode 100644 SarahsDailyApp/Services/ProjectService.cs create mode 100644 SarahsDailyApp/Services/ShoppingService.cs create mode 100644 SarahsDailyApp/Services/TaskService.cs create mode 100644 SarahsDailyApp/Services/UserStatsService.cs create mode 100644 SarahsDailyApp/Services/WishListService.cs create mode 100644 SarahsDailyApp/ViewModels/DashboardViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/FinanceDetailViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/FinancesViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/HabitDetailViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/HabitsViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/NoteDetailViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/NotesViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/ProjectDetailViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/ProjectsViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/SettingsViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/ShoppingItemDetailViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/ShoppingListViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/TaskDetailViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/TasksViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/WishItemDetailViewModel.cs create mode 100644 SarahsDailyApp/ViewModels/WishListViewModel.cs create mode 100644 SarahsDailyApp/Views/DashboardPage.xaml create mode 100644 SarahsDailyApp/Views/DashboardPage.xaml.cs create mode 100644 SarahsDailyApp/Views/FinanceDetailPage.xaml create mode 100644 SarahsDailyApp/Views/FinanceDetailPage.xaml.cs create mode 100644 SarahsDailyApp/Views/FinancesPage.xaml create mode 100644 SarahsDailyApp/Views/FinancesPage.xaml.cs create mode 100644 SarahsDailyApp/Views/HabitDetailPage.xaml create mode 100644 SarahsDailyApp/Views/HabitDetailPage.xaml.cs create mode 100644 SarahsDailyApp/Views/HabitsPage.xaml create mode 100644 SarahsDailyApp/Views/HabitsPage.xaml.cs create mode 100644 SarahsDailyApp/Views/NoteDetailPage.xaml create mode 100644 SarahsDailyApp/Views/NoteDetailPage.xaml.cs create mode 100644 SarahsDailyApp/Views/NotesPage.xaml create mode 100644 SarahsDailyApp/Views/NotesPage.xaml.cs create mode 100644 SarahsDailyApp/Views/ProjectDetailPage.xaml create mode 100644 SarahsDailyApp/Views/ProjectDetailPage.xaml.cs create mode 100644 SarahsDailyApp/Views/ProjectsPage.xaml create mode 100644 SarahsDailyApp/Views/ProjectsPage.xaml.cs create mode 100644 SarahsDailyApp/Views/SettingsPage.xaml create mode 100644 SarahsDailyApp/Views/SettingsPage.xaml.cs create mode 100644 SarahsDailyApp/Views/ShoppingItemDetailPage.xaml create mode 100644 SarahsDailyApp/Views/ShoppingItemDetailPage.xaml.cs create mode 100644 SarahsDailyApp/Views/ShoppingListPage.xaml create mode 100644 SarahsDailyApp/Views/ShoppingListPage.xaml.cs create mode 100644 SarahsDailyApp/Views/TaskDetailPage.xaml create mode 100644 SarahsDailyApp/Views/TaskDetailPage.xaml.cs create mode 100644 SarahsDailyApp/Views/TasksPage.xaml create mode 100644 SarahsDailyApp/Views/TasksPage.xaml.cs create mode 100644 SarahsDailyApp/Views/WishItemDetailPage.xaml create mode 100644 SarahsDailyApp/Views/WishItemDetailPage.xaml.cs create mode 100644 SarahsDailyApp/Views/WishListPage.xaml create mode 100644 SarahsDailyApp/Views/WishListPage.xaml.cs create mode 100644 Spec.md diff --git a/SarahsDailyApp.slnx b/SarahsDailyApp.slnx index 3080fe6..1facaf6 100644 --- a/SarahsDailyApp.slnx +++ b/SarahsDailyApp.slnx @@ -1,3 +1,8 @@ - + + + + + + diff --git a/SarahsDailyApp/App.xaml b/SarahsDailyApp/App.xaml index 329ef40..6b19106 100644 --- a/SarahsDailyApp/App.xaml +++ b/SarahsDailyApp/App.xaml @@ -2,6 +2,7 @@ @@ -9,6 +10,19 @@ + + + + + + + + + + + + + diff --git a/SarahsDailyApp/AppShell.xaml b/SarahsDailyApp/AppShell.xaml index 8790d92..f1b9223 100644 --- a/SarahsDailyApp/AppShell.xaml +++ b/SarahsDailyApp/AppShell.xaml @@ -3,12 +3,37 @@ x:Class="SarahsDailyApp.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" - xmlns:local="clr-namespace:SarahsDailyApp" - Title="SarahsDailyApp"> + xmlns:views="clr-namespace:SarahsDailyApp.Views" + Title="πŸ“‹ Task Manager"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SarahsDailyApp/AppShell.xaml.cs b/SarahsDailyApp/AppShell.xaml.cs index 0616858..80b0549 100644 --- a/SarahsDailyApp/AppShell.xaml.cs +++ b/SarahsDailyApp/AppShell.xaml.cs @@ -1,10 +1,21 @@ -ο»Ώnamespace SarahsDailyApp +ο»Ώusing SarahsDailyApp.Views; + +namespace SarahsDailyApp { public partial class AppShell : Shell { public AppShell() { InitializeComponent(); + + // Register detail page routes for navigation + Routing.RegisterRoute(nameof(TaskDetailPage), typeof(TaskDetailPage)); + Routing.RegisterRoute(nameof(ProjectDetailPage), typeof(ProjectDetailPage)); + Routing.RegisterRoute(nameof(HabitDetailPage), typeof(HabitDetailPage)); + Routing.RegisterRoute(nameof(FinanceDetailPage), typeof(FinanceDetailPage)); + Routing.RegisterRoute(nameof(WishItemDetailPage), typeof(WishItemDetailPage)); + Routing.RegisterRoute(nameof(ShoppingItemDetailPage), typeof(ShoppingItemDetailPage)); + Routing.RegisterRoute(nameof(NoteDetailPage), typeof(NoteDetailPage)); } } } diff --git a/SarahsDailyApp/Converters/BoolToStrikethroughConverter.cs b/SarahsDailyApp/Converters/BoolToStrikethroughConverter.cs new file mode 100644 index 0000000..95360ec --- /dev/null +++ b/SarahsDailyApp/Converters/BoolToStrikethroughConverter.cs @@ -0,0 +1,16 @@ +using System.Globalization; + +namespace SarahsDailyApp.Converters; + +public class BoolToStrikethroughConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is bool completed && completed) + return TextDecorations.Strikethrough; + return TextDecorations.None; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} diff --git a/SarahsDailyApp/Converters/InverseBoolConverter.cs b/SarahsDailyApp/Converters/InverseBoolConverter.cs new file mode 100644 index 0000000..3fb52a8 --- /dev/null +++ b/SarahsDailyApp/Converters/InverseBoolConverter.cs @@ -0,0 +1,12 @@ +using System.Globalization; + +namespace SarahsDailyApp.Converters; + +public class InverseBoolConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is bool b ? !b : value; + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is bool b ? !b : value; +} diff --git a/SarahsDailyApp/Converters/ValueConverters.cs b/SarahsDailyApp/Converters/ValueConverters.cs new file mode 100644 index 0000000..8b3933b --- /dev/null +++ b/SarahsDailyApp/Converters/ValueConverters.cs @@ -0,0 +1,103 @@ +using System.Globalization; +using SarahsDailyApp.Models; + +namespace SarahsDailyApp.Converters; + +/// Converts a percentage (0–100) to a ProgressBar progress value (0.0–1.0). +public class PercentToProgressConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is double pct ? pct / 100.0 : 0.0; + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Returns true when the value is not null (and not empty string). +public class IsNotNullConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is not null && (value is not string s || !string.IsNullOrEmpty(s)); + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Returns true when an int value is not zero. +public class IsNotZeroConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is int i && i != 0; + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Returns true when a RepeatType is not None. +public class IsNotNoneConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is RepeatType rt && rt != RepeatType.None; + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Maps a completed bool to a status color. +public class StatusColorConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is bool completed && completed + ? Color.FromArgb("#4CAF50") + : Color.FromArgb("#FF9800"); + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Maps a completed bool to a status text. +public class StatusTextConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is bool completed && completed ? "completed" : "pending"; + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Maps a bool (IsComplete) to a color for completion status text. +public class CompletionColorConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is bool complete && complete + ? Color.FromArgb("#4CAF50") + : Color.FromArgb("#FF9800"); + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Maps a bool (CanComplete) to an action button color. +public class ActionButtonColorConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + => value is bool can && can + ? Color.FromArgb("#4CAF50") + : Color.FromArgb("#9E9E9E"); + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Converts IsEditing bool to "Edit {Parameter}" or "Add {Parameter}" title. +public class EditTitleConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + var entity = parameter as string ?? "Item"; + return value is bool editing && editing ? $"Edit {entity}" : $"Add {entity}"; + } + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotImplementedException(); +} diff --git a/SarahsDailyApp/MainPage.xaml b/SarahsDailyApp/MainPage.xaml deleted file mode 100644 index e8fa7d6..0000000 --- a/SarahsDailyApp/MainPage.xaml +++ /dev/null @@ -1,36 +0,0 @@ -ο»Ώ - - - - - - -