Resume update

This commit is contained in:
2026-09-09 13:22:50 -04:00
parent af48f386e0
commit faf3805960
20 changed files with 24 additions and 684 deletions
-13
View File
@@ -1,13 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/.idea.Resume.iml
/contentModel.xml
/modules.xml
/projectSettingsUpdater.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="singleClickDiffPreview" value="1" />
<option name="unhandledExceptionsIgnoreList" value="1" />
<option name="vcsConfiguration" value="3" />
</component>
</project>
-63
View File
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.lookFeel&quot;
}
}</component>
<component name="RunManager" selected=".NET Launch Settings Profile.Website: https">
<configuration name="Website.Client" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="ENV_FILE_PATHS" value="" />
<option name="REDIRECT_INPUT_PATH" value="" />
<option name="MIXED_MODE_DEBUG" value="0" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="AUTO_ATTACH_CHILDREN" value="0" />
<option name="PROJECT_PATH" value="$PROJECT_DIR$/Website.Client/Website.Client.csproj" />
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value="" />
<method v="2">
<option name="Build" />
</method>
</configuration>
<configuration name="Website: http" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/Website/Website.csproj" />
<option name="LAUNCH_PROFILE_TFM" value="net10.0" />
<option name="LAUNCH_PROFILE_NAME" value="http" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="GENERATE_APPLICATIONHOST_CONFIG" value="1" />
<option name="SHOW_IIS_EXPRESS_OUTPUT" value="0" />
<option name="SEND_DEBUG_REQUEST" value="1" />
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<option name="AUTO_ATTACH_CHILDREN" value="0" />
<option name="MIXED_MODE_DEBUG" value="0" />
<method v="2">
<option name="Build" />
</method>
</configuration>
<configuration name="Website: https" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/Website/Website.csproj" />
<option name="LAUNCH_PROFILE_TFM" value="net10.0" />
<option name="LAUNCH_PROFILE_NAME" value="https" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="GENERATE_APPLICATIONHOST_CONFIG" value="1" />
<option name="SHOW_IIS_EXPRESS_OUTPUT" value="0" />
<option name="SEND_DEBUG_REQUEST" value="1" />
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<option name="AUTO_ATTACH_CHILDREN" value="0" />
<option name="MIXED_MODE_DEBUG" value="0" />
<method v="2">
<option name="Build" />
</method>
</configuration>
</component>
</project>
-1
View File
@@ -1,4 +1,3 @@
<Solution>
<Project Path="Website.Client/Website.Client.csproj" />
<Project Path="Website/Website.csproj" />
</Solution>
-5
View File
@@ -1,5 +0,0 @@
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
await builder.Build().RunAsync();
-16
View File
@@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.6" />
</ItemGroup>
</Project>
-9
View File
@@ -1,9 +0,0 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using Website.Client
@@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
-8
View File
@@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
+13 -10
View File
@@ -38,18 +38,21 @@
<div class="experience">
@foreach (var experience in WorkExperience.Get().Experiences)
{
<div><b>@experience.Role</b></div>
<div>@experience.Location</div>
<div>@experience.DateRange</div>
<ul>
@foreach (var point in experience.Points)
{
@if (point.IsVisible)
@if (experience.IsVisible)
{
<div><b>@experience.Role</b></div>
<div>@experience.Location</div>
<div>@experience.DateRange</div>
<ul>
@foreach (var point in experience.Points)
{
<li>@point.Description</li>
@if (point.IsVisible)
{
<li>@point.Description</li>
}
}
}
</ul>
</ul>
}
}
</div>
</div>
+1 -1
View File
@@ -1,4 +1,4 @@
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Client._Imports).Assembly }" NotFoundPage="typeof(Pages.NotFound)">
<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
-1
View File
@@ -7,6 +7,5 @@
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using Website
@using Website.Client
@using Website.Components
@using Website.Components.Layout
+1 -1
View File
@@ -13,7 +13,7 @@ public static class Overview
IsVisible = true,
Order = 1,
Description =
"Software Developer with a focus on the .NET tech stack.",
"In the industry since 2012, while playing a pivotal role in all aspects of the software stack, from prototype to release, and improving applications with patches based on customer feedback and data in production.",
LastModified = new DateTime(2025, 9, 8)
}
]
+6 -2
View File
@@ -63,6 +63,7 @@ public static class WorkExperience
Role = "Fullstack Blazor Developer",
Location = "Personal Projects, on various interests",
DateRange = "2021, 2026",
IsVisible = false,
Points =
[
new Point
@@ -87,15 +88,16 @@ public static class WorkExperience
},
new Experience
{
Role = "Angular Web Developer",
Role = "Angular Website Developer",
Location = "CleanCode, Software consultancy on various projects",
DateRange = "2020 - 2021",
IsVisible = true,
Points =
[
new Point
{
Description =
"Came to the conclusion that I wanted to focus my career in .NET, and left the company to pursue Blazor research and C# opportunities. Unfortunately, Blazor development work is not as popular as one would hope.",
"Came to the conclusion that I wanted to focus my career in .NET, and left the company to pursue Blazor research and C# opportunities. Unfortunately, Blazor development work is not popular.",
IsVisible = true
}
]
@@ -200,6 +202,8 @@ public static class WorkExperience
public string Location { get; set; }
public string DateRange { get; set; }
public bool IsVisible { get; set; } = true;
public List<Point> Points { get; set; }
}
+1 -2
View File
@@ -27,7 +27,6 @@ app.UseAntiforgery();
app.MapStaticAssets();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(Website.Client._Imports).Assembly);
.AddInteractiveWebAssemblyRenderMode();
app.Run();
+1 -1
View File
@@ -5,10 +5,10 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
<RootNamespace>Website</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Website.Client\Website.Client.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.6" />
</ItemGroup>
-157
View File
@@ -1,157 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jon McCaffrey - .NET Developer</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="sidebar">
<div class="profile">
<div class="avatar">JM</div>
<h1>Jon McCaffrey</h1>
<p class="tagline">.NET Developer</p>
</div>
<div class="info-section">
<ul class="contact-list">
<li><span class="label">Location</span><span>Ottawa, ON</span></li>
<li><span class="label">Email</span><span>jonmcc0723@gmail.com</span></li>
<li><span class="label">Phone</span><span>613-277-8353</span></li>
<li><span class="label">Experience</span><span>14 years in tech, 3 in education</span></li>
<li><span class="label">Education</span><span>Game Development (2012)</span></li>
<li><span class="label">Rate</span><span>$50 / hr</span></li>
</ul>
</div>
<div class="info-section skills-section">
<h2>Skills</h2>
<div class="skill-group">
<h3>.NET Ecosystem</h3>
<ul class="skill-list">
<li>C# / .NET</li>
<li>Blazor</li>
<li>Entity Framework</li>
<li>ASP.NET Core</li>
<li>REST APIs / GraphQL</li>
<li>SQL / SQL Server</li>
</ul>
</div>
<div class="skill-group">
<h3>Frontend & Web</h3>
<ul class="skill-list">
<li>HTML / CSS</li>
<li>JavaScript / TypeScript</li>
<li>React</li>
<li>Angular</li>
</ul>
</div>
<div class="skill-group">
<h3>DevOps & Tools</h3>
<ul class="skill-list">
<li>Azure / AWS</li>
<li>Azure Pipelines / Jenkins</li>
<li>Git</li>
<li>Jira / Azure DevOps</li>
<li>Unit Testing / Test Automation</li>
<li>CI/CD</li>
</ul>
</div>
<div class="skill-group">
<h3>Other</h3>
<ul class="skill-list">
<li>Agile / Scrum</li>
<li>Documentation & Training</li>
<li>Customer Support & Debugging</li>
<li>Self-Hosting (Ubuntu Server)</li>
<li>Google Analytics / 3rd Party APIs</li>
</ul>
</div>
</div>
</div>
<div class="main">
<div class="overview">
<h2>About Me</h2>
<p>Software Developer with a focus on the <strong>.NET tech stack</strong>. Passionate about building robust backends, crafting clean APIs, and writing maintainable C# code. Experienced across the full stack with a drive to deliver quality software.</p>
</div>
<div class="experience-section">
<h2>Experience</h2>
<div class="experience">
<div class="exp-header">
<h3>.NET Server Developer</h3>
<span class="exp-date">2021 2026</span>
</div>
<p class="exp-location">TotalETO — Engineering to Order Solutions</p>
<ul>
<li>Wrote various API calls, unit tests to test said calls, and exact examples to show the frontend team on how to consume the GraphQL API.</li>
<li>Converted SQL stored procedures into views usable by Entity Framework to support old functionality with new web app features.</li>
<li>Moved from backend to frontend as needed to fix bugs and add features to React frontend to help the UI team with their higher workload.</li>
<li>Took part in converting legacy VB-coded app functionality to a <strong>C# .NET web development server</strong>.</li>
<li>Taken the initiative in creating a variety of onboarding internal wiki documents explaining parts of the codebase that were well-loved by the team.</li>
<li>Created an <strong>Azure DevOps pipeline</strong> to automate taking snapshots of the database schema to be aware of changes from multiple teams altering the database.</li>
</ul>
</div>
<div class="experience">
<div class="exp-header">
<h3>Fullstack Blazor Developer</h3>
<span class="exp-date">2021</span>
</div>
<p class="exp-location">Personal Projects</p>
<ul>
<li>Created igpfanreference.ca to teach players in unreleased game basic play patterns, and to experiment with <strong>Blazor</strong>, Linux self-hosting and Azure web hosting.</li>
<li>Twitch streamed live coding sessions to demonstrate developing the website, and crowd-sourced and credited players on ideas and functionality for the website.</li>
</ul>
</div>
<div class="experience">
<div class="exp-header">
<h3>Angular Web Developer</h3>
<span class="exp-date">2020 2021</span>
</div>
<p class="exp-location">CleanCode — Software Consultancy</p>
<ul>
<li>Came to the conclusion that I wanted to focus my career in <strong>.NET</strong>, and left the company to pursue Blazor research and C# opportunities.</li>
</ul>
</div>
<div class="experience">
<div class="exp-header">
<h3>Full Stack Developer</h3>
<span class="exp-date">2015 2020</span>
</div>
<p class="exp-location">bitHeads — Cloud-Based Technology</p>
<ul>
<li>Worked on a portal and mobile-facing web app for a SaaS project written in React.</li>
<li>Eliminated routine project hours spent documenting by creating a Node.js tool in TypeScript that generated the API doc contents.</li>
<li>Created brainCloud's Command Line tool in Node.js and other test tools, for developers and QA to test and stress test API and server features.</li>
<li>Maintained customer success and brainCloud's unit tests, examples, and libraries in <strong>Java, ObjC, C++, C#, JS, Unity, and Unreal</strong>.</li>
<li>Wrote documentation, tutorials, and offered guidance to bring new co-workers up to speed on the BaaS environment.</li>
<li>Maintained and wrote Jenkins Pipeline in Groovy for improved test reporting and team CI.</li>
<li>Developed Test Automation for brainCloud and Nortec/Condair Help websites in Java, to reduce manual testing time spent on an agile team.</li>
</ul>
</div>
<div class="experience">
<div class="exp-header">
<h3>Mobile Game Developer</h3>
<span class="exp-date">2012 2015</span>
</div>
<p class="exp-location">Smoke Labs — Mobile Games Startup</p>
<ul>
<li>Developed key systems in Blokus, Mattel-branded title nominated in the Canadian Video Game Awards for "Best Game Design" and "Best Social or Casual Game."</li>
<li>Experience integrating a multitude of analytics, ad systems, and backends, including Google Analytics, Game Analytics, Flurry, Mopub, and Playhaven.</li>
<li>Spent time working with the external QA team to bridge the company's knowledge gaps between the developer and QA workflows.</li>
<li>Integrated ads, in-app purchases, analytics, and handled product releases of legacy client apps.</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
-373
View File
@@ -1,373 +0,0 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
background: #e8ecf1;
color: #2d3436;
line-height: 1.5;
}
.container {
display: flex;
max-width: 1100px;
margin: 40px auto;
background: #fff;
border-radius: 12px;
box-shadow: 0 8px 40px rgba(0,0,0,0.12);
overflow: hidden;
}
/* Sidebar */
.sidebar {
width: 300px;
min-width: 300px;
background: #1a1d23;
color: #e0e0e0;
padding: 36px 28px;
}
.profile {
text-align: center;
margin-bottom: 28px;
}
.avatar {
width: 72px;
height: 72px;
border-radius: 50%;
background: linear-gradient(135deg, #6c5ce7, #512da8);
color: #fff;
font-size: 26px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 14px;
}
.profile h1 {
font-size: 20px;
color: #fff;
margin-bottom: 4px;
}
.tagline {
color: #a29bfe;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.5px;
}
.info-section {
margin-bottom: 24px;
}
.info-section h2 {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1.5px;
color: #a29bfe;
border-bottom: 1px solid #2d2d35;
padding-bottom: 6px;
margin-bottom: 12px;
}
.contact-list {
list-style: none;
}
.contact-list li {
display: flex;
flex-direction: column;
margin-bottom: 8px;
font-size: 12px;
}
.contact-list .label {
color: #888;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 1px;
}
.skill-group {
margin-bottom: 16px;
}
.skill-group h3 {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.8px;
color: #a29bfe;
margin-bottom: 6px;
}
.skill-list {
list-style: none;
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.skill-list li {
background: #2d2d35;
color: #ccc;
padding: 3px 9px;
border-radius: 4px;
font-size: 11px;
}
.skill-list li:first-child {
background: #6c5ce7;
color: #fff;
font-weight: 600;
}
/* Main content */
.main {
flex: 1;
padding: 36px 40px;
}
.overview {
margin-bottom: 32px;
}
.overview h2 {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1.5px;
color: #6c5ce7;
margin-bottom: 8px;
}
.overview p {
font-size: 14px;
color: #555;
}
.overview strong {
color: #512da8;
}
/* Experience */
.experience-section h2 {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1.5px;
color: #6c5ce7;
margin-bottom: 18px;
}
.experience {
margin-bottom: 24px;
padding-left: 14px;
border-left: 3px solid #e0e0e0;
page-break-inside: avoid;
}
.experience:last-child {
margin-bottom: 0;
}
.exp-header {
display: flex;
justify-content: space-between;
align-items: baseline;
flex-wrap: wrap;
gap: 6px;
}
.exp-header h3 {
font-size: 15px;
color: #1a1d23;
}
.exp-date {
font-size: 12px;
color: #888;
white-space: nowrap;
}
.exp-location {
font-size: 12px;
color: #6c5ce7;
margin-bottom: 8px;
font-weight: 500;
}
.experience ul {
list-style: none;
}
.experience ul li {
position: relative;
padding-left: 16px;
margin-bottom: 5px;
font-size: 13px;
color: #444;
}
.experience ul li::before {
content: "";
position: absolute;
left: 1px;
color: #6c5ce7;
}
.experience ul li strong {
color: #512da8;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
margin: 16px;
}
.sidebar {
width: 100%;
min-width: unset;
}
.main {
padding: 24px 20px;
}
}
@media print {
body {
background: #fff;
color: #000;
font-size: 11px;
line-height: 1.35;
}
.container {
flex-direction: row;
max-width: 100%;
margin: 0;
border-radius: 0;
box-shadow: none;
}
.sidebar {
width: 260px;
min-width: 260px;
background: #fff;
color: #000;
padding: 24px 20px;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.sidebar h2 {
color: #512da8 !important;
border-bottom-color: #ccc !important;
}
.profile h1 {
color: #000;
font-size: 18px;
}
.tagline {
color: #512da8;
}
.avatar {
width: 60px;
height: 60px;
font-size: 20px;
background: #512da8 !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.contact-list .label {
color: #666;
}
.contact-list li {
font-size: 11px;
}
.skill-group h3 {
color: #512da8 !important;
}
.skill-list li {
background: #ddd !important;
color: #000 !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
font-size: 10px;
padding: 2px 7px;
}
.skill-list li:first-child {
background: #512da8 !important;
color: #fff !important;
}
.main {
padding: 24px 28px;
}
.overview h2,
.experience-section h2 {
color: #512da8 !important;
font-size: 11px;
}
.overview p {
color: #333;
font-size: 12px;
}
.overview strong,
.experience ul li strong {
color: #512da8 !important;
}
.exp-header h3 {
color: #000;
font-size: 13px;
}
.exp-date {
color: #666;
font-size: 11px;
}
.exp-location {
color: #512da8 !important;
font-size: 11px;
}
.experience {
padding-left: 10px;
border-left-color: #ccc;
margin-bottom: 14px;
page-break-inside: avoid;
}
.experience ul li {
color: #333;
font-size: 11px;
margin-bottom: 3px;
}
.experience ul li::before {
color: #512da8 !important;
}
.experience:last-of-type {
page-break-after: avoid;
}
}