From 2c69bc0d2375a6f4fd40a1de465ed42a3256fdac Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sat, 25 Oct 2025 20:48:18 +0100 Subject: [PATCH 01/26] Added coding session model --- .../Models/CodingSession.cs | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs new file mode 100644 index 0000000..2bdc09d --- /dev/null +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs @@ -0,0 +1,81 @@ +namespace CodingTrackerApp.JJHH17; + +public class CodingSession +{ + public long Id { get; set; } + public string StartTime { get; set; } + public string EndTime { get; set; } + public string Duration { get; set; } + + public DateTime? stopwatchStartTime; + public DateTime? stopwatchEndTime; + + public CodingSession() + { + } + + public CodingSession(string startTime, string endTime, string duration) + { + StartTime = startTime; + EndTime = endTime; + Duration = duration; + } + + public void CalculateDuration() + { + DateTime start = DateTime.Parse(StartTime); + DateTime end = DateTime.Parse(EndTime); + + int years = end.Year - start.Year; + int months = end.Month - start.Month; + int days = end.Day - start.Day; + + if (days < 0) + { + months--; + var previousMonth = end.AddMonths(-1); + days += DateTime.DaysInMonth(previousMonth.Year, previousMonth.Month); + } + + if (months < 0) + { + years--; + months += 12; + } + + TimeSpan timespan = end - start; + + int totalDays = (int)timespan.TotalDays; + int totalHours = (int)timespan.TotalHours % 24; + int totalMinutes = (int)timespan.TotalMinutes % 60; + int totalSeconds = (int)timespan.TotalSeconds % 60; + + Duration = $"{years} years, {months} months, {days} days, {totalHours} hours, {totalMinutes} minutes, {totalSeconds} seconds"; + } + + public void StartStopwatch() + { + stopwatchStartTime = DateTime.Now; + Console.WriteLine("Stopwatch started at: " + stopwatchStartTime.Value.ToString("yyyy-MM-dd HH:mm:ss")); + } + + public void StopStopwatch() + { + if (stopwatchStartTime == null) + { + Console.WriteLine("Stopwatch has not been started."); + return; + } + + stopwatchEndTime = DateTime.Now; + Console.WriteLine($"Stopwatch stopped at {stopwatchEndTime}"); + + StartTime = stopwatchStartTime.Value.ToString("yyyy-MM-dd HH:mm:ss"); + EndTime = stopwatchEndTime.Value.ToString("yyyy-MM-dd HH:mm:ss"); + + CalculateDuration(); + + stopwatchStartTime = null; + stopwatchEndTime = null; + } +} \ No newline at end of file From 57eb60d4fe0e376eb670bfdb3aa9d0f5079277f7 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sat, 25 Oct 2025 20:52:04 +0100 Subject: [PATCH 02/26] Added database values --- .../CodingTrackerApp.JJHH17/Database/App.config | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/App.config diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/App.config b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/App.config new file mode 100644 index 0000000..3ad7955 --- /dev/null +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/App.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 08090694d4532620c01c025484a7c3118c1ae6de Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sat, 25 Oct 2025 20:59:56 +0100 Subject: [PATCH 03/26] Added dapper package --- .../CodingTrackerApp.JJHH17.csproj | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj new file mode 100644 index 0000000..a9cac7b --- /dev/null +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + From 6c5c0e9b0ec2fe35e1a9009c26b2639a777908f8 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sat, 25 Oct 2025 21:01:28 +0100 Subject: [PATCH 04/26] installed sqlite and app.configuration package --- .../CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj index a9cac7b..4aabe9b 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj @@ -9,6 +9,8 @@ + + From bd25e057d4e2098c652f893b062d1b280c578c65 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sat, 25 Oct 2025 21:18:05 +0100 Subject: [PATCH 05/26] Added database creation, and database model --- .../Database/Database.cs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs new file mode 100644 index 0000000..12c6933 --- /dev/null +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs @@ -0,0 +1,60 @@ +using Dapper; +using System.Configuration; +using System.Data.SQLite; + +namespace CodingTrackerApp.JJHH17.Database; + +public class Database +{ + private static readonly string dbPath = ConfigurationManager.AppSettings["databasePath"]; + private static readonly string tableName = ConfigurationManager.AppSettings["tableName"]; + private static readonly string connectionString = $"Data Source={dbPath};"; + + public static void CreateDatabase() + { + if (!File.Exists(dbPath)) + { + SQLiteConnection.CreateFile(dbPath); + Console.WriteLine("Database created successfully"); + } + else + { + Console.WriteLine("Database already exists"); + } + + CreateTable(); + } + + private static void CreateTable() + { + using (var connection = new SQLiteConnection(connectionString)) + { + connection.Open(); + + string tableCreation = @"CREATE TABLE IF NOT EXISTS CodeTracker ( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + StartTime TEXT NOT NULL, + EndTime TEXT NOT NULL, + Duration TEXT);"; + + connection.Execute(tableCreation); + Console.WriteLine("Table created successfully or already exists"); + } + } + + public static long AddEntry(string startTime, string endTime, string duration) + { + using (var connection = new SQLiteConnection(connectionString)) + { + connection.Open(); + var sql = "INSERT INTO CodeTracker (StartTime, EndTime, Duration) VALUES (@StartTime, @EndTime, @Duration);" + + $"SELECT last_insert_rowid();"; + + var newEntry = new CodingSession(startTime, endTime, duration); + + long newId = connection.ExecuteScalar(sql, newEntry); + + return newId; + } + } +} \ No newline at end of file From c8fbdb153fe9b76761d4db45ea623262eaba3505 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sat, 25 Oct 2025 21:19:02 +0100 Subject: [PATCH 06/26] Added delete methods for database --- .../Database/Database.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs index 12c6933..95df119 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs @@ -57,4 +57,38 @@ public static long AddEntry(string startTime, string endTime, string duration) return newId; } } + + public static List GetAllEntries() + { + using (var connection = new SQLiteConnection(connectionString)) + { + connection.Open(); + var sql = "SELECT * FROM CodeTracker;"; + var entries = connection.Query(sql).ToList(); + return entries; + } + } + + public static void DeleteAllEntries() + { + using (var connection = new SQLiteConnection(connectionString)) + { + connection.Open(); + var sql = $"DELETE FROM {tableName};"; + connection.Execute(sql); + } + } + + public static void DeleteEntryById(long id) + { + using (var connection = new SQLiteConnection(connectionString)) + { + // Get list of existing entries for ID selection + GetAllEntries(); + + connection.Open(); + var sql = $"DELETE FROM {tableName} WHERE Id = @Id;"; + connection.Execute(sql, new { Id = id } ); + } + } } \ No newline at end of file From f3616948adf74598eceacdc3167e04727da9fd5f Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sat, 25 Oct 2025 21:43:48 +0100 Subject: [PATCH 07/26] Added third constructor, which calculates duration via the method --- .../CodingTrackerApp.JJHH17/Models/CodingSession.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs index 2bdc09d..0fcebad 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs @@ -14,6 +14,12 @@ public CodingSession() { } + public CodingSession(string startTime, string endTime) + { + StartTime = startTime; + EndTime = endTime; + } + public CodingSession(string startTime, string endTime, string duration) { StartTime = startTime; From efb1a40e39a980111540ca502d2c8b411293998f Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sat, 25 Oct 2025 21:52:09 +0100 Subject: [PATCH 08/26] Installed sqlite.core package --- .../CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj index 4aabe9b..114ca59 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj @@ -9,8 +9,10 @@ + + From ef55fa88418e8982ddea2dfc444003e6e33d7fc1 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 10:07:19 +0000 Subject: [PATCH 09/26] Added sqlite3 package --- .../CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj index 114ca59..4363f1d 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.csproj @@ -10,6 +10,7 @@ + From 1b5aa54455cad95a73ee0aa62a466443d2a2650b Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 10:08:41 +0000 Subject: [PATCH 10/26] Added menu method, and method for adding new entries --- .../UserInterface/UserInterface.cs | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs new file mode 100644 index 0000000..d5a3c7c --- /dev/null +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs @@ -0,0 +1,79 @@ +using Spectre.Console; +using CodingTrackerApp.JJHH17; + +namespace CodingTrackerApp.JJHH17; + +public class UserInterface +{ + enum MenuOptions + { + AddEvent, + ViewAllEvents, + DeleteAll, + DeleteSingleEvent, + Exit + } + + public static void Running() + { + bool active = true; + + while (active) + { + Console.Clear(); + + var choice = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Select an option:") + .AddChoices(Enum.GetValues())); + + switch (choice) + { + case MenuOptions.AddEvent: + AnsiConsole.MarkupLine("[green]Add Event selected.[/]"); + AddEntry(); + break; + + case MenuOptions.ViewAllEvents: + break; + + case MenuOptions.DeleteAll: + break; + + case MenuOptions.DeleteSingleEvent: + break; + + case MenuOptions.Exit: + active = false; + break; + } + } + } + + public static void AddEntry() + { + string startTime = AnsiConsole.Ask("Enter start time (YYYY-MM-DD HH:MM):"); + + DateTime parsedStartTime; + while (!DateTime.TryParse(startTime, out parsedStartTime)) + { + AnsiConsole.MarkupLine("[red]Invalid date format. Please try again.[/]"); + startTime = AnsiConsole.Ask("Enter start time (YYYY-MM-DD HH:MM):"); + } + + string endTime = AnsiConsole.Ask("Enter end time (YYYY-MM-DD HH:MM)"); + + DateTime parsedEndTime; + while (!DateTime.TryParse(endTime, out parsedEndTime) || parsedEndTime <= parsedStartTime) + { + AnsiConsole.MarkupLine("[red]Invalid date format or end time is before start time. Please try again.[/]"); + endTime = AnsiConsole.Ask("Enter end time (YYYY-MM-DD HH:MM):"); + } + + AnsiConsole.MarkupLine("[green]Entry added successfully! Enter a key to continue[/]"); + Console.ReadKey(); + var newEntry = new CodingSession(startTime, endTime); + newEntry.CalculateDuration(); + Database.Database.AddEntry(newEntry.StartTime, newEntry.EndTime, newEntry.Duration); + } +} \ No newline at end of file From 92e61bd511be8b206545f52a8dc63d6c935af6a2 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 10:11:56 +0000 Subject: [PATCH 11/26] Created method for displaying all events --- .../UserInterface/UserInterface.cs | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs index d5a3c7c..22ca42b 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs @@ -35,6 +35,8 @@ public static void Running() break; case MenuOptions.ViewAllEvents: + AnsiConsole.MarkupLine("[green]View All Events selected.[/]"); + ViewAllEntries(); break; case MenuOptions.DeleteAll: @@ -52,7 +54,7 @@ public static void Running() public static void AddEntry() { - string startTime = AnsiConsole.Ask("Enter start time (YYYY-MM-DD HH:MM):"); + string startTime = AnsiConsole.Ask("Enter start time (YYYY-MM-DD HH:MM) (Time is optional):"); DateTime parsedStartTime; while (!DateTime.TryParse(startTime, out parsedStartTime)) @@ -61,7 +63,7 @@ public static void AddEntry() startTime = AnsiConsole.Ask("Enter start time (YYYY-MM-DD HH:MM):"); } - string endTime = AnsiConsole.Ask("Enter end time (YYYY-MM-DD HH:MM)"); + string endTime = AnsiConsole.Ask("Enter end time (YYYY-MM-DD HH:MM) (Time is optional)"); DateTime parsedEndTime; while (!DateTime.TryParse(endTime, out parsedEndTime) || parsedEndTime <= parsedStartTime) @@ -76,4 +78,23 @@ public static void AddEntry() newEntry.CalculateDuration(); Database.Database.AddEntry(newEntry.StartTime, newEntry.EndTime, newEntry.Duration); } + + public static void ViewAllEntries() + { + var table = new Table(); + table.AddColumn("ID"); + table.AddColumn("Start Time"); + table.AddColumn("End Time"); + table.AddColumn("Duration"); + + List entries = Database.Database.GetAllEntries(); + foreach (var entry in entries) + { + table.AddRow(entry.Id.ToString(), entry.StartTime, entry.EndTime, entry.Duration); + } + + AnsiConsole.Write(table); + AnsiConsole.MarkupLine("[green]Press any key to continue...[/]"); + Console.ReadKey(); + } } \ No newline at end of file From bc9c1cc4783381900abd7cd9ccfa78c10dced532 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 10:13:58 +0000 Subject: [PATCH 12/26] Created method for deleting all entries --- .../UserInterface/UserInterface.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs index 22ca42b..287ddbc 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs @@ -40,6 +40,8 @@ public static void Running() break; case MenuOptions.DeleteAll: + AnsiConsole.MarkupLine("[green]Delete All selected.[/]"); + DeleteAllEntries(); break; case MenuOptions.DeleteSingleEvent: @@ -97,4 +99,20 @@ public static void ViewAllEntries() AnsiConsole.MarkupLine("[green]Press any key to continue...[/]"); Console.ReadKey(); } + + public static void DeleteAllEntries() + { + string confirmation = AnsiConsole.Ask("Are you sure you want to delete all entries? (yes/no):"); + if (confirmation.ToLower() == "yes") + { + Database.Database.DeleteAllEntries(); + AnsiConsole.MarkupLine("[green]All entries deleted successfully! Press any key to continue...[/]"); + } + else + { + AnsiConsole.MarkupLine("[yellow]Deletion cancelled. Press any key to continue...[/]"); + } + + Console.ReadKey(); + } } \ No newline at end of file From b0a1844f625780d5be042ea3a3b4c28f4ac1c4c1 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 10:22:37 +0000 Subject: [PATCH 13/26] Added method for deleting a single entry --- .../UserInterface/UserInterface.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs index 287ddbc..d38f2be 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs @@ -45,6 +45,8 @@ public static void Running() break; case MenuOptions.DeleteSingleEvent: + AnsiConsole.MarkupLine("[green]Delete Single Event selected.[/]"); + DeleteSingleEntry(); break; case MenuOptions.Exit: @@ -115,4 +117,24 @@ public static void DeleteAllEntries() Console.ReadKey(); } + + public static void DeleteSingleEntry() + { + ViewAllEntries(); + int idToDelete = AnsiConsole.Ask("Enter the ID of the entry to delete:"); + AnsiConsole.MarkupLine($"[red]Are you sure you want to delete entry ID {idToDelete}[/]"); + string confirmation = AnsiConsole.Ask("Type 'yes' to confirm deletion:"); + + if (confirmation.ToLower() == "yes") + { + Database.Database.DeleteEntryById(idToDelete); + AnsiConsole.MarkupLine("[green]Entry deleted successfully! Press any key to continue...[/]"); + } + else + { + AnsiConsole.MarkupLine("[yellow]Deletion cancelled. Press any key to continue...[/]"); + } + + Console.ReadKey(); + } } \ No newline at end of file From dd80ef10a96573717070f189d75ecd7e2b3f596f Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 10:23:07 +0000 Subject: [PATCH 14/26] Added reference for creating database file and launching UI --- .../CodingTrackerApp.JJHH17/Program.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs new file mode 100644 index 0000000..26cbec4 --- /dev/null +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs @@ -0,0 +1,13 @@ +using Menu = CodingTrackerApp.JJHH17.UserInterface; +using Database = CodingTrackerApp.JJHH17.Database; + +namespace CodingTrackerApp.JJHH17; + +class Program +{ + public static void Main(string[] args) + { + Database.Database.CreateDatabase(); + Menu.Running(); + } +} \ No newline at end of file From 7d0248e574cab240999091d91a9eae1234eb2bfe Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 10:23:51 +0000 Subject: [PATCH 15/26] Removed unused using call --- CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs index 26cbec4..0f2aa1d 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs @@ -1,5 +1,4 @@ using Menu = CodingTrackerApp.JJHH17.UserInterface; -using Database = CodingTrackerApp.JJHH17.Database; namespace CodingTrackerApp.JJHH17; From 6b4c19433c7d7b4cf9113cc7da1dc4e46506a065 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 17:38:18 +0000 Subject: [PATCH 16/26] Added testing csproj contents --- .../CodingTrackerApp.JJHH17.Tests.csproj | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/CodingTrackerApp.JJHH17.Tests.csproj diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/CodingTrackerApp.JJHH17.Tests.csproj b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/CodingTrackerApp.JJHH17.Tests.csproj new file mode 100644 index 0000000..733a20c --- /dev/null +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/CodingTrackerApp.JJHH17.Tests.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + From 23a54f37dff3cd30a30d053141e39b858aab2976 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 20:34:39 +0000 Subject: [PATCH 17/26] Scoped out using statement to be more detailed --- .../CodingTrackerApp.JJHH17/Database/Database.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs index 95df119..9e00ebc 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Database/Database.cs @@ -1,6 +1,7 @@ using Dapper; using System.Configuration; using System.Data.SQLite; +using CodingTrackerApp.JJHH17.Models; namespace CodingTrackerApp.JJHH17.Database; From 8c613adef2974b0012fc82791710cdf10a584726 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 20:34:53 +0000 Subject: [PATCH 18/26] Removed unused stopwatch methods --- .../CodingTrackerApp.JJHH17/Models/CodingSession.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs index 0fcebad..2316b44 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs @@ -1,4 +1,4 @@ -namespace CodingTrackerApp.JJHH17; +namespace CodingTrackerApp.JJHH17.Models; public class CodingSession { @@ -18,6 +18,7 @@ public CodingSession(string startTime, string endTime) { StartTime = startTime; EndTime = endTime; + CalculateDuration(); } public CodingSession(string startTime, string endTime, string duration) From d8dae202456018e1328e1b8e3c14d1b02be3c9fc Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 20:35:05 +0000 Subject: [PATCH 19/26] Scoped down using methods --- .../CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs index d38f2be..33abf91 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/UserInterface/UserInterface.cs @@ -1,5 +1,6 @@ using Spectre.Console; using CodingTrackerApp.JJHH17; +using CodingTrackerApp.JJHH17.Models; namespace CodingTrackerApp.JJHH17; From 7be6bd13ff18ac1a97d2206a71863cad1ea47114 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 20:35:41 +0000 Subject: [PATCH 20/26] Added getter for duration --- .../Models/CodingSession.cs | 25 ++----------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs index 2316b44..21c2034 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Models/CodingSession.cs @@ -60,29 +60,8 @@ public void CalculateDuration() Duration = $"{years} years, {months} months, {days} days, {totalHours} hours, {totalMinutes} minutes, {totalSeconds} seconds"; } - public void StartStopwatch() + public string GetDuration() { - stopwatchStartTime = DateTime.Now; - Console.WriteLine("Stopwatch started at: " + stopwatchStartTime.Value.ToString("yyyy-MM-dd HH:mm:ss")); - } - - public void StopStopwatch() - { - if (stopwatchStartTime == null) - { - Console.WriteLine("Stopwatch has not been started."); - return; - } - - stopwatchEndTime = DateTime.Now; - Console.WriteLine($"Stopwatch stopped at {stopwatchEndTime}"); - - StartTime = stopwatchStartTime.Value.ToString("yyyy-MM-dd HH:mm:ss"); - EndTime = stopwatchEndTime.Value.ToString("yyyy-MM-dd HH:mm:ss"); - - CalculateDuration(); - - stopwatchStartTime = null; - stopwatchEndTime = null; + return Duration; } } \ No newline at end of file From 3fde33190973e0bda5928aae460efe9676a15ed9 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 21:02:58 +0000 Subject: [PATCH 21/26] Added duration validation check for correct input --- .../CodingTrackerApp.JJHH17.Tests/AppTests.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs new file mode 100644 index 0000000..a7816e7 --- /dev/null +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs @@ -0,0 +1,19 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using CodingTrackerApp.JJHH17.Models; +using System; + +namespace CodingTrackerApp.JJHH17.Tests; + +[TestClass] +public class AppTests +{ + [TestMethod] + public void Duration_CalculateDurationCorrectly() + { + var start = "2024-01-01 10:00:00"; + var end = "2024-01-01 12:30:45"; + var session = new CodingTrackerApp.JJHH17.Models.CodingSession(start, end); + + Assert.AreEqual("0 years, 0 months, 0 days, 2 hours, 30 minutes, 45 seconds", session.GetDuration()); + } +} \ No newline at end of file From f1cd9c4688a48fad616e91fd093e5e6dd7bc5749 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 21:03:22 +0000 Subject: [PATCH 22/26] Added reference to main app project --- .../CodingTrackerApp.JJHH17.Tests.csproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/CodingTrackerApp.JJHH17.Tests.csproj b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/CodingTrackerApp.JJHH17.Tests.csproj index 733a20c..1bf2f0f 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/CodingTrackerApp.JJHH17.Tests.csproj +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/CodingTrackerApp.JJHH17.Tests.csproj @@ -1,5 +1,4 @@ - net8.0 false @@ -8,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -18,5 +17,4 @@ - From d89ae0fa22e3a2fb8e038c08406f53a3570e210e Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 21:06:14 +0000 Subject: [PATCH 23/26] Added invalid duration calculation check --- .../CodingTrackerApp.JJHH17.Tests/AppTests.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs index a7816e7..33f64fc 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs @@ -16,4 +16,14 @@ public void Duration_CalculateDurationCorrectly() Assert.AreEqual("0 years, 0 months, 0 days, 2 hours, 30 minutes, 45 seconds", session.GetDuration()); } + + [TestMethod] + public void Duration_InvalidDurationCalculation_PassesIfTestPasses() + { + var start = "2024-01-01 10:00:00"; + var end = "2024-01-01 11:00:00"; + var session = new CodingTrackerApp.JJHH17.Models.CodingSession(start, end); + + Assert.AreNotEqual("0 years, 0 months, 0 days, 3 hours, 0 minutes, 0 seconds", session.GetDuration()); + } } \ No newline at end of file From eb4c759ffd2a398d86cb473a7469d14821667573 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Sun, 26 Oct 2025 21:14:13 +0000 Subject: [PATCH 24/26] Added zero Duration check test --- .../CodingTrackerApp.JJHH17.Tests/AppTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs index 33f64fc..11819ae 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs @@ -26,4 +26,13 @@ public void Duration_InvalidDurationCalculation_PassesIfTestPasses() Assert.AreNotEqual("0 years, 0 months, 0 days, 3 hours, 0 minutes, 0 seconds", session.GetDuration()); } + + [TestMethod] + public void Duration_ZeroDuration_PassesIfTestPasses() + { + var start = "2024-01-01 10:00:00"; + var end = "2024-01-01 10:00:00"; + var session = new CodingTrackerApp.JJHH17.Models.CodingSession(start, end); + Assert.AreEqual("0 years, 0 months, 0 days, 0 hours, 0 minutes, 0 seconds", session.GetDuration()); + } } \ No newline at end of file From 1596b93b2917faaed23e89ac28dfd10fb8a93dd5 Mon Sep 17 00:00:00 2001 From: James Hatfield Date: Mon, 27 Oct 2025 14:03:49 +0000 Subject: [PATCH 25/26] Added method for checking valid date format --- .../CodingTrackerApp.JJHH17.Tests/AppTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs index 11819ae..3a5a7b8 100644 --- a/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs +++ b/CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs @@ -35,4 +35,13 @@ public void Duration_ZeroDuration_PassesIfTestPasses() var session = new CodingTrackerApp.JJHH17.Models.CodingSession(start, end); Assert.AreEqual("0 years, 0 months, 0 days, 0 hours, 0 minutes, 0 seconds", session.GetDuration()); } + + [TestMethod] + public void DateInput_ValidDateFormat_PassesIfValidFormat() + { + var dateString = "2024-06-15 14:30"; + DateTime parsedDate; + var isValid = DateTime.TryParse(dateString, out parsedDate); + Assert.IsTrue(isValid); + } } \ No newline at end of file From f82a04353d3229143add6f8debe9791fb9444ae9 Mon Sep 17 00:00:00 2001 From: JJHH17 Date: Mon, 27 Oct 2025 14:22:33 +0000 Subject: [PATCH 26/26] Create README.md for Coding Tracking Application Added detailed README for Coding Tracking Application, covering technologies, installation steps, application details, and unit tests. --- CodingTrackerApp.JJHH17/README.md | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 CodingTrackerApp.JJHH17/README.md diff --git a/CodingTrackerApp.JJHH17/README.md b/CodingTrackerApp.JJHH17/README.md new file mode 100644 index 0000000..2ec71d4 --- /dev/null +++ b/CodingTrackerApp.JJHH17/README.md @@ -0,0 +1,44 @@ +### Coding Tracking Application - Unit Tests + +A command line based code tracking application - allows the user to enter time studied, which is then stored to a local instance of SQLite. +This project follows the "Unit Testing" project of the CSharpAcademy, found on: https://www.thecsharpacademy.com/project/21/unit-testing. + +## Technologies used and installed + +- SQLite database. +- Dapper (for integrating with SQLite). +- Spectre console (for terminal styling). +- Microsoft.VisualStudio.TestTools.UnitTesting - For unit testing. + +## Installation and Running Steps: +- This project uses SQLite, meaning a local instance needs to exist in order to store data. +- The project (program.cs) file contains a method that creates the database if it doesn't already exist, meaning you don't need to create this manually. +- Furthermore, it will also create the relevant SQL table needed for storing events. + +## Application Details + +- The application can be started by cloning the directory and running the program.cs file. +- You're then presented with a list of options - use the arrow keys to navigate via the terminal options: + +image + +- The user can add entries via the "Add Event" option, which takes in the start and end date and time: + +image + +- View a full list of coding events added. + +image + +- Delete a single event (by the unique event ID) + +image + +- Delete all events on the database. + +image + +## Unit Tests +- This project contains a suite of unit tests, which can be found under the "CodingTrackerApp.JJHH17.Tests" directory. +- To run the tests, cd to the test directory via terminal and run ```dotnet test```. +- This command will execute all tests in the testing class.