From 17756cb7e199b9e891ac81652fe435fd89fe7572 Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Mon, 20 Jul 2026 17:24:48 +0300 Subject: [PATCH 01/13] Start few things --- .../CodingTracker.Solomonlol.csproj | 24 ++++++++ .../CodingTracker.Solomonlol.slnx | 3 + .../Controllers/CodingController.cs | 61 +++++++++++++++++++ .../Controllers/ICodingController.cs | 17 ++++++ CodingTracker.Solomonlol/Menu.cs | 29 +++++++++ .../Model/CodingSession.cs | 15 +++++ CodingTracker.Solomonlol/Model/Enums.cs | 18 ++++++ CodingTracker.Solomonlol/Program.cs | 8 +++ CodingTracker.Solomonlol/appsetings.json | 15 +++++ 9 files changed, 190 insertions(+) create mode 100644 CodingTracker.Solomonlol/CodingTracker.Solomonlol.csproj create mode 100644 CodingTracker.Solomonlol/CodingTracker.Solomonlol.slnx create mode 100644 CodingTracker.Solomonlol/Controllers/CodingController.cs create mode 100644 CodingTracker.Solomonlol/Controllers/ICodingController.cs create mode 100644 CodingTracker.Solomonlol/Menu.cs create mode 100644 CodingTracker.Solomonlol/Model/CodingSession.cs create mode 100644 CodingTracker.Solomonlol/Model/Enums.cs create mode 100644 CodingTracker.Solomonlol/Program.cs create mode 100644 CodingTracker.Solomonlol/appsetings.json diff --git a/CodingTracker.Solomonlol/CodingTracker.Solomonlol.csproj b/CodingTracker.Solomonlol/CodingTracker.Solomonlol.csproj new file mode 100644 index 000000000..5e419a358 --- /dev/null +++ b/CodingTracker.Solomonlol/CodingTracker.Solomonlol.csproj @@ -0,0 +1,24 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/CodingTracker.Solomonlol/CodingTracker.Solomonlol.slnx b/CodingTracker.Solomonlol/CodingTracker.Solomonlol.slnx new file mode 100644 index 000000000..6e762a04d --- /dev/null +++ b/CodingTracker.Solomonlol/CodingTracker.Solomonlol.slnx @@ -0,0 +1,3 @@ + + + diff --git a/CodingTracker.Solomonlol/Controllers/CodingController.cs b/CodingTracker.Solomonlol/Controllers/CodingController.cs new file mode 100644 index 000000000..1fcf19156 --- /dev/null +++ b/CodingTracker.Solomonlol/Controllers/CodingController.cs @@ -0,0 +1,61 @@ +using CodingTracker.Solomonlol.Model; +using Dapper; +using Microsoft.Data.Sqlite; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; + +namespace CodingTracker.Solomonlol.Controllers +{ + internal class CodingController : ICodingController + { + public List GetData() + { + using(IDbConnection db = new SqliteConnection(GetConString())) + { + return db.Query("SELECT * FROM CodingSessions").ToList(); + } + } + public void DeleteData() + { + throw new NotImplementedException(); + } + + public void UpdateData() + { + throw new NotImplementedException(); + } + + public void WriteData() + { + throw new NotImplementedException(); + } + + public string GetConString() + { + IConfiguration config = new ConfigurationBuilder() + .AddJsonFile("appsetings.json") + .Build(); + + var connectionString = config.GetConnectionString("SQLiteConnection"); + return connectionString; + } + + public void CreateTableIfNotExists() + { + using (IDbConnection db = new SqliteConnection(GetConString())) + { + + var sqlQuery = "CREATE TABLE IF NOT EXISTS CodingSessions" + + "(Id INTEGER PRIMARY KEY AUTOINCREMENT," + + "Date TEXT NOT NULL," + + "StartTime TEXT NOT NULL," + + "EndTime TEXT NOT NULL," + + "Duration TEXT NOT NULL)"; + db.Execute(sqlQuery); + } + } + } +} diff --git a/CodingTracker.Solomonlol/Controllers/ICodingController.cs b/CodingTracker.Solomonlol/Controllers/ICodingController.cs new file mode 100644 index 000000000..36d20abc4 --- /dev/null +++ b/CodingTracker.Solomonlol/Controllers/ICodingController.cs @@ -0,0 +1,17 @@ +using CodingTracker.Solomonlol.Model; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CodingTracker.Solomonlol.Controllers +{ + internal interface ICodingController + { + public List GetData(); + public void UpdateData(); + public void CreateTableIfNotExists(); + public void DeleteData(); + public void WriteData(); + public string GetConString(); + } +} diff --git a/CodingTracker.Solomonlol/Menu.cs b/CodingTracker.Solomonlol/Menu.cs new file mode 100644 index 000000000..cd280eaaf --- /dev/null +++ b/CodingTracker.Solomonlol/Menu.cs @@ -0,0 +1,29 @@ +using CodingTracker.Solomonlol.Controllers; +using Spectre.Console; +using System; +using System.Collections.Generic; +using System.Text; + + +namespace CodingTracker.Solomonlol +{ + internal class Menu + { + + public void MainMenu() + { + CodingController controller = new CodingController(); + controller.CreateTableIfNotExists(); + controller.GetData(); + var choice = AnsiConsole.Prompt(new SelectionPrompt() + .Title("Select an [green]environment[/]:") + .AddChoices("Development", "Staging", "Production")); + + AnsiConsole.MarkupLine($"Deploying to [blue]{choice}[/]"); + + + } + + } + +} diff --git a/CodingTracker.Solomonlol/Model/CodingSession.cs b/CodingTracker.Solomonlol/Model/CodingSession.cs new file mode 100644 index 000000000..43e53e575 --- /dev/null +++ b/CodingTracker.Solomonlol/Model/CodingSession.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CodingTracker.Solomonlol.Model +{ + internal class CodingSession + { + private static List session = new(); + private int Id { get; set; } + private DateTime StartTime { get; set; } + private DateTime EndTime { get; set; } + private TimeOnly Duration { get; set; } + } +} diff --git a/CodingTracker.Solomonlol/Model/Enums.cs b/CodingTracker.Solomonlol/Model/Enums.cs new file mode 100644 index 000000000..c75a3bf47 --- /dev/null +++ b/CodingTracker.Solomonlol/Model/Enums.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CodingTracker.Solomonlol.Model +{ + internal class Enums + { + public enum MainMenu + { + View, + Add, + Update, + Delete, + Exit + } + } +} diff --git a/CodingTracker.Solomonlol/Program.cs b/CodingTracker.Solomonlol/Program.cs new file mode 100644 index 000000000..7b814e272 --- /dev/null +++ b/CodingTracker.Solomonlol/Program.cs @@ -0,0 +1,8 @@ +using CodingTracker.Solomonlol; +using Microsoft.Extensions.Configuration; +using Spectre.Console; + + + +Menu menu = new(); +menu.MainMenu(); \ No newline at end of file diff --git a/CodingTracker.Solomonlol/appsetings.json b/CodingTracker.Solomonlol/appsetings.json new file mode 100644 index 000000000..718be077c --- /dev/null +++ b/CodingTracker.Solomonlol/appsetings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "DatabaseSettings": { + "SQLiteDbPath": "ApplicationDatabase.db" + }, + "ConnectionStrings": { + "SQLiteConnection": "Data Source=ApplicationDatabase.db;" + } +} \ No newline at end of file From f7465508f83ce722df5ff148808325b1f6bfb481 Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Mon, 20 Jul 2026 19:34:30 +0300 Subject: [PATCH 02/13] add db creation --- .../Controllers/CodingController.cs | 22 ++++++++++++++----- .../Controllers/ICodingController.cs | 6 ++--- CodingTracker.Solomonlol/Menu.cs | 4 ++-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CodingTracker.Solomonlol/Controllers/CodingController.cs b/CodingTracker.Solomonlol/Controllers/CodingController.cs index 1fcf19156..3b5b7b778 100644 --- a/CodingTracker.Solomonlol/Controllers/CodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/CodingController.cs @@ -2,6 +2,7 @@ using Dapper; using Microsoft.Data.Sqlite; using Microsoft.Extensions.Configuration; +using Spectre.Console; using System; using System.Collections.Generic; using System.Data; @@ -18,17 +19,27 @@ public List GetData() return db.Query("SELECT * FROM CodingSessions").ToList(); } } - public void DeleteData() + public void DeleteData(int id) { - throw new NotImplementedException(); + using (IDbConnection db = new SqliteConnection(GetConString())) + { + var sqlQuery="DELETE FROM CodingSessions WHERE Id=@id"; + var check=db.Execute(sqlQuery, new { id }); + if (check == 0) + { + AnsiConsole.MarkupLine($"[red]Cannot found record whith Id={id} to delete.[/]"); + + } + else AnsiConsole.MarkupLine($"[green]Record whith Id={id} was deleted.[/]"); + } } - public void UpdateData() + public void UpdateData(int id) { throw new NotImplementedException(); } - public void WriteData() + public void PrintData() { throw new NotImplementedException(); } @@ -47,7 +58,7 @@ public void CreateTableIfNotExists() { using (IDbConnection db = new SqliteConnection(GetConString())) { - + db.Open(); var sqlQuery = "CREATE TABLE IF NOT EXISTS CodingSessions" + "(Id INTEGER PRIMARY KEY AUTOINCREMENT," + "Date TEXT NOT NULL," + @@ -55,6 +66,7 @@ public void CreateTableIfNotExists() "EndTime TEXT NOT NULL," + "Duration TEXT NOT NULL)"; db.Execute(sqlQuery); + db.Close(); } } } diff --git a/CodingTracker.Solomonlol/Controllers/ICodingController.cs b/CodingTracker.Solomonlol/Controllers/ICodingController.cs index 36d20abc4..f58ce10aa 100644 --- a/CodingTracker.Solomonlol/Controllers/ICodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/ICodingController.cs @@ -8,10 +8,10 @@ namespace CodingTracker.Solomonlol.Controllers internal interface ICodingController { public List GetData(); - public void UpdateData(); + public void UpdateData(int id); public void CreateTableIfNotExists(); - public void DeleteData(); - public void WriteData(); + public void DeleteData(int id); + public void PrintData(); public string GetConString(); } } diff --git a/CodingTracker.Solomonlol/Menu.cs b/CodingTracker.Solomonlol/Menu.cs index cd280eaaf..f698ac158 100644 --- a/CodingTracker.Solomonlol/Menu.cs +++ b/CodingTracker.Solomonlol/Menu.cs @@ -16,8 +16,8 @@ public void MainMenu() controller.CreateTableIfNotExists(); controller.GetData(); var choice = AnsiConsole.Prompt(new SelectionPrompt() - .Title("Select an [green]environment[/]:") - .AddChoices("Development", "Staging", "Production")); + .Title("Select an [green]option[/]:") + .AddChoices("Show Data", "Add new record", "Update record", "Delete record", "Close app")); AnsiConsole.MarkupLine($"Deploying to [blue]{choice}[/]"); From eace702c18e681fc06fde81ef687a477d714bad5 Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Tue, 21 Jul 2026 15:13:02 +0300 Subject: [PATCH 03/13] Baseline ready --- .../Controllers/CodingController.cs | 96 ++++++++++++++++--- .../Controllers/ICodingController.cs | 10 +- CodingTracker.Solomonlol/Menu.cs | 22 ++--- .../Model/CodingSession.cs | 25 +++-- CodingTracker.Solomonlol/Model/Enums.cs | 18 ---- CodingTracker.Solomonlol/Model/MenuValues.cs | 22 +++++ 6 files changed, 138 insertions(+), 55 deletions(-) delete mode 100644 CodingTracker.Solomonlol/Model/Enums.cs create mode 100644 CodingTracker.Solomonlol/Model/MenuValues.cs diff --git a/CodingTracker.Solomonlol/Controllers/CodingController.cs b/CodingTracker.Solomonlol/Controllers/CodingController.cs index 3b5b7b778..707d41740 100644 --- a/CodingTracker.Solomonlol/Controllers/CodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/CodingController.cs @@ -6,12 +6,30 @@ using System; using System.Collections.Generic; using System.Data; +using System.Globalization; using System.Text; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace CodingTracker.Solomonlol.Controllers { internal class CodingController : ICodingController { + public void CreateTableIfNotExists() + { + using (IDbConnection db = new SqliteConnection(GetConString())) + { + db.Open(); + var sqlQuery = "CREATE TABLE IF NOT EXISTS CodingSessions" + + "(Id INTEGER PRIMARY KEY AUTOINCREMENT," + + "Date TEXT NOT NULL," + + "StartTime TEXT NOT NULL," + + "EndTime TEXT NOT NULL," + + "Duration TEXT NOT NULL)"; + db.Execute(sqlQuery); + db.Close(); + } + } + public List GetData() { using(IDbConnection db = new SqliteConnection(GetConString())) @@ -19,8 +37,21 @@ public List GetData() return db.Query("SELECT * FROM CodingSessions").ToList(); } } - public void DeleteData(int id) + + public void CreateData() + { + var session = NewRecord(); + using (IDbConnection db = new SqliteConnection(GetConString())) + { + var sqlQuery = "INSERT INTO CodingSessions (Date, StartTime, EndTime, Duration)" + + "VALUES (@Date, @StartTime, @EndTime, @Duration)"; + db.Execute(sqlQuery, session); + } + } + + public void DeleteData() { + NumberInput("Write record Id to delete:", out int id); using (IDbConnection db = new SqliteConnection(GetConString())) { var sqlQuery="DELETE FROM CodingSessions WHERE Id=@id"; @@ -34,14 +65,36 @@ public void DeleteData(int id) } } - public void UpdateData(int id) + public void UpdateData() { - throw new NotImplementedException(); + NumberInput("Write record Id to update:", out int id); + var session = NewRecord(id); + using (IDbConnection db = new SqliteConnection(GetConString())) + { + var sqlQuery= "UPDATE CodingSessions SET Date=@Date," + + "StartTime=@StartTime," + + "EndTime=@EndTime," + + "Duration=@Duration " + + "WHERE Id=@Id"; + db.Execute(sqlQuery, session); + } } public void PrintData() { - throw new NotImplementedException(); + var toPrint = GetData(); + var table = new Table(); + table.AddColumns("ID", "Date", "Start time", "End time", "Duration"); + + foreach (var c in toPrint) + { + table.AddRow($"{c.Id}", + $"{c.Date}", + $"{c.StartTime}", + $"{c.EndTime}", + $"{c.Duration}"); + } + AnsiConsole.Write(table); } public string GetConString() @@ -54,20 +107,33 @@ public string GetConString() return connectionString; } - public void CreateTableIfNotExists() + private CodingSession NewRecord(int? id = null) { - using (IDbConnection db = new SqliteConnection(GetConString())) + DateInput("Write start time in 'dd.MM.yyyy HH:mm' format:", out DateTime startTime); + DateInput("Write start time in 'dd.MM.yyyy HH:mm' format:", out DateTime endTime); + CodingSession session = new(startTime, endTime, id); + return session; + + } + private static void DateInput(string s, out DateTime date) + { + Console.WriteLine(s); + while (!DateTime.TryParseExact(Console.ReadLine(), "dd.MM.yyyy H:m", CultureInfo.InvariantCulture, DateTimeStyles.None, out date)) { - db.Open(); - var sqlQuery = "CREATE TABLE IF NOT EXISTS CodingSessions" + - "(Id INTEGER PRIMARY KEY AUTOINCREMENT," + - "Date TEXT NOT NULL," + - "StartTime TEXT NOT NULL," + - "EndTime TEXT NOT NULL," + - "Duration TEXT NOT NULL)"; - db.Execute(sqlQuery); - db.Close(); + Console.WriteLine("Wrong data format. Write it like 'dd.MM.yyyy H:m' and try again."); } } + private static void NumberInput(string s, out int id) + { + Console.WriteLine(s); + while (!int.TryParse(Console.ReadLine(), out id) || id <= 0) + { + Console.WriteLine("Wrong data format. The string must contain only digits above zero. Try again."); + } + } + public void Exit() + { + Environment.Exit(0); + } } } diff --git a/CodingTracker.Solomonlol/Controllers/ICodingController.cs b/CodingTracker.Solomonlol/Controllers/ICodingController.cs index f58ce10aa..d8e6bd7c0 100644 --- a/CodingTracker.Solomonlol/Controllers/ICodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/ICodingController.cs @@ -7,11 +7,13 @@ namespace CodingTracker.Solomonlol.Controllers { internal interface ICodingController { - public List GetData(); - public void UpdateData(int id); public void CreateTableIfNotExists(); - public void DeleteData(int id); - public void PrintData(); + public List GetData(); public string GetConString(); + public void UpdateData(); + public void DeleteData(); + public void PrintData(); + public void CreateData(); + public void Exit(); } } diff --git a/CodingTracker.Solomonlol/Menu.cs b/CodingTracker.Solomonlol/Menu.cs index f698ac158..36c85c613 100644 --- a/CodingTracker.Solomonlol/Menu.cs +++ b/CodingTracker.Solomonlol/Menu.cs @@ -1,29 +1,27 @@ using CodingTracker.Solomonlol.Controllers; +using CodingTracker.Solomonlol.Model; +using Dapper; using Spectre.Console; using System; using System.Collections.Generic; using System.Text; +using static CodingTracker.Solomonlol.Model.MenuValues; namespace CodingTracker.Solomonlol { internal class Menu { - public void MainMenu() { - CodingController controller = new CodingController(); - controller.CreateTableIfNotExists(); - controller.GetData(); - var choice = AnsiConsole.Prompt(new SelectionPrompt() - .Title("Select an [green]option[/]:") - .AddChoices("Show Data", "Add new record", "Update record", "Delete record", "Close app")); + while (true) + { + var choice = AnsiConsole.Prompt(new SelectionPrompt() + .Title("Select an [green]option[/]:") + .AddChoices(menuValues.Keys)); - AnsiConsole.MarkupLine($"Deploying to [blue]{choice}[/]"); - - + menuValues[choice](); + } } - } - } diff --git a/CodingTracker.Solomonlol/Model/CodingSession.cs b/CodingTracker.Solomonlol/Model/CodingSession.cs index 43e53e575..ecd63322c 100644 --- a/CodingTracker.Solomonlol/Model/CodingSession.cs +++ b/CodingTracker.Solomonlol/Model/CodingSession.cs @@ -1,4 +1,5 @@ -using System; +using Spectre.Console; +using System; using System.Collections.Generic; using System.Text; @@ -6,10 +7,22 @@ namespace CodingTracker.Solomonlol.Model { internal class CodingSession { - private static List session = new(); - private int Id { get; set; } - private DateTime StartTime { get; set; } - private DateTime EndTime { get; set; } - private TimeOnly Duration { get; set; } + public int? Id { get; set; } = null; + public string Date { get; set; } + public string StartTime { get; set; } + public string EndTime { get; set; } + public string Duration { get; set; } + + public CodingSession() + { } + + public CodingSession(DateTime startTime, DateTime endTime, int? id = null) + { + Id= id; + Date = DateOnly.FromDateTime(startTime).ToString(); + StartTime = TimeOnly.FromDateTime(startTime).ToString(); + EndTime = TimeOnly.FromDateTime(endTime).ToString(); + Duration = ((int)endTime.Subtract(startTime).TotalMinutes) + " minutes"; + } } } diff --git a/CodingTracker.Solomonlol/Model/Enums.cs b/CodingTracker.Solomonlol/Model/Enums.cs deleted file mode 100644 index c75a3bf47..000000000 --- a/CodingTracker.Solomonlol/Model/Enums.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace CodingTracker.Solomonlol.Model -{ - internal class Enums - { - public enum MainMenu - { - View, - Add, - Update, - Delete, - Exit - } - } -} diff --git a/CodingTracker.Solomonlol/Model/MenuValues.cs b/CodingTracker.Solomonlol/Model/MenuValues.cs new file mode 100644 index 000000000..f28f8163c --- /dev/null +++ b/CodingTracker.Solomonlol/Model/MenuValues.cs @@ -0,0 +1,22 @@ +using CodingTracker.Solomonlol.Controllers; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; +using static CodingTracker.Solomonlol.Controllers.CodingController; + +namespace CodingTracker.Solomonlol.Model +{ + public class MenuValues + { + private static CodingController cod = new(); + public static Dictionary menuValues = new() + { + { "Print all records", () => cod.PrintData() }, + { "New record", () => cod.CreateData() }, + { "Update record", () => cod.UpdateData() }, + { "Delete record", () => cod.DeleteData() }, + { "Exit", () => cod.Exit() } + }; + } +} From 98cd0d6511f79cca82136ce8bac1f35f4a70c59f Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Tue, 21 Jul 2026 17:10:07 +0300 Subject: [PATCH 04/13] small fix --- .../Controllers/CodingController.cs | 50 ++++++++++++++----- .../Controllers/ICodingController.cs | 1 - CodingTracker.Solomonlol/Menu.cs | 2 + .../Model/CodingSession.cs | 2 +- CodingTracker.Solomonlol/Model/MenuValues.cs | 7 +-- 5 files changed, 44 insertions(+), 18 deletions(-) diff --git a/CodingTracker.Solomonlol/Controllers/CodingController.cs b/CodingTracker.Solomonlol/Controllers/CodingController.cs index 707d41740..840bf405a 100644 --- a/CodingTracker.Solomonlol/Controllers/CodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/CodingController.cs @@ -40,6 +40,7 @@ public List GetData() public void CreateData() { + PrintData(); var session = NewRecord(); using (IDbConnection db = new SqliteConnection(GetConString())) { @@ -51,6 +52,7 @@ public void CreateData() public void DeleteData() { + PrintData(); NumberInput("Write record Id to delete:", out int id); using (IDbConnection db = new SqliteConnection(GetConString())) { @@ -58,7 +60,7 @@ public void DeleteData() var check=db.Execute(sqlQuery, new { id }); if (check == 0) { - AnsiConsole.MarkupLine($"[red]Cannot found record whith Id={id} to delete.[/]"); + AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); } else AnsiConsole.MarkupLine($"[green]Record whith Id={id} was deleted.[/]"); @@ -67,21 +69,32 @@ public void DeleteData() public void UpdateData() { + PrintData(); NumberInput("Write record Id to update:", out int id); - var session = NewRecord(id); + string sql = "SELECT COUNT(1) FROM CodingSessions WHERE Id = @Id"; + + using (IDbConnection db = new SqliteConnection(GetConString())) { - var sqlQuery= "UPDATE CodingSessions SET Date=@Date," + - "StartTime=@StartTime," + - "EndTime=@EndTime," + - "Duration=@Duration " + - "WHERE Id=@Id"; - db.Execute(sqlQuery, session); + var checkIfExist = db.ExecuteScalar(sql, new { Id = id }); + if (checkIfExist) + { + var session = NewRecord(id); + + var sqlQuery = "UPDATE CodingSessions SET Date=@Date," + + "StartTime=@StartTime," + + "EndTime=@EndTime," + + "Duration=@Duration " + + "WHERE Id=@Id"; + db.Execute(sqlQuery, session); + } + else AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); } } public void PrintData() { + AnsiConsole.Clear(); var toPrint = GetData(); var table = new Table(); table.AddColumns("ID", "Date", "Start time", "End time", "Duration"); @@ -97,7 +110,7 @@ public void PrintData() AnsiConsole.Write(table); } - public string GetConString() + private string GetConString() { IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsetings.json") @@ -109,8 +122,19 @@ public string GetConString() private CodingSession NewRecord(int? id = null) { - DateInput("Write start time in 'dd.MM.yyyy HH:mm' format:", out DateTime startTime); - DateInput("Write start time in 'dd.MM.yyyy HH:mm' format:", out DateTime endTime); + DateTime startTime = default, endTime = default; + do + { + PrintData(); + DateInput("Write start time in 'dd.MM.yyyy H:m' format:", out startTime); + DateInput("Write end time in 'dd.MM.yyyy H:m' format:", out endTime); + if (!(endTime > startTime)) + { + AnsiConsole.MarkupLine("[red]The end time cannot be earlier than or the same as the start time.[/]" + + "\nPress any key to continue"); + AnsiConsole.Console.Input.ReadKey(true); + } + } while (!(endTime > startTime)); CodingSession session = new(startTime, endTime, id); return session; @@ -120,7 +144,7 @@ private static void DateInput(string s, out DateTime date) Console.WriteLine(s); while (!DateTime.TryParseExact(Console.ReadLine(), "dd.MM.yyyy H:m", CultureInfo.InvariantCulture, DateTimeStyles.None, out date)) { - Console.WriteLine("Wrong data format. Write it like 'dd.MM.yyyy H:m' and try again."); + AnsiConsole.MarkupLine("[red]Wrong data format. Write it like 'dd.MM.yyyy H:m' and try again.[/]"); } } private static void NumberInput(string s, out int id) @@ -128,7 +152,7 @@ private static void NumberInput(string s, out int id) Console.WriteLine(s); while (!int.TryParse(Console.ReadLine(), out id) || id <= 0) { - Console.WriteLine("Wrong data format. The string must contain only digits above zero. Try again."); + AnsiConsole.MarkupLine("[red]Wrong data format. The string must contain only digits above zero. Try again.[/]"); } } public void Exit() diff --git a/CodingTracker.Solomonlol/Controllers/ICodingController.cs b/CodingTracker.Solomonlol/Controllers/ICodingController.cs index d8e6bd7c0..99a7391e2 100644 --- a/CodingTracker.Solomonlol/Controllers/ICodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/ICodingController.cs @@ -9,7 +9,6 @@ internal interface ICodingController { public void CreateTableIfNotExists(); public List GetData(); - public string GetConString(); public void UpdateData(); public void DeleteData(); public void PrintData(); diff --git a/CodingTracker.Solomonlol/Menu.cs b/CodingTracker.Solomonlol/Menu.cs index 36c85c613..e9aa2e902 100644 --- a/CodingTracker.Solomonlol/Menu.cs +++ b/CodingTracker.Solomonlol/Menu.cs @@ -12,8 +12,10 @@ namespace CodingTracker.Solomonlol { internal class Menu { + public void MainMenu() { + cod.CreateTableIfNotExists(); while (true) { var choice = AnsiConsole.Prompt(new SelectionPrompt() diff --git a/CodingTracker.Solomonlol/Model/CodingSession.cs b/CodingTracker.Solomonlol/Model/CodingSession.cs index ecd63322c..a08b8edcd 100644 --- a/CodingTracker.Solomonlol/Model/CodingSession.cs +++ b/CodingTracker.Solomonlol/Model/CodingSession.cs @@ -18,7 +18,7 @@ public CodingSession() public CodingSession(DateTime startTime, DateTime endTime, int? id = null) { - Id= id; + Id = id; Date = DateOnly.FromDateTime(startTime).ToString(); StartTime = TimeOnly.FromDateTime(startTime).ToString(); EndTime = TimeOnly.FromDateTime(endTime).ToString(); diff --git a/CodingTracker.Solomonlol/Model/MenuValues.cs b/CodingTracker.Solomonlol/Model/MenuValues.cs index f28f8163c..671c325d9 100644 --- a/CodingTracker.Solomonlol/Model/MenuValues.cs +++ b/CodingTracker.Solomonlol/Model/MenuValues.cs @@ -3,13 +3,12 @@ using System.Collections.Generic; using System.ComponentModel; using System.Text; -using static CodingTracker.Solomonlol.Controllers.CodingController; namespace CodingTracker.Solomonlol.Model { - public class MenuValues + public static class MenuValues { - private static CodingController cod = new(); + internal static CodingController cod = new(); public static Dictionary menuValues = new() { { "Print all records", () => cod.PrintData() }, @@ -18,5 +17,7 @@ public class MenuValues { "Delete record", () => cod.DeleteData() }, { "Exit", () => cod.Exit() } }; + + } } From 2f2a59b77e2108cc2b9623e1e2ab1e441552fc9f Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Tue, 21 Jul 2026 17:13:51 +0300 Subject: [PATCH 05/13] change print --- .../Controllers/CodingController.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/CodingTracker.Solomonlol/Controllers/CodingController.cs b/CodingTracker.Solomonlol/Controllers/CodingController.cs index 840bf405a..b94090b41 100644 --- a/CodingTracker.Solomonlol/Controllers/CodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/CodingController.cs @@ -96,18 +96,22 @@ public void PrintData() { AnsiConsole.Clear(); var toPrint = GetData(); - var table = new Table(); - table.AddColumns("ID", "Date", "Start time", "End time", "Duration"); - - foreach (var c in toPrint) + if (toPrint.Count>0) { - table.AddRow($"{c.Id}", - $"{c.Date}", - $"{c.StartTime}", - $"{c.EndTime}", - $"{c.Duration}"); + var table = new Table(); + table.AddColumns("ID", "Date", "Start time", "End time", "Duration"); + + foreach (var c in toPrint) + { + table.AddRow($"{c.Id}", + $"{c.Date}", + $"{c.StartTime}", + $"{c.EndTime}", + $"{c.Duration}"); + } + AnsiConsole.Write(table); } - AnsiConsole.Write(table); + else AnsiConsole.MarkupLine("[red]Database is empty.[/]"); } private string GetConString() From 9ea358b06f7c9becce9493b5b67a3e25f9fb167e Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Wed, 22 Jul 2026 14:30:47 +0300 Subject: [PATCH 06/13] Create timer --- .../Controllers/CodingController.cs | 125 +++++++++++------- .../Controllers/ICodingController.cs | 2 +- CodingTracker.Solomonlol/Menu.cs | 2 +- CodingTracker.Solomonlol/Model/MenuValues.cs | 1 + CodingTracker.Solomonlol/Program.cs | 2 +- 5 files changed, 80 insertions(+), 52 deletions(-) diff --git a/CodingTracker.Solomonlol/Controllers/CodingController.cs b/CodingTracker.Solomonlol/Controllers/CodingController.cs index b94090b41..c1702d92d 100644 --- a/CodingTracker.Solomonlol/Controllers/CodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/CodingController.cs @@ -6,9 +6,10 @@ using System; using System.Collections.Generic; using System.Data; +using System.Diagnostics; using System.Globalization; using System.Text; -using static System.Runtime.InteropServices.JavaScript.JSType; +using System.Timers; namespace CodingTracker.Solomonlol.Controllers { @@ -16,55 +17,52 @@ internal class CodingController : ICodingController { public void CreateTableIfNotExists() { - using (IDbConnection db = new SqliteConnection(GetConString())) - { - db.Open(); - var sqlQuery = "CREATE TABLE IF NOT EXISTS CodingSessions" + - "(Id INTEGER PRIMARY KEY AUTOINCREMENT," + - "Date TEXT NOT NULL," + - "StartTime TEXT NOT NULL," + - "EndTime TEXT NOT NULL," + - "Duration TEXT NOT NULL)"; - db.Execute(sqlQuery); - db.Close(); - } + using IDbConnection db = new SqliteConnection(GetConString()); + db.Open(); + var sqlQuery = "CREATE TABLE IF NOT EXISTS CodingSessions" + + "(Id INTEGER PRIMARY KEY AUTOINCREMENT," + + "Date TEXT NOT NULL," + + "StartTime TEXT NOT NULL," + + "EndTime TEXT NOT NULL," + + "Duration TEXT NOT NULL)"; + db.Execute(sqlQuery); + db.Close(); } public List GetData() { - using(IDbConnection db = new SqliteConnection(GetConString())) - { - return db.Query("SELECT * FROM CodingSessions").ToList(); - } + using IDbConnection db = new SqliteConnection(GetConString()); + return [.. db.Query("SELECT * FROM CodingSessions")]; } - public void CreateData() + public void CreateData(CodingSession? codingSession=null) { PrintData(); - var session = NewRecord(); - using (IDbConnection db = new SqliteConnection(GetConString())) + CodingSession session = new(); + if (codingSession == null) { - var sqlQuery = "INSERT INTO CodingSessions (Date, StartTime, EndTime, Duration)" + - "VALUES (@Date, @StartTime, @EndTime, @Duration)"; - db.Execute(sqlQuery, session); + session = NewRecord(); } + else session = codingSession; + using IDbConnection db = new SqliteConnection(GetConString()); + var sqlQuery = "INSERT INTO CodingSessions (Date, StartTime, EndTime, Duration)" + + "VALUES (@Date, @StartTime, @EndTime, @Duration)"; + db.Execute(sqlQuery, session); } public void DeleteData() { PrintData(); NumberInput("Write record Id to delete:", out int id); - using (IDbConnection db = new SqliteConnection(GetConString())) + using IDbConnection db = new SqliteConnection(GetConString()); + var sqlQuery = "DELETE FROM CodingSessions WHERE Id=@id"; + var check = db.Execute(sqlQuery, new { id }); + if (check == 0) { - var sqlQuery="DELETE FROM CodingSessions WHERE Id=@id"; - var check=db.Execute(sqlQuery, new { id }); - if (check == 0) - { - AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); + AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); - } - else AnsiConsole.MarkupLine($"[green]Record whith Id={id} was deleted.[/]"); } + else AnsiConsole.MarkupLine($"[green]Record whith Id={id} was deleted.[/]"); } public void UpdateData() @@ -72,24 +70,22 @@ public void UpdateData() PrintData(); NumberInput("Write record Id to update:", out int id); string sql = "SELECT COUNT(1) FROM CodingSessions WHERE Id = @Id"; - - - using (IDbConnection db = new SqliteConnection(GetConString())) + + + using IDbConnection db = new SqliteConnection(GetConString()); + var checkIfExist = db.ExecuteScalar(sql, new { Id = id }); + if (checkIfExist) { - var checkIfExist = db.ExecuteScalar(sql, new { Id = id }); - if (checkIfExist) - { - var session = NewRecord(id); - - var sqlQuery = "UPDATE CodingSessions SET Date=@Date," + - "StartTime=@StartTime," + - "EndTime=@EndTime," + - "Duration=@Duration " + - "WHERE Id=@Id"; - db.Execute(sqlQuery, session); - } - else AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); + var session = NewRecord(id); + + var sqlQuery = "UPDATE CodingSessions SET Date=@Date," + + "StartTime=@StartTime," + + "EndTime=@EndTime," + + "Duration=@Duration " + + "WHERE Id=@Id"; + db.Execute(sqlQuery, session); } + else AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); } public void PrintData() @@ -114,7 +110,7 @@ public void PrintData() else AnsiConsole.MarkupLine("[red]Database is empty.[/]"); } - private string GetConString() + private static string GetConString() { IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsetings.json") @@ -126,7 +122,7 @@ private string GetConString() private CodingSession NewRecord(int? id = null) { - DateTime startTime = default, endTime = default; + DateTime startTime, endTime; do { PrintData(); @@ -159,6 +155,37 @@ private static void NumberInput(string s, out int id) AnsiConsole.MarkupLine("[red]Wrong data format. The string must contain only digits above zero. Try again.[/]"); } } + public void StartTimer() + { + Stopwatch stopwatch = new Stopwatch(); + bool isRunning=true; + DateTime start = DateTime.Now; + DateTime end = new(); + stopwatch.Start(); + while(true) + { + if(Console.KeyAvailable) + { + var key = Console.ReadKey(true).Key; + if(key==ConsoleKey.Enter) + { + stopwatch.Stop(); + isRunning = false; + end = start+stopwatch.Elapsed; + CreateData(new CodingSession(start, end)); + break; + } + } + if(isRunning) + { + Console.Clear(); + AnsiConsole.MarkupLine("[green]IT'S CODING TIME![/]\nPress Enter key to stop this session..."); + AnsiConsole.MarkupLine($"Current session: {stopwatch.Elapsed.ToString(@"mm\:ss")}"); + Thread.Sleep(1000); + } + } + } + public void Exit() { Environment.Exit(0); diff --git a/CodingTracker.Solomonlol/Controllers/ICodingController.cs b/CodingTracker.Solomonlol/Controllers/ICodingController.cs index 99a7391e2..641858890 100644 --- a/CodingTracker.Solomonlol/Controllers/ICodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/ICodingController.cs @@ -12,7 +12,7 @@ internal interface ICodingController public void UpdateData(); public void DeleteData(); public void PrintData(); - public void CreateData(); + public void CreateData(CodingSession? codingSession=null); public void Exit(); } } diff --git a/CodingTracker.Solomonlol/Menu.cs b/CodingTracker.Solomonlol/Menu.cs index e9aa2e902..48c1300a6 100644 --- a/CodingTracker.Solomonlol/Menu.cs +++ b/CodingTracker.Solomonlol/Menu.cs @@ -13,7 +13,7 @@ namespace CodingTracker.Solomonlol internal class Menu { - public void MainMenu() + public static void MainMenu() { cod.CreateTableIfNotExists(); while (true) diff --git a/CodingTracker.Solomonlol/Model/MenuValues.cs b/CodingTracker.Solomonlol/Model/MenuValues.cs index 671c325d9..7d3d03ec3 100644 --- a/CodingTracker.Solomonlol/Model/MenuValues.cs +++ b/CodingTracker.Solomonlol/Model/MenuValues.cs @@ -15,6 +15,7 @@ public static class MenuValues { "New record", () => cod.CreateData() }, { "Update record", () => cod.UpdateData() }, { "Delete record", () => cod.DeleteData() }, + { "Timer", ()=>cod.StartTimer() }, { "Exit", () => cod.Exit() } }; diff --git a/CodingTracker.Solomonlol/Program.cs b/CodingTracker.Solomonlol/Program.cs index 7b814e272..3564f7ef4 100644 --- a/CodingTracker.Solomonlol/Program.cs +++ b/CodingTracker.Solomonlol/Program.cs @@ -5,4 +5,4 @@ Menu menu = new(); -menu.MainMenu(); \ No newline at end of file +Menu.MainMenu(); \ No newline at end of file From 7ed56fed2e4f32ca6fd4ed4cee1465f9241b837e Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Wed, 22 Jul 2026 16:00:08 +0300 Subject: [PATCH 07/13] Order by des and asc implemented --- .../Controllers/CodingController.cs | 59 +++++++++++++------ .../Controllers/ICodingController.cs | 3 +- CodingTracker.Solomonlol/Model/MenuValues.cs | 26 ++++++-- 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/CodingTracker.Solomonlol/Controllers/CodingController.cs b/CodingTracker.Solomonlol/Controllers/CodingController.cs index c1702d92d..2f26ce31f 100644 --- a/CodingTracker.Solomonlol/Controllers/CodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/CodingController.cs @@ -3,13 +3,10 @@ using Microsoft.Data.Sqlite; using Microsoft.Extensions.Configuration; using Spectre.Console; -using System; -using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Globalization; -using System.Text; -using System.Timers; +using static CodingTracker.Solomonlol.Model.MenuValues; namespace CodingTracker.Solomonlol.Controllers { @@ -29,10 +26,10 @@ public void CreateTableIfNotExists() db.Close(); } - public List GetData() + public List GetData(string? s = null) { using IDbConnection db = new SqliteConnection(GetConString()); - return [.. db.Query("SELECT * FROM CodingSessions")]; + return [.. db.Query(s)]; } public void CreateData(CodingSession? codingSession=null) @@ -44,10 +41,12 @@ public void CreateData(CodingSession? codingSession=null) session = NewRecord(); } else session = codingSession; + using IDbConnection db = new SqliteConnection(GetConString()); var sqlQuery = "INSERT INTO CodingSessions (Date, StartTime, EndTime, Duration)" + "VALUES (@Date, @StartTime, @EndTime, @Duration)"; db.Execute(sqlQuery, session); + PrintData(); } public void DeleteData() @@ -62,7 +61,12 @@ public void DeleteData() AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); } - else AnsiConsole.MarkupLine($"[green]Record whith Id={id} was deleted.[/]"); + else + { + PrintData(); + AnsiConsole.MarkupLine($"[green]Record whith Id={id} was deleted.[/]"); + } + } public void UpdateData() @@ -84,14 +88,26 @@ public void UpdateData() "Duration=@Duration " + "WHERE Id=@Id"; db.Execute(sqlQuery, session); + PrintData(); + AnsiConsole.MarkupLine($"[green]Record whith Id={id} was upadted.[/]"); } - else AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); + else + { + PrintData(); + AnsiConsole.MarkupLine($"[red]Record whith Id={id} does not exists.[/]"); + } + } - public void PrintData() + public void PrintData(string? s = null) { AnsiConsole.Clear(); - var toPrint = GetData(); + List toPrint = new List(); + if (s != null) + { + toPrint = GetData(s); + } + else toPrint = GetData(); if (toPrint.Count>0) { var table = new Table(); @@ -158,7 +174,6 @@ private static void NumberInput(string s, out int id) public void StartTimer() { Stopwatch stopwatch = new Stopwatch(); - bool isRunning=true; DateTime start = DateTime.Now; DateTime end = new(); stopwatch.Start(); @@ -170,21 +185,27 @@ public void StartTimer() if(key==ConsoleKey.Enter) { stopwatch.Stop(); - isRunning = false; end = start+stopwatch.Elapsed; CreateData(new CodingSession(start, end)); break; } } - if(isRunning) - { - Console.Clear(); - AnsiConsole.MarkupLine("[green]IT'S CODING TIME![/]\nPress Enter key to stop this session..."); - AnsiConsole.MarkupLine($"Current session: {stopwatch.Elapsed.ToString(@"mm\:ss")}"); - Thread.Sleep(1000); - } + + Console.Clear(); + AnsiConsole.MarkupLine("[green]IT'S CODING TIME![/]\nPress Enter key to stop this session..."); + AnsiConsole.MarkupLine($"Current session: {stopwatch.Elapsed.ToString(@"mm\:ss")}"); + Thread.Sleep(1000); } } + public void PrintOrderby() + { + var choice = AnsiConsole.Prompt(new SelectionPrompt() + .Title("Select an [green]option[/]:") + .AddChoices(printValues.Keys)); + + printValues[choice](""); + + } public void Exit() { diff --git a/CodingTracker.Solomonlol/Controllers/ICodingController.cs b/CodingTracker.Solomonlol/Controllers/ICodingController.cs index 641858890..4cb742704 100644 --- a/CodingTracker.Solomonlol/Controllers/ICodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/ICodingController.cs @@ -8,10 +8,9 @@ namespace CodingTracker.Solomonlol.Controllers internal interface ICodingController { public void CreateTableIfNotExists(); - public List GetData(); public void UpdateData(); public void DeleteData(); - public void PrintData(); + public void PrintData(string? s=null); public void CreateData(CodingSession? codingSession=null); public void Exit(); } diff --git a/CodingTracker.Solomonlol/Model/MenuValues.cs b/CodingTracker.Solomonlol/Model/MenuValues.cs index 7d3d03ec3..421e876b2 100644 --- a/CodingTracker.Solomonlol/Model/MenuValues.cs +++ b/CodingTracker.Solomonlol/Model/MenuValues.cs @@ -1,8 +1,5 @@ using CodingTracker.Solomonlol.Controllers; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Text; + namespace CodingTracker.Solomonlol.Model { @@ -11,7 +8,7 @@ public static class MenuValues internal static CodingController cod = new(); public static Dictionary menuValues = new() { - { "Print all records", () => cod.PrintData() }, + { "Print all records", () => cod.PrintOrderby() }, { "New record", () => cod.CreateData() }, { "Update record", () => cod.UpdateData() }, { "Delete record", () => cod.DeleteData() }, @@ -19,6 +16,23 @@ public static class MenuValues { "Exit", () => cod.Exit() } }; - + public static Dictionary> printValues = new() + { + { "Print all records", (s) => cod.PrintData("SELECT * FROM CodingSessions") }, + { "Order by Date Ascending", (s) => cod.PrintData("SELECT * FROM CodingSessions ORDER BY Date ASC") }, + { "Order by Date Descending", (s) => cod.PrintData("SELECT * FROM CodingSessions ORDER BY Date DESC") }, + { "Order by Duration Ascending", (s) => cod.PrintData("SELECT * FROM CodingSessions ORDER BY Duration ASC") }, + { "Order by Duration Descending", (s) => cod.PrintData("SELECT * FROM CodingSessions ORDER BY Duration DESC") }, + }; + + //public static Dictionary> printOrderByValuesColumn = new() + //{ + // { "Date Ascending", (s) => cod.PrintData(s) }, + // { "Date Descending", (s) => cod.PrintData(s) }, + // { "Duration Ascending", (s) => cod.PrintData(s) }, + // { "Duration Descending", (s) => cod.PrintData(s) } + //}; + + } } From ea81a036195e5972c081ec16810e8d65dd108f1d Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Wed, 22 Jul 2026 16:36:44 +0300 Subject: [PATCH 08/13] small fix --- .../Controllers/CodingController.cs | 1 + CodingTracker.Solomonlol/Model/MenuValues.cs | 11 +---------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/CodingTracker.Solomonlol/Controllers/CodingController.cs b/CodingTracker.Solomonlol/Controllers/CodingController.cs index 2f26ce31f..450d00f81 100644 --- a/CodingTracker.Solomonlol/Controllers/CodingController.cs +++ b/CodingTracker.Solomonlol/Controllers/CodingController.cs @@ -28,6 +28,7 @@ public void CreateTableIfNotExists() public List GetData(string? s = null) { + if (s == null) s = "SELECT * FROM CodingSessions"; using IDbConnection db = new SqliteConnection(GetConString()); return [.. db.Query(s)]; } diff --git a/CodingTracker.Solomonlol/Model/MenuValues.cs b/CodingTracker.Solomonlol/Model/MenuValues.cs index 421e876b2..6cf45d0cc 100644 --- a/CodingTracker.Solomonlol/Model/MenuValues.cs +++ b/CodingTracker.Solomonlol/Model/MenuValues.cs @@ -18,21 +18,12 @@ public static class MenuValues public static Dictionary> printValues = new() { - { "Print all records", (s) => cod.PrintData("SELECT * FROM CodingSessions") }, + { "Print", (s) => cod.PrintData() }, { "Order by Date Ascending", (s) => cod.PrintData("SELECT * FROM CodingSessions ORDER BY Date ASC") }, { "Order by Date Descending", (s) => cod.PrintData("SELECT * FROM CodingSessions ORDER BY Date DESC") }, { "Order by Duration Ascending", (s) => cod.PrintData("SELECT * FROM CodingSessions ORDER BY Duration ASC") }, { "Order by Duration Descending", (s) => cod.PrintData("SELECT * FROM CodingSessions ORDER BY Duration DESC") }, }; - //public static Dictionary> printOrderByValuesColumn = new() - //{ - // { "Date Ascending", (s) => cod.PrintData(s) }, - // { "Date Descending", (s) => cod.PrintData(s) }, - // { "Duration Ascending", (s) => cod.PrintData(s) }, - // { "Duration Descending", (s) => cod.PrintData(s) } - //}; - - } } From 631acfdea3f5d0b5091596b92d5ed9d45f140baf Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Wed, 22 Jul 2026 16:43:16 +0300 Subject: [PATCH 09/13] Create README.md --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..b518a342d --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +#ABOUT CODING TRACKER +A .NET 10-based console application that allows users to create, view, update, and delete records of time spent coding. +It supports both manual data entry and automatic time tracking via a timer. +Users can view all database records in their original order or sort them in ascending or descending order. + +#FEATURES +The program creates a database upon startup. +The user can select a menu item; navigation is performed using the arrow keys. +image + +1. Print all records +This option give user another choises of how to print data +image +Print - Output data without sorting +The other menu items speak for themselves. +After selecting the menu item, a table appears containing data read from the database. +image +2.New record +This create new record. User write start and end time in 'dd.MM.yyyy H:m' format: +image +Data entered by the user must be correct. Otherwise, the program will indicate the incorrectly entered data. +3.Update record +This option allows the user to make changes to an existing record. +4.Delete record +This option allows the user to delete an existing record. +5.Timer +This menu item starts a timer and displays the current session time on the console. +Once the user stops the timer, a new record containing the current session's timing data is created in the database. +6.Exit +This option close the app + +#Lessons Learned +Learned how to use Stopwatch. + +Tried creating a menu using a Dictionary instead of a switch statement. + +Learned how to use Dapper—it is simpler than ADO.NET. + +Gained experience in using a separate JSON file to store the database connection string. + + +#My thoughts +I still have a lot to improve, but progress is evident, as this project was completed faster +than the previous one despite the use of new technologies. From 5372d6a3deef89e8f02ac7a7b8ff5ff4b8ed25be Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Wed, 22 Jul 2026 16:43:59 +0300 Subject: [PATCH 10/13] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index b518a342d..a80390e6c 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,30 @@ #ABOUT CODING TRACKER + A .NET 10-based console application that allows users to create, view, update, and delete records of time spent coding. It supports both manual data entry and automatic time tracking via a timer. Users can view all database records in their original order or sort them in ascending or descending order. #FEATURES + The program creates a database upon startup. The user can select a menu item; navigation is performed using the arrow keys. image 1. Print all records + This option give user another choises of how to print data image + Print - Output data without sorting The other menu items speak for themselves. After selecting the menu item, a table appears containing data read from the database. image + 2.New record + This create new record. User write start and end time in 'dd.MM.yyyy H:m' format: image + Data entered by the user must be correct. Otherwise, the program will indicate the incorrectly entered data. 3.Update record This option allows the user to make changes to an existing record. From 91b409767ede50a48f1d6a65c88d41951517c431 Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Wed, 22 Jul 2026 16:44:56 +0300 Subject: [PATCH 11/13] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a80390e6c..a2de3102c 100644 --- a/README.md +++ b/README.md @@ -28,11 +28,14 @@ This create new record. User write start and end time in 'dd.MM.yyyy H:m' format Data entered by the user must be correct. Otherwise, the program will indicate the incorrectly entered data. 3.Update record This option allows the user to make changes to an existing record. + 4.Delete record This option allows the user to delete an existing record. + 5.Timer This menu item starts a timer and displays the current session time on the console. Once the user stops the timer, a new record containing the current session's timing data is created in the database. + 6.Exit This option close the app From 2263017bdac56167f3e002f1ee553dd0d81626f5 Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Wed, 22 Jul 2026 16:45:32 +0300 Subject: [PATCH 12/13] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a2de3102c..f727e455b 100644 --- a/README.md +++ b/README.md @@ -40,15 +40,14 @@ Once the user stops the timer, a new record containing the current session's tim This option close the app #Lessons Learned -Learned how to use Stopwatch. +Learned how to use Stopwatch. Tried creating a menu using a Dictionary instead of a switch statement. - Learned how to use Dapper—it is simpler than ADO.NET. - Gained experience in using a separate JSON file to store the database connection string. #My thoughts + I still have a lot to improve, but progress is evident, as this project was completed faster than the previous one despite the use of new technologies. From 815d289c20996884c755c81e7379885e30266347 Mon Sep 17 00:00:00 2001 From: Arsenii Hapechkin Date: Wed, 22 Jul 2026 16:45:51 +0300 Subject: [PATCH 13/13] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f727e455b..e1d60d4b3 100644 --- a/README.md +++ b/README.md @@ -27,16 +27,20 @@ This create new record. User write start and end time in 'dd.MM.yyyy H:m' format Data entered by the user must be correct. Otherwise, the program will indicate the incorrectly entered data. 3.Update record + This option allows the user to make changes to an existing record. 4.Delete record + This option allows the user to delete an existing record. 5.Timer + This menu item starts a timer and displays the current session time on the console. Once the user stops the timer, a new record containing the current session's timing data is created in the database. 6.Exit + This option close the app #Lessons Learned