From d8a19d9cedc01b11c8025bcd789891f68aea28a2 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 2 Feb 2026 05:32:23 -0500 Subject: [PATCH 01/23] Main Menu interface completed --- Flashcards.davetn657/Enums/OptionUtils.cs | 34 ++++++++++ Flashcards.davetn657/Enums/Options.cs | 12 ++++ .../Flashcards.davetn657.csproj | 14 ++++ Flashcards.davetn657/Flashcards.davetn657.sln | 25 ++++++++ Flashcards.davetn657/Program.cs | 11 ++++ Flashcards.davetn657/UserInterface.cs | 64 +++++++++++++++++++ 6 files changed, 160 insertions(+) create mode 100644 Flashcards.davetn657/Enums/OptionUtils.cs create mode 100644 Flashcards.davetn657/Enums/Options.cs create mode 100644 Flashcards.davetn657/Flashcards.davetn657.csproj create mode 100644 Flashcards.davetn657/Flashcards.davetn657.sln create mode 100644 Flashcards.davetn657/Program.cs create mode 100644 Flashcards.davetn657/UserInterface.cs diff --git a/Flashcards.davetn657/Enums/OptionUtils.cs b/Flashcards.davetn657/Enums/OptionUtils.cs new file mode 100644 index 00000000..c0b5e3a2 --- /dev/null +++ b/Flashcards.davetn657/Enums/OptionUtils.cs @@ -0,0 +1,34 @@ +using System.ComponentModel; +using System.Reflection; + +namespace Flashcards.davetn657.Enums; +public class OptionUtils +{ + public static string GetStringValue(Enum value) + { + FieldInfo? info = value.GetType().GetField(value.ToString()); + DescriptionAttribute[] attributes = (DescriptionAttribute[])info.GetCustomAttributes(typeof(DescriptionAttribute), false); + if (attributes.Length > 0) + { + return attributes[0].Description; + } + else + { + return string.Empty; + } + } + + public static Enum GetEnumValue(string description, Type enumType) + { + var enumValues = enumType.GetEnumValues(); + + foreach (var value in enumValues) + { + if(GetStringValue((Enum)value).Equals(description)) + { + return (Enum)value; + } + } + throw new Exception("Not Found."); + } +} diff --git a/Flashcards.davetn657/Enums/Options.cs b/Flashcards.davetn657/Enums/Options.cs new file mode 100644 index 00000000..0ba6b050 --- /dev/null +++ b/Flashcards.davetn657/Enums/Options.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; +using System.Reflection; + +namespace Flashcards.davetn657.Enums; + +public enum MainMenuOptions +{ + [Description("Create a Stack")]CreateStack, + [Description("Manage Stacks")] ManageStack, + [Description("Study Sessions")] StudySession +} + diff --git a/Flashcards.davetn657/Flashcards.davetn657.csproj b/Flashcards.davetn657/Flashcards.davetn657.csproj new file mode 100644 index 00000000..354a3ae4 --- /dev/null +++ b/Flashcards.davetn657/Flashcards.davetn657.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + diff --git a/Flashcards.davetn657/Flashcards.davetn657.sln b/Flashcards.davetn657/Flashcards.davetn657.sln new file mode 100644 index 00000000..3e93d416 --- /dev/null +++ b/Flashcards.davetn657/Flashcards.davetn657.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36705.20 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flashcards.davetn657", "Flashcards.davetn657.csproj", "{24ED61BB-F123-42B5-BDBD-81949CE56058}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {24ED61BB-F123-42B5-BDBD-81949CE56058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24ED61BB-F123-42B5-BDBD-81949CE56058}.Debug|Any CPU.Build.0 = Debug|Any CPU + {24ED61BB-F123-42B5-BDBD-81949CE56058}.Release|Any CPU.ActiveCfg = Release|Any CPU + {24ED61BB-F123-42B5-BDBD-81949CE56058}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {67AA5100-C966-4C99-9966-C07253D916DA} + EndGlobalSection +EndGlobal diff --git a/Flashcards.davetn657/Program.cs b/Flashcards.davetn657/Program.cs new file mode 100644 index 00000000..3a424d0f --- /dev/null +++ b/Flashcards.davetn657/Program.cs @@ -0,0 +1,11 @@ +namespace Flashcards.davetn657 +{ + class Program + { + static void Main(string[] args) + { + UserInterface ui = new UserInterface(); + ui.MainMenu(); + } + } +} \ No newline at end of file diff --git a/Flashcards.davetn657/UserInterface.cs b/Flashcards.davetn657/UserInterface.cs new file mode 100644 index 00000000..58f77a5c --- /dev/null +++ b/Flashcards.davetn657/UserInterface.cs @@ -0,0 +1,64 @@ +using Spectre.Console; +using Flashcards.davetn657; +using Flashcards.davetn657.Enums; + +namespace Flashcards.davetn657; +public class UserInterface +{ + public void MainMenu() + { + TitlePanel("Main Menu"); + + string[] menuOptions = new string[] + { + OptionUtils.GetStringValue(MainMenuOptions.CreateStack), + OptionUtils.GetStringValue(MainMenuOptions.ManageStack), + OptionUtils.GetStringValue(MainMenuOptions.StudySession) + }; + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var menuOption = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); + + + switch (menuOption) + { + case MainMenuOptions.CreateStack: + CreateStack(); + break; + case MainMenuOptions.ManageStack: + break; + case MainMenuOptions.StudySession: + break; + } + } + + internal void CreateStack() + { + TitlePanel("Create a New Stack"); + } + + internal void ManageStack() + { + TitlePanel("Manage Stacks"); + } + + internal void StudySession() + { + TitlePanel("Study Session"); + } + + private void TitlePanel(string title) + { + var titlePanel = new Panel(title) + { + Border = BoxBorder.Double, + Padding = new Padding(2, 0) + }; + + AnsiConsole.Clear(); + AnsiConsole.Write(titlePanel); + } + + +} + From 5d37e2701661669c704002596e7db0c58f5caa62 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Fri, 6 Feb 2026 17:30:02 -0500 Subject: [PATCH 02/23] Created new Option Utility to return all Description Values of an Enum type --- .../Controllers/StackController.cs | 31 +++++++++++++ Flashcards.davetn657/Enums/OptionUtils.cs | 15 +++++++ Flashcards.davetn657/Enums/Options.cs | 6 ++- .../Flashcards.davetn657.csproj | 2 + Flashcards.davetn657/UserInterface.cs | 45 ++++++++++++------- Flashcards.davetn657/Validation.cs | 5 +++ Flashcards.davetn657/appsetting.json | 5 +++ 7 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 Flashcards.davetn657/Controllers/StackController.cs create mode 100644 Flashcards.davetn657/Validation.cs create mode 100644 Flashcards.davetn657/appsetting.json diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs new file mode 100644 index 00000000..6a1e4d78 --- /dev/null +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.Configuration; + +namespace Flashcards.davetn657.Controllers; +public class StackController +{ + private static readonly IConfiguration _configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appseting.json") + .Build(); + private string? _connection = _configuration.GetConnectionString("DatabaseConnection"); + + public void AddStack() + { + + } + + public void RemoveStack() + { + + } + + public void EditStack() + { + + } + + public void ReadAllStacks() + { + + } +} diff --git a/Flashcards.davetn657/Enums/OptionUtils.cs b/Flashcards.davetn657/Enums/OptionUtils.cs index c0b5e3a2..1182d463 100644 --- a/Flashcards.davetn657/Enums/OptionUtils.cs +++ b/Flashcards.davetn657/Enums/OptionUtils.cs @@ -18,6 +18,19 @@ public static string GetStringValue(Enum value) } } + public static string[] GetAllStringValues(Type enumType) + { + var enumValues = enumType.GetEnumValues(); + List allValues = new List(); + + foreach (var value in enumValues) + { + allValues.Add(GetStringValue((Enum)value)); + } + + return allValues.ToArray(); + } + public static Enum GetEnumValue(string description, Type enumType) { var enumValues = enumType.GetEnumValues(); @@ -31,4 +44,6 @@ public static Enum GetEnumValue(string description, Type enumType) } throw new Exception("Not Found."); } + + } diff --git a/Flashcards.davetn657/Enums/Options.cs b/Flashcards.davetn657/Enums/Options.cs index 0ba6b050..81ae93e9 100644 --- a/Flashcards.davetn657/Enums/Options.cs +++ b/Flashcards.davetn657/Enums/Options.cs @@ -5,8 +5,12 @@ namespace Flashcards.davetn657.Enums; public enum MainMenuOptions { - [Description("Create a Stack")]CreateStack, [Description("Manage Stacks")] ManageStack, [Description("Study Sessions")] StudySession } +public enum ManageStackOptions +{ + [Description("Create Stack")] CreateStack, + [Description("Or Choose a Stack to Edit")]ChooseStack +}; \ No newline at end of file diff --git a/Flashcards.davetn657/Flashcards.davetn657.csproj b/Flashcards.davetn657/Flashcards.davetn657.csproj index 354a3ae4..63abfdb6 100644 --- a/Flashcards.davetn657/Flashcards.davetn657.csproj +++ b/Flashcards.davetn657/Flashcards.davetn657.csproj @@ -8,6 +8,8 @@ + + diff --git a/Flashcards.davetn657/UserInterface.cs b/Flashcards.davetn657/UserInterface.cs index 58f77a5c..e2ee490a 100644 --- a/Flashcards.davetn657/UserInterface.cs +++ b/Flashcards.davetn657/UserInterface.cs @@ -9,40 +9,55 @@ public void MainMenu() { TitlePanel("Main Menu"); - string[] menuOptions = new string[] - { - OptionUtils.GetStringValue(MainMenuOptions.CreateStack), - OptionUtils.GetStringValue(MainMenuOptions.ManageStack), - OptionUtils.GetStringValue(MainMenuOptions.StudySession) - }; + string[] menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var menuOption = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); + var inputValue = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); - switch (menuOption) + switch (inputValue) { - case MainMenuOptions.CreateStack: - CreateStack(); - break; case MainMenuOptions.ManageStack: + ManageStack(); break; case MainMenuOptions.StudySession: break; } } - internal void CreateStack() + private void ManageStack() + { + TitlePanel("Manage Stacks"); + + string[] menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var inputValue = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); + + switch (inputValue) + { + case ManageStackOptions.CreateStack: + CreateStack(); + break; + case ManageStackOptions.ChooseStack: + ChooseStack(); + break; + } + } + + private void CreateStack() { TitlePanel("Create a New Stack"); + + var input = AnsiConsole.Ask("Name your Stack:"); } - internal void ManageStack() + private void ChooseStack() { - TitlePanel("Manage Stacks"); + TitlePanel("Choose a Stack to Edit"); } - internal void StudySession() + private void StudySession() { TitlePanel("Study Session"); } diff --git a/Flashcards.davetn657/Validation.cs b/Flashcards.davetn657/Validation.cs new file mode 100644 index 00000000..d108e9ae --- /dev/null +++ b/Flashcards.davetn657/Validation.cs @@ -0,0 +1,5 @@ +namespace Flashcards.davetn657; +public class Validation +{ + +} diff --git a/Flashcards.davetn657/appsetting.json b/Flashcards.davetn657/appsetting.json new file mode 100644 index 00000000..8a3b9db2 --- /dev/null +++ b/Flashcards.davetn657/appsetting.json @@ -0,0 +1,5 @@ +{ + "ConnectionStrings": { + "DatabaseConnection": "Server=(localbd)\\Flashcards;Database=FlashcardsDB;TrustServerCertificate=True;" + } +} \ No newline at end of file From 218fcb52e627a3e8b34ed38e8ffa9f6260fb74df Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 05:31:10 -0500 Subject: [PATCH 03/23] working stack creation and viewing functionality --- .../Controllers/StackController.cs | 67 ++++++++++++++++--- Flashcards.davetn657/DTOs/StackDTO.cs | 6 ++ Flashcards.davetn657/Enums/Options.cs | 5 +- .../Flashcards.davetn657.csproj | 1 + Flashcards.davetn657/Globals.cs | 7 ++ Flashcards.davetn657/Program.cs | 4 +- .../Properties/launchSettings.json | 8 +++ Flashcards.davetn657/UserInterface.cs | 55 +++++++++++---- .../{appsetting.json => appsettings.json} | 2 +- 9 files changed, 129 insertions(+), 26 deletions(-) create mode 100644 Flashcards.davetn657/DTOs/StackDTO.cs create mode 100644 Flashcards.davetn657/Globals.cs create mode 100644 Flashcards.davetn657/Properties/launchSettings.json rename Flashcards.davetn657/{appsetting.json => appsettings.json} (54%) diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index 6a1e4d78..ab538e1f 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -1,17 +1,43 @@ -using Microsoft.Extensions.Configuration; +using Flashcards.davetn657.DTOs; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; +using System.Data; namespace Flashcards.davetn657.Controllers; public class StackController { - private static readonly IConfiguration _configuration = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appseting.json") - .Build(); - private string? _connection = _configuration.GetConnectionString("DatabaseConnection"); + private IConfiguration configuration; + private string? connectionString; - public void AddStack() + public StackController() { - + this.configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + this.connectionString = configuration.GetConnectionString("DatabaseConnection"); + } + + public void AddStack(string name) + { + using(var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + + tableCmd.CommandText = @"INSERT INTO STACKS (StackName, CreateDate) + VALUES (@Name, @Date)"; + + var currentDate = DateTime.Now.ToString(Globals.CULTURE_INFO); + + tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = name; + tableCmd.Parameters.Add("@Date", SqlDbType.DateTime2).Value = currentDate; + + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } } public void RemoveStack() @@ -24,8 +50,31 @@ public void EditStack() } - public void ReadAllStacks() + public List ReadAllStacks() { + var allStacks = new List(); + + using (SqlConnection connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"SELECT * FROM STACKS"; + + var reader = tableCmd.ExecuteReader(); + + while (reader.Read()) + { + var stack = new StackDTO(); + stack.Id = reader.GetInt32("StackId"); + stack.Name = reader.GetString("StackName"); + + allStacks.Add(stack); + } + + connection.Close(); + } + return allStacks; } } diff --git a/Flashcards.davetn657/DTOs/StackDTO.cs b/Flashcards.davetn657/DTOs/StackDTO.cs new file mode 100644 index 00000000..93991553 --- /dev/null +++ b/Flashcards.davetn657/DTOs/StackDTO.cs @@ -0,0 +1,6 @@ +namespace Flashcards.davetn657.DTOs; +public class StackDTO +{ + public int Id { get; set; } + public string Name { get; set; } +} diff --git a/Flashcards.davetn657/Enums/Options.cs b/Flashcards.davetn657/Enums/Options.cs index 81ae93e9..02e345cf 100644 --- a/Flashcards.davetn657/Enums/Options.cs +++ b/Flashcards.davetn657/Enums/Options.cs @@ -6,11 +6,12 @@ namespace Flashcards.davetn657.Enums; public enum MainMenuOptions { [Description("Manage Stacks")] ManageStack, - [Description("Study Sessions")] StudySession + [Description("Study Sessions")] StudySession, + [Description("Exit")] ExitApp } public enum ManageStackOptions { [Description("Create Stack")] CreateStack, - [Description("Or Choose a Stack to Edit")]ChooseStack + [Description("Choose a Stack to Edit")]ChooseStack }; \ No newline at end of file diff --git a/Flashcards.davetn657/Flashcards.davetn657.csproj b/Flashcards.davetn657/Flashcards.davetn657.csproj index 63abfdb6..25dea488 100644 --- a/Flashcards.davetn657/Flashcards.davetn657.csproj +++ b/Flashcards.davetn657/Flashcards.davetn657.csproj @@ -8,6 +8,7 @@ + diff --git a/Flashcards.davetn657/Globals.cs b/Flashcards.davetn657/Globals.cs new file mode 100644 index 00000000..f135995c --- /dev/null +++ b/Flashcards.davetn657/Globals.cs @@ -0,0 +1,7 @@ +using System.Globalization; + +namespace Flashcards.davetn657; +public class Globals +{ + public static readonly IFormatProvider CULTURE_INFO = new CultureInfo("en-US"); +} \ No newline at end of file diff --git a/Flashcards.davetn657/Program.cs b/Flashcards.davetn657/Program.cs index 3a424d0f..c365d748 100644 --- a/Flashcards.davetn657/Program.cs +++ b/Flashcards.davetn657/Program.cs @@ -2,10 +2,10 @@ { class Program { - static void Main(string[] args) + public static void Main(string[] args) { UserInterface ui = new UserInterface(); - ui.MainMenu(); + ui.StartApp(); } } } \ No newline at end of file diff --git a/Flashcards.davetn657/Properties/launchSettings.json b/Flashcards.davetn657/Properties/launchSettings.json new file mode 100644 index 00000000..30f1fad6 --- /dev/null +++ b/Flashcards.davetn657/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Flashcards.davetn657": { + "commandName": "Project", + "workingDirectory": "C:\\Users\\davei\\Documents\\.Coding\\.C#Academy\\CodeReviews.Console.Flashcards\\Flashcards.davetn657" + } + } +} \ No newline at end of file diff --git a/Flashcards.davetn657/UserInterface.cs b/Flashcards.davetn657/UserInterface.cs index e2ee490a..f5fe4a17 100644 --- a/Flashcards.davetn657/UserInterface.cs +++ b/Flashcards.davetn657/UserInterface.cs @@ -1,28 +1,45 @@ using Spectre.Console; using Flashcards.davetn657; using Flashcards.davetn657.Enums; +using Flashcards.davetn657.Controllers; namespace Flashcards.davetn657; public class UserInterface { - public void MainMenu() + private StackController stackController; + + public UserInterface() { - TitlePanel("Main Menu"); + stackController = new StackController(); + } - string[] menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); + public void StartApp() + { + var endApp = false; - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var inputValue = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); + while (!endApp) + { + TitlePanel("Main Menu"); + string[] menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); - switch (inputValue) - { - case MainMenuOptions.ManageStack: - ManageStack(); - break; - case MainMenuOptions.StudySession: - break; + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var inputValue = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); + + + switch (inputValue) + { + case MainMenuOptions.ManageStack: + ManageStack(); + break; + case MainMenuOptions.StudySession: + break; + case MainMenuOptions.ExitApp: + endApp = true; + break; + } } + } private void ManageStack() @@ -50,11 +67,25 @@ private void CreateStack() TitlePanel("Create a New Stack"); var input = AnsiConsole.Ask("Name your Stack:"); + stackController.AddStack(input); + + AnsiConsole.WriteLine($"Stack named {input} created!\n"); + AnsiConsole.Ask("Press Enter to Return"); } private void ChooseStack() { TitlePanel("Choose a Stack to Edit"); + + var allStacks = stackController.ReadAllStacks(); + var stacks = new List(); + + foreach (var stack in allStacks) + { + stacks.Add($"{stack.Id} {stack.Name}"); + } + + AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks)); } private void StudySession() diff --git a/Flashcards.davetn657/appsetting.json b/Flashcards.davetn657/appsettings.json similarity index 54% rename from Flashcards.davetn657/appsetting.json rename to Flashcards.davetn657/appsettings.json index 8a3b9db2..5f40f1b6 100644 --- a/Flashcards.davetn657/appsetting.json +++ b/Flashcards.davetn657/appsettings.json @@ -1,5 +1,5 @@ { "ConnectionStrings": { - "DatabaseConnection": "Server=(localbd)\\Flashcards;Database=FlashcardsDB;TrustServerCertificate=True;" + "DatabaseConnection": "Server=(localdb)\\Flashcards;Database=FlashcardsDB;TrustServerCertificate=True;" } } \ No newline at end of file From f1b0443a3ec25e5d6ef04aa9d6fc017f9a609de7 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 17:28:16 -0500 Subject: [PATCH 04/23] New title panel UI and choose stack UI --- Flashcards.davetn657/Enums/Options.cs | 12 +++++++++-- Flashcards.davetn657/UserInterface.cs | 29 +++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Flashcards.davetn657/Enums/Options.cs b/Flashcards.davetn657/Enums/Options.cs index 02e345cf..811bf786 100644 --- a/Flashcards.davetn657/Enums/Options.cs +++ b/Flashcards.davetn657/Enums/Options.cs @@ -13,5 +13,13 @@ public enum MainMenuOptions public enum ManageStackOptions { [Description("Create Stack")] CreateStack, - [Description("Choose a Stack to Edit")]ChooseStack -}; \ No newline at end of file + [Description("Edit Stack")]ChooseStack +}; + +public enum EditStackOptions +{ + [Description("Rename Stack")]RenameStack, + [Description("Add a Flashcard")]AddCard, + [Description("Remove a Flashcard")]RemoveCard, + [Description("Delete Stack")]DeleteStack +} \ No newline at end of file diff --git a/Flashcards.davetn657/UserInterface.cs b/Flashcards.davetn657/UserInterface.cs index f5fe4a17..abe634f2 100644 --- a/Flashcards.davetn657/UserInterface.cs +++ b/Flashcards.davetn657/UserInterface.cs @@ -49,9 +49,9 @@ private void ManageStack() string[] menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var inputValue = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); + var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); - switch (inputValue) + switch (optionSelected) { case ManageStackOptions.CreateStack: CreateStack(); @@ -82,10 +82,25 @@ private void ChooseStack() foreach (var stack in allStacks) { - stacks.Add($"{stack.Id} {stack.Name}"); + stacks.Add($"{stack.Name}"); } + stacks.Add("Return"); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks)); + + switch (input) + { + case "Return": + break; + default: + EditStack(input); + break; + } + } + + private void EditStack(string stackName) + { - AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks)); } private void StudySession() @@ -98,11 +113,13 @@ private void TitlePanel(string title) var titlePanel = new Panel(title) { Border = BoxBorder.Double, - Padding = new Padding(2, 0) + Padding = new Padding(20, 1) }; + var centered = Align.Center(titlePanel); + AnsiConsole.Clear(); - AnsiConsole.Write(titlePanel); + AnsiConsole.Write(centered); } From 40160cf2bb23ebcce3bcc2dd206b013893d0c81e Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 18:09:09 -0500 Subject: [PATCH 05/23] Added validation to stack name creation, changed datatype of readallstacks function to dictionary for faster lookup --- .../Controllers/StackController.cs | 6 +- Flashcards.davetn657/Enums/OptionUtils.cs | 4 +- Flashcards.davetn657/Enums/Options.cs | 3 +- Flashcards.davetn657/UserInterface.cs | 59 ++++++++++++++----- Flashcards.davetn657/Validation.cs | 14 ++++- 5 files changed, 62 insertions(+), 24 deletions(-) diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index ab538e1f..61341d63 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -50,9 +50,9 @@ public void EditStack() } - public List ReadAllStacks() + public Dictionary ReadAllStacks() { - var allStacks = new List(); + var allStacks = new Dictionary(); using (SqlConnection connection = new SqlConnection(connectionString)) { @@ -69,7 +69,7 @@ public List ReadAllStacks() stack.Id = reader.GetInt32("StackId"); stack.Name = reader.GetString("StackName"); - allStacks.Add(stack); + allStacks.Add(stack.Name, stack); } connection.Close(); diff --git a/Flashcards.davetn657/Enums/OptionUtils.cs b/Flashcards.davetn657/Enums/OptionUtils.cs index 1182d463..7426ed7d 100644 --- a/Flashcards.davetn657/Enums/OptionUtils.cs +++ b/Flashcards.davetn657/Enums/OptionUtils.cs @@ -18,7 +18,7 @@ public static string GetStringValue(Enum value) } } - public static string[] GetAllStringValues(Type enumType) + public static List GetAllStringValues(Type enumType) { var enumValues = enumType.GetEnumValues(); List allValues = new List(); @@ -28,7 +28,7 @@ public static string[] GetAllStringValues(Type enumType) allValues.Add(GetStringValue((Enum)value)); } - return allValues.ToArray(); + return allValues; } public static Enum GetEnumValue(string description, Type enumType) diff --git a/Flashcards.davetn657/Enums/Options.cs b/Flashcards.davetn657/Enums/Options.cs index 811bf786..61bdff0c 100644 --- a/Flashcards.davetn657/Enums/Options.cs +++ b/Flashcards.davetn657/Enums/Options.cs @@ -21,5 +21,6 @@ public enum EditStackOptions [Description("Rename Stack")]RenameStack, [Description("Add a Flashcard")]AddCard, [Description("Remove a Flashcard")]RemoveCard, - [Description("Delete Stack")]DeleteStack + [Description("Delete Stack")]DeleteStack, + [Description("Return")]Return } \ No newline at end of file diff --git a/Flashcards.davetn657/UserInterface.cs b/Flashcards.davetn657/UserInterface.cs index abe634f2..c656c14b 100644 --- a/Flashcards.davetn657/UserInterface.cs +++ b/Flashcards.davetn657/UserInterface.cs @@ -2,6 +2,7 @@ using Flashcards.davetn657; using Flashcards.davetn657.Enums; using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.DTOs; namespace Flashcards.davetn657; public class UserInterface @@ -21,7 +22,7 @@ public void StartApp() { TitlePanel("Main Menu"); - string[] menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); + var menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); var inputValue = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); @@ -46,7 +47,7 @@ private void ManageStack() { TitlePanel("Manage Stacks"); - string[] menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); + var menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); @@ -66,41 +67,67 @@ private void CreateStack() { TitlePanel("Create a New Stack"); - var input = AnsiConsole.Ask("Name your Stack:"); - stackController.AddStack(input); + var input = string.Empty; + + while (true) + { + input = AnsiConsole.Ask("Name your Stack:"); + + if (Validation.IsValidName(input, stackController.ReadAllStacks())) + { + stackController.AddStack(input); + break; + } + else + { + AnsiConsole.Markup("[red]Stack Name Already in Use Choose a Different Name![/]\n"); + } + } AnsiConsole.WriteLine($"Stack named {input} created!\n"); - AnsiConsole.Ask("Press Enter to Return"); + AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Press Enter to Return")); } private void ChooseStack() { TitlePanel("Choose a Stack to Edit"); - var allStacks = stackController.ReadAllStacks(); - var stacks = new List(); - - foreach (var stack in allStacks) - { - stacks.Add($"{stack.Name}"); - } - stacks.Add("Return"); + var stacks = stackController.ReadAllStacks(); - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks)); + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks.Keys) ); switch (input) { case "Return": break; default: - EditStack(input); + EditStack(stacks[input]); break; } } - private void EditStack(string stackName) + private void EditStack(StackDTO stackName) { + TitlePanel($"Edit : {stackName}"); + var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var optionSelected = OptionUtils.GetEnumValue(input, typeof(EditStackOptions)); + + switch (optionSelected) + { + case EditStackOptions.RenameStack: + break; + case EditStackOptions.AddCard: + break; + case EditStackOptions.RemoveCard: + break; + case EditStackOptions.DeleteStack: + break; + case EditStackOptions.Return: + break; + } } private void StudySession() diff --git a/Flashcards.davetn657/Validation.cs b/Flashcards.davetn657/Validation.cs index d108e9ae..8c773edc 100644 --- a/Flashcards.davetn657/Validation.cs +++ b/Flashcards.davetn657/Validation.cs @@ -1,5 +1,15 @@ -namespace Flashcards.davetn657; +using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.DTOs; + +namespace Flashcards.davetn657; public class Validation { - + public static bool IsValidName(string name, Dictionary stacks) + { + if (stacks.ContainsKey(name)) + { + return false; + } + return true; + } } From 97e6413c7d4a7f7246419d3d5e7412c07adf7180 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 18:17:49 -0500 Subject: [PATCH 06/23] working deletion of stack (need to add deletion of related cards) --- .../Controllers/CardController.cs | 6 ++++++ .../Controllers/StackController.cs | 20 +++++++++++++++++-- Flashcards.davetn657/UserInterface.cs | 8 +++++--- Flashcards.davetn657/Validation.cs | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 Flashcards.davetn657/Controllers/CardController.cs diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs new file mode 100644 index 00000000..5d9ccf88 --- /dev/null +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -0,0 +1,6 @@ +namespace Flashcards.davetn657.Controllers; + +public class CardController +{ + +} diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index 61341d63..81725029 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -40,12 +40,28 @@ public void AddStack(string name) } } - public void RemoveStack() + public void RemoveStack(StackDTO stack) { + using(SqlConnection connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"DELETE FROM STACKS + WHERE + StackId = @Id AND + StackName = @Name;"; + + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = stack.Id; + tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = stack.Name; + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } } - public void EditStack() + public void EditStack(StackDTO stack) { } diff --git a/Flashcards.davetn657/UserInterface.cs b/Flashcards.davetn657/UserInterface.cs index c656c14b..e37f89f6 100644 --- a/Flashcards.davetn657/UserInterface.cs +++ b/Flashcards.davetn657/UserInterface.cs @@ -73,7 +73,7 @@ private void CreateStack() { input = AnsiConsole.Ask("Name your Stack:"); - if (Validation.IsValidName(input, stackController.ReadAllStacks())) + if (Validation.IsValidStackName(input, stackController.ReadAllStacks())) { stackController.AddStack(input); break; @@ -106,9 +106,9 @@ private void ChooseStack() } } - private void EditStack(StackDTO stackName) + private void EditStack(StackDTO stack) { - TitlePanel($"Edit : {stackName}"); + TitlePanel($"Edit : {stack}"); var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); @@ -118,12 +118,14 @@ private void EditStack(StackDTO stackName) switch (optionSelected) { case EditStackOptions.RenameStack: + stackController.EditStack(stack); break; case EditStackOptions.AddCard: break; case EditStackOptions.RemoveCard: break; case EditStackOptions.DeleteStack: + stackController.RemoveStack(stack); break; case EditStackOptions.Return: break; diff --git a/Flashcards.davetn657/Validation.cs b/Flashcards.davetn657/Validation.cs index 8c773edc..10c3411f 100644 --- a/Flashcards.davetn657/Validation.cs +++ b/Flashcards.davetn657/Validation.cs @@ -4,7 +4,7 @@ namespace Flashcards.davetn657; public class Validation { - public static bool IsValidName(string name, Dictionary stacks) + public static bool IsValidStackName(string name, Dictionary stacks) { if (stacks.ContainsKey(name)) { From 20ca38e370e84bb0a65a17ff577a45c012f6d7c8 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 20:28:09 -0500 Subject: [PATCH 07/23] working create card UI --- .../Controllers/CardController.cs | 63 ++++++++++++++++- .../Controllers/StackController.cs | 7 +- Flashcards.davetn657/DTOs/StackDTO.cs | 6 -- Flashcards.davetn657/Models/DTOs/CardDTO.cs | 9 +++ Flashcards.davetn657/Models/DTOs/StackDTO.cs | 6 ++ .../{ => Models}/Enums/OptionUtils.cs | 2 +- .../{ => Models}/Enums/Options.cs | 5 +- Flashcards.davetn657/{ => Models}/Globals.cs | 2 +- Flashcards.davetn657/Program.cs | 16 ++--- Flashcards.davetn657/Validation.cs | 15 ---- .../{ => Views}/UserInterface.cs | 70 ++++++++++++++----- 11 files changed, 144 insertions(+), 57 deletions(-) delete mode 100644 Flashcards.davetn657/DTOs/StackDTO.cs create mode 100644 Flashcards.davetn657/Models/DTOs/CardDTO.cs create mode 100644 Flashcards.davetn657/Models/DTOs/StackDTO.cs rename Flashcards.davetn657/{ => Models}/Enums/OptionUtils.cs (96%) rename Flashcards.davetn657/{ => Models}/Enums/Options.cs (79%) rename Flashcards.davetn657/{ => Models}/Globals.cs (78%) delete mode 100644 Flashcards.davetn657/Validation.cs rename Flashcards.davetn657/{ => Views}/UserInterface.cs (64%) diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index 5d9ccf88..6484f453 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -1,6 +1,65 @@ -namespace Flashcards.davetn657.Controllers; +using Flashcards.davetn657.Models.DTOs; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; +using System.Data; + +namespace Flashcards.davetn657.Controllers; public class CardController -{ +{ + private IConfiguration configuration; + private string? connectionString; + + public CardController() + { + this.configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + this.connectionString = configuration.GetConnectionString("DatabaseConnection"); + } + + public void AddCard(CardDTO card) + { + + } + + public void RemoveCard() + { + + } + + public void EditCard() + { + + } + + public Dictionary ReadAllCards() + { + var allCards = new Dictionary(); + + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tabldCmd = connection.CreateCommand(); + tabldCmd.CommandText = @"SELECT * FROM CARDS"; + + var reader = tabldCmd.ExecuteReader(); + + while (reader.Read()) + { + var card = new CardDTO(); + card.Id = reader.GetInt32("CardId"); + card.Name = reader.GetString("CardName"); + card.Question = reader.GetString("CardQuestion"); + card.Answer = reader.GetString("CardAnswer"); + allCards.Add(card.Name, card); + } + + connection.Close(); + } + return allCards; + } } diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index 81725029..1b558d8f 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -1,4 +1,5 @@ -using Flashcards.davetn657.DTOs; +using Flashcards.davetn657.Models; +using Flashcards.davetn657.Models.DTOs; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Configuration; using System.Data; @@ -42,7 +43,7 @@ public void AddStack(string name) public void RemoveStack(StackDTO stack) { - using(SqlConnection connection = new SqlConnection(connectionString)) + using(var connection = new SqlConnection(connectionString)) { connection.Open(); @@ -70,7 +71,7 @@ public Dictionary ReadAllStacks() { var allStacks = new Dictionary(); - using (SqlConnection connection = new SqlConnection(connectionString)) + using (var connection = new SqlConnection(connectionString)) { connection.Open(); diff --git a/Flashcards.davetn657/DTOs/StackDTO.cs b/Flashcards.davetn657/DTOs/StackDTO.cs deleted file mode 100644 index 93991553..00000000 --- a/Flashcards.davetn657/DTOs/StackDTO.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Flashcards.davetn657.DTOs; -public class StackDTO -{ - public int Id { get; set; } - public string Name { get; set; } -} diff --git a/Flashcards.davetn657/Models/DTOs/CardDTO.cs b/Flashcards.davetn657/Models/DTOs/CardDTO.cs new file mode 100644 index 00000000..2ba75bba --- /dev/null +++ b/Flashcards.davetn657/Models/DTOs/CardDTO.cs @@ -0,0 +1,9 @@ +namespace Flashcards.davetn657.Models.DTOs; + +public class CardDTO +{ + public int Id { get; set; } + public string? Name { get; set; } + public string? Question { get; set; } + public string? Answer { get; set; } +} diff --git a/Flashcards.davetn657/Models/DTOs/StackDTO.cs b/Flashcards.davetn657/Models/DTOs/StackDTO.cs new file mode 100644 index 00000000..30ced85e --- /dev/null +++ b/Flashcards.davetn657/Models/DTOs/StackDTO.cs @@ -0,0 +1,6 @@ +namespace Flashcards.davetn657.Models.DTOs; +public class StackDTO +{ + public int Id { get; set; } + public string? Name { get; set; } +} diff --git a/Flashcards.davetn657/Enums/OptionUtils.cs b/Flashcards.davetn657/Models/Enums/OptionUtils.cs similarity index 96% rename from Flashcards.davetn657/Enums/OptionUtils.cs rename to Flashcards.davetn657/Models/Enums/OptionUtils.cs index 7426ed7d..2a476c30 100644 --- a/Flashcards.davetn657/Enums/OptionUtils.cs +++ b/Flashcards.davetn657/Models/Enums/OptionUtils.cs @@ -1,7 +1,7 @@ using System.ComponentModel; using System.Reflection; -namespace Flashcards.davetn657.Enums; +namespace Flashcards.davetn657.Models.Enums; public class OptionUtils { public static string GetStringValue(Enum value) diff --git a/Flashcards.davetn657/Enums/Options.cs b/Flashcards.davetn657/Models/Enums/Options.cs similarity index 79% rename from Flashcards.davetn657/Enums/Options.cs rename to Flashcards.davetn657/Models/Enums/Options.cs index 61bdff0c..69b6ac5a 100644 --- a/Flashcards.davetn657/Enums/Options.cs +++ b/Flashcards.davetn657/Models/Enums/Options.cs @@ -1,7 +1,7 @@ using System.ComponentModel; using System.Reflection; -namespace Flashcards.davetn657.Enums; +namespace Flashcards.davetn657.Models.Enums; public enum MainMenuOptions { @@ -19,8 +19,7 @@ public enum ManageStackOptions public enum EditStackOptions { [Description("Rename Stack")]RenameStack, - [Description("Add a Flashcard")]AddCard, - [Description("Remove a Flashcard")]RemoveCard, + [Description("Edit Card")]ChooseCard, [Description("Delete Stack")]DeleteStack, [Description("Return")]Return } \ No newline at end of file diff --git a/Flashcards.davetn657/Globals.cs b/Flashcards.davetn657/Models/Globals.cs similarity index 78% rename from Flashcards.davetn657/Globals.cs rename to Flashcards.davetn657/Models/Globals.cs index f135995c..0709fb7a 100644 --- a/Flashcards.davetn657/Globals.cs +++ b/Flashcards.davetn657/Models/Globals.cs @@ -1,6 +1,6 @@ using System.Globalization; -namespace Flashcards.davetn657; +namespace Flashcards.davetn657.Models; public class Globals { public static readonly IFormatProvider CULTURE_INFO = new CultureInfo("en-US"); diff --git a/Flashcards.davetn657/Program.cs b/Flashcards.davetn657/Program.cs index c365d748..2b8be118 100644 --- a/Flashcards.davetn657/Program.cs +++ b/Flashcards.davetn657/Program.cs @@ -1,11 +1,11 @@ -namespace Flashcards.davetn657 +using Flashcards.davetn657.Views; + +namespace Flashcards.davetn657; +class Program { - class Program + public static void Main(string[] args) { - public static void Main(string[] args) - { - UserInterface ui = new UserInterface(); - ui.StartApp(); - } + UserInterface ui = new UserInterface(); + ui.StartApp(); } -} \ No newline at end of file +} diff --git a/Flashcards.davetn657/Validation.cs b/Flashcards.davetn657/Validation.cs deleted file mode 100644 index 10c3411f..00000000 --- a/Flashcards.davetn657/Validation.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Flashcards.davetn657.Controllers; -using Flashcards.davetn657.DTOs; - -namespace Flashcards.davetn657; -public class Validation -{ - public static bool IsValidStackName(string name, Dictionary stacks) - { - if (stacks.ContainsKey(name)) - { - return false; - } - return true; - } -} diff --git a/Flashcards.davetn657/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs similarity index 64% rename from Flashcards.davetn657/UserInterface.cs rename to Flashcards.davetn657/Views/UserInterface.cs index e37f89f6..907bc91d 100644 --- a/Flashcards.davetn657/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -1,17 +1,19 @@ using Spectre.Console; -using Flashcards.davetn657; -using Flashcards.davetn657.Enums; using Flashcards.davetn657.Controllers; -using Flashcards.davetn657.DTOs; +using Flashcards.davetn657.Models; +using Flashcards.davetn657.Models.Enums; +using Flashcards.davetn657.Models.DTOs; -namespace Flashcards.davetn657; +namespace Flashcards.davetn657.Views; public class UserInterface { private StackController stackController; + private CardController cardController; public UserInterface() { stackController = new StackController(); + cardController = new CardController(); } public void StartApp() @@ -24,7 +26,7 @@ public void StartApp() var menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); var inputValue = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); @@ -40,7 +42,6 @@ public void StartApp() break; } } - } private void ManageStack() @@ -49,7 +50,7 @@ private void ManageStack() var menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); switch (optionSelected) @@ -68,12 +69,13 @@ private void CreateStack() TitlePanel("Create a New Stack"); var input = string.Empty; + var cards = stackController.ReadAllStacks(); while (true) { - input = AnsiConsole.Ask("Name your Stack:"); - - if (Validation.IsValidStackName(input, stackController.ReadAllStacks())) + input = AnsiConsole.Ask("Name your stack:"); + + if(!cards.ContainsKey(input)) { stackController.AddStack(input); break; @@ -85,16 +87,16 @@ private void CreateStack() } AnsiConsole.WriteLine($"Stack named {input} created!\n"); - AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Press Enter to Return")); + AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Press Enter to Return")); } private void ChooseStack() { - TitlePanel("Choose a Stack to Edit"); + TitlePanel("Choose a stack to edit"); var stacks = stackController.ReadAllStacks(); - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks.Keys) ); + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks.Keys) ); switch (input) { @@ -112,17 +114,16 @@ private void EditStack(StackDTO stack) var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); var optionSelected = OptionUtils.GetEnumValue(input, typeof(EditStackOptions)); switch (optionSelected) { case EditStackOptions.RenameStack: - stackController.EditStack(stack); - break; - case EditStackOptions.AddCard: + CreateCard(); break; - case EditStackOptions.RemoveCard: + case EditStackOptions.ChooseCard: + ChooseCard(stack); break; case EditStackOptions.DeleteStack: stackController.RemoveStack(stack); @@ -132,6 +133,39 @@ private void EditStack(StackDTO stack) } } + private void CreateCard() + { + TitlePanel("Create a new Card"); + + var input = string.Empty; + var cards = cardController.ReadAllCards(); + var card = new CardDTO(); + + while (true) + { + input = AnsiConsole.Ask("Name your card:"); + + if (!cards.ContainsKey(input)) + { + card.Name = input; + break; + } + } + + input = AnsiConsole.Ask("Input question details:"); + card.Question = input; + + input = AnsiConsole.Ask("Input answer details:"); + card.Answer = input; + + cardController.AddCard(card); + } + + private void ChooseCard(StackDTO stack) + { + + } + private void StudySession() { TitlePanel("Study Session"); From c7dee066cefbfd14b94c67753e71c4e165bfe80e Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 20:51:37 -0500 Subject: [PATCH 08/23] working card creation --- .../Controllers/CardController.cs | 24 +++++++++++++++---- .../Controllers/StackController.cs | 6 ++--- Flashcards.davetn657/Models/DTOs/CardDTO.cs | 1 - Flashcards.davetn657/Models/Enums/Options.cs | 1 + Flashcards.davetn657/Views/UserInterface.cs | 21 +++++----------- 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index 6484f453..6b90a183 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -1,4 +1,5 @@ -using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models; +using Flashcards.davetn657.Models.DTOs; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Configuration; using System.Data; @@ -19,9 +20,25 @@ public CardController() this.connectionString = configuration.GetConnectionString("DatabaseConnection"); } - public void AddCard(CardDTO card) + public void AddCard(CardDTO card, StackDTO stack) { + using (SqlConnection connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"INSERT INTO CARDS (StackId, CardQuestion, CardAnswer, CreateDate) + VALUES (@StackId, @Question, @Answer, @Date)"; + + tableCmd.Parameters.Add("@StackId", SqlDbType.Int).Value = stack.Id; + tableCmd.Parameters.Add("@Question", SqlDbType.Text).Value = card.Question; + tableCmd.Parameters.Add("@Answer", SqlDbType.Text).Value = card.Answer; + tableCmd.Parameters.Add("@Date", SqlDbType.DateTime2).Value = DateTime.Now.ToString(Globals.CULTURE_INFO); + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } } public void RemoveCard() @@ -51,10 +68,9 @@ public Dictionary ReadAllCards() { var card = new CardDTO(); card.Id = reader.GetInt32("CardId"); - card.Name = reader.GetString("CardName"); card.Question = reader.GetString("CardQuestion"); card.Answer = reader.GetString("CardAnswer"); - allCards.Add(card.Name, card); + allCards.Add(card.Question, card); } connection.Close(); diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index 1b558d8f..864ad332 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -30,10 +30,8 @@ public void AddStack(string name) tableCmd.CommandText = @"INSERT INTO STACKS (StackName, CreateDate) VALUES (@Name, @Date)"; - var currentDate = DateTime.Now.ToString(Globals.CULTURE_INFO); - tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = name; - tableCmd.Parameters.Add("@Date", SqlDbType.DateTime2).Value = currentDate; + tableCmd.Parameters.Add("@Date", SqlDbType.DateTime2).Value = DateTime.Now.ToString(Globals.CULTURE_INFO); tableCmd.ExecuteNonQuery(); @@ -51,7 +49,7 @@ public void RemoveStack(StackDTO stack) tableCmd.CommandText = @"DELETE FROM STACKS WHERE StackId = @Id AND - StackName = @Name;"; + StackName = @Name"; tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = stack.Id; tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = stack.Name; diff --git a/Flashcards.davetn657/Models/DTOs/CardDTO.cs b/Flashcards.davetn657/Models/DTOs/CardDTO.cs index 2ba75bba..1d310692 100644 --- a/Flashcards.davetn657/Models/DTOs/CardDTO.cs +++ b/Flashcards.davetn657/Models/DTOs/CardDTO.cs @@ -3,7 +3,6 @@ public class CardDTO { public int Id { get; set; } - public string? Name { get; set; } public string? Question { get; set; } public string? Answer { get; set; } } diff --git a/Flashcards.davetn657/Models/Enums/Options.cs b/Flashcards.davetn657/Models/Enums/Options.cs index 69b6ac5a..a2911452 100644 --- a/Flashcards.davetn657/Models/Enums/Options.cs +++ b/Flashcards.davetn657/Models/Enums/Options.cs @@ -19,6 +19,7 @@ public enum ManageStackOptions public enum EditStackOptions { [Description("Rename Stack")]RenameStack, + [Description("Add a Card")]CreateCard, [Description("Edit Card")]ChooseCard, [Description("Delete Stack")]DeleteStack, [Description("Return")]Return diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index 907bc91d..b7d80ad3 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -120,7 +120,9 @@ private void EditStack(StackDTO stack) switch (optionSelected) { case EditStackOptions.RenameStack: - CreateCard(); + break; + case EditStackOptions.CreateCard: + CreateCard(stack); break; case EditStackOptions.ChooseCard: ChooseCard(stack); @@ -133,7 +135,7 @@ private void EditStack(StackDTO stack) } } - private void CreateCard() + private void CreateCard(StackDTO stack) { TitlePanel("Create a new Card"); @@ -141,29 +143,18 @@ private void CreateCard() var cards = cardController.ReadAllCards(); var card = new CardDTO(); - while (true) - { - input = AnsiConsole.Ask("Name your card:"); - - if (!cards.ContainsKey(input)) - { - card.Name = input; - break; - } - } - input = AnsiConsole.Ask("Input question details:"); card.Question = input; input = AnsiConsole.Ask("Input answer details:"); card.Answer = input; - cardController.AddCard(card); + cardController.AddCard(card, stack); } private void ChooseCard(StackDTO stack) { - + } private void StudySession() From ba564fc69ad498a2440fa5b871e6274cf3b54c00 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 21:34:57 -0500 Subject: [PATCH 09/23] working stack editing and changed method name and function to reduce repeating code --- .../Controllers/StackController.cs | 19 ++++++- Flashcards.davetn657/Views/UserInterface.cs | 53 ++++++++++--------- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index 864ad332..fe1bef49 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -60,9 +60,26 @@ public void RemoveStack(StackDTO stack) } } - public void EditStack(StackDTO stack) + public void EditStack(StackDTO stack, string name) { + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"UPDATE STACKS + SET StackName = @NewName + WHERE StackId = @Id AND + StackName = @Name"; + + tableCmd.Parameters.Add("@NewName", SqlDbType.Text).Value = name; + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = stack.Id; + tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = stack.Name; + + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } } public Dictionary ReadAllStacks() diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index b7d80ad3..8a83c699 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -56,7 +56,9 @@ private void ManageStack() switch (optionSelected) { case ManageStackOptions.CreateStack: - CreateStack(); + stackController.AddStack(NameStack()); + AnsiConsole.WriteLine($"Stack named {input} created!\n"); + AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Press Enter to Return")); break; case ManageStackOptions.ChooseStack: ChooseStack(); @@ -64,31 +66,7 @@ private void ManageStack() } } - private void CreateStack() - { - TitlePanel("Create a New Stack"); - - var input = string.Empty; - var cards = stackController.ReadAllStacks(); - - while (true) - { - input = AnsiConsole.Ask("Name your stack:"); - - if(!cards.ContainsKey(input)) - { - stackController.AddStack(input); - break; - } - else - { - AnsiConsole.Markup("[red]Stack Name Already in Use Choose a Different Name![/]\n"); - } - } - - AnsiConsole.WriteLine($"Stack named {input} created!\n"); - AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Press Enter to Return")); - } + private void ChooseStack() { @@ -120,6 +98,7 @@ private void EditStack(StackDTO stack) switch (optionSelected) { case EditStackOptions.RenameStack: + stackController.EditStack(stack, NameStack()); break; case EditStackOptions.CreateCard: CreateCard(stack); @@ -135,6 +114,28 @@ private void EditStack(StackDTO stack) } } + private string NameStack() + { + TitlePanel("Name your Stack"); + + var input = string.Empty; + var cards = stackController.ReadAllStacks(); + + while (true) + { + input = AnsiConsole.Ask("Name your stack:"); + + if (!cards.ContainsKey(input)) + { + return input; + } + else + { + AnsiConsole.Markup("[red]Stack Name Already in Use Choose a Different Name![/]\n"); + } + } + } + private void CreateCard(StackDTO stack) { TitlePanel("Create a new Card"); From 2ecc354f03e6ae3df8b956f12b35ee9f4cccb3eb Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 22:12:55 -0500 Subject: [PATCH 10/23] Added return option to UIs and handled user inputing specified menu options as a stack --- Flashcards.davetn657/Views/UserInterface.cs | 59 +++++++++++++-------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index 8a83c699..62364262 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -74,7 +74,7 @@ private void ChooseStack() var stacks = stackController.ReadAllStacks(); - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks.Keys) ); + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks.Keys).AddChoices("Return") ); switch (input) { @@ -88,30 +88,37 @@ private void ChooseStack() private void EditStack(StackDTO stack) { - TitlePanel($"Edit : {stack}"); + var endEdit = false; - var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); + while (!endEdit) + { + TitlePanel($"Edit : {stack}"); - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var optionSelected = OptionUtils.GetEnumValue(input, typeof(EditStackOptions)); + var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); - switch (optionSelected) - { - case EditStackOptions.RenameStack: - stackController.EditStack(stack, NameStack()); - break; - case EditStackOptions.CreateCard: - CreateCard(stack); - break; - case EditStackOptions.ChooseCard: - ChooseCard(stack); - break; - case EditStackOptions.DeleteStack: - stackController.RemoveStack(stack); - break; - case EditStackOptions.Return: - break; + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var optionSelected = OptionUtils.GetEnumValue(input, typeof(EditStackOptions)); + + switch (optionSelected) + { + case EditStackOptions.RenameStack: + stackController.EditStack(stack, NameStack()); + break; + case EditStackOptions.CreateCard: + CreateCard(stack); + break; + case EditStackOptions.ChooseCard: + ChooseCard(stack); + break; + case EditStackOptions.DeleteStack: + stackController.RemoveStack(stack); + break; + case EditStackOptions.Return: + endEdit = true; + break; + } } + } private string NameStack() @@ -125,7 +132,7 @@ private string NameStack() { input = AnsiConsole.Ask("Name your stack:"); - if (!cards.ContainsKey(input)) + if (!cards.ContainsKey(input) && input != "Return") { return input; } @@ -155,7 +162,13 @@ private void CreateCard(StackDTO stack) private void ChooseCard(StackDTO stack) { - + TitlePanel($"{stack.Name} cards"); + + var allCards = cardController.ReadAllCards(); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(allCards.Keys).AddChoices("Return")); + + } private void StudySession() From b503af5c832bb07148b80777a77212a1c8d2969a Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Mon, 9 Feb 2026 22:33:49 -0500 Subject: [PATCH 11/23] working EditCard UI and changed UI to force user to return when deleting stack/card --- .../Controllers/CardController.cs | 20 +++++++- Flashcards.davetn657/Models/Enums/Options.cs | 12 ++++- Flashcards.davetn657/Views/UserInterface.cs | 46 +++++++++++++++++-- 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index 6b90a183..c28fbda3 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -41,8 +41,26 @@ public void AddCard(CardDTO card, StackDTO stack) } } - public void RemoveCard() + public void RemoveCard(CardDTO card) { + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"DELETE FROM CARDS + WHERE CardId = @Id + CardQuestion = @Question + CardAnswer = @Answer"; + + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = card.Id; + tableCmd.Parameters.Add("@Question", SqlDbType.Text).Value = card.Question; + tableCmd.Parameters.Add("@Answer", SqlDbType.Text).Value = card.Answer; + + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } } diff --git a/Flashcards.davetn657/Models/Enums/Options.cs b/Flashcards.davetn657/Models/Enums/Options.cs index a2911452..8fea8ad6 100644 --- a/Flashcards.davetn657/Models/Enums/Options.cs +++ b/Flashcards.davetn657/Models/Enums/Options.cs @@ -14,7 +14,7 @@ public enum ManageStackOptions { [Description("Create Stack")] CreateStack, [Description("Edit Stack")]ChooseStack -}; +} public enum EditStackOptions { @@ -23,4 +23,12 @@ public enum EditStackOptions [Description("Edit Card")]ChooseCard, [Description("Delete Stack")]DeleteStack, [Description("Return")]Return -} \ No newline at end of file +} + +public enum EditCardOptions +{ + [Description("Change Question")]ChangeQuestion, + [Description("Change Answer")]ChangeAnswer, + [Description("Delete Card")]DeleteCard, + [Description("Return")]Return +} diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index 62364262..066f3c4a 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -112,13 +112,15 @@ private void EditStack(StackDTO stack) break; case EditStackOptions.DeleteStack: stackController.RemoveStack(stack); + AnsiConsole.WriteLine("Successfully removed stack!"); + AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Return?")); + endEdit = true; break; case EditStackOptions.Return: endEdit = true; break; } } - } private string NameStack() @@ -138,7 +140,7 @@ private string NameStack() } else { - AnsiConsole.Markup("[red]Stack Name Already in Use Choose a Different Name![/]\n"); + AnsiConsole.Markup("[red]Stack Name Already in Use or Not Available Choose a Different Name![/]\n"); } } } @@ -162,12 +164,50 @@ private void CreateCard(StackDTO stack) private void ChooseCard(StackDTO stack) { - TitlePanel($"{stack.Name} cards"); + TitlePanel($"{stack.Name} Cards"); var allCards = cardController.ReadAllCards(); var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(allCards.Keys).AddChoices("Return")); + switch (input) + { + case "Return": + break; + default: + EditCard(allCards[input]); + break; + } + } + + private void EditCard(CardDTO card) + { + var endEdit = false; + + while (!endEdit) + { + TitlePanel($"Edit Card : {card.Question}"); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(OptionUtils.GetAllStringValues(typeof(EditCardOptions)))); + var selectedOption = OptionUtils.GetEnumValue(input, typeof(EditCardOptions)); + + switch (selectedOption) + { + case EditCardOptions.ChangeQuestion: + break; + case EditCardOptions.ChangeAnswer: + break; + case EditCardOptions.DeleteCard: + cardController.RemoveCard(card); + AnsiConsole.WriteLine("Successfully removed card!"); + AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Return?")); + endEdit = true; + break; + case EditCardOptions.Return: + endEdit = true; + break; + } + } } From cf95b37b2cc7a219565d8a52d46db7e2bf34c266 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Tue, 10 Feb 2026 08:31:01 -0500 Subject: [PATCH 12/23] working Edit card method --- .../Controllers/CardController.cs | 28 ++++++++++++++++++- Flashcards.davetn657/Views/UserInterface.cs | 11 ++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index c28fbda3..2c657327 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -1,5 +1,6 @@ using Flashcards.davetn657.Models; using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models.Enums; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Configuration; using System.Data; @@ -64,9 +65,34 @@ public void RemoveCard(CardDTO card) } - public void EditCard() + public void EditCard(CardDTO card, Enum option) { + using(var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + + if (option.Equals(EditCardOptions.ChangeAnswer)) + { + tableCmd.CommandText = @"UPDATE FROM CARDS + SET CardAnswer = @Answer + WHERE CardId = @id"; + tableCmd.Parameters.Add("@Answer", SqlDbType.Text).Value = card.Answer; + } + else if(option.Equals(EditCardOptions.ChangeQuestion)) + { + tableCmd.CommandText = @"UPDATE FROM CARDS + SET CardQuestion = @Question + WHERE CardId = @id"; + tableCmd.Parameters.Add("@Question", SqlDbType.Text).Value = card.Question; + } + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = card.Id; + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } } public Dictionary ReadAllCards() diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index 066f3c4a..e2a51872 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -194,8 +194,10 @@ private void EditCard(CardDTO card) switch (selectedOption) { case EditCardOptions.ChangeQuestion: + ChangeCardDetails(card, selectedOption); break; case EditCardOptions.ChangeAnswer: + ChangeCardDetails(card, selectedOption); break; case EditCardOptions.DeleteCard: cardController.RemoveCard(card); @@ -211,6 +213,15 @@ private void EditCard(CardDTO card) } + private void ChangeCardDetails(CardDTO card, Enum option) + { + TitlePanel(OptionUtils.GetStringValue(option)); + + var input = AnsiConsole.Ask("Enter details:"); + + cardController.EditCard(card, option); + } + private void StudySession() { TitlePanel("Study Session"); From e395a6844e380be776cb8c5519af342115b965f3 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Tue, 10 Feb 2026 23:20:01 -0500 Subject: [PATCH 13/23] added ability for user to return on textprompts --- Flashcards.davetn657/Models/Enums/Options.cs | 3 ++- Flashcards.davetn657/Views/UserInterface.cs | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Flashcards.davetn657/Models/Enums/Options.cs b/Flashcards.davetn657/Models/Enums/Options.cs index 8fea8ad6..0abc1929 100644 --- a/Flashcards.davetn657/Models/Enums/Options.cs +++ b/Flashcards.davetn657/Models/Enums/Options.cs @@ -5,8 +5,9 @@ namespace Flashcards.davetn657.Models.Enums; public enum MainMenuOptions { + [Description("Start Studying")]StartStudy, [Description("Manage Stacks")] ManageStack, - [Description("Study Sessions")] StudySession, + [Description("Manage Study Sessions")] ManageStudy, [Description("Exit")] ExitApp } diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index e2a51872..6def3759 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -1,6 +1,5 @@ using Spectre.Console; using Flashcards.davetn657.Controllers; -using Flashcards.davetn657.Models; using Flashcards.davetn657.Models.Enums; using Flashcards.davetn657.Models.DTOs; @@ -32,10 +31,12 @@ public void StartApp() switch (inputValue) { + case MainMenuOptions.StartStudy: + break; case MainMenuOptions.ManageStack: ManageStack(); break; - case MainMenuOptions.StudySession: + case MainMenuOptions.ManageStudy: break; case MainMenuOptions.ExitApp: endApp = true; @@ -102,7 +103,8 @@ private void EditStack(StackDTO stack) switch (optionSelected) { case EditStackOptions.RenameStack: - stackController.EditStack(stack, NameStack()); + var name = NameStack(); + if(name != string.Empty) stackController.EditStack(stack, name); break; case EditStackOptions.CreateCard: CreateCard(stack); @@ -132,12 +134,16 @@ private string NameStack() while (true) { - input = AnsiConsole.Ask("Name your stack:"); + input = AnsiConsole.Ask("Name your stack (type: r to return):"); if (!cards.ContainsKey(input) && input != "Return") { return input; } + else if(input.ToLower() == "r") + { + return string.Empty; + } else { AnsiConsole.Markup("[red]Stack Name Already in Use or Not Available Choose a Different Name![/]\n"); @@ -153,10 +159,12 @@ private void CreateCard(StackDTO stack) var cards = cardController.ReadAllCards(); var card = new CardDTO(); - input = AnsiConsole.Ask("Input question details:"); + input = AnsiConsole.Ask("Input question details (type: r to return):"); + if (input.ToLower() == "r") return; card.Question = input; - input = AnsiConsole.Ask("Input answer details:"); + input = AnsiConsole.Ask("Input answer details (type: r to return):"); + if (input.ToLower() == "r") return; card.Answer = input; cardController.AddCard(card, stack); From d0245c14bf460ba3c5c1fa46274e8aa1d7f0c36d Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Wed, 11 Feb 2026 15:41:19 -0500 Subject: [PATCH 14/23] Updated SQL queries --- .../Controllers/CardController.cs | 4 +- Flashcards.davetn657/Views/UserInterface.cs | 39 ++++++++++--------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index 2c657327..adcc690f 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -75,14 +75,14 @@ public void EditCard(CardDTO card, Enum option) if (option.Equals(EditCardOptions.ChangeAnswer)) { - tableCmd.CommandText = @"UPDATE FROM CARDS + tableCmd.CommandText = @"UPDATE CARDS SET CardAnswer = @Answer WHERE CardId = @id"; tableCmd.Parameters.Add("@Answer", SqlDbType.Text).Value = card.Answer; } else if(option.Equals(EditCardOptions.ChangeQuestion)) { - tableCmd.CommandText = @"UPDATE FROM CARDS + tableCmd.CommandText = @"UPDATE CARDS SET CardQuestion = @Question WHERE CardId = @id"; tableCmd.Parameters.Add("@Question", SqlDbType.Text).Value = card.Question; diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index 6def3759..46c49908 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -21,7 +21,7 @@ public void StartApp() while (!endApp) { - TitlePanel("Main Menu"); + TitleCard("Main Menu"); var menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); @@ -47,7 +47,7 @@ public void StartApp() private void ManageStack() { - TitlePanel("Manage Stacks"); + TitleCard("Manage Stacks"); var menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); @@ -71,7 +71,7 @@ private void ManageStack() private void ChooseStack() { - TitlePanel("Choose a stack to edit"); + TitleCard("Edit a Stack"); var stacks = stackController.ReadAllStacks(); @@ -93,7 +93,7 @@ private void EditStack(StackDTO stack) while (!endEdit) { - TitlePanel($"Edit : {stack}"); + TitleCard($"Edit : {stack.Name}"); var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); @@ -127,7 +127,7 @@ private void EditStack(StackDTO stack) private string NameStack() { - TitlePanel("Name your Stack"); + TitleCard("Name your Stack"); var input = string.Empty; var cards = stackController.ReadAllStacks(); @@ -153,7 +153,7 @@ private string NameStack() private void CreateCard(StackDTO stack) { - TitlePanel("Create a new Card"); + TitleCard("Create a new Card"); var input = string.Empty; var cards = cardController.ReadAllCards(); @@ -172,7 +172,7 @@ private void CreateCard(StackDTO stack) private void ChooseCard(StackDTO stack) { - TitlePanel($"{stack.Name} Cards"); + TitleCard($"{stack.Name} Cards"); var allCards = cardController.ReadAllCards(); @@ -194,7 +194,7 @@ private void EditCard(CardDTO card) while (!endEdit) { - TitlePanel($"Edit Card : {card.Question}"); + TitleCard($"Edit Card : {card.Question}"); var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(OptionUtils.GetAllStringValues(typeof(EditCardOptions)))); var selectedOption = OptionUtils.GetEnumValue(input, typeof(EditCardOptions)); @@ -223,27 +223,30 @@ private void EditCard(CardDTO card) private void ChangeCardDetails(CardDTO card, Enum option) { - TitlePanel(OptionUtils.GetStringValue(option)); + TitleCard(OptionUtils.GetStringValue(option)); - var input = AnsiConsole.Ask("Enter details:"); + var input = AnsiConsole.Ask("Enter details (type: r to return):"); + + if (input.ToLower() == "r") return; cardController.EditCard(card, option); } private void StudySession() { - TitlePanel("Study Session"); + TitleCard("Study Session"); } - private void TitlePanel(string title) + private void ManageStudySessions() { - var titlePanel = new Panel(title) - { - Border = BoxBorder.Double, - Padding = new Padding(20, 1) - }; - var centered = Align.Center(titlePanel); + } + + private void TitleCard(string title) + { + var titleFiglet = new FigletText(title); + + var centered = Align.Center(titleFiglet); AnsiConsole.Clear(); AnsiConsole.Write(centered); From e26ff8f21b6fa2d014c1acaa50e044c1e5d25af6 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Wed, 11 Feb 2026 15:41:38 -0500 Subject: [PATCH 15/23] Updated SQL queries --- Flashcards.davetn657/Controllers/CardController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index adcc690f..92b272e0 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -50,8 +50,8 @@ public void RemoveCard(CardDTO card) var tableCmd = connection.CreateCommand(); tableCmd.CommandText = @"DELETE FROM CARDS - WHERE CardId = @Id - CardQuestion = @Question + WHERE CardId = @Id, + CardQuestion = @Question, CardAnswer = @Answer"; tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = card.Id; From e1dd2513d4407262e486827dc285a45e50197fab Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Fri, 13 Feb 2026 23:31:28 -0500 Subject: [PATCH 16/23] Added base study session controller functions and removing of all cards from a stack if the stack is deleted --- .../Controllers/CardController.cs | 23 +++- .../Controllers/StackController.cs | 13 +-- .../Controllers/StudyController.cs | 103 ++++++++++++++++++ Flashcards.davetn657/Models/DTOs/CardDTO.cs | 2 + Flashcards.davetn657/Models/DTOs/StudyDTO.cs | 8 ++ Flashcards.davetn657/Models/Enums/Options.cs | 12 +- Flashcards.davetn657/Views/UserInterface.cs | 51 ++++++--- 7 files changed, 184 insertions(+), 28 deletions(-) create mode 100644 Flashcards.davetn657/Controllers/StudyController.cs create mode 100644 Flashcards.davetn657/Models/DTOs/StudyDTO.cs diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index 92b272e0..b1c6555c 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -28,13 +28,28 @@ public void AddCard(CardDTO card, StackDTO stack) connection.Open(); var tableCmd = connection.CreateCommand(); - tableCmd.CommandText = @"INSERT INTO CARDS (StackId, CardQuestion, CardAnswer, CreateDate) - VALUES (@StackId, @Question, @Answer, @Date)"; + tableCmd.CommandText = @"INSERT INTO CARDS (StackId, CardQuestion, CardAnswer) + VALUES (@StackId, @Question, @Answer)"; tableCmd.Parameters.Add("@StackId", SqlDbType.Int).Value = stack.Id; tableCmd.Parameters.Add("@Question", SqlDbType.Text).Value = card.Question; tableCmd.Parameters.Add("@Answer", SqlDbType.Text).Value = card.Answer; - tableCmd.Parameters.Add("@Date", SqlDbType.DateTime2).Value = DateTime.Now.ToString(Globals.CULTURE_INFO); + + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } + } + + public void RemoveCardsFromStack(StackDTO stack) + { + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + var tableCmd = connection.CreateCommand(); + + tableCmd.CommandText = @"DELETE FROM CARDS + WHERE StackId = @Id"; tableCmd.ExecuteNonQuery(); @@ -114,6 +129,8 @@ public Dictionary ReadAllCards() card.Id = reader.GetInt32("CardId"); card.Question = reader.GetString("CardQuestion"); card.Answer = reader.GetString("CardAnswer"); + card.LastAppearance = reader.GetDateTime("LastAppearance"); + card.NextAppearance = reader.GetDateTime("NextAppearance"); allCards.Add(card.Question, card); } diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index fe1bef49..d05eb882 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -27,11 +27,10 @@ public void AddStack(string name) var tableCmd = connection.CreateCommand(); - tableCmd.CommandText = @"INSERT INTO STACKS (StackName, CreateDate) - VALUES (@Name, @Date)"; + tableCmd.CommandText = @"INSERT INTO STACKS (StackName) + VALUES (@Name)"; tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = name; - tableCmd.Parameters.Add("@Date", SqlDbType.DateTime2).Value = DateTime.Now.ToString(Globals.CULTURE_INFO); tableCmd.ExecuteNonQuery(); @@ -60,7 +59,7 @@ public void RemoveStack(StackDTO stack) } } - public void EditStack(StackDTO stack, string name) + public void EditStack(StackDTO stack) { using (var connection = new SqlConnection(connectionString)) { @@ -69,12 +68,10 @@ public void EditStack(StackDTO stack, string name) var tableCmd = connection.CreateCommand(); tableCmd.CommandText = @"UPDATE STACKS SET StackName = @NewName - WHERE StackId = @Id AND - StackName = @Name"; + WHERE StackId = @Id"; - tableCmd.Parameters.Add("@NewName", SqlDbType.Text).Value = name; + tableCmd.Parameters.Add("@NewName", SqlDbType.Text).Value = stack.Name; tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = stack.Id; - tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = stack.Name; tableCmd.ExecuteNonQuery(); diff --git a/Flashcards.davetn657/Controllers/StudyController.cs b/Flashcards.davetn657/Controllers/StudyController.cs new file mode 100644 index 00000000..9a8d6e54 --- /dev/null +++ b/Flashcards.davetn657/Controllers/StudyController.cs @@ -0,0 +1,103 @@ +using Flashcards.davetn657.Models.DTOs; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; +using System.Data; + +namespace Flashcards.davetn657.Controllers; + +public class StudyController +{ + private IConfiguration configuration; + private string? connectionString; + + public StudyController() + { + this.configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + this.connectionString = configuration.GetConnectionString("DatabaseConnection"); + } + + public void AddSession(StudyDTO session) + { + using(var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"INSERT INTO SESSIONS (SessionName) + VALUES (@Name)"; + + tableCmd.Parameters.Add("@Name", System.Data.SqlDbType.Text).Value = session.Name; + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } + } + + public void RemoveSession(StudyDTO session) + { + using(var connection = new SqlConnection(connectionString)) + { + connection.Open(); + var tableCmd = connection.CreateCommand(); + + tableCmd.CommandText = @"DELETE FROM SESSIONS + WHERE SessionId = @Id AND + SessionName = @Name"; + + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } + } + + public void EditSession(StudyDTO session) + { + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"UPDATE SESSIONS + SET StudyName = @Name + WHERE StudyId = @Id"; + + tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = session.Name; + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = session.Id; + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } + } + + public Dictionary ReadAllSessions() + { + var allSessions = new Dictionary(); + + using(var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"SELECT * FROM SESSIONS"; + + var reader = tableCmd.ExecuteReader(); + + while (reader.Read()) + { + var session = new StudyDTO(); + session.Id = reader.GetInt32("StudyId"); + session.Id = reader.GetInt32("StackId"); + session.Name = reader.GetString("StudyName"); + + allSessions.Add(session.Name, session); + } + + connection.Close(); + } + + return allSessions; + } +} \ No newline at end of file diff --git a/Flashcards.davetn657/Models/DTOs/CardDTO.cs b/Flashcards.davetn657/Models/DTOs/CardDTO.cs index 1d310692..2f8952cf 100644 --- a/Flashcards.davetn657/Models/DTOs/CardDTO.cs +++ b/Flashcards.davetn657/Models/DTOs/CardDTO.cs @@ -5,4 +5,6 @@ public class CardDTO public int Id { get; set; } public string? Question { get; set; } public string? Answer { get; set; } + public DateTime LastAppearance { get; set; } + public DateTime NextAppearance { get; set; } } diff --git a/Flashcards.davetn657/Models/DTOs/StudyDTO.cs b/Flashcards.davetn657/Models/DTOs/StudyDTO.cs new file mode 100644 index 00000000..7e2daf2d --- /dev/null +++ b/Flashcards.davetn657/Models/DTOs/StudyDTO.cs @@ -0,0 +1,8 @@ +namespace Flashcards.davetn657.Models.DTOs; + +public class StudyDTO +{ + public int Id { get; set; } + public int StackId { get; set; } + public string Name { get; set; } +} \ No newline at end of file diff --git a/Flashcards.davetn657/Models/Enums/Options.cs b/Flashcards.davetn657/Models/Enums/Options.cs index 0abc1929..bd92e8e8 100644 --- a/Flashcards.davetn657/Models/Enums/Options.cs +++ b/Flashcards.davetn657/Models/Enums/Options.cs @@ -6,15 +6,23 @@ namespace Flashcards.davetn657.Models.Enums; public enum MainMenuOptions { [Description("Start Studying")]StartStudy, - [Description("Manage Stacks")] ManageStack, [Description("Manage Study Sessions")] ManageStudy, + [Description("Manage Stacks")] ManageStack, [Description("Exit")] ExitApp } +public enum ManageStudySessionOptions +{ + [Description("Create a Study Session")]CreateSeession, + [Description("Edit Study Session")] ChooseSession, + [Description("Return")] Return +} + public enum ManageStackOptions { [Description("Create Stack")] CreateStack, - [Description("Edit Stack")]ChooseStack + [Description("Edit Stack")]ChooseStack, + [Description("Return")] Return } public enum EditStackOptions diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index 46c49908..1e2a0bdc 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -32,12 +32,14 @@ public void StartApp() switch (inputValue) { case MainMenuOptions.StartStudy: + StudySession(); + break; + case MainMenuOptions.ManageStudy: + ManageStudySessions(); break; case MainMenuOptions.ManageStack: ManageStack(); break; - case MainMenuOptions.ManageStudy: - break; case MainMenuOptions.ExitApp: endApp = true; break; @@ -45,6 +47,33 @@ public void StartApp() } } + private void StudySession() + { + TitleCard("Study Session"); + } + + private void ManageStudySessions() + { + TitleCard("Manage Sessions"); + + var menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStudySessionOptions)); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStudySessionOptions)); + + switch (optionSelected) + { + case ManageStudySessionOptions.CreateSeession: + break; + case ManageStudySessionOptions.ChooseSession: + break; + case ManageStudySessionOptions.Return: + break; + } + } + + + private void ManageStack() { TitleCard("Manage Stacks"); @@ -64,11 +93,11 @@ private void ManageStack() case ManageStackOptions.ChooseStack: ChooseStack(); break; + case ManageStackOptions.Return: + break; } } - - private void ChooseStack() { TitleCard("Edit a Stack"); @@ -104,7 +133,8 @@ private void EditStack(StackDTO stack) { case EditStackOptions.RenameStack: var name = NameStack(); - if(name != string.Empty) stackController.EditStack(stack, name); + stack.Name = name; + if(name != string.Empty) stackController.EditStack(stack); break; case EditStackOptions.CreateCard: CreateCard(stack); @@ -114,6 +144,7 @@ private void EditStack(StackDTO stack) break; case EditStackOptions.DeleteStack: stackController.RemoveStack(stack); + cardController.RemoveCardsFromStack(stack); AnsiConsole.WriteLine("Successfully removed stack!"); AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Return?")); endEdit = true; @@ -232,16 +263,6 @@ private void ChangeCardDetails(CardDTO card, Enum option) cardController.EditCard(card, option); } - private void StudySession() - { - TitleCard("Study Session"); - } - - private void ManageStudySessions() - { - - } - private void TitleCard(string title) { var titleFiglet = new FigletText(title); From 4a03e222a96b336eb791c85e62d8ba8869bd934f Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Tue, 17 Feb 2026 07:21:16 -0500 Subject: [PATCH 17/23] created overload methods for deleting sessions and cards when a stack is deleted --- .../Controllers/CardController.cs | 19 +++++++------- .../Controllers/StackController.cs | 23 ++++++++++++++++ .../Controllers/StudyController.cs | 26 ++++++++++++++++--- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index b1c6555c..ee5b841f 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -41,23 +41,26 @@ public void AddCard(CardDTO card, StackDTO stack) } } - public void RemoveCardsFromStack(StackDTO stack) + public void RemoveCard(CardDTO card) { using (var connection = new SqlConnection(connectionString)) { connection.Open(); - var tableCmd = connection.CreateCommand(); + var tableCmd = connection.CreateCommand(); tableCmd.CommandText = @"DELETE FROM CARDS - WHERE StackId = @Id"; + WHERE CardId = @Id"; + + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = card.Id; tableCmd.ExecuteNonQuery(); connection.Close(); } + } - public void RemoveCard(CardDTO card) + public void RemoveCard(StackDTO stack) { using (var connection = new SqlConnection(connectionString)) { @@ -65,13 +68,9 @@ public void RemoveCard(CardDTO card) var tableCmd = connection.CreateCommand(); tableCmd.CommandText = @"DELETE FROM CARDS - WHERE CardId = @Id, - CardQuestion = @Question, - CardAnswer = @Answer"; + WHERE StackId = @Id"; - tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = card.Id; - tableCmd.Parameters.Add("@Question", SqlDbType.Text).Value = card.Question; - tableCmd.Parameters.Add("@Answer", SqlDbType.Text).Value = card.Answer; + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = stack.Id; tableCmd.ExecuteNonQuery(); diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index d05eb882..9c8b0db2 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -59,6 +59,29 @@ public void RemoveStack(StackDTO stack) } } + public void RemoveStack(StackDTO stack, CardController cardController, StudyController sessionController) + { + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"DELETE FROM STACKS + WHERE + StackId = @Id AND + StackName = @Name"; + + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = stack.Id; + tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = stack.Name; + + cardController.RemoveCard(stack); + sessionController.RemoveSession(stack); + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } + } + public void EditStack(StackDTO stack) { using (var connection = new SqlConnection(connectionString)) diff --git a/Flashcards.davetn657/Controllers/StudyController.cs b/Flashcards.davetn657/Controllers/StudyController.cs index 9a8d6e54..33905741 100644 --- a/Flashcards.davetn657/Controllers/StudyController.cs +++ b/Flashcards.davetn657/Controllers/StudyController.cs @@ -29,7 +29,7 @@ public void AddSession(StudyDTO session) tableCmd.CommandText = @"INSERT INTO SESSIONS (SessionName) VALUES (@Name)"; - tableCmd.Parameters.Add("@Name", System.Data.SqlDbType.Text).Value = session.Name; + tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = session.Name; tableCmd.ExecuteNonQuery(); connection.Close(); @@ -44,8 +44,27 @@ public void RemoveSession(StudyDTO session) var tableCmd = connection.CreateCommand(); tableCmd.CommandText = @"DELETE FROM SESSIONS - WHERE SessionId = @Id AND - SessionName = @Name"; + WHERE SessionId = @Id"; + + tableCmd.Parameters.Add("@Id", SqlDbType.Text).Value = session.Id; + + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } + } + + public void RemoveSession(StackDTO stack) + { + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + var tableCmd = connection.CreateCommand(); + + tableCmd.CommandText = @"DELETE FROM SESSIONS + WHERE SessionId = @Id"; + + tableCmd.Parameters.Add("@Id", SqlDbType.Text).Value = stack.Id; tableCmd.ExecuteNonQuery(); @@ -53,6 +72,7 @@ public void RemoveSession(StudyDTO session) } } + public void EditSession(StudyDTO session) { using (var connection = new SqlConnection(connectionString)) From 604a9bfcd33865eaf6ce6796fe4247a417c3d718 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Thu, 19 Feb 2026 20:56:44 -0500 Subject: [PATCH 18/23] Organized UserInterface into 4 main views --- .../Controllers/CardController.cs | 3 +- .../Controllers/StackController.cs | 3 +- .../Controllers/StudyController.cs | 4 +- .../Models/Enums/OptionUtils.cs | 2 - Flashcards.davetn657/Models/Enums/Options.cs | 17 +- Flashcards.davetn657/Program.cs | 9 +- Flashcards.davetn657/Views/CardView.cs | 93 +++++++ Flashcards.davetn657/Views/MainView.cs | 46 ++++ Flashcards.davetn657/Views/StackView.cs | 98 +++++++ .../Views/StudySessionView.cs | 79 ++++++ Flashcards.davetn657/Views/UserInterface.cs | 259 +----------------- 11 files changed, 349 insertions(+), 264 deletions(-) create mode 100644 Flashcards.davetn657/Views/CardView.cs create mode 100644 Flashcards.davetn657/Views/MainView.cs create mode 100644 Flashcards.davetn657/Views/StackView.cs create mode 100644 Flashcards.davetn657/Views/StudySessionView.cs diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index ee5b841f..73d02c2d 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -1,5 +1,4 @@ -using Flashcards.davetn657.Models; -using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models.DTOs; using Flashcards.davetn657.Models.Enums; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Configuration; diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index 9c8b0db2..dbf17291 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -1,5 +1,4 @@ -using Flashcards.davetn657.Models; -using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models.DTOs; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Configuration; using System.Data; diff --git a/Flashcards.davetn657/Controllers/StudyController.cs b/Flashcards.davetn657/Controllers/StudyController.cs index 33905741..8bb75261 100644 --- a/Flashcards.davetn657/Controllers/StudyController.cs +++ b/Flashcards.davetn657/Controllers/StudyController.cs @@ -19,7 +19,7 @@ public StudyController() this.connectionString = configuration.GetConnectionString("DatabaseConnection"); } - public void AddSession(StudyDTO session) + public void AddSession(string session) { using(var connection = new SqlConnection(connectionString)) { @@ -29,7 +29,7 @@ public void AddSession(StudyDTO session) tableCmd.CommandText = @"INSERT INTO SESSIONS (SessionName) VALUES (@Name)"; - tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = session.Name; + tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = session; tableCmd.ExecuteNonQuery(); connection.Close(); diff --git a/Flashcards.davetn657/Models/Enums/OptionUtils.cs b/Flashcards.davetn657/Models/Enums/OptionUtils.cs index 2a476c30..1b792687 100644 --- a/Flashcards.davetn657/Models/Enums/OptionUtils.cs +++ b/Flashcards.davetn657/Models/Enums/OptionUtils.cs @@ -44,6 +44,4 @@ public static Enum GetEnumValue(string description, Type enumType) } throw new Exception("Not Found."); } - - } diff --git a/Flashcards.davetn657/Models/Enums/Options.cs b/Flashcards.davetn657/Models/Enums/Options.cs index bd92e8e8..721ecaa1 100644 --- a/Flashcards.davetn657/Models/Enums/Options.cs +++ b/Flashcards.davetn657/Models/Enums/Options.cs @@ -6,22 +6,26 @@ namespace Flashcards.davetn657.Models.Enums; public enum MainMenuOptions { [Description("Start Studying")]StartStudy, - [Description("Manage Study Sessions")] ManageStudy, [Description("Manage Stacks")] ManageStack, [Description("Exit")] ExitApp } public enum ManageStudySessionOptions { - [Description("Create a Study Session")]CreateSeession, - [Description("Edit Study Session")] ChooseSession, + [Description("Create a Study Session")]CreateSession, [Description("Return")] Return } +public enum StudySessionOptions +{ + [Description("Start Session")]StartSession, + [Description("Rename Session")]RenameSession, + [Description("Return")]Return +} + public enum ManageStackOptions { [Description("Create Stack")] CreateStack, - [Description("Edit Stack")]ChooseStack, [Description("Return")] Return } @@ -41,3 +45,8 @@ public enum EditCardOptions [Description("Delete Card")]DeleteCard, [Description("Return")]Return } + +public enum ChooseCardsOptions +{ + [Description("Return")]Return +} \ No newline at end of file diff --git a/Flashcards.davetn657/Program.cs b/Flashcards.davetn657/Program.cs index 2b8be118..dc873ed2 100644 --- a/Flashcards.davetn657/Program.cs +++ b/Flashcards.davetn657/Program.cs @@ -1,11 +1,14 @@ -using Flashcards.davetn657.Views; +using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.Views; namespace Flashcards.davetn657; class Program { public static void Main(string[] args) { - UserInterface ui = new UserInterface(); - ui.StartApp(); + var sessionView = new StudySessionView(new StudyController()); + var stackView = new StackView(new StackController(), new CardView(new CardController())); + MainView view = new MainView(sessionView, stackView); + view.StartApp(); } } diff --git a/Flashcards.davetn657/Views/CardView.cs b/Flashcards.davetn657/Views/CardView.cs new file mode 100644 index 00000000..f658c4dc --- /dev/null +++ b/Flashcards.davetn657/Views/CardView.cs @@ -0,0 +1,93 @@ +using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models.Enums; +using Spectre.Console; + +namespace Flashcards.davetn657.Views; +public class CardView : UserInterface +{ + private readonly CardController _cardController; + + public CardView(CardController cardController) + { + _cardController = cardController; + } + + internal void CreateCard(StackDTO stack) + { + TitleCard("Create a new Card"); + + var input = string.Empty; + var card = new CardDTO(); + + input = AnsiConsole.Ask("Input question details (type: r to return):"); + if (input.ToLower() == "r") return; + card.Question = input; + + input = AnsiConsole.Ask("Input answer details (type: r to return):"); + if (input.ToLower() == "r") return; + card.Answer = input; + + _cardController.AddCard(card, stack); + } + + internal void ChooseCard(StackDTO stack) + { + TitleCard($"{stack.Name} Cards"); + + var menuOptions = OptionUtils.GetAllStringValues(typeof(ChooseCardsOptions)); + var cards = _cardController.ReadAllCards(); + menuOptions.Concat(cards.Keys); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + + if (cards.ContainsKey(input)) + { + EditCard(cards[input]); + } + } + + internal void EditCard(CardDTO card) + { + var endEdit = false; + + while (!endEdit) + { + TitleCard($"Edit Card : {card.Question}"); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(OptionUtils.GetAllStringValues(typeof(EditCardOptions)))); + var selectedOption = OptionUtils.GetEnumValue(input, typeof(EditCardOptions)); + + switch (selectedOption) + { + case EditCardOptions.ChangeQuestion: + ChangeCardDetails(card, selectedOption); + break; + case EditCardOptions.ChangeAnswer: + ChangeCardDetails(card, selectedOption); + break; + case EditCardOptions.DeleteCard: + _cardController.RemoveCard(card); + AnsiConsole.WriteLine("Successfully removed card!"); + AnsiConsole.MarkupLine("Press Enter to Return"); + endEdit = true; + break; + case EditCardOptions.Return: + endEdit = true; + break; + } + } + + } + + private void ChangeCardDetails(CardDTO card, Enum option) + { + TitleCard(OptionUtils.GetStringValue(option)); + + var input = AnsiConsole.Ask("Enter details (type: r to return):"); + + if (input.ToLower() == "r") return; + + _cardController.EditCard(card, option); + } +} diff --git a/Flashcards.davetn657/Views/MainView.cs b/Flashcards.davetn657/Views/MainView.cs new file mode 100644 index 00000000..f3dd8c9f --- /dev/null +++ b/Flashcards.davetn657/Views/MainView.cs @@ -0,0 +1,46 @@ +using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.Models.Enums; +using Spectre.Console; + +namespace Flashcards.davetn657.Views; + +public class MainView : UserInterface +{ + private readonly StudySessionView _studySessionView; + private readonly StackView _stackView; + + public MainView(StudySessionView studySessionView, StackView stackView) + { + _studySessionView = studySessionView; + _stackView = stackView; + } + + public void StartApp() + { + var endApp = false; + + while (!endApp) + { + TitleCard("Main Menu"); + + var menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var inputValue = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); + + + switch (inputValue) + { + case MainMenuOptions.StartStudy: + _studySessionView.StudySession(); + break; + case MainMenuOptions.ManageStack: + _stackView.ManageStack(); + break; + case MainMenuOptions.ExitApp: + endApp = true; + break; + } + } + } +} \ No newline at end of file diff --git a/Flashcards.davetn657/Views/StackView.cs b/Flashcards.davetn657/Views/StackView.cs new file mode 100644 index 00000000..c57327cb --- /dev/null +++ b/Flashcards.davetn657/Views/StackView.cs @@ -0,0 +1,98 @@ +using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models.Enums; +using Spectre.Console; + +namespace Flashcards.davetn657.Views; + +public class StackView : UserInterface +{ + private readonly StackController _stackController; + private readonly CardView _cardView; + + public StackView(StackController stackController, CardView cardView) + { + _stackController = stackController; + _cardView = cardView; + } + + internal void ManageStack() + { + TitleCard("Manage Stacks"); + + var options = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); + var stacks = _stackController.ReadAllStacks(); + var menuOptions = options.Concat(stacks.Keys); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); + + if (stacks.ContainsKey(input)) + { + EditStack(stacks[input]); + } + else + { + switch (optionSelected) + { + case ManageStackOptions.CreateStack: + var name = ChooseName(stacks.Keys); + if (name != string.Empty) + { + _stackController.AddStack(name); + AnsiConsole.WriteLine($"Stack named {name} created!\n"); + } + AnsiConsole.MarkupLine("Press Enter to Return"); + break; + case ManageStackOptions.Return: + break; + } + } + + } + + private void EditStack(StackDTO stack) + { + var endEdit = false; + + while (!endEdit) + { + TitleCard($"Edit : {stack.Name}"); + + var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var optionSelected = OptionUtils.GetEnumValue(input, typeof(EditStackOptions)); + + switch (optionSelected) + { + case EditStackOptions.RenameStack: + var stacks = _stackController.ReadAllStacks(); + var name = ChooseName(stacks.Keys); + if (name != string.Empty) + { + stack.Name = name; + _stackController.EditStack(stack); + AnsiConsole.WriteLine($"Stack renamed to: {name}\n"); + } + AnsiConsole.MarkupLine("Press Enter to Return"); + break; + case EditStackOptions.CreateCard: + _cardView.CreateCard(stack); + break; + case EditStackOptions.ChooseCard: + _cardView.ChooseCard(stack); + break; + case EditStackOptions.DeleteStack: + _stackController.RemoveStack(stack); + AnsiConsole.WriteLine("Successfully removed stack!"); + AnsiConsole.MarkupLine("Press Enter to Return"); + endEdit = true; + break; + case EditStackOptions.Return: + endEdit = true; + break; + } + } + } +} \ No newline at end of file diff --git a/Flashcards.davetn657/Views/StudySessionView.cs b/Flashcards.davetn657/Views/StudySessionView.cs new file mode 100644 index 00000000..7f998af1 --- /dev/null +++ b/Flashcards.davetn657/Views/StudySessionView.cs @@ -0,0 +1,79 @@ +using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models.Enums; +using Spectre.Console; + +namespace Flashcards.davetn657.Views; + +public class StudySessionView : UserInterface +{ + private readonly StudyController _studyController; + + public StudySessionView(StudyController studyController) + { + _studyController = studyController; + } + + internal void StudySession() + { + TitleCard("Study Session"); + + var options = OptionUtils.GetAllStringValues(typeof(ManageStudySessionOptions)); + var sessions = _studyController.ReadAllSessions(); + var menuOptions = options.Concat(sessions.Keys); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + + if (sessions.ContainsKey(input)) + { + StartOrEditSession(sessions[input]); + } + else + { + var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStudySessionOptions)); + + switch (optionSelected) + { + case ManageStudySessionOptions.CreateSession: + var name = ChooseName(sessions.Keys); + if (!string.IsNullOrEmpty(name)) + { + _studyController.AddSession(name); + AnsiConsole.WriteLine($"Study session named {name} created!\n"); + } + AnsiConsole.MarkupLine("Press Enter to Return"); + break; + case ManageStudySessionOptions.Return: + break; + } + } + } + + private void StartOrEditSession(StudyDTO session) + { + TitleCard(session.Name); + + var menuOptions = OptionUtils.GetAllStringValues(typeof(StudySessionOptions)); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var optionSelected = OptionUtils.GetEnumValue(input, typeof(StudySessionOptions)); + + switch (optionSelected) + { + case StudySessionOptions.StartSession: + break; + case StudySessionOptions.RenameSession: + var sessions = _studyController.ReadAllSessions(); + var name = ChooseName(sessions.Keys); + if(name != string.Empty) + { + _studyController.AddSession(name); + AnsiConsole.WriteLine($"Study session renamed {name}!\n"); + } + AnsiConsole.MarkupLine("Press Enter to Return"); + break; + case StudySessionOptions.Return: + break; + } + } +} \ No newline at end of file diff --git a/Flashcards.davetn657/Views/UserInterface.cs b/Flashcards.davetn657/Views/UserInterface.cs index 1e2a0bdc..76d94354 100644 --- a/Flashcards.davetn657/Views/UserInterface.cs +++ b/Flashcards.davetn657/Views/UserInterface.cs @@ -1,269 +1,32 @@ using Spectre.Console; -using Flashcards.davetn657.Controllers; -using Flashcards.davetn657.Models.Enums; -using Flashcards.davetn657.Models.DTOs; namespace Flashcards.davetn657.Views; public class UserInterface { - private StackController stackController; - private CardController cardController; - - public UserInterface() + internal string ChooseName(IEnumerable namesInUse) { - stackController = new StackController(); - cardController = new CardController(); - } - - public void StartApp() - { - var endApp = false; - - while (!endApp) - { - TitleCard("Main Menu"); - - var menuOptions = OptionUtils.GetAllStringValues(typeof(MainMenuOptions)); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var inputValue = OptionUtils.GetEnumValue(input, typeof(MainMenuOptions)); - - - switch (inputValue) - { - case MainMenuOptions.StartStudy: - StudySession(); - break; - case MainMenuOptions.ManageStudy: - ManageStudySessions(); - break; - case MainMenuOptions.ManageStack: - ManageStack(); - break; - case MainMenuOptions.ExitApp: - endApp = true; - break; - } - } - } - - private void StudySession() - { - TitleCard("Study Session"); - } - - private void ManageStudySessions() - { - TitleCard("Manage Sessions"); - - var menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStudySessionOptions)); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStudySessionOptions)); - - switch (optionSelected) - { - case ManageStudySessionOptions.CreateSeession: - break; - case ManageStudySessionOptions.ChooseSession: - break; - case ManageStudySessionOptions.Return: - break; - } - } - - - - private void ManageStack() - { - TitleCard("Manage Stacks"); - - var menuOptions = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); - - switch (optionSelected) - { - case ManageStackOptions.CreateStack: - stackController.AddStack(NameStack()); - AnsiConsole.WriteLine($"Stack named {input} created!\n"); - AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Press Enter to Return")); - break; - case ManageStackOptions.ChooseStack: - ChooseStack(); - break; - case ManageStackOptions.Return: - break; - } - } - - private void ChooseStack() - { - TitleCard("Edit a Stack"); - - var stacks = stackController.ReadAllStacks(); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(stacks.Keys).AddChoices("Return") ); - - switch (input) - { - case "Return": - break; - default: - EditStack(stacks[input]); - break; - } - } - - private void EditStack(StackDTO stack) - { - var endEdit = false; - - while (!endEdit) - { - TitleCard($"Edit : {stack.Name}"); - - var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var optionSelected = OptionUtils.GetEnumValue(input, typeof(EditStackOptions)); - - switch (optionSelected) - { - case EditStackOptions.RenameStack: - var name = NameStack(); - stack.Name = name; - if(name != string.Empty) stackController.EditStack(stack); - break; - case EditStackOptions.CreateCard: - CreateCard(stack); - break; - case EditStackOptions.ChooseCard: - ChooseCard(stack); - break; - case EditStackOptions.DeleteStack: - stackController.RemoveStack(stack); - cardController.RemoveCardsFromStack(stack); - AnsiConsole.WriteLine("Successfully removed stack!"); - AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Return?")); - endEdit = true; - break; - case EditStackOptions.Return: - endEdit = true; - break; - } - } - } - - private string NameStack() - { - TitleCard("Name your Stack"); + TitleCard("Choose a Name"); var input = string.Empty; - var cards = stackController.ReadAllStacks(); - + while (true) { - input = AnsiConsole.Ask("Name your stack (type: r to return):"); - - if (!cards.ContainsKey(input) && input != "Return") - { - return input; - } - else if(input.ToLower() == "r") + input = AnsiConsole.Ask("Type a Name (type: r to return):"); + if (input.ToLower() == "r") { return string.Empty; } - else - { - AnsiConsole.Markup("[red]Stack Name Already in Use or Not Available Choose a Different Name![/]\n"); - } - } - } - - private void CreateCard(StackDTO stack) - { - TitleCard("Create a new Card"); - - var input = string.Empty; - var cards = cardController.ReadAllCards(); - var card = new CardDTO(); - input = AnsiConsole.Ask("Input question details (type: r to return):"); - if (input.ToLower() == "r") return; - card.Question = input; - - input = AnsiConsole.Ask("Input answer details (type: r to return):"); - if (input.ToLower() == "r") return; - card.Answer = input; - - cardController.AddCard(card, stack); - } - - private void ChooseCard(StackDTO stack) - { - TitleCard($"{stack.Name} Cards"); - - var allCards = cardController.ReadAllCards(); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(allCards.Keys).AddChoices("Return")); - - switch (input) - { - case "Return": - break; - default: - EditCard(allCards[input]); - break; - } - } - - private void EditCard(CardDTO card) - { - var endEdit = false; - - while (!endEdit) - { - TitleCard($"Edit Card : {card.Question}"); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(OptionUtils.GetAllStringValues(typeof(EditCardOptions)))); - var selectedOption = OptionUtils.GetEnumValue(input, typeof(EditCardOptions)); - - switch (selectedOption) + if (!namesInUse.Contains(input)) { - case EditCardOptions.ChangeQuestion: - ChangeCardDetails(card, selectedOption); - break; - case EditCardOptions.ChangeAnswer: - ChangeCardDetails(card, selectedOption); - break; - case EditCardOptions.DeleteCard: - cardController.RemoveCard(card); - AnsiConsole.WriteLine("Successfully removed card!"); - AnsiConsole.Prompt(new SelectionPrompt().AddChoices("Return?")); - endEdit = true; - break; - case EditCardOptions.Return: - endEdit = true; - break; + return input; } + + AnsiConsole.Markup("[red]Name Already in Use or Not Available Choose a Different Name![/]\n"); } - } - private void ChangeCardDetails(CardDTO card, Enum option) - { - TitleCard(OptionUtils.GetStringValue(option)); - - var input = AnsiConsole.Ask("Enter details (type: r to return):"); - - if (input.ToLower() == "r") return; - - cardController.EditCard(card, option); - } - - private void TitleCard(string title) + internal void TitleCard(string title) { var titleFiglet = new FigletText(title); @@ -272,7 +35,5 @@ private void TitleCard(string title) AnsiConsole.Clear(); AnsiConsole.Write(centered); } - - } From a55e2a2fb5bbb37e4c075cdbd10b6c191b77cc48 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Wed, 25 Feb 2026 04:07:56 -0500 Subject: [PATCH 19/23] Added flashcard display and functionality for study sessions, added past week report, refactored views to align with main menu format --- .../Controllers/CardController.cs | 69 +++- .../Controllers/ScoreController.cs | 77 +++++ .../Controllers/StackController.cs | 41 ++- .../Controllers/StudyController.cs | 39 +-- Flashcards.davetn657/Models/DTOs/ScoreDTO.cs | 9 + Flashcards.davetn657/Models/DTOs/StudyDTO.cs | 1 + Flashcards.davetn657/Models/Enums/Options.cs | 56 +-- Flashcards.davetn657/Models/Globals.cs | 2 +- Flashcards.davetn657/Program.cs | 11 +- Flashcards.davetn657/Views/CardView.cs | 93 ----- Flashcards.davetn657/Views/MainView.cs | 19 +- Flashcards.davetn657/Views/ManageDataView.cs | 320 ++++++++++++++++++ Flashcards.davetn657/Views/StackView.cs | 98 ------ .../Views/StartStudySessionView.cs | 190 +++++++++++ .../Views/StudySessionView.cs | 79 ----- 15 files changed, 755 insertions(+), 349 deletions(-) create mode 100644 Flashcards.davetn657/Controllers/ScoreController.cs create mode 100644 Flashcards.davetn657/Models/DTOs/ScoreDTO.cs delete mode 100644 Flashcards.davetn657/Views/CardView.cs create mode 100644 Flashcards.davetn657/Views/ManageDataView.cs delete mode 100644 Flashcards.davetn657/Views/StackView.cs create mode 100644 Flashcards.davetn657/Views/StartStudySessionView.cs delete mode 100644 Flashcards.davetn657/Views/StudySessionView.cs diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index 73d02c2d..8511dd35 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -1,4 +1,5 @@ -using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models; +using Flashcards.davetn657.Models.DTOs; using Flashcards.davetn657.Models.Enums; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Configuration; @@ -20,7 +21,7 @@ public CardController() this.connectionString = configuration.GetConnectionString("DatabaseConnection"); } - public void AddCard(CardDTO card, StackDTO stack) + internal void AddCard(CardDTO card, StackDTO stack) { using (SqlConnection connection = new SqlConnection(connectionString)) { @@ -40,7 +41,7 @@ public void AddCard(CardDTO card, StackDTO stack) } } - public void RemoveCard(CardDTO card) + internal void RemoveCard(CardDTO card) { using (var connection = new SqlConnection(connectionString)) { @@ -59,7 +60,7 @@ public void RemoveCard(CardDTO card) } - public void RemoveCard(StackDTO stack) + internal void RemoveCard(StackDTO stack) { using (var connection = new SqlConnection(connectionString)) { @@ -78,7 +79,7 @@ public void RemoveCard(StackDTO stack) } - public void EditCard(CardDTO card, Enum option) + internal void EditCard(CardDTO card, Enum option) { using(var connection = new SqlConnection(connectionString)) { @@ -108,7 +109,29 @@ public void EditCard(CardDTO card, Enum option) } } - public Dictionary ReadAllCards() + internal void ChangeTime(CardDTO card, DateTime timeChange) + { + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"UPDATE CARDS + SET LastAppearance = @today, + NextAppearance = @time + WHERE CardId = @id"; + + tableCmd.Parameters.Add("@today", SqlDbType.DateTime).Value = DateTime.Now; + tableCmd.Parameters.Add("@time", SqlDbType.DateTime).Value = timeChange; + tableCmd.Parameters.Add("@id", SqlDbType.Int).Value = card.Id; + + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } + } + + internal Dictionary ReadAllCards() { var allCards = new Dictionary(); @@ -137,4 +160,38 @@ public Dictionary ReadAllCards() return allCards; } + + internal Dictionary ReadAllCards(StudyDTO session) + { + var allCards = new Dictionary(); + + using(var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"SELECT * FROM CARDS + WHERE StackId = @id + ORDER BY NextAppearance DESC"; + + tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = session.StackId; + + var reader = tableCmd.ExecuteReader(); + + while (reader.Read()) + { + var card = new CardDTO(); + card.Id = reader.GetInt32("CardId"); + card.Question = reader.GetString("CardQuestion"); + card.Answer = reader.GetString("CardAnswer"); + card.LastAppearance = reader.GetDateTime("LastAppearance"); + card.NextAppearance = reader.GetDateTime("NextAppearance"); + allCards.Add(card.Question, card); + } + + connection.Close(); + } + + return allCards; + } } diff --git a/Flashcards.davetn657/Controllers/ScoreController.cs b/Flashcards.davetn657/Controllers/ScoreController.cs new file mode 100644 index 00000000..f922c427 --- /dev/null +++ b/Flashcards.davetn657/Controllers/ScoreController.cs @@ -0,0 +1,77 @@ +using Flashcards.davetn657.Models.DTOs; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; +using System.Data; + +namespace Flashcards.davetn657.Controllers; + +public class ScoreController +{ + private IConfiguration configuration; + private string? connectionString; + + public ScoreController() + { + this.configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + this.connectionString = configuration.GetConnectionString("DatabaseConnection"); + } + + internal void AddScore(StudyDTO session, ScoreDTO score) + { + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"INSERT INTO SCORES (SessionId, Score) + VALUES (@id, @score)"; + + tableCmd.Parameters.Add("@id", SqlDbType.Int).Value = session.Id; + tableCmd.Parameters.Add("@score", SqlDbType.Int).Value = score.Score; + + tableCmd.ExecuteNonQuery(); + + connection.Close(); + } + } + + internal List GetScores(int numberOfDays) + { + var pastScores = new List(); + + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"SELECT Sessions.StackId, Sessions.SessionName, Scores.Score, Scores.CreateDate + FROM Sessions + LEFT JOIN Scores ON Sessions.SessionId = Scores.SessionId + WHERE CAST(Scores.CreateDate AS DATE) >= DATEADD(day, @numDays, GETDATE()) + GROUP BY Sessions.StackId, Sessions.SessionName, Scores.Score, Scores.CreateDate + ORDER BY Scores.CreateDate DESC"; + + tableCmd.Parameters.Add("@numDays", SqlDbType.Int).Value = -numberOfDays; + + var reader = tableCmd.ExecuteReader(); + + while (reader.Read()) + { + var data = new ScoreDTO(); + data.SessionId = reader.GetInt32("StackId"); + data.Name = reader.GetString("SessionName"); + data.Score = reader.GetInt32("Score"); + data.CreateDate = reader.GetDateTime("CreateDate"); + + pastScores.Add(data); + } + + connection.Close(); + } + + return pastScores; + } +} diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index dbf17291..38f583a5 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -18,7 +18,7 @@ public StackController() this.connectionString = configuration.GetConnectionString("DatabaseConnection"); } - public void AddStack(string name) + internal void AddStack(string name) { using(var connection = new SqlConnection(connectionString)) { @@ -37,7 +37,7 @@ public void AddStack(string name) } } - public void RemoveStack(StackDTO stack) + internal void RemoveStack(StackDTO stack) { using(var connection = new SqlConnection(connectionString)) { @@ -46,11 +46,9 @@ public void RemoveStack(StackDTO stack) var tableCmd = connection.CreateCommand(); tableCmd.CommandText = @"DELETE FROM STACKS WHERE - StackId = @Id AND - StackName = @Name"; + StackId = @Id"; tableCmd.Parameters.Add("@Id", SqlDbType.Int).Value = stack.Id; - tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = stack.Name; tableCmd.ExecuteNonQuery(); @@ -58,7 +56,7 @@ public void RemoveStack(StackDTO stack) } } - public void RemoveStack(StackDTO stack, CardController cardController, StudyController sessionController) + internal void RemoveStack(StackDTO stack, CardController cardController, StudyController sessionController) { using (var connection = new SqlConnection(connectionString)) { @@ -81,7 +79,7 @@ public void RemoveStack(StackDTO stack, CardController cardController, StudyCont } } - public void EditStack(StackDTO stack) + internal void EditStack(StackDTO stack) { using (var connection = new SqlConnection(connectionString)) { @@ -101,7 +99,7 @@ public void EditStack(StackDTO stack) } } - public Dictionary ReadAllStacks() + internal Dictionary ReadAllStacks() { var allStacks = new Dictionary(); @@ -128,4 +126,31 @@ public Dictionary ReadAllStacks() return allStacks; } + internal StackDTO ReadAllStacks(StudyDTO session) + { + var stack = new StackDTO(); + + using (var connection = new SqlConnection(connectionString)) + { + connection.Open(); + + var tableCmd = connection.CreateCommand(); + tableCmd.CommandText = @"SELECT * FROM STACKS + WHERE StackId = @id"; + + tableCmd.Parameters.Add("@id", SqlDbType.Int).Value = session.StackId; + + var reader = tableCmd.ExecuteReader(); + + while (reader.Read()) + { + stack.Id = reader.GetInt32("StackId"); + stack.Name = reader.GetString("StackName"); + } + + connection.Close(); + } + + return stack; + } } diff --git a/Flashcards.davetn657/Controllers/StudyController.cs b/Flashcards.davetn657/Controllers/StudyController.cs index 8bb75261..4e28bcdd 100644 --- a/Flashcards.davetn657/Controllers/StudyController.cs +++ b/Flashcards.davetn657/Controllers/StudyController.cs @@ -19,42 +19,25 @@ public StudyController() this.connectionString = configuration.GetConnectionString("DatabaseConnection"); } - public void AddSession(string session) + internal void AddSession(StudyDTO session) { using(var connection = new SqlConnection(connectionString)) { connection.Open(); var tableCmd = connection.CreateCommand(); - tableCmd.CommandText = @"INSERT INTO SESSIONS (SessionName) - VALUES (@Name)"; - - tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = session; - tableCmd.ExecuteNonQuery(); - - connection.Close(); - } - } - - public void RemoveSession(StudyDTO session) - { - using(var connection = new SqlConnection(connectionString)) - { - connection.Open(); - var tableCmd = connection.CreateCommand(); - - tableCmd.CommandText = @"DELETE FROM SESSIONS - WHERE SessionId = @Id"; - - tableCmd.Parameters.Add("@Id", SqlDbType.Text).Value = session.Id; + tableCmd.CommandText = @"INSERT INTO SESSIONS (StackId, SessionName) + VALUES (@id, @Name)"; + tableCmd.Parameters.Add("@id", SqlDbType.Int).Value = session.StackId; + tableCmd.Parameters.Add("@Name", SqlDbType.Text).Value = session.Name; tableCmd.ExecuteNonQuery(); connection.Close(); } } - public void RemoveSession(StackDTO stack) + internal void RemoveSession(StackDTO stack) { using (var connection = new SqlConnection(connectionString)) { @@ -73,7 +56,7 @@ public void RemoveSession(StackDTO stack) } - public void EditSession(StudyDTO session) + internal void EditSession(StudyDTO session) { using (var connection = new SqlConnection(connectionString)) { @@ -92,7 +75,7 @@ public void EditSession(StudyDTO session) } } - public Dictionary ReadAllSessions() + internal Dictionary ReadAllSessions() { var allSessions = new Dictionary(); @@ -108,9 +91,9 @@ public Dictionary ReadAllSessions() while (reader.Read()) { var session = new StudyDTO(); - session.Id = reader.GetInt32("StudyId"); - session.Id = reader.GetInt32("StackId"); - session.Name = reader.GetString("StudyName"); + session.Id = reader.GetInt32("SessionId"); + session.StackId = reader.GetInt32("StackId"); + session.Name = reader.GetString("SessionName"); allSessions.Add(session.Name, session); } diff --git a/Flashcards.davetn657/Models/DTOs/ScoreDTO.cs b/Flashcards.davetn657/Models/DTOs/ScoreDTO.cs new file mode 100644 index 00000000..3c2ab044 --- /dev/null +++ b/Flashcards.davetn657/Models/DTOs/ScoreDTO.cs @@ -0,0 +1,9 @@ +namespace Flashcards.davetn657.Models.DTOs; + +internal class ScoreDTO +{ + public int SessionId { get; set; } + public string Name { get; set; } + public int Score { get; set; } + public DateTime CreateDate { get; set; } +} diff --git a/Flashcards.davetn657/Models/DTOs/StudyDTO.cs b/Flashcards.davetn657/Models/DTOs/StudyDTO.cs index 7e2daf2d..d87ff9a0 100644 --- a/Flashcards.davetn657/Models/DTOs/StudyDTO.cs +++ b/Flashcards.davetn657/Models/DTOs/StudyDTO.cs @@ -5,4 +5,5 @@ public class StudyDTO public int Id { get; set; } public int StackId { get; set; } public string Name { get; set; } + public int Score { get; set; } } \ No newline at end of file diff --git a/Flashcards.davetn657/Models/Enums/Options.cs b/Flashcards.davetn657/Models/Enums/Options.cs index 721ecaa1..83c36b3e 100644 --- a/Flashcards.davetn657/Models/Enums/Options.cs +++ b/Flashcards.davetn657/Models/Enums/Options.cs @@ -1,52 +1,62 @@ using System.ComponentModel; -using System.Reflection; - namespace Flashcards.davetn657.Models.Enums; public enum MainMenuOptions { - [Description("Start Studying")]StartStudy, - [Description("Manage Stacks")] ManageStack, + [Description("Start studying")]StartStudy, + [Description("Manage data")] ManageData, [Description("Exit")] ExitApp } -public enum ManageStudySessionOptions +public enum ManageDataOptions { - [Description("Create a Study Session")]CreateSession, - [Description("Return")] Return + [Description("Return")] Return, + [Description("Manage study sessions")]ManageSessions, + [Description("Manage stacks")]ManageStacks } -public enum StudySessionOptions +public enum ManageStudySessionOptions { - [Description("Start Session")]StartSession, - [Description("Rename Session")]RenameSession, - [Description("Return")]Return + [Description("Return")] Return, + [Description("Create a new session")]CreateSession } public enum ManageStackOptions { - [Description("Create Stack")] CreateStack, - [Description("Return")] Return + [Description("Return")] Return, + [Description("Create stack")] CreateStack } public enum EditStackOptions { - [Description("Rename Stack")]RenameStack, - [Description("Add a Card")]CreateCard, - [Description("Edit Card")]ChooseCard, - [Description("Delete Stack")]DeleteStack, - [Description("Return")]Return + [Description("Return")] Return, + [Description("Rename stack")]RenameStack, + [Description("Add a card")]CreateCard, + [Description("Edit card")]ChooseCard, + [Description("Delete stack")]DeleteStack } -public enum EditCardOptions +public enum EditCardOptions +{ + [Description("Return")] Return, + [Description("Change question")]ChangeQuestion, + [Description("Change answer")]ChangeAnswer, + [Description("Delete card")]DeleteCard +} + +public enum ChooseDataOptions { - [Description("Change Question")]ChangeQuestion, - [Description("Change Answer")]ChangeAnswer, - [Description("Delete Card")]DeleteCard, [Description("Return")]Return } -public enum ChooseCardsOptions +public enum FlashcardOptions { + [Description("Reveal card")]Reveal, [Description("Return")]Return +} + +public enum RevealedFlashcardOptions +{ + [Description("Need to study more")]StudyAgain, + [Description("I understood it well")]Understood, } \ No newline at end of file diff --git a/Flashcards.davetn657/Models/Globals.cs b/Flashcards.davetn657/Models/Globals.cs index 0709fb7a..c3445981 100644 --- a/Flashcards.davetn657/Models/Globals.cs +++ b/Flashcards.davetn657/Models/Globals.cs @@ -3,5 +3,5 @@ namespace Flashcards.davetn657.Models; public class Globals { - public static readonly IFormatProvider CULTURE_INFO = new CultureInfo("en-US"); + public static readonly string DATE_FORMAT = "dd/MM/yyyy"; } \ No newline at end of file diff --git a/Flashcards.davetn657/Program.cs b/Flashcards.davetn657/Program.cs index dc873ed2..8ca23843 100644 --- a/Flashcards.davetn657/Program.cs +++ b/Flashcards.davetn657/Program.cs @@ -6,9 +6,14 @@ class Program { public static void Main(string[] args) { - var sessionView = new StudySessionView(new StudyController()); - var stackView = new StackView(new StackController(), new CardView(new CardController())); - MainView view = new MainView(sessionView, stackView); + var studyController = new StudyController(); + var stackController = new StackController(); + var cardController = new CardController(); + var scoreController = new ScoreController(); + + var manageDataview = new ManageDataView(studyController, stackController, cardController); + var startStudySession = new StartStudySessionView(studyController, cardController, scoreController); + MainView view = new MainView(manageDataview, startStudySession); view.StartApp(); } } diff --git a/Flashcards.davetn657/Views/CardView.cs b/Flashcards.davetn657/Views/CardView.cs deleted file mode 100644 index f658c4dc..00000000 --- a/Flashcards.davetn657/Views/CardView.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Flashcards.davetn657.Controllers; -using Flashcards.davetn657.Models.DTOs; -using Flashcards.davetn657.Models.Enums; -using Spectre.Console; - -namespace Flashcards.davetn657.Views; -public class CardView : UserInterface -{ - private readonly CardController _cardController; - - public CardView(CardController cardController) - { - _cardController = cardController; - } - - internal void CreateCard(StackDTO stack) - { - TitleCard("Create a new Card"); - - var input = string.Empty; - var card = new CardDTO(); - - input = AnsiConsole.Ask("Input question details (type: r to return):"); - if (input.ToLower() == "r") return; - card.Question = input; - - input = AnsiConsole.Ask("Input answer details (type: r to return):"); - if (input.ToLower() == "r") return; - card.Answer = input; - - _cardController.AddCard(card, stack); - } - - internal void ChooseCard(StackDTO stack) - { - TitleCard($"{stack.Name} Cards"); - - var menuOptions = OptionUtils.GetAllStringValues(typeof(ChooseCardsOptions)); - var cards = _cardController.ReadAllCards(); - menuOptions.Concat(cards.Keys); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - - if (cards.ContainsKey(input)) - { - EditCard(cards[input]); - } - } - - internal void EditCard(CardDTO card) - { - var endEdit = false; - - while (!endEdit) - { - TitleCard($"Edit Card : {card.Question}"); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(OptionUtils.GetAllStringValues(typeof(EditCardOptions)))); - var selectedOption = OptionUtils.GetEnumValue(input, typeof(EditCardOptions)); - - switch (selectedOption) - { - case EditCardOptions.ChangeQuestion: - ChangeCardDetails(card, selectedOption); - break; - case EditCardOptions.ChangeAnswer: - ChangeCardDetails(card, selectedOption); - break; - case EditCardOptions.DeleteCard: - _cardController.RemoveCard(card); - AnsiConsole.WriteLine("Successfully removed card!"); - AnsiConsole.MarkupLine("Press Enter to Return"); - endEdit = true; - break; - case EditCardOptions.Return: - endEdit = true; - break; - } - } - - } - - private void ChangeCardDetails(CardDTO card, Enum option) - { - TitleCard(OptionUtils.GetStringValue(option)); - - var input = AnsiConsole.Ask("Enter details (type: r to return):"); - - if (input.ToLower() == "r") return; - - _cardController.EditCard(card, option); - } -} diff --git a/Flashcards.davetn657/Views/MainView.cs b/Flashcards.davetn657/Views/MainView.cs index f3dd8c9f..3ec1efbd 100644 --- a/Flashcards.davetn657/Views/MainView.cs +++ b/Flashcards.davetn657/Views/MainView.cs @@ -1,18 +1,17 @@ -using Flashcards.davetn657.Controllers; -using Flashcards.davetn657.Models.Enums; +using Flashcards.davetn657.Models.Enums; using Spectre.Console; namespace Flashcards.davetn657.Views; public class MainView : UserInterface { - private readonly StudySessionView _studySessionView; - private readonly StackView _stackView; + private readonly ManageDataView _manageDataView; + private readonly StartStudySessionView _startStudySession; - public MainView(StudySessionView studySessionView, StackView stackView) + public MainView(ManageDataView manageDataView, StartStudySessionView startStudySession) { - _studySessionView = studySessionView; - _stackView = stackView; + _manageDataView = manageDataView; + _startStudySession = startStudySession; } public void StartApp() @@ -32,10 +31,10 @@ public void StartApp() switch (inputValue) { case MainMenuOptions.StartStudy: - _studySessionView.StudySession(); + _startStudySession.ChooseStudySession(); break; - case MainMenuOptions.ManageStack: - _stackView.ManageStack(); + case MainMenuOptions.ManageData: + _manageDataView.ChooseDataToManage(); break; case MainMenuOptions.ExitApp: endApp = true; diff --git a/Flashcards.davetn657/Views/ManageDataView.cs b/Flashcards.davetn657/Views/ManageDataView.cs new file mode 100644 index 00000000..f2bdbfaa --- /dev/null +++ b/Flashcards.davetn657/Views/ManageDataView.cs @@ -0,0 +1,320 @@ +using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models.Enums; +using Spectre.Console; + +namespace Flashcards.davetn657.Views; + +public class ManageDataView : UserInterface +{ + private readonly StudyController _studyController; + private readonly StackController _stackController; + private readonly CardController _cardController; + + public ManageDataView(StudyController studyController, StackController stackController, CardController cardController) + { + _studyController = studyController; + _stackController = stackController; + _cardController = cardController; + } + + internal void ChooseDataToManage() + { + var endEdit = false; + + while (!endEdit) + { + TitleCard("Edit Data"); + + var menuOptions = OptionUtils.GetAllStringValues(typeof(ManageDataOptions)); + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var selectedOption = OptionUtils.GetEnumValue(input, typeof(ManageDataOptions)); + + switch (selectedOption) + { + case ManageDataOptions.ManageSessions: + ManageStudySession(); + break; + case ManageDataOptions.ManageStacks: + ManageStack(); + break; + case ManageDataOptions.Return: + endEdit = true; + break; + } + } + } + + // STUDY SESSIONS + + private void ManageStudySession() + { + var endEdit = false; + + while (!endEdit) + { + TitleCard("Study Session"); + + var options = OptionUtils.GetAllStringValues(typeof(ManageStudySessionOptions)); + var sessions = _studyController.ReadAllSessions(); + var menuOptions = options.Concat(sessions.Keys); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + + if (sessions.ContainsKey(input)) + { + SessionDetails(sessions[input]); + } + else + { + var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStudySessionOptions)); + + switch (optionSelected) + { + case ManageStudySessionOptions.CreateSession: + CreateSession(); + break; + case ManageStudySessionOptions.Return: + endEdit = true; + break; + } + } + } + } + + private void CreateSession() + { + TitleCard("Create a new session"); + + var input = AnsiConsole.Ask("Name your session (or type r to cancel):"); + + if (input.Equals('r')) return; + + TitleCard("What stack to add?"); + AnsiConsole.WriteLine("Choose which stack to add onto the study session"); + + var session = new StudyDTO(); + session.Name = input; + + var options = OptionUtils.GetAllStringValues(typeof(ChooseDataOptions)); + var stackOptions = _stackController.ReadAllStacks(); + var menuOptions = options.Concat(stackOptions.Keys); + + input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + + if (stackOptions.ContainsKey(input)) + { + session.StackId = stackOptions[input].Id; + + _studyController.AddSession(session); + AnsiConsole.Prompt(new TextPrompt("Press Enter to return...").AllowEmpty()); + } + } + + private void SessionDetails(StudyDTO session) + { + TitleCard(session.Name); + + var stack = _stackController.ReadAllStacks(session); + var cards = _cardController.ReadAllCards(session); + + var table = new Table(); + table.AddColumn("Stack Id"); + table.AddColumn("Stack"); + table.AddColumn("# of Cards"); + + table.AddRow(new string[] { stack.Id.ToString(), stack.Name, cards.Count.ToString() }); + + AnsiConsole.Write(table); + + AnsiConsole.Prompt(new TextPrompt("Press Enter to return...").AllowEmpty()); + } + + // STACKS + + private void ManageStack() + { + var endEdit = false; + + while (!endEdit) + { + TitleCard("Manage Stacks"); + + var options = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); + var stacks = _stackController.ReadAllStacks(); + var menuOptions = options.Concat(stacks.Keys); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + + if (stacks.ContainsKey(input)) + { + EditStack(stacks[input]); + } + else + { + var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); + + switch (optionSelected) + { + case ManageStackOptions.CreateStack: + var name = ChooseName(stacks.Keys); + if (name != string.Empty) + { + _stackController.AddStack(name); + AnsiConsole.WriteLine($"Stack named {name} created!\n"); + } + AnsiConsole.Prompt(new TextPrompt("Press Enter to return...").AllowEmpty()); + break; + case ManageStackOptions.Return: + endEdit = true; + break; + } + } + } + + } + + private void EditStack(StackDTO stack) + { + var endEdit = false; + + while (!endEdit) + { + TitleCard($"Edit : {stack.Name}"); + + var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + var optionSelected = OptionUtils.GetEnumValue(input, typeof(EditStackOptions)); + + switch (optionSelected) + { + case EditStackOptions.RenameStack: + var stacks = _stackController.ReadAllStacks(); + var name = ChooseName(stacks.Keys); + if (name != string.Empty) + { + stack.Name = name; + _stackController.EditStack(stack); + AnsiConsole.WriteLine($"Stack renamed to: {name}\n"); + } + AnsiConsole.Prompt(new TextPrompt("Press Enter to return...").AllowEmpty()); + break; + case EditStackOptions.CreateCard: + CreateCard(stack); + break; + case EditStackOptions.ChooseCard: + ChooseCard(stack); + break; + case EditStackOptions.DeleteStack: + _stackController.RemoveStack(stack); + AnsiConsole.WriteLine("Successfully removed stack!"); + AnsiConsole.Prompt(new TextPrompt("Press Enter to return...").AllowEmpty()); + endEdit = true; + break; + case EditStackOptions.Return: + endEdit = true; + break; + } + } + } + + // CARDS + + internal void CreateCard(StackDTO stack) + { + TitleCard("Create a new Card"); + + var input = string.Empty; + var card = new CardDTO(); + + input = AnsiConsole.Ask("Input question details (type: r to cancel):"); + if (input.ToLower() == "r") return; + card.Question = input; + + input = AnsiConsole.Ask("Input answer details (type: r to cancel):"); + if (input.ToLower() == "r") return; + card.Answer = input; + + _cardController.AddCard(card, stack); + } + + internal void ChooseCard(StackDTO stack) + { + var endEdit = false; + + while (!endEdit) + { + TitleCard($"{stack.Name} Cards"); + + var options = OptionUtils.GetAllStringValues(typeof(ChooseDataOptions)); + var cards = _cardController.ReadAllCards(); + var menuOptions = options.Concat(cards.Keys); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + + if (cards.ContainsKey(input)) + { + EditCard(cards[input]); + } + else + { + endEdit = true; + } + } + } + + internal void EditCard(CardDTO card) + { + var endEdit = false; + + while (!endEdit) + { + TitleCard($"Edit Card : {card.Question}"); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(OptionUtils.GetAllStringValues(typeof(EditCardOptions)))); + var selectedOption = OptionUtils.GetEnumValue(input, typeof(EditCardOptions)); + + switch (selectedOption) + { + case EditCardOptions.ChangeQuestion: + ChangeCardDetails(card, selectedOption); + break; + case EditCardOptions.ChangeAnswer: + ChangeCardDetails(card, selectedOption); + break; + case EditCardOptions.DeleteCard: + _cardController.RemoveCard(card); + AnsiConsole.WriteLine("Successfully removed card!"); + AnsiConsole.Prompt(new TextPrompt("Press Enter to return...").AllowEmpty()); + endEdit = true; + break; + case EditCardOptions.Return: + endEdit = true; + break; + } + } + + } + + private void ChangeCardDetails(CardDTO card, Enum option) + { + TitleCard(OptionUtils.GetStringValue(option)); + + var input = AnsiConsole.Ask("Enter details (type: r to return):"); + + if (input.ToLower() == "r") return; + + switch (option) + { + case EditCardOptions.ChangeQuestion: + card.Question = input; + break; + case EditCardOptions.ChangeAnswer: + card.Answer = input; + break; + } + + _cardController.EditCard(card, option); + } +} \ No newline at end of file diff --git a/Flashcards.davetn657/Views/StackView.cs b/Flashcards.davetn657/Views/StackView.cs deleted file mode 100644 index c57327cb..00000000 --- a/Flashcards.davetn657/Views/StackView.cs +++ /dev/null @@ -1,98 +0,0 @@ -using Flashcards.davetn657.Controllers; -using Flashcards.davetn657.Models.DTOs; -using Flashcards.davetn657.Models.Enums; -using Spectre.Console; - -namespace Flashcards.davetn657.Views; - -public class StackView : UserInterface -{ - private readonly StackController _stackController; - private readonly CardView _cardView; - - public StackView(StackController stackController, CardView cardView) - { - _stackController = stackController; - _cardView = cardView; - } - - internal void ManageStack() - { - TitleCard("Manage Stacks"); - - var options = OptionUtils.GetAllStringValues(typeof(ManageStackOptions)); - var stacks = _stackController.ReadAllStacks(); - var menuOptions = options.Concat(stacks.Keys); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStackOptions)); - - if (stacks.ContainsKey(input)) - { - EditStack(stacks[input]); - } - else - { - switch (optionSelected) - { - case ManageStackOptions.CreateStack: - var name = ChooseName(stacks.Keys); - if (name != string.Empty) - { - _stackController.AddStack(name); - AnsiConsole.WriteLine($"Stack named {name} created!\n"); - } - AnsiConsole.MarkupLine("Press Enter to Return"); - break; - case ManageStackOptions.Return: - break; - } - } - - } - - private void EditStack(StackDTO stack) - { - var endEdit = false; - - while (!endEdit) - { - TitleCard($"Edit : {stack.Name}"); - - var menuOptions = OptionUtils.GetAllStringValues(typeof(EditStackOptions)); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var optionSelected = OptionUtils.GetEnumValue(input, typeof(EditStackOptions)); - - switch (optionSelected) - { - case EditStackOptions.RenameStack: - var stacks = _stackController.ReadAllStacks(); - var name = ChooseName(stacks.Keys); - if (name != string.Empty) - { - stack.Name = name; - _stackController.EditStack(stack); - AnsiConsole.WriteLine($"Stack renamed to: {name}\n"); - } - AnsiConsole.MarkupLine("Press Enter to Return"); - break; - case EditStackOptions.CreateCard: - _cardView.CreateCard(stack); - break; - case EditStackOptions.ChooseCard: - _cardView.ChooseCard(stack); - break; - case EditStackOptions.DeleteStack: - _stackController.RemoveStack(stack); - AnsiConsole.WriteLine("Successfully removed stack!"); - AnsiConsole.MarkupLine("Press Enter to Return"); - endEdit = true; - break; - case EditStackOptions.Return: - endEdit = true; - break; - } - } - } -} \ No newline at end of file diff --git a/Flashcards.davetn657/Views/StartStudySessionView.cs b/Flashcards.davetn657/Views/StartStudySessionView.cs new file mode 100644 index 00000000..831a7cf0 --- /dev/null +++ b/Flashcards.davetn657/Views/StartStudySessionView.cs @@ -0,0 +1,190 @@ +using Flashcards.davetn657.Controllers; +using Flashcards.davetn657.Models; +using Flashcards.davetn657.Models.DTOs; +using Flashcards.davetn657.Models.Enums; +using Microsoft.IdentityModel.Tokens; +using Spectre.Console; + +namespace Flashcards.davetn657.Views; + +public class StartStudySessionView : UserInterface +{ + private readonly StudyController _studyController; + private readonly CardController _cardController; + private readonly ScoreController _scoreController; + + public StartStudySessionView(StudyController studyController, CardController cardController, ScoreController scoreController) + { + _studyController = studyController; + _cardController = cardController; + _scoreController = scoreController; + } + + internal void ChooseStudySession() + { + DisplayWeeklySummary(); + + var options = OptionUtils.GetAllStringValues(typeof(ChooseDataOptions)); + var session = _studyController.ReadAllSessions(); + var menuOptions = options.Concat(session.Keys); + + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + + if (session.ContainsKey(input)) + { + GenerateCards(session[input]); + } + else return; + } + + private void GenerateCards(StudyDTO session) + { + var cards = _cardController.ReadAllCards(session); + var menuOptions = OptionUtils.GetAllStringValues(typeof(FlashcardOptions)); + var revealedMenuOptions = OptionUtils.GetAllStringValues(typeof(RevealedFlashcardOptions)); + + var score = new ScoreDTO() + { + SessionId = session.Id, + Score = 0 + }; + + if (cards.IsNullOrEmpty()) + { + AnsiConsole.WriteLine("!!! This Study Session Has No Cards !!!\n!!! Please Add Cards in the Manage Data Options !!!"); + AnsiConsole.Prompt(new TextPrompt("Press Enter to return...").AllowEmpty()); + return; + } + + while (true) + { + TitleCard("Session in Progress..."); + + var currentCard = cards.FirstOrDefault().Value; + + var selectedOption = OptionUtils.GetEnumValue(DisplayCard(currentCard.Question, menuOptions), typeof(FlashcardOptions)); + + if (selectedOption.Equals(FlashcardOptions.Return)) break; + + TitleCard("The answer is..."); + + selectedOption = OptionUtils.GetEnumValue(DisplayCard(currentCard.Answer, revealedMenuOptions), typeof(RevealedFlashcardOptions)); + + var timeChange = new DateTime(); + var lastCard = cards.LastOrDefault().Value; + + AnsiConsole.WriteLine("How well did you understand?"); + switch (selectedOption) + { + case RevealedFlashcardOptions.StudyAgain: + timeChange = lastCard.NextAppearance.AddMinutes(10); + break; + case RevealedFlashcardOptions.Understood: + timeChange = lastCard.NextAppearance.AddHours(1); + break; + } + + _cardController.ChangeTime(currentCard, timeChange); + score.Score++; + + cards.Remove(currentCard.Question); + + if (cards.Count == 0) + { + cards = _cardController.ReadAllCards(session); + } + } + + _scoreController.AddScore(session, score); + + } + + private string DisplayCard(string cardDetails, List menuOptions) + { + var panel = new Panel(cardDetails) + { + Border = BoxBorder.Ascii + }; + + AnsiConsole.Write(panel); + var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); + + return input; + } + + //Should Display past week session summary + //should display breakdown of session types + private void DisplayWeeklySummary() + { + var allScoresBar = new BarChart() + .Label("Study Sessions in the Past Week") + .LeftAlignLabel(); + + var sessionsBreakdown = new BreakdownChart() + .Compact() + .ShowPercentage(); + + var sessions = new Dictionary(); + var dailyScores = new Dictionary(); + var totalScore = 0; + + var scores = _scoreController.GetScores(7); + if(scores.IsNullOrEmpty()) return; + + var colors = new Color[] + { + Color.Yellow, + Color.Green, + Color.Blue, + Color.Gold3, + Color.White, + Color.Red, + Color.Violet + }; + + foreach (var score in scores) + { + if (sessions.ContainsKey(score.Name)) + { + sessions[score.Name] += score.Score; + } + else + { + sessions.Add(score.Name, score.Score); + } + + if (dailyScores.ContainsKey(score.CreateDate.Date)) + { + dailyScores[score.CreateDate.Date] += score.Score; + } + else + { + dailyScores.Add(score.CreateDate.Date, score.Score); + } + totalScore += score.Score; + } + + var colorCount = colors.Count() - 1; + var randomHexDigit = new Random(); + + foreach (var score in dailyScores) + { + allScoresBar.AddItem(score.Key.ToString(Globals.DATE_FORMAT), score.Value, colors[colorCount]); + + colorCount--; + } + + foreach(var session in sessions) + { + var percentageOfTotalSessions = Math.Round(((float)session.Value / (float)totalScore) * 100, 2); + + sessionsBreakdown.AddItem(session.Key, percentageOfTotalSessions, Color.FromInt32(randomHexDigit.Next(1, 250))); + } + + var dailyScorePanel = new Panel(allScoresBar).Border(BoxBorder.Ascii); + + AnsiConsole.Clear(); + AnsiConsole.Write(dailyScorePanel); + AnsiConsole.Write(sessionsBreakdown); + } +} \ No newline at end of file diff --git a/Flashcards.davetn657/Views/StudySessionView.cs b/Flashcards.davetn657/Views/StudySessionView.cs deleted file mode 100644 index 7f998af1..00000000 --- a/Flashcards.davetn657/Views/StudySessionView.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Flashcards.davetn657.Controllers; -using Flashcards.davetn657.Models.DTOs; -using Flashcards.davetn657.Models.Enums; -using Spectre.Console; - -namespace Flashcards.davetn657.Views; - -public class StudySessionView : UserInterface -{ - private readonly StudyController _studyController; - - public StudySessionView(StudyController studyController) - { - _studyController = studyController; - } - - internal void StudySession() - { - TitleCard("Study Session"); - - var options = OptionUtils.GetAllStringValues(typeof(ManageStudySessionOptions)); - var sessions = _studyController.ReadAllSessions(); - var menuOptions = options.Concat(sessions.Keys); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - - if (sessions.ContainsKey(input)) - { - StartOrEditSession(sessions[input]); - } - else - { - var optionSelected = OptionUtils.GetEnumValue(input, typeof(ManageStudySessionOptions)); - - switch (optionSelected) - { - case ManageStudySessionOptions.CreateSession: - var name = ChooseName(sessions.Keys); - if (!string.IsNullOrEmpty(name)) - { - _studyController.AddSession(name); - AnsiConsole.WriteLine($"Study session named {name} created!\n"); - } - AnsiConsole.MarkupLine("Press Enter to Return"); - break; - case ManageStudySessionOptions.Return: - break; - } - } - } - - private void StartOrEditSession(StudyDTO session) - { - TitleCard(session.Name); - - var menuOptions = OptionUtils.GetAllStringValues(typeof(StudySessionOptions)); - - var input = AnsiConsole.Prompt(new SelectionPrompt().AddChoices(menuOptions)); - var optionSelected = OptionUtils.GetEnumValue(input, typeof(StudySessionOptions)); - - switch (optionSelected) - { - case StudySessionOptions.StartSession: - break; - case StudySessionOptions.RenameSession: - var sessions = _studyController.ReadAllSessions(); - var name = ChooseName(sessions.Keys); - if(name != string.Empty) - { - _studyController.AddSession(name); - AnsiConsole.WriteLine($"Study session renamed {name}!\n"); - } - AnsiConsole.MarkupLine("Press Enter to Return"); - break; - case StudySessionOptions.Return: - break; - } - } -} \ No newline at end of file From e110ba2715939f9d7fe02abda1e9f35562e075c9 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Wed, 25 Feb 2026 04:36:49 -0500 Subject: [PATCH 20/23] README.md --- Flashcards.davetn657/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Flashcards.davetn657/README.md diff --git a/Flashcards.davetn657/README.md b/Flashcards.davetn657/README.md new file mode 100644 index 00000000..94f7f7ff --- /dev/null +++ b/Flashcards.davetn657/README.md @@ -0,0 +1,23 @@ +# Flashcards Console Application +## Overview +A console based application that uses paced repition and flashcards to promote learning. Created for the C# Academy based learning + +## Requirements +- Users are able to create stacks of flashcards +- Atleast two tables for stacks and flashcards. Both tables should be linked by a foreign key +- Stacks should have unique names +- Every flashcard must be linked to a stack. If a stack is deleted all related flashcards should be deleted +- Use DTOs +- Study Session area, where users can study their stacks +- Stacks and Study Sessions should have tables and should be linked by a foreign key + +### Technologies +- C# +- SQLServer +- Spectre.Console + +## Features +Features user friendly user interface allowing navigation through menu options + +Launching the application will display a menu with the following options: +Start Study \ No newline at end of file From 02f695623777bf4892b52c445da4f3772b72c02f Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Wed, 25 Feb 2026 04:47:48 -0500 Subject: [PATCH 21/23] Codaccy fixes --- Flashcards.davetn657/README.md | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/Flashcards.davetn657/README.md b/Flashcards.davetn657/README.md index 94f7f7ff..5d68fe8a 100644 --- a/Flashcards.davetn657/README.md +++ b/Flashcards.davetn657/README.md @@ -1,23 +1,43 @@ # Flashcards Console Application + ## Overview -A console based application that uses paced repition and flashcards to promote learning. Created for the C# Academy based learning +A console based application that uses paced repition and flashcards to promote learning. +Created for the C# Academy based learning ## Requirements + - Users are able to create stacks of flashcards -- Atleast two tables for stacks and flashcards. Both tables should be linked by a foreign key +- Stacks and flashcards tables. Both tables should be linked by a foreign key - Stacks should have unique names -- Every flashcard must be linked to a stack. If a stack is deleted all related flashcards should be deleted +- Every flashcard must be linked to a stack. +- If a stack is deleted all related flashcards should be deleted - Use DTOs - Study Session area, where users can study their stacks -- Stacks and Study Sessions should have tables and should be linked by a foreign key +- Stacks and Sessions should have tables and should be linked by a foreign key ### Technologies + - C# - SQLServer - Spectre.Console ## Features + Features user friendly user interface allowing navigation through menu options Launching the application will display a menu with the following options: -Start Study \ No newline at end of file +Start studying -> Opens a new menu where users will be able to see the past weeks study sessions and choose which stack to study +Manage data -> Opens a menu where users will be able to create/edit new study sessions and stacks. Users are able to create new cards by editing a stack +Exit -> Closes application + +## Looking back + +### Positives + +- Looking back to when I first started the project it was alot of fun learning new tools. +- Tried to stick to a MVC design, I felt I did well + +### Improvements + +- Due to poor planning of the UI I ended up refactoring my UI alot +- At the start of the project I had trouble connecting to SQLserver in Visual Studio \ No newline at end of file From 7010bb096a41399bc2754112aad3c9c29f26fe26 Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Wed, 25 Feb 2026 04:59:52 -0500 Subject: [PATCH 22/23] More Codacy fixes --- .../Controllers/CardController.cs | 22 +++++++++---------- .../Controllers/ScoreController.cs | 8 +++---- .../Controllers/StackController.cs | 16 +++++++------- .../Controllers/StudyController.cs | 12 +++++----- Flashcards.davetn657/Models/DTOs/CardDTO.cs | 2 +- Flashcards.davetn657/Models/DTOs/ScoreDTO.cs | 2 +- Flashcards.davetn657/Models/DTOs/StackDTO.cs | 2 +- Flashcards.davetn657/Models/DTOs/StudyDTO.cs | 2 +- Flashcards.davetn657/Views/ManageDataView.cs | 16 +++++++------- .../Views/StartStudySessionView.cs | 4 ++-- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Flashcards.davetn657/Controllers/CardController.cs b/Flashcards.davetn657/Controllers/CardController.cs index 8511dd35..73e45835 100644 --- a/Flashcards.davetn657/Controllers/CardController.cs +++ b/Flashcards.davetn657/Controllers/CardController.cs @@ -21,7 +21,7 @@ public CardController() this.connectionString = configuration.GetConnectionString("DatabaseConnection"); } - internal void AddCard(CardDTO card, StackDTO stack) + internal void AddCard(CardDto card, StackDto stack) { using (SqlConnection connection = new SqlConnection(connectionString)) { @@ -41,7 +41,7 @@ internal void AddCard(CardDTO card, StackDTO stack) } } - internal void RemoveCard(CardDTO card) + internal void RemoveCard(CardDto card) { using (var connection = new SqlConnection(connectionString)) { @@ -60,7 +60,7 @@ internal void RemoveCard(CardDTO card) } - internal void RemoveCard(StackDTO stack) + internal void RemoveCard(StackDto stack) { using (var connection = new SqlConnection(connectionString)) { @@ -79,7 +79,7 @@ internal void RemoveCard(StackDTO stack) } - internal void EditCard(CardDTO card, Enum option) + internal void EditCard(CardDto card, Enum option) { using(var connection = new SqlConnection(connectionString)) { @@ -109,7 +109,7 @@ internal void EditCard(CardDTO card, Enum option) } } - internal void ChangeTime(CardDTO card, DateTime timeChange) + internal void ChangeTime(CardDto card, DateTime timeChange) { using (var connection = new SqlConnection(connectionString)) { @@ -131,9 +131,9 @@ internal void ChangeTime(CardDTO card, DateTime timeChange) } } - internal Dictionary ReadAllCards() + internal Dictionary ReadAllCards() { - var allCards = new Dictionary(); + var allCards = new Dictionary(); using (var connection = new SqlConnection(connectionString)) { @@ -146,7 +146,7 @@ internal Dictionary ReadAllCards() while (reader.Read()) { - var card = new CardDTO(); + var card = new CardDto(); card.Id = reader.GetInt32("CardId"); card.Question = reader.GetString("CardQuestion"); card.Answer = reader.GetString("CardAnswer"); @@ -161,9 +161,9 @@ internal Dictionary ReadAllCards() return allCards; } - internal Dictionary ReadAllCards(StudyDTO session) + internal Dictionary ReadAllCards(StudyDto session) { - var allCards = new Dictionary(); + var allCards = new Dictionary(); using(var connection = new SqlConnection(connectionString)) { @@ -180,7 +180,7 @@ internal Dictionary ReadAllCards(StudyDTO session) while (reader.Read()) { - var card = new CardDTO(); + var card = new CardDto(); card.Id = reader.GetInt32("CardId"); card.Question = reader.GetString("CardQuestion"); card.Answer = reader.GetString("CardAnswer"); diff --git a/Flashcards.davetn657/Controllers/ScoreController.cs b/Flashcards.davetn657/Controllers/ScoreController.cs index f922c427..b836791e 100644 --- a/Flashcards.davetn657/Controllers/ScoreController.cs +++ b/Flashcards.davetn657/Controllers/ScoreController.cs @@ -19,7 +19,7 @@ public ScoreController() this.connectionString = configuration.GetConnectionString("DatabaseConnection"); } - internal void AddScore(StudyDTO session, ScoreDTO score) + internal void AddScore(StudyDto session, ScoreDto score) { using (var connection = new SqlConnection(connectionString)) { @@ -38,9 +38,9 @@ internal void AddScore(StudyDTO session, ScoreDTO score) } } - internal List GetScores(int numberOfDays) + internal List GetScores(int numberOfDays) { - var pastScores = new List(); + var pastScores = new List(); using (var connection = new SqlConnection(connectionString)) { @@ -60,7 +60,7 @@ WHERE CAST(Scores.CreateDate AS DATE) >= DATEADD(day, @numDays, GETDATE()) while (reader.Read()) { - var data = new ScoreDTO(); + var data = new ScoreDto(); data.SessionId = reader.GetInt32("StackId"); data.Name = reader.GetString("SessionName"); data.Score = reader.GetInt32("Score"); diff --git a/Flashcards.davetn657/Controllers/StackController.cs b/Flashcards.davetn657/Controllers/StackController.cs index 38f583a5..de3e53e4 100644 --- a/Flashcards.davetn657/Controllers/StackController.cs +++ b/Flashcards.davetn657/Controllers/StackController.cs @@ -37,7 +37,7 @@ internal void AddStack(string name) } } - internal void RemoveStack(StackDTO stack) + internal void RemoveStack(StackDto stack) { using(var connection = new SqlConnection(connectionString)) { @@ -56,7 +56,7 @@ internal void RemoveStack(StackDTO stack) } } - internal void RemoveStack(StackDTO stack, CardController cardController, StudyController sessionController) + internal void RemoveStack(StackDto stack, CardController cardController, StudyController sessionController) { using (var connection = new SqlConnection(connectionString)) { @@ -79,7 +79,7 @@ internal void RemoveStack(StackDTO stack, CardController cardController, StudyCo } } - internal void EditStack(StackDTO stack) + internal void EditStack(StackDto stack) { using (var connection = new SqlConnection(connectionString)) { @@ -99,9 +99,9 @@ internal void EditStack(StackDTO stack) } } - internal Dictionary ReadAllStacks() + internal Dictionary ReadAllStacks() { - var allStacks = new Dictionary(); + var allStacks = new Dictionary(); using (var connection = new SqlConnection(connectionString)) { @@ -114,7 +114,7 @@ internal Dictionary ReadAllStacks() while (reader.Read()) { - var stack = new StackDTO(); + var stack = new StackDto(); stack.Id = reader.GetInt32("StackId"); stack.Name = reader.GetString("StackName"); @@ -126,9 +126,9 @@ internal Dictionary ReadAllStacks() return allStacks; } - internal StackDTO ReadAllStacks(StudyDTO session) + internal StackDto ReadAllStacks(StudyDto session) { - var stack = new StackDTO(); + var stack = new StackDto(); using (var connection = new SqlConnection(connectionString)) { diff --git a/Flashcards.davetn657/Controllers/StudyController.cs b/Flashcards.davetn657/Controllers/StudyController.cs index 4e28bcdd..a3881720 100644 --- a/Flashcards.davetn657/Controllers/StudyController.cs +++ b/Flashcards.davetn657/Controllers/StudyController.cs @@ -19,7 +19,7 @@ public StudyController() this.connectionString = configuration.GetConnectionString("DatabaseConnection"); } - internal void AddSession(StudyDTO session) + internal void AddSession(StudyDto session) { using(var connection = new SqlConnection(connectionString)) { @@ -37,7 +37,7 @@ internal void AddSession(StudyDTO session) } } - internal void RemoveSession(StackDTO stack) + internal void RemoveSession(StackDto stack) { using (var connection = new SqlConnection(connectionString)) { @@ -56,7 +56,7 @@ internal void RemoveSession(StackDTO stack) } - internal void EditSession(StudyDTO session) + internal void EditSession(StudyDto session) { using (var connection = new SqlConnection(connectionString)) { @@ -75,9 +75,9 @@ internal void EditSession(StudyDTO session) } } - internal Dictionary ReadAllSessions() + internal Dictionary ReadAllSessions() { - var allSessions = new Dictionary(); + var allSessions = new Dictionary(); using(var connection = new SqlConnection(connectionString)) { @@ -90,7 +90,7 @@ internal Dictionary ReadAllSessions() while (reader.Read()) { - var session = new StudyDTO(); + var session = new StudyDto(); session.Id = reader.GetInt32("SessionId"); session.StackId = reader.GetInt32("StackId"); session.Name = reader.GetString("SessionName"); diff --git a/Flashcards.davetn657/Models/DTOs/CardDTO.cs b/Flashcards.davetn657/Models/DTOs/CardDTO.cs index 2f8952cf..c0cf082d 100644 --- a/Flashcards.davetn657/Models/DTOs/CardDTO.cs +++ b/Flashcards.davetn657/Models/DTOs/CardDTO.cs @@ -1,6 +1,6 @@ namespace Flashcards.davetn657.Models.DTOs; -public class CardDTO +public class CardDto { public int Id { get; set; } public string? Question { get; set; } diff --git a/Flashcards.davetn657/Models/DTOs/ScoreDTO.cs b/Flashcards.davetn657/Models/DTOs/ScoreDTO.cs index 3c2ab044..d76149b4 100644 --- a/Flashcards.davetn657/Models/DTOs/ScoreDTO.cs +++ b/Flashcards.davetn657/Models/DTOs/ScoreDTO.cs @@ -1,6 +1,6 @@ namespace Flashcards.davetn657.Models.DTOs; -internal class ScoreDTO +internal class ScoreDto { public int SessionId { get; set; } public string Name { get; set; } diff --git a/Flashcards.davetn657/Models/DTOs/StackDTO.cs b/Flashcards.davetn657/Models/DTOs/StackDTO.cs index 30ced85e..5494ada9 100644 --- a/Flashcards.davetn657/Models/DTOs/StackDTO.cs +++ b/Flashcards.davetn657/Models/DTOs/StackDTO.cs @@ -1,5 +1,5 @@ namespace Flashcards.davetn657.Models.DTOs; -public class StackDTO +public class StackDto { public int Id { get; set; } public string? Name { get; set; } diff --git a/Flashcards.davetn657/Models/DTOs/StudyDTO.cs b/Flashcards.davetn657/Models/DTOs/StudyDTO.cs index d87ff9a0..5f5efc61 100644 --- a/Flashcards.davetn657/Models/DTOs/StudyDTO.cs +++ b/Flashcards.davetn657/Models/DTOs/StudyDTO.cs @@ -1,6 +1,6 @@ namespace Flashcards.davetn657.Models.DTOs; -public class StudyDTO +public class StudyDto { public int Id { get; set; } public int StackId { get; set; } diff --git a/Flashcards.davetn657/Views/ManageDataView.cs b/Flashcards.davetn657/Views/ManageDataView.cs index f2bdbfaa..87a5174c 100644 --- a/Flashcards.davetn657/Views/ManageDataView.cs +++ b/Flashcards.davetn657/Views/ManageDataView.cs @@ -93,7 +93,7 @@ private void CreateSession() TitleCard("What stack to add?"); AnsiConsole.WriteLine("Choose which stack to add onto the study session"); - var session = new StudyDTO(); + var session = new StudyDto(); session.Name = input; var options = OptionUtils.GetAllStringValues(typeof(ChooseDataOptions)); @@ -111,7 +111,7 @@ private void CreateSession() } } - private void SessionDetails(StudyDTO session) + private void SessionDetails(StudyDto session) { TitleCard(session.Name); @@ -174,7 +174,7 @@ private void ManageStack() } - private void EditStack(StackDTO stack) + private void EditStack(StackDto stack) { var endEdit = false; @@ -221,12 +221,12 @@ private void EditStack(StackDTO stack) // CARDS - internal void CreateCard(StackDTO stack) + internal void CreateCard(StackDto stack) { TitleCard("Create a new Card"); var input = string.Empty; - var card = new CardDTO(); + var card = new CardDto(); input = AnsiConsole.Ask("Input question details (type: r to cancel):"); if (input.ToLower() == "r") return; @@ -239,7 +239,7 @@ internal void CreateCard(StackDTO stack) _cardController.AddCard(card, stack); } - internal void ChooseCard(StackDTO stack) + internal void ChooseCard(StackDto stack) { var endEdit = false; @@ -264,7 +264,7 @@ internal void ChooseCard(StackDTO stack) } } - internal void EditCard(CardDTO card) + internal void EditCard(CardDto card) { var endEdit = false; @@ -297,7 +297,7 @@ internal void EditCard(CardDTO card) } - private void ChangeCardDetails(CardDTO card, Enum option) + private void ChangeCardDetails(CardDto card, Enum option) { TitleCard(OptionUtils.GetStringValue(option)); diff --git a/Flashcards.davetn657/Views/StartStudySessionView.cs b/Flashcards.davetn657/Views/StartStudySessionView.cs index 831a7cf0..fc09d12f 100644 --- a/Flashcards.davetn657/Views/StartStudySessionView.cs +++ b/Flashcards.davetn657/Views/StartStudySessionView.cs @@ -37,13 +37,13 @@ internal void ChooseStudySession() else return; } - private void GenerateCards(StudyDTO session) + private void GenerateCards(StudyDto session) { var cards = _cardController.ReadAllCards(session); var menuOptions = OptionUtils.GetAllStringValues(typeof(FlashcardOptions)); var revealedMenuOptions = OptionUtils.GetAllStringValues(typeof(RevealedFlashcardOptions)); - var score = new ScoreDTO() + var score = new ScoreDto() { SessionId = session.Id, Score = 0 From 45581caa829f4675bd5a978ecc82d09ce153402f Mon Sep 17 00:00:00 2001 From: Dave Ngo Date: Sat, 28 Feb 2026 23:25:17 -0500 Subject: [PATCH 23/23] Added Sql script --- Flashcards.davetn657/README.md | 22 +++++++++++----- Flashcards.davetn657/SqlScript.txt | 41 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 Flashcards.davetn657/SqlScript.txt diff --git a/Flashcards.davetn657/README.md b/Flashcards.davetn657/README.md index 5d68fe8a..2f7083ac 100644 --- a/Flashcards.davetn657/README.md +++ b/Flashcards.davetn657/README.md @@ -1,7 +1,9 @@ # Flashcards Console Application ## Overview -A console based application that uses paced repition and flashcards to promote learning. + +A console based app that uses spaced repetition to promote learning. + Created for the C# Academy based learning ## Requirements @@ -9,7 +11,7 @@ Created for the C# Academy based learning - Users are able to create stacks of flashcards - Stacks and flashcards tables. Both tables should be linked by a foreign key - Stacks should have unique names -- Every flashcard must be linked to a stack. +- Every flashcard must be linked to a stack. - If a stack is deleted all related flashcards should be deleted - Use DTOs - Study Session area, where users can study their stacks @@ -26,18 +28,24 @@ Created for the C# Academy based learning Features user friendly user interface allowing navigation through menu options Launching the application will display a menu with the following options: -Start studying -> Opens a new menu where users will be able to see the past weeks study sessions and choose which stack to study -Manage data -> Opens a menu where users will be able to create/edit new study sessions and stacks. Users are able to create new cards by editing a stack -Exit -> Closes application + +Start studying -> Opens a new menu where users will be able to see the past +weeks study sessions and choose which stack to study + +Manage data -> Opens a menu where users will be able to create/edit new +study sessions and stacks. Users are able to create new +cards by editing a stack + +Exit -> Closes application ## Looking back ### Positives -- Looking back to when I first started the project it was alot of fun learning new tools. +- When I first started the project it was alot of fun learning new tools. - Tried to stick to a MVC design, I felt I did well ### Improvements - Due to poor planning of the UI I ended up refactoring my UI alot -- At the start of the project I had trouble connecting to SQLserver in Visual Studio \ No newline at end of file +- At the start of the project I had trouble connecting to SQLserver in Visual Studio diff --git a/Flashcards.davetn657/SqlScript.txt b/Flashcards.davetn657/SqlScript.txt new file mode 100644 index 00000000..726b3638 --- /dev/null +++ b/Flashcards.davetn657/SqlScript.txt @@ -0,0 +1,41 @@ +CREATE TABLE Stacks( + StackId INT IDENTITY(1,1) PRIMARY KEY, + StackName NVARCHAR(50) NOT NULL, + CreateDate DATETIME2 DEFAULT GETDATE() +); + +CREATE TABLE Cards( + CardId INT IDENTITY(1,1) PRIMARY KEY, + StackId INT NOT NULL, + CardQuestion NVARCHAR(100) NOT NULL, + CardAnswer NVARCHAR(100) NOT NULL, + LastAppearance DATETIME2 DEFAULT GETDATE(), + NextAppearance DATETIME2 DEFAULT GETDATE(), + CREATEDATE DATETIME2 DEFAULT GETDATE(), + CONSTRAINT FK_Cards_StackId + FOREIGN KEY (StackId) + REFERENCES Stacks(StackId) + ON DELETE CASCADE +); + +CREATE TABLE Sessions( + SessionId INT IDENTITY(1,1) PRIMARY KEY, + StackId INT NOT NULL, + SessionName NVARCHAR(50) NOT NULL, + CreateDate DATETIME2 DEFAULT GETDATE(), + CONSTRAINT FK_Session_StackId + FOREIGN KEY (StackId) + REFERENCES Stacks(StackId) + ON DELETE CASCADE +); + +CREATE TABLE Scores( + ScoreId INT IDENTITY(1,1) PRIMARY KEY, + SessionId INT NOT NULL, + Score INT DEFAULT 0, + CreateDate DATETIME2 DEFAULT GETDATE(), + CONSTRAINT FK_Scores_SessionId + FOREIGN KEY (SessionId) + REFERENCES Sessions(SessionId) + ON DELETE CASCADE +); \ No newline at end of file