Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -478,3 +478,5 @@ $RECYCLE.BIN/
*.lnk
/MathGame2
/CodingTracker.TomDonegan/TextFile1.txt

*.db
24 changes: 24 additions & 0 deletions CodeReviews.Console.CodingTracker.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodingTracker.Kaylubr", "CodingTracker.Kaylubr\CodingTracker.Kaylubr.csproj", "{6AABB9C0-5449-298C-1EB0-59B25D4A6CAC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6AABB9C0-5449-298C-1EB0-59B25D4A6CAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AABB9C0-5449-298C-1EB0-59B25D4A6CAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AABB9C0-5449-298C-1EB0-59B25D4A6CAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6AABB9C0-5449-298C-1EB0-59B25D4A6CAC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {67FA8CC2-65C3-4683-B605-8F131556E3AC}
EndGlobalSection
EndGlobal
21 changes: 21 additions & 0 deletions CodingTracker.Kaylubr/CodingTracker.Kaylubr.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.2" />
<PackageReference Include="Spectre.Console" Version="0.54.0" />
</ItemGroup>

</Project>
76 changes: 76 additions & 0 deletions CodingTracker.Kaylubr/Controllers/CodingSessionController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using CodingTracker.Utils;

namespace CodingTracker.Controllers;

internal static class CodingTrackerController
{
internal static void InsertSession()
{
var (startTime, endTime) = UserInput.GetStartAndEndTime();
string duration = UserInput.GetDuration(startTime, endTime);
Database.Insert(startTime, endTime, duration);
Helper.Pause("Successful Operation!", success: true);
}

internal static void LogAllRecords()
{
Helper.RenderCodingSessionInTable(Database.GetAll());
Helper.Pause();
}

internal static void UpdateRecord()
{
bool exists = Helper.RenderCodingSessionInTable(Database.GetAll());

if (exists)
{
int id = UserInput.GetID("EDITED");

if (!Database.FindOneSession(id))
{
Helper.Pause("Record not found!", success: false);
return;
}

var (startTime, endTime) = UserInput.GetStartAndEndTime();
string duration = UserInput.GetDuration(startTime, endTime);

Database.Update(id, startTime, endTime, duration);

Helper.Pause("Successful Operation!", success: true);
}
else
{
Helper.Pause();
}
}

internal static void DeleteRecord()
{
bool exists = Helper.RenderCodingSessionInTable(Database.GetAll());

if (exists)
{
int id = UserInput.GetID("DELETED");

if (!Database.FindOneSession(id))
{
Helper.Pause("Record not found!", success: false);
return;
}

if (!Helper.Confirmation("Are you sure?"))
{
return;
}

Database.DeleteOne(id);

Helper.Pause("Successful Operation!", success: true);
}
else
{
Helper.Pause();
}
}
}
10 changes: 10 additions & 0 deletions CodingTracker.Kaylubr/Enums/MenuChoices.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace CodingTracker.Enums;

internal enum MenuChoices
{
View,
Insert,
Update,
Delete,
Exit
}
9 changes: 9 additions & 0 deletions CodingTracker.Kaylubr/Models/CodingSession.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace CodingTracker.Models;

public class CodingSession
{
public int Id { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Duration { get; set; } = string.Empty;
}
5 changes: 5 additions & 0 deletions CodingTracker.Kaylubr/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using CodingTracker.Views;
using CodingTracker.Utils;

Database.CreateDatabase();
UserInterface.Run();
16 changes: 16 additions & 0 deletions CodingTracker.Kaylubr/Utils/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.Extensions.Configuration;

namespace CodingTracker.Utils;

internal static class Config
{
internal static string? InitializeConfig()
{
var configuration = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();

return configuration.GetConnectionString("DefaultConnection");
}
}
70 changes: 70 additions & 0 deletions CodingTracker.Kaylubr/Utils/Database.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using CodingTracker.Models;
using Dapper;
using Microsoft.Data.Sqlite;

namespace CodingTracker.Utils;

internal static class Database
{
readonly static string? connectionString = Config.InitializeConfig();
readonly static SqliteConnection connection = new(connectionString);

internal static void CreateDatabase()
{
var sql = @"CREATE TABLE IF NOT EXISTS coding_session (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
StartTime TEXT,
EndTime TEXT,
Duration TEXT
)";

connection.Execute(sql);
}

internal static void Insert(string st, string et, string duration)
{
var sql = @"INSERT INTO coding_session (StartTime, EndTime, Duration)
VALUES (@start, @end, @duration)
";

connection.Execute(sql, new { start = st, end = et, duration });
}

internal static List<CodingSession> GetAll()
{
var sql = "SELECT * FROM coding_session";
List<CodingSession> records = connection.Query<CodingSession>(sql).ToList();

return records;
}

internal static void Update(int id, string st, string et, string duration)
{
var sql = "UPDATE coding_session SET StartTime = @st, EndTime = @et, Duration = @duration WHERE Id = @id";
var obj = new { id, st, et, duration };

connection.Execute(sql, obj);
}

internal static void DeleteOne(int id)
{
var sql = "DELETE FROM coding_session WHERE id = @id";
connection.Execute(sql, new { id });
}

internal static bool FindOneSession(int id)
{
var sql = "SELECT * FROM coding_session WHERE Id = @id";
var obj = new { id };

try
{
connection.QuerySingle<CodingSession>(sql, obj);
return true;
}
catch
{
return false;
}
}
}
89 changes: 89 additions & 0 deletions CodingTracker.Kaylubr/Utils/Helper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using CodingTracker.Models;
using Spectre.Console;

namespace CodingTracker.Utils;

internal static class Helper
{
internal static bool ValidateTime(DateTime start, DateTime end)
{
if (start > end)
{
AnsiConsole.MarkupLine("[red]Starting time shouldn't be greater than the end time.[/]");
return false;
}

return true;
}

internal static bool RenderCodingSessionInTable(List<CodingSession> codingSessions)
{
AnsiConsole.Clear();

if (codingSessions.Count >= 1)
{
var table = new Table()
.Title("[green bold]Session Records[/]")
.Border(TableBorder.Heavy);

table.AddColumn("ID");
table.AddColumn("Starting time");
table.AddColumn("End time");
table.AddColumn("Duration");

foreach (var session in codingSessions)
{
table.AddRow(session.Id.ToString(), session.StartTime.ToString(), session.EndTime.ToString(), session.Duration);
}

AnsiConsole.Write(table);

return true;
}
else
{
AnsiConsole.MarkupLine("[red]No coding sessions to display. Add a session to see it here.[/]");
return false;
}

}

internal static bool Confirmation(string message)
{
AnsiConsole.WriteLine();

string? choice;
do
{
choice = AnsiConsole.Ask<string>($"{message} [bold green]Y[/] or [bold red]N[/]:").Trim().ToUpper();
} while (choice != "Y" && choice != "N");

if (choice == "N")
return false;

return true;
}

internal static void Pause()
{
AnsiConsole.Write("\nPress any key to continue..");
Console.ReadKey();
}

internal static void Pause(string message, bool success)
{
if (success)
{
AnsiConsole.MarkupLine($"\n[green]{message}[/]");
}
else
{
AnsiConsole.MarkupLine($"\n[red]{message}[/]");
}

AnsiConsole.Write("\nPress any key to continue..");
Console.ReadKey();

AnsiConsole.Clear();
}
}
56 changes: 56 additions & 0 deletions CodingTracker.Kaylubr/Utils/UserInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Spectre.Console;
using System.Globalization;

namespace CodingTracker.Utils;

internal static class UserInput
{
internal static int GetID(string mode)
{
AnsiConsole.WriteLine();
return AnsiConsole.Ask<int>($"\nEnter the [green]ID[/] of the row to be [bold]{mode}[/]: ");
}

internal static (string StartTime, string EndTime) GetStartAndEndTime()
{
DateTime start;
DateTime end;

do
{
AnsiConsole.WriteLine();
start = GetTime("START");
end = GetTime("END");
} while (!Helper.ValidateTime(start, end));

string startTime = start.ToString();
string endTime = end.ToString();

return (startTime, endTime);
}

static DateTime GetTime(string message)
{
while (true)
{
var time = AnsiConsole.Ask<string>($"Enter [bold green]{message}[/] session time in the format (dd-MM-yy HH-mm): ");

if (DateTime.TryParseExact(time, "dd-MM-yy HH:mm", new CultureInfo("en-US"), DateTimeStyles.None, out _))
{
return DateTime.ParseExact(time, "dd-MM-yy HH:mm", new CultureInfo("en-US"));
}

AnsiConsole.MarkupLine("[red]Invalid Format or Invalid Date & Time[/]");
}

}

internal static string GetDuration(string start, string end)
{
DateTime startTime = DateTime.Parse(start);
DateTime endTime = DateTime.Parse(end);

return (endTime - startTime).ToString(@"hh\:mm\:ss");
}

}
Loading