From ec040894c1ea641f322d0a2d624d5d61dd54f4be Mon Sep 17 00:00:00 2001 From: Cade Date: Sun, 15 Feb 2026 19:05:02 -0500 Subject: [PATCH 1/6] Commit for C#Academy PR --- jcshepherd63.CodingTracker/codingtracker.db | Bin 0 -> 12288 bytes .../jcshepherd63.CodingTracker.slnx | 3 + .../jcshepherd63.CodingTracker/.gitattributes | 63 +++ .../jcshepherd63.CodingTracker/.gitignore | 363 ++++++++++++++++++ .../Controllers/CodeSessionController.cs | 52 +++ .../Controllers/ProjectController.cs | 68 ++++ .../Menus/CodeSessionMenu.cs | 154 ++++++++ .../Menus/MainMenu.cs | 62 +++ .../Menus/ProjectMenu.cs | 57 +++ .../Models/Enums.cs | 24 ++ .../Models/_CodingTimeModel.cs | 11 + .../Models/_ProjectModel.cs | 18 + .../jcshepherd63.CodingTracker/Program.cs | 4 + .../jcshepherd63.CodingTracker/README.md | 1 + .../Services/CodeSessionService.cs | 84 ++++ .../Services/ProjectService.cs | 78 ++++ .../_DatabaseCreation.cs | 36 ++ .../appsettings.json | 5 + .../codingtracker.db | Bin 0 -> 16384 bytes .../jcshepherd63.CodingTracker.csproj | 28 ++ 20 files changed, 1111 insertions(+) create mode 100644 jcshepherd63.CodingTracker/codingtracker.db create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker.slnx create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/.gitattributes create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/.gitignore create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/ProjectController.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/CodeSessionMenu.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/MainMenu.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/ProjectMenu.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/Enums.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/_CodingTimeModel.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/_ProjectModel.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Program.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/README.md create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Services/CodeSessionService.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Services/ProjectService.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/_DatabaseCreation.cs create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/appsettings.json create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker.csproj diff --git a/jcshepherd63.CodingTracker/codingtracker.db b/jcshepherd63.CodingTracker/codingtracker.db new file mode 100644 index 0000000000000000000000000000000000000000..f5feafe0851431af4760b656a74c6c6adfa688a8 GIT binary patch literal 12288 zcmeI%F-yZh6u|MjRCJQMb-ivWEiQfmqaG4$V;WDelf?9tNR!YuE^b}?++KpE*u_=K z|G_2ig}Vp&WqRacI?ijWUaM7+*6Ko>2`R;;QbGvnR>!SvH1*N8aQCMEE2KF88l1Xa zUe_1hPj?{@KmY**5I_I{1Q0*~0R#~E#{#i;+#3$%tWIARcD-DACUv8|(N8XI8vms6s(QCs-B#^v?uLE>0R#|0009IL sKmY**5I_I{1P)lB`8Ut}f50D@S3>{+1Q0*~0R#|0009ILK)?xn15+JMX#fBK literal 0 HcmV?d00001 diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker.slnx b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker.slnx new file mode 100644 index 000000000..6cfe1ab76 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker.slnx @@ -0,0 +1,3 @@ + + + diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/.gitattributes b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/.gitattributes new file mode 100644 index 000000000..1ff0c4230 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/.gitignore b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/.gitignore new file mode 100644 index 000000000..9491a2fda --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs new file mode 100644 index 000000000..5b49d11a4 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs @@ -0,0 +1,52 @@ +using Spectre.Console; +using System; +using System.Collections.Generic; +using System.Text; + +public class CodeSessionController +{ + public static Calendar CodingCalendarOutput() + { + var today = DateTime.Now; + var calendar = new Calendar(today) + .Border(TableBorder.Rounded) + .HeaderStyle(new Style(foreground: Color.Blue, decoration: Decoration.Italic)); + + return calendar; + } + + + private static Table CodingTimeTableOutput() + { + var table = new Table() + .RoundedBorder() + .BorderColor(Color.DarkCyan) + .Title("[yellow bold]Time Spent Coding[/]"); + + table.AddColumn("[italic]Session ID[/]"); + table.AddColumn("[italic]Session Date[/]"); + table.AddColumn("[italic]Session Start Time[/]"); + table.AddColumn("[italic]Session End Time[/]"); + table.AddColumn("[italic]Project Worked On[/]"); + + return table; + } + + public static void OutputSessionListToTable() + { + List codingSessions = CodeSessionService.GetAllCodeSessions(); + var table = CodingTimeTableOutput(); + + foreach (CodingTime session in codingSessions) + { + table.AddRow( + session.Id.ToString(), + session.Date.ToString("MM-dd-yyyy"), + session.StartTime.ToString(), + session.EndTime.ToString(), + ProjectService.GetProjectNameFromId(session)); + } + AnsiConsole.Write(table); + } +} + diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/ProjectController.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/ProjectController.cs new file mode 100644 index 000000000..aafa76871 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/ProjectController.cs @@ -0,0 +1,68 @@ +using jcshepherd63.CodingTracker.Models; +using Spectre.Console; +using System; +using System.Collections.Generic; +using System.Text; + + +public class ProjectController +{ + public static void ProjectRouter(Enums.ProjectMenuOptions selection) + { + switch (selection) + { + case Enums.ProjectMenuOptions.Add_Project: + { + var project = ProjectMenu.NewProjectCreation(); + ProjectService.AddProject(project); + break; + } + case Enums.ProjectMenuOptions.Update_Project: + { + int id = ProjectMenu.UpdateProjectGetId(); + var project = ProjectMenu.NewProjectCreation(); + project.Id = id; + ProjectService.UpdateProject(project); + break; + } + case Enums.ProjectMenuOptions.Delete_Project: + { + OutputProjectListToTable(); + var project = ProjectMenu.DeleteProjectById(); + ProjectService.DeleteProject(project); + break; + } + case Enums.ProjectMenuOptions.View_Projects: + { + OutputProjectListToTable(); + break; + } + } + } + + private static Table ProjectTable() + { + var table = new Table() + .RoundedBorder() + .BorderColor(Color.DarkCyan) + .Title("[yellow bold]Projects[/]"); + + table.AddColumn("[italic]Project ID[/]"); + table.AddColumn("[italic]Project Name[/]"); + return table; + } + + public static void OutputProjectListToTable() + { + List projects = ProjectService.GetAllProjects(); + var table = ProjectTable(); + + foreach (Project project in projects) + { + table.AddRow( + project.Id.ToString(), + project.Name); + } + AnsiConsole.Write(table); + } +} \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/CodeSessionMenu.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/CodeSessionMenu.cs new file mode 100644 index 000000000..f730860d4 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/CodeSessionMenu.cs @@ -0,0 +1,154 @@ +using Spectre.Console; + +public class CodeSessionMenu +{ + private static DateTime CodeDateSelectionMenu() + { + Console.Clear(); + DateTime today; + var CodeTimeMenuOutput = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("[yellow]How would you like to perform date entry?[/]") + .AddChoices("Use today's date", "Custom date entry")); + + if (CodeTimeMenuOutput == "Use today's date") + { + today = DateTime.Now; + Console.WriteLine($"{today:d}"); + } + else + { + today = AnsiConsole.Ask("[yellow]What day did you work on coding? (Required Format MM-dd-yyyy)[/]"); + Console.WriteLine($"{today:d}"); + } + + return today; + } + + private static string TimeFormatSelection() + { + var CodeTimeMenuOutput = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("[yellow bold]Session Timer Screen[/]") + .AddChoices("Start Session Now", "Custom Start Time")); + return CodeTimeMenuOutput; + } + + private static DateTime SessionStartTimeSelectionMenu() + { + Console.Clear(); + DateTime startTime = DateTime.Now; + var CodeTimeMenuOutput = TimeFormatSelection(); + + if (CodeTimeMenuOutput == "Start Session Now") + { + startTime = DateTime.Now; + } + else + { + startTime = UserSessionStartTimeEntry(); + } + + return startTime; + } + + private static DateTime UserSessionStartTimeEntry() + { + Console.Clear(); + DateTime startTime = AnsiConsole.Ask("[yellow bold]What time did you start your coding session? (Format 24Hour HH:MM:SS)[/]"); + return startTime; + } + + private static DateTime SessionEndTimeSelectionMenu() + { + Console.Clear(); + var result = AnsiConsole.Ask("[yellow]Please enter 'Stop' to end the timed session or 'Custom' to enter the endtime manually[/]").ToLower(); + if(result == "stop") + { + return DateTime.Now; + } + else if(result == "custom") + { + return UserSessionEndTimeEntry(); + } + else + { + AnsiConsole.MarkupLine("[red italic]That was not a valid entry. Please try again. \n[/]"); + return SessionEndTimeSelectionMenu(); + } + } + + private static DateTime UserSessionEndTimeEntry() + { + Console.Clear(); + DateTime endTime = AnsiConsole.Ask("[yellow bold]What time did you end your coding session? (Format 24Hour HH:MM:SS)[/]"); + return endTime; + } + + public static Project CodeProjectSelectionMenu() + { + Console.Clear(); + Project project = null; + var projects = ProjectService.GetAllProjects(); + var prompt = new SelectionPrompt() + .Title("[yellow]What project are/were you working on[/]") + .AddChoiceGroup("New Project"); + + foreach(Project proj in projects) + { + prompt.AddChoice(proj.ToString()); + } + + var selection = AnsiConsole.Prompt(prompt); + + if (selection == "New Project") + { + project = ProjectMenu.NewProjectCreation(); + ProjectService.AddProject(project); + } + else + { + foreach(Project proj in projects) + { + if(selection == proj.Name) + { + project = proj; + } + } + } + + return project; + } + + + public static int UpdateCodeGetID() + { + var UpdateSessionByID = AnsiConsole.Ask("[yellow]Which session do you want to update?[/]"); + return UpdateSessionByID; + } + + public static int DeleteCodeGetID() + { + var DeleteSessionByID = AnsiConsole.Ask("[red bold]Which session do you want to delete?[/]"); + return DeleteSessionByID; + } + + public static CodingTime CodingTimeCreation() + { + var date = CodeSessionMenu.CodeDateSelectionMenu(); + var startTime = CodeSessionMenu.SessionStartTimeSelectionMenu(); + var endTime = CodeSessionMenu.SessionEndTimeSelectionMenu(); + var projectId = ProjectService.GetProjectId(); + + CodingTime codeTime = new() + { + Date = date, + StartTime = startTime, + EndTime = endTime, + ProjectId = Convert.ToInt32(projectId) + }; + + return codeTime; + } +} + diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/MainMenu.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/MainMenu.cs new file mode 100644 index 000000000..b779981d3 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/MainMenu.cs @@ -0,0 +1,62 @@ +using Spectre.Console; +using jcshepherd63.CodingTracker.Models; +namespace App; + +public class MainMenu +{ + public static void Menu() + { + bool running = true; + while (running) + { + Console.Clear(); + AnsiConsole.MarkupLine("[yellow]Coding Tracker Application:\n[/]"); + + var selection = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("What would you like to do?") + .AddChoices(Enum.GetValues())); + + switch (selection) + { + case Enums.MainMenuOptions.Add_Coding_Session: + CodeSessionService.AddCodingSession(); + AnsiConsole.MarkupLine("[red italic]Session Added.\nPress Any Key to Return to the Main Menu[/]"); + Console.ReadKey(); + break; + + case Enums.MainMenuOptions.Update_Coding_Session: + CodeSessionService.UpdateCodingSession(); + AnsiConsole.MarkupLine("[red]Session Updated.\nPress Any Key to Return to the Main Menu[/]"); + Console.ReadKey(); + break; + + case Enums.MainMenuOptions.Delete_Coding_Session: + CodeSessionService.DeleteCodingSession(); + AnsiConsole.MarkupLine("[red bold]Session Deleted.\nPress Any Key to Return to the Main Menu[/]"); + Console.ReadKey(); + break; + + case Enums.MainMenuOptions.View_Coding_Session: + CodeSessionController.OutputSessionListToTable(); + AnsiConsole.MarkupLine("[red italic]Press Any Key to Return to the Main Menu[/]"); + Console.ReadKey(); + break; + case Enums.MainMenuOptions.View_Coding_Calendar: + CodeSessionService.GetCodeSessionDates(); + AnsiConsole.MarkupLine("[red italic]Press Any Key to Return to the Main Menu[/]"); + Console.ReadKey(); + break; + case Enums.MainMenuOptions.Project_Modification: + var projectMenuSelection = ProjectMenu.ProjectMenuUserInteraction(); + ProjectController.ProjectRouter(projectMenuSelection); + AnsiConsole.MarkupLine("[red italic]Press Any Key to Return to the Main Menu[/]"); + Console.ReadKey(); + break; + case Enums.MainMenuOptions.Close_Application: + running = false; + break; + } + } + } +} diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/ProjectMenu.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/ProjectMenu.cs new file mode 100644 index 000000000..436e508a2 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Menus/ProjectMenu.cs @@ -0,0 +1,57 @@ +using jcshepherd63.CodingTracker.Models; +using Spectre.Console; + +public class ProjectMenu +{ + public static Enums.ProjectMenuOptions ProjectMenuUserInteraction() + { + Console.Clear(); + var selection = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("What would you like to do in the project menu?") + .AddChoices(Enum.GetValues())); + + return selection; + } + + + public static Project NewProjectCreation() + { + var newProjectName = AnsiConsole.Ask("[yellow]What is the name of the project?[/]"); + var project = new Project(newProjectName); + return project; + + } + + public static int UpdateProjectGetId() + { + List projects = ProjectService.GetAllProjects(); + var prompt = new SelectionPrompt() + .Title("[yellow bold]Which project would you like to update?[/]"); + + foreach (Project proj in projects) + { + prompt.AddChoice(proj); + } + var result = AnsiConsole.Prompt(prompt); + + return result.Id; + } + + public static Project DeleteProjectById() + { + var projects = ProjectService.GetAllProjects(); + Project projectToDelete = null; + var DeleteProjByID = AnsiConsole.Ask("[red bold]Please enter the ID of the project you want to delete.[/]"); + foreach(var proj in projects) + { + if(proj.Id == DeleteProjByID) + { + projectToDelete = proj; + break; + } + } + return projectToDelete; + } + +} \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/Enums.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/Enums.cs new file mode 100644 index 000000000..c1c6e385e --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/Enums.cs @@ -0,0 +1,24 @@ +namespace jcshepherd63.CodingTracker.Models; + +public class Enums +{ + public enum MainMenuOptions + { + Add_Coding_Session, + Update_Coding_Session, + Delete_Coding_Session, + View_Coding_Session, + View_Coding_Calendar, + Project_Modification, + Close_Application + } + + public enum ProjectMenuOptions + { + Add_Project, + Update_Project, + Delete_Project, + View_Projects + } + +} \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/_CodingTimeModel.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/_CodingTimeModel.cs new file mode 100644 index 000000000..c68f095f8 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/_CodingTimeModel.cs @@ -0,0 +1,11 @@ +using System; + +public class CodingTime +{ + public int Id { get; set; } + public DateTime Date { get; set; } + public DateTime StartTime { get; set; } + public DateTime EndTime { get; set; } + public int ProjectId { get; set; } + +} \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/_ProjectModel.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/_ProjectModel.cs new file mode 100644 index 000000000..08ed0cac8 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Models/_ProjectModel.cs @@ -0,0 +1,18 @@ + public class Project + { + public int Id { get; set; } + public string? Name { get; set; } + + + public Project() { } + public Project(string name) + { + Name = name; + } + + public override string ToString() + { + return Name; + } + } + diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Program.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Program.cs new file mode 100644 index 000000000..9265c0e71 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Program.cs @@ -0,0 +1,4 @@ +using App; + +_DatabaseCreation.dbTableCreate(); +MainMenu.Menu(); diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/README.md b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/README.md new file mode 100644 index 000000000..3ab1e5c44 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/README.md @@ -0,0 +1 @@ +# jcshepherd63.CodingTracker \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Services/CodeSessionService.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Services/CodeSessionService.cs new file mode 100644 index 000000000..e3e667aec --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Services/CodeSessionService.cs @@ -0,0 +1,84 @@ +using Dapper; +using Microsoft.Data.Sqlite; +using Spectre.Console; + +public class CodeSessionService +{ + public static void AddCodingSession() + { + var codeTime = CodeSessionMenu.CodingTimeCreation(); + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var addCmd = @"INSERT INTO CodingSessions (Date, StartTime, EndTime, ProjectId) + VALUES (@Date, @StartTime, @EndTime, @ProjectId)"; + connection.Execute(addCmd, codeTime); + connection.Close(); + } + } + + public static void UpdateCodingSession() + { + CodingTime codeTime = new(); + CodeSessionController.OutputSessionListToTable(); + int Id = CodeSessionMenu.UpdateCodeGetID(); + codeTime = CodeSessionMenu.CodingTimeCreation(); + codeTime.Id = Id; + + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var updateCmd = @"UPDATE CodingSessions SET Date = @Date, StartTime = @StartTime, EndTime = @EndTime, ProjectId = @ProjectId WHERE Id = @Id"; + connection.Execute(updateCmd, codeTime); + connection.Close(); + } + } + + public static void DeleteCodingSession() + { + CodingTime codeTime = new(); + CodeSessionController.OutputSessionListToTable(); + codeTime.Id = CodeSessionMenu.DeleteCodeGetID(); + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var deleteCmd = @"DELETE FROM CodingSessions WHERE Id = @Id"; + connection.Execute(deleteCmd, codeTime); + connection.Close(); + } + } + + public static List GetAllCodeSessions() + { + CodingTime codeTime = new(); + List sessions; + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + + var getCodingTimeCmd = @"SELECT * FROM CodingSessions"; + sessions = connection.Query(getCodingTimeCmd, codeTime).ToList(); + + connection.Close(); + } + return sessions; + } + + public static void GetCodeSessionDates() + { + var calendar = CodeSessionController.CodingCalendarOutput(); + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var getSessionDatesCmd = "SELECT Date FROM codingSessions"; + var reader = connection.ExecuteReader(getSessionDatesCmd); + while (reader.Read()) + { + calendar.AddCalendarEvent(DateTime.Parse(reader.GetString(reader.GetOrdinal("Date"))), new Style(foreground: Color.Red, decoration: Decoration.Bold)); + } + connection.Close(); + } + AnsiConsole.Write(calendar); + } + +} \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Services/ProjectService.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Services/ProjectService.cs new file mode 100644 index 000000000..50466a6ac --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Services/ProjectService.cs @@ -0,0 +1,78 @@ + +using Microsoft.Data.Sqlite; +using Dapper; + +public class ProjectService +{ + public static void AddProject(Project project) + { + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var addProjectCmd = @"INSERT INTO projects (Name) + VALUES (@Name)"; + connection.Execute(addProjectCmd, project); + connection.Close(); + } + } + + public static void UpdateProject(Project project) + { + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var updateByIdCmd = "UPDATE Projects SET Name = @Name WHERE Id = @Id"; + connection.Execute(updateByIdCmd, project); + connection.Close(); + } + } + + public static void DeleteProject(Project project) + { + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var DeleteProjectCmd = @"DELETE FROM projects WHERE Id = @Id"; + connection.Execute(DeleteProjectCmd, project); + connection.Close(); + } + } + + public static int GetProjectId() + { + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + Project project = CodeSessionMenu.CodeProjectSelectionMenu(); + var getProjectIdCmd = $"SELECT Id from Projects WHERE Name = '{project.Name}'"; + var projectID = connection.QuerySingle(getProjectIdCmd); + connection.Close(); + + return projectID; + } + } + + public static List GetAllProjects() + { + using (var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var getProjectsCmd = "SELECT * From projects"; + var projects = connection.Query(getProjectsCmd).ToList(); + connection.Close(); + return projects; + } + } + + public static string GetProjectNameFromId(CodingTime session) + { + using(var connection = new SqliteConnection(_DatabaseCreation.GetConnection())) + { + connection.Open(); + var getProjectNameById = "SELECT Name FROM Projects WHERE Id = @ProjectId"; + var projectName = connection.QuerySingle(getProjectNameById, session); + connection.Close(); + return projectName; + } + } +} diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/_DatabaseCreation.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/_DatabaseCreation.cs new file mode 100644 index 000000000..88db56f41 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/_DatabaseCreation.cs @@ -0,0 +1,36 @@ +using Dapper; +using Microsoft.Data.Sqlite; +using Microsoft.Extensions.Configuration; + +public class _DatabaseCreation +{ + public static string GetConnection() + { + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + + var connectionString = config.GetConnectionString("DefaultConnection"); + return connectionString; + } + + public static void dbTableCreate() + { + var connectionString = GetConnection(); + using (var connection = new SqliteConnection(connectionString)) + { + connection.Open(); + var tableCmd = @"CREATE TABLE IF NOT EXISTS CodingSessions + (Id INTEGER PRIMARY KEY AUTOINCREMENT, + Date TEXT, StartTime TEXT, EndTime TEXT, ProjectId INTEGER); + + CREATE TABLE IF NOT EXISTS Projects( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + Name TEXT);"; + + connection.Execute(tableCmd); + connection.Close(); + } + } +} \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/appsettings.json b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/appsettings.json new file mode 100644 index 000000000..306151b6e --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/appsettings.json @@ -0,0 +1,5 @@ +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=../../../codingtracker.db" + } +} \ No newline at end of file diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db new file mode 100644 index 0000000000000000000000000000000000000000..16877270eedcdefc9636f941bbd9c92f2fa2766a GIT binary patch literal 16384 zcmeI&%T9wp6b9fKFx6@lU3FnF+xa6E@N_unj$ye zk7*Q0=u@O{r%%fR)R`R7=4T#chXw%%KmY;|fB*y_009U<00O^Q;ATM`&t$XoRtvr3 zbI};|&qOB-qJGS2@~X?3TV3DgEZUo!o@5EF)@8N2%QtzGHJY`ZYO~F@c$-!C-Q8MU zCfwn5H=mrM?p+Ax@Mtq?^Pww zxZiy@dVMf&*BsU6vgjw;{V#s`Ff|B300Izz00bZa0SG_<0uX?}{}4E!DdIRz+A^%t zl3^{GMP{z78un_@DA=V+$u`Pgh069y*(?`7hpfVK#i|&lIs7)SXpcmDk}EU_KmY;| zfB*y_009U<00Izz00jP|z?`D$>G%%`Q&i2SqhBCa6j>j@K1~7Z%&8Gynhq literal 0 HcmV?d00001 diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker.csproj b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker.csproj new file mode 100644 index 000000000..fb791a692 --- /dev/null +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker.csproj @@ -0,0 +1,28 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + + + PreserveNewest + + + + + + + + + + + + From 31cff3f6e9c4fc250c77b3c7025bdaabecbf19cf Mon Sep 17 00:00:00 2001 From: Joseph Cade Shepherd <162059812+jcshepherd63@users.noreply.github.com> Date: Mon, 16 Feb 2026 17:59:53 -0500 Subject: [PATCH 2/6] Create README.md --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..8f5ebac50 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +Coding Tracker + +Features: +- SQLite DB with the connection strip stored in an appsettings.json file +- Console built with Spectre for tidy user interaction + +Challenges: +- This was my first time using configuration builder to interact with a json file. I got some help from the C#Sharp Academy discord in the form of a YouTube video to watch that explained it well. +- This project was larger than previous projects so organization was difficult at first. I changed the overall organization of the code more times than I could count, but the end product is organized and understandable + + +Areas to Improve: +- I really need to improve my overall naming abilities. I kept getting confused by the names on my methods, properties, and variables. The KISS standard of keeping things simple should help with that going forward. +- I also need to improve my understanding of access identifiers, static, and the abstract keyword. +- Finally, I need to do a better job of passing parameters into methods as opposed to setting them equal to a variable inside a method to make it accessible within. From 845b926489a0dc105b29a7f1e181ea6bb68fbe1c Mon Sep 17 00:00:00 2001 From: Cade Date: Mon, 16 Feb 2026 18:04:59 -0500 Subject: [PATCH 3/6] Tried to change a method to private. But decided to keep it public --- .../Controllers/CodeSessionController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs index 5b49d11a4..363c0e023 100644 --- a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs @@ -16,7 +16,7 @@ public static Calendar CodingCalendarOutput() } - private static Table CodingTimeTableOutput() + private static Table CodeSessionTableOutput() { var table = new Table() .RoundedBorder() @@ -35,7 +35,7 @@ private static Table CodingTimeTableOutput() public static void OutputSessionListToTable() { List codingSessions = CodeSessionService.GetAllCodeSessions(); - var table = CodingTimeTableOutput(); + var table = CodeSessionTableOutput(); foreach (CodingTime session in codingSessions) { From 658076fcf201c579a1a03201fc3294e6f4c56948 Mon Sep 17 00:00:00 2001 From: Cade Date: Mon, 16 Feb 2026 18:06:41 -0500 Subject: [PATCH 4/6] Reset the database --- .../jcshepherd63.CodingTracker/codingtracker.db | Bin 16384 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db deleted file mode 100644 index 16877270eedcdefc9636f941bbd9c92f2fa2766a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI&%T9wp6b9fKFx6@lU3FnF+xa6E@N_unj$ye zk7*Q0=u@O{r%%fR)R`R7=4T#chXw%%KmY;|fB*y_009U<00O^Q;ATM`&t$XoRtvr3 zbI};|&qOB-qJGS2@~X?3TV3DgEZUo!o@5EF)@8N2%QtzGHJY`ZYO~F@c$-!C-Q8MU zCfwn5H=mrM?p+Ax@Mtq?^Pww zxZiy@dVMf&*BsU6vgjw;{V#s`Ff|B300Izz00bZa0SG_<0uX?}{}4E!DdIRz+A^%t zl3^{GMP{z78un_@DA=V+$u`Pgh069y*(?`7hpfVK#i|&lIs7)SXpcmDk}EU_KmY;| zfB*y_009U<00Izz00jP|z?`D$>G%%`Q&i2SqhBCa6j>j@K1~7Z%&8Gynhq From 936d92646b286be65bad07998d2c0a0c5debe9a8 Mon Sep 17 00:00:00 2001 From: Cade Date: Mon, 16 Feb 2026 18:12:23 -0500 Subject: [PATCH 5/6] Removed using statements per codacy --- .../Controllers/CodeSessionController.cs | 1 - .../Controllers/ProjectController.cs | 3 --- 2 files changed, 4 deletions(-) diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs index 363c0e023..1bd61ea9c 100644 --- a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/CodeSessionController.cs @@ -1,7 +1,6 @@ using Spectre.Console; using System; using System.Collections.Generic; -using System.Text; public class CodeSessionController { diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/ProjectController.cs b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/ProjectController.cs index aafa76871..b97cc1cb3 100644 --- a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/ProjectController.cs +++ b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/Controllers/ProjectController.cs @@ -1,9 +1,6 @@ using jcshepherd63.CodingTracker.Models; using Spectre.Console; -using System; using System.Collections.Generic; -using System.Text; - public class ProjectController { From 7c645a69c089ef8cea3759643e63e184be29f258 Mon Sep 17 00:00:00 2001 From: Cade Date: Mon, 16 Feb 2026 18:13:00 -0500 Subject: [PATCH 6/6] Empty db created --- .../jcshepherd63.CodingTracker/codingtracker.db | Bin 0 -> 16384 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db diff --git a/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db b/jcshepherd63.CodingTracker/jcshepherd63.CodingTracker/codingtracker.db new file mode 100644 index 0000000000000000000000000000000000000000..96a312317c7f70d3ec2980c1ba27568c65fcab7d GIT binary patch literal 16384 zcmeI%K}*9h6bJC68xDkR-gc15JGQKN@e5dIkm6Qn7r~yS+oDvqmaX+Xwu9fzZ)H|i zv^x}!GX4)jNYlP1zx49x_;C2j{C+Lu%!Ke40SG_< z0uX=z1Rwwb2tWV=5P-lD3+(>Qqy9hQ1IE@M009U<00Izz00bZa0SG_<0$Kp|KRyEp YKmY;|fB*y_009U<00Izz!0`)w1ANVh2><{9 literal 0 HcmV?d00001