first commit

This commit is contained in:
2026-03-22 00:29:34 +01:00
commit c16b4e3933
1729 changed files with 162013 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
@page "/employeedetail/{EmployeeId:int}"
@if(Employee == null)
{
<div>Loading...</div>
} else
{
<section class="employee-detail">
<h1 class="page-title">Details for @Employee.FirstName @Employee.LastName</h1>
<br />
<div class="col-12 row">
<div class="col-2 text-center">
<img src="@($"https://gillcleerenpluralsight.blob.core.windows.net/person/{Employee.EmployeeId}.jpg")" class="img-fluid rounded-circle employee-detail-img" />
</div>
<div class="col-10 row">
<div class="col-12 col-xxl-8">
<div class="form-group row">
<label class="col-sm-4 col-form-label">Employee ID</label>
<div class="col-sm-8">
<label type="text" class="form-control-plaintext">@Employee.EmployeeId</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">First name</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.FirstName</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Last name</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.LastName</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Birthdate</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.BirthDate.ToShortDateString()</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Email</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.Email</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Street</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.Street</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Zip</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.Zip</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">City</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.City</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Phone number</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.PhoneNumber</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Gender</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.Gender</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Smoker</label>
<div class="col-sm-8">
@if (Employee.Smoker)
{
<label type="text" readonly class="form-control-plaintext">Yes</label>
}
else
{
<label type="text" readonly class="form-control-plaintext">No</label>
}
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Joined us</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.JoinedDate?.ToShortDateString()</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Left us</label>
<div class="col-sm-8">
<label type="text" readonly class="form-control-plaintext">@Employee.ExitDate?.ToShortDateString()</label>
</div>
</div>
</div>
<div class="col-12 col-xxl-4">
</div>
</div>
</div>
</section>
}
@@ -0,0 +1,33 @@
using BethanysPieShopHRM.Shared.Domain;
using Microsoft.AspNetCore.Components;
using Webshop.App.Services;
namespace Webshop.App.Pages
{
public partial class EmployeeDetails
{
[Inject]
public NavigationManager NavigationManager { get; set; } = default!;
[Inject]
public IEmployeeDataService? EmployeeDataService { get; set; }
[Parameter]
public int EmployeeId { get; set; }
public Employee? Employee { get; set; } = default;
protected async override Task OnInitializedAsync()
{
Employee = await RetrieveEmployee();
}
public async Task<Employee?> RetrieveEmployee()
{
var employeeFound = await EmployeeDataService.GetEmployeeDetails(EmployeeId);
if(employeeFound == null)
{
NavigationManager.NavigateTo("/not-found");
}
return employeeFound;
}
}
}
+228
View File
@@ -0,0 +1,228 @@
@page "/employeeEdit"
@page "/employeeEdit/{EmployeeId:int}"
@using BethanysPieShopHRM.Shared.Domain
@if (!Saved)
{
<section id="EmployeeEditSectionForm" class="employee-edit">
@if (Employee != null)
{
<h1 class="page-title">Details de @Employee.FirstName @Employee.LastName</h1>
<EditForm Model="Employee" OnValidSubmit="HandleValidSubmit" OnInvalidSubmit="HandleInvalidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
@if (!EmployeeId.HasValue)
{
<div class="row mb-3">
<label for="image" class="col-12 col-sm-3">Select Image:</label>
<InputFile OnChange="OnInputFileChange" />
</div>
}
<div class="row mb-3">
<label for="lastName" class="col-form-label col-md-3">Last name: </label>
<div class="col-md-8">
<InputText id="lastName" class="form-control col-md-8" @bind-Value="@Employee.LastName" placeholder="Enter last name"></InputText>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.LastName)" />
</div>
</div>
<div class="row mb-3">
<label for="firstName" class="col-form-label col-md-3">First name: </label>
<div class="col-md-8">
<InputText id="firstName" class="form-control col-md-8" @bind-Value="@Employee.FirstName" placeholder="Enter first name"></InputText>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.FirstName)" />
</div>
</div>
<div class="row mb-3">
<label for="birthdate" class="col-form-label col-md-3">Birthdate: </label>
<div class="col-md-8">
<InputDate id="birthdate" class="form-control col-md-8" @bind-Value="@Employee.BirthDate" placeholder="Enter birthdate"></InputDate>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.BirthDate)" />
</div>
</div>
<div class="row mb-3">
<label for="email" class="col-form-label col-md-3">Email: </label>
<div class="col-md-8">
<InputText id="email" class="form-control col-md-8" @bind-Value="@Employee.Email" placeholder="Enter email"></InputText>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.Email)" />
</div>
</div>
<div class="row mb-3">
<label for="street" class="col-form-label col-md-3">Street: </label>
<div class="col-md-8">
<InputText id="street" class="form-control col-md-8" @bind-Value="@Employee.Street" placeholder="Enter street"></InputText>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.Street)" />
</div>
</div>
<div class="row mb-3">
<label for="zip" class="col-form-label col-md-3">Zip code: </label>
<div class="col-md-8">
<InputText id="zip" class="form-control col-md-8" @bind-Value="@Employee.Zip" placeholder="Enter zip code"></InputText>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.Zip)" />
</div>
</div>
<div class="row mb-3">
<label for="city" class="col-form-label col-md-3">City: </label>
<div class="col-md-8">
<InputText id="city" class="form-control col-md-8" @bind-Value="@Employee.City" placeholder="Enter city"></InputText>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.City)" />
</div>
</div>
<div class="row mb-3">
<label for="country" class="col-form-label col-md-3">Country: </label>
<div class="col-md-8">
<InputSelect id="country" class="form-control col-md-8" @bind-Value="Employee.CountryId">
@foreach (var country in Countries)
{
<option value="@country.CountryId">@country.Name</option>
}
</InputSelect>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.CountryId)" />
</div>
</div>
<div class="row mb-3">
<label for="phonenumber" class="col-form-label col-md-3">Phone number: </label>
<div class="col-md-8">
<InputText id="phonenumber" class="form-control col-md-8" @bind-Value="@Employee.PhoneNumber" placeholder="Enter phone number"></InputText>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.PhoneNumber)" />
</div>
</div>
<div class="row mb-3">
<label for="longitude" class="col-form-label col-md-3">Longitude: </label>
<div class="col-md-8">
<InputNumber id="longitude" class="form-control col-md-8" @bind-Value="@Employee.Longitude"></InputNumber>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.Longitude)" />
</div>
</div>
<div class="row mb-3">
<label for="latitude" class="col-form-label col-md-3">Latitude: </label>
<div class="col-md-8">
<InputNumber id="latitude" class="form-control col-md-8" @bind-Value="@Employee.Latitude"></InputNumber>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.Latitude)" />
</div>
</div>
<div class="row mb-3">
<div class="col-md-8 offset-md-3">
<div class="form-check">
<InputCheckbox id="smoker" class="form-check-input" @bind-Value="@Employee.Smoker"></InputCheckbox>
<label class="form-check-label" for="smoker">
Smoker
</label>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.Smoker)" />
</div>
</div>
</div>
<div class="row mb-3">
<label for="jobcategory" class="col-form-label col-md-3">Job category: </label>
<div class="col-md-8">
<InputSelect id="jobcategory" class="form-select col-md-8" @bind-Value="@Employee.JobCategoryId">
@foreach (var jobCategory in JobCategories)
{
<option value="@jobCategory.JobCategoryId">@jobCategory.JobCategoryName</option>
}
</InputSelect>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.JobCategoryId)" />
</div>
</div>
<div class="row mb-3">
<InputRadioGroup Name="genderRadioGroup" @bind-Value="@Employee.Gender">
<label class="col-form-label col-md-3">Gender: </label>
<div class="col-md-8">
@foreach (var gender in (Gender[])Enum.GetValues(typeof(Gender)))
{
<InputRadio Name="genderRadioGroup" Value="gender" class="form-check-input" />
<label class="form-check-label">
@gender
</label>
<br />
}
</div>
</InputRadioGroup>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.Gender)" />
</div>
<div class="row mb-3">
<label for="maritalstatus" class="col-form-label col-md-3">Marital status: </label>
<div class="col-md-8">
<InputSelect id="maritalstatus" class="form-select col-md-8" @bind-Value=@Employee.MaritalStatus>
<option value="@(MaritalStatus.Single)">Single</option>
<option value="@(MaritalStatus.Married)">Married</option>
<option value="@(MaritalStatus.Other)">Other</option>
</InputSelect>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.MaritalStatus)" />
</div>
</div>
<div class="row mb-3">
<label for="joineddate" class="col-form-label col-md-3">Joined on: </label>
<div class="col-md-8">
<InputDate id="joineddate" class="form-control" @bind-Value="@Employee.JoinedDate" placeholder="Enter date joined"></InputDate>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.JoinedDate)" />
</div>
</div>
<div class="row mb-3">
<label for="exitdate" class="col-form-label col-md-3">Left on: </label>
<div class="col-md-8">
<InputDate id="exitdate" class="form-control" @bind-Value="@Employee.ExitDate" placeholder="Enter exit date"></InputDate>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.ExitDate)" />
</div>
</div>
<div class="row mb-3">
<label for="comment" class="col-form-label col-md-3">Comment: </label>
<div class="col-md-8">
<InputTextArea id="comment" class="form-control" @bind-Value="@Employee.Comment" placeholder="Enter comment"></InputTextArea>
<ValidationMessage class="offset-md-3 col-md-8 text-danger" For="@(() => Employee.Comment)" />
</div>
</div>
<button class="btn btn-secondary" @onclick="BackToOverview">Cancel</button>
<button class="btn btn-primary me-1" type="submit">Submit</button>
@if(EmployeeId.HasValue){
<button class="btn btn-danger" @onclick="DeleteEmployee">Delete</button>
}
</EditForm>
}
else
{
<div>Loading...</div>
}
</section>
} else
{
<div class="alert @StatusClass">@Message</div>
<button class="btn btn-secondary" @onclick="BackToOverview">Back to overview</button>
}
+124
View File
@@ -0,0 +1,124 @@
using BethanysPieShopHRM.Shared.Domain;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Webshop.App.Services;
namespace Webshop.App.Pages
{
public partial class EmployeeEdit
{
[Inject]
public IEmployeeDataService EmployeeDataService { get; set; } = default!;
[Inject]
public ICountryDataService CountryDataService { get; set; } = default!;
[Inject]
public IJobCategoryDataService JobCategoryDataService { get; set; } = default!;
[Inject]
public NavigationManager NavigationManager { get; set; } = default!;
[Parameter]
public int? EmployeeId { get; set; }
public Employee? Employee { get; set; }
public IEnumerable<Country> Countries { get; set; } = new List<Country>();
public IEnumerable<JobCategory> JobCategories { get; set; } = new List<JobCategory>();
protected string Message = string.Empty;
protected string StatusClass = string.Empty;
protected bool Saved;
private IBrowserFile selectedFile;
private async Task<Employee?> GetEmployee(int employeeId)
{
return await EmployeeDataService.GetEmployeeDetails(employeeId);
}
private void OnInputFileChange(InputFileChangeEventArgs e)
{
selectedFile = e.File;
StateHasChanged();
}
protected async override Task OnInitializedAsync()
{
Countries = await CountryDataService.GetCountries();
JobCategories = await JobCategoryDataService.GetJobCategories();
Saved = false;
}
protected async override Task OnParametersSetAsync()
{
if (!EmployeeId.HasValue)
{
Employee = new Employee();
return;
}
var employee = await GetEmployee(EmployeeId.Value);
if (employee is null)
{
NavigationManager.NavigateTo("/not-found");
return;
}
Employee = employee;
}
protected async Task HandleValidSubmit()
{
Saved = false;
if (!EmployeeId.HasValue && Employee != null)
{
if (selectedFile != null)
{
var file = selectedFile;
Stream stream = file.OpenReadStream();
MemoryStream ms = new();
await stream.CopyToAsync(ms);
stream.Close();
Employee.ImageName = file.Name;
Employee.ImageContent = ms.ToArray();
}
var addedEmployee = await EmployeeDataService.AddEmployee(Employee);
if (addedEmployee != null)
{
StatusClass = "alert-success";
Message = "New employee added successfully.";
Saved = true;
}
else
{
StatusClass = "alert-danger";
Message = "Something went wrong adding the new employee. Please try again.";
Saved = false;
}
}
else if (Employee != null)
{
await EmployeeDataService.UpdateEmployee(Employee);
StatusClass = "alert-success";
Message = "Employee updated successfully.";
Saved = true;
}
}
protected async Task HandleInvalidSubmit()
{
StatusClass = "alert-danger";
Message = "validation errors";
}
protected async Task DeleteEmployee()
{
if(Employee != null && Employee.EmployeeId > 0)
{
await EmployeeDataService.DeleteEmployee(Employee.EmployeeId);
StatusClass = "alert-success";
Message = "Deleted successful";
}
}
protected void BackToOverview()
{
NavigationManager.NavigateTo("/employeeoverview");
}
}
}
+27
View File
@@ -0,0 +1,27 @@
@page "/employeeoverview"
<PageTitle>@Title</PageTitle>
<h2>Employee Overview</h2>
@if(Employees == null)
{
<div>Loading...</div>
} else
{
<QuickViewPopup Employee="_employeeSelected"></QuickViewPopup>
<div class="row">
@foreach (var employee in Employees)
{
<div class="col-12 col-sm-12 col-md-6 col-lg-4 col-xl-3">
<ErrorBoundary>
<ChildContent>
<EmployeeCard Employee="employee" EmployeeQuickViewClicked="ShowQuickViewPopup"></EmployeeCard>
</ChildContent>
<ErrorContent>
<p class="errorUI">Invalid Employee!</p>
</ErrorContent>
</ErrorBoundary>
</div>
}
</div>
}
@@ -0,0 +1,32 @@
using BethanysPieShopHRM.Shared.Domain;
using Microsoft.AspNetCore.Components;
using Webshop.App.Services;
namespace Webshop.App.Pages
{
public partial class EmployeeOverview
{
[Inject]
public NavigationManager NavigationManager { get; set; } = default!;
[Inject]
public IEmployeeDataService EmployeeDataService { get; set; } = default!;
public IEnumerable<Employee>? Employees { get; set; } = default;
private Employee? _employeeSelected;
private string Title = "Employee overview";
protected async override Task OnInitializedAsync()
{
Employees = await GetEmployees();
}
public void ShowQuickViewPopup(Employee employee)
{
_employeeSelected = employee;
}
public async Task<IEnumerable<Employee>> GetEmployees()
{
return await EmployeeDataService.GetAllEmployees();
}
}
}
+38
View File
@@ -0,0 +1,38 @@
@page "/"
<PageTitle>Salut</PageTitle>
<h1>Salut t'es ici c'est cool</h1>
@foreach(var widget in Widgets)
{
<DynamicComponent Type="widget"></DynamicComponent>
}
<div>
<h2>One way Data Binding</h2>
Employee First Name: <label>@Employee.FirstName</label>
Employee Last name: <label>@Employee.LastName</label>
</div>
<div>
<h2>One way data binding in form controls</h2>
Employee First Name:
<input type="text" value="@Employee.FirstName" />
Employee Last Name:
<input type="text" value="@Employee.LastName"/>
</div>
<div>
<h2>Two way data binding in form controls</h2>
Employee First Name:
<input type="text" @bind="@Employee.FirstName" />
Employee Last Name:
<input type="text" @bind="@Employee.LastName" />
</div>
<div>
<h2>Two way data binding in form controls on a different event</h2>
Employee First Name:
<input type="text" @bind-value="@Employee.FirstName" @bind-value:event="oninput" />
Employee Last Name:
<input type="text" @bind-value="@Employee.LastName" @bind-value:event="oninput" />
</div>
<button @onclick="ButtonClick" class="btn btn-primary">Click me</button>
+35
View File
@@ -0,0 +1,35 @@
using BethanysPieShopHRM.Shared.Domain;
using Webshop.App.Components.Widgets;
namespace Webshop.App.Pages
{
public partial class Home
{
public Employee Employee { get; set; }
public List<Type> Widgets { get; set; } = new List<Type>()
{
typeof(EmployeeCountWidget),
typeof(InboxWidget),
};
protected override Task OnInitializedAsync()
{
Employee = new Employee
{
FirstName = "Caca",
LastName = "Pipi"
};
return base.OnInitializedAsync();
}
public void ButtonClick()
{
Employee.FirstName = "ProutProut";
}
public void Test()
{
}
}
}
+5
View File
@@ -0,0 +1,5 @@
@page "/not-found"
@layout MainLayout
<h3>Not Found</h3>
<p>Sorry, the content you are looking for does not exist.</p>