WIP system user create web shop user

This commit is contained in:
Frede Hundewadt 2023-07-01 12:51:39 +02:00
parent 5258adfa07
commit ff9d9ae3c5
14 changed files with 217 additions and 236 deletions

View file

@ -60,7 +60,7 @@
<td class="align-middle state">
@if (activity.Lines.Any() && activity.StatusTypeEnum == "Order")
{
<ProcessStateComponent StateClass="@Utils.MapProcessStatus(activity.ProcessStatusEnum)"/>
<ProcessStateComponent StateClass="@Mapper.MapProcessStatus(activity.ProcessStatusEnum)"/>
}
</td>
<td class="align-middle font-monospace text-sm-start">@activity.ESalesNumber</td>

View file

@ -36,10 +36,10 @@
{
<tr @onclick="@(() => { ViewCustomer(company.CompanyId); })" class="action-link-element">
<td class="state align-middle">
<DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.MapVisitState(company.NextVisit))"/>
<DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Mapper.MapVisitState(company.NextVisit))"/>
</td>
<td class="state align-middle">
<DisplayStateComponent StateClass="@(Utils.MapOrgState(company.ValidVat))"/>
<DisplayStateComponent StateClass="@(Mapper.MapOrgState(company.ValidVat))"/>
</td>
<td class="align-middle">
@if (!string.IsNullOrWhiteSpace(company.Note))

View file

@ -59,13 +59,13 @@
<tr>
<th scope="row">Sidst besøgt</th>
<td>
@(Utils.MapVisitState(company.LastVisit) == "the-draw" ? "?" : company.LastVisit)
@(Mapper.MapVisitState(company.LastVisit) == "the-draw" ? "?" : company.LastVisit)
</td>
</tr>
<tr>
<th scope="row">Næste besøg</th>
<td>
@(Utils.MapVisitState(company.LastVisit) == "the-draw" ? "?" : company.NextVisit)
@(Mapper.MapVisitState(company.LastVisit) == "the-draw" ? "?" : company.NextVisit)
</td>
</tr>
</table>

View file

@ -60,7 +60,7 @@
<td class="align-middle state">
@if (activity.Lines.Any() && activity.StatusTypeEnum == "Order")
{
<ProcessStateComponent StateClass="@Utils.MapProcessStatus(activity.ProcessStatusEnum)"/>
<ProcessStateComponent StateClass="@Mapper.MapProcessStatus(activity.ProcessStatusEnum)"/>
}
</td>
</tr>

View file

@ -60,7 +60,7 @@
<td class="align-middle state">
@if (activity.Lines.Any() && activity.StatusTypeEnum == "Order")
{
<ProcessStateComponent StateClass="@Utils.MapProcessStatus(activity.ProcessStatusEnum)"/>
<ProcessStateComponent StateClass="@Mapper.MapProcessStatus(activity.ProcessStatusEnum)"/>
}
</td>
</tr>

View file

@ -1,43 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Wonky.Client.Models;
using Wonky.Entity.DTO;
namespace Wonky.Client.Helpers;
public class MapUtils
{
public static ManagerNewUserDto MapCreateUser(NewUserForm model)
{
return new ManagerNewUserDto
{
Description = model.Description,
Email = model.Email,
Passwd = model.NewPassword,
AssignedRoles = model.AssignedRoles,
CompanyId = model.CompanyId,
CountryCode = model.CountryCode,
EmailConfirmed = true,
EShop = model.EShop,
FirstName = model.FirstName,
LastName = model.LastName,
LockoutEnabled = false,
PhoneNumber = model.PhoneNumber,
SalesRep = model.SalesRep,
UserId = ""
};
}
}

View file

@ -12,7 +12,7 @@ public class Mapper
{
Description = model.Description,
Email = model.Email,
Passwd = model.NewPassword,
Passwd = model.PasswordInput.NewPassword,
AssignedRoles = model.AssignedRoles,
CompanyId = model.CompanyId,
CountryCode = model.CountryCode,
@ -26,4 +26,95 @@ public class Mapper
UserId = ""
};
}
public static string MapOrgState(int validVat)
{
return validVat == 0 ? "no-vat" : "the-good";
}
public static string MapVisitState(string dtNextVisit)
{
if (dtNextVisit is "0001-01-01" or "1970-01-01" or "2010-01-01" or "2020-01-01")
return "the-draw";
if (!DateTime.TryParse(dtNextVisit, out _))
return "the-draw";
var dtNow = DateTime.Now;
var dtNext = DateTime.Parse(dtNextVisit);
if (dtNow > dtNext)
return "the-ugly";
return dtNow > dtNext.AddDays(-14) ? "the-bad" : "the-good";
}
public static string MapProcessStatus(string processStatus)
{
return processStatus.ToLower() switch
{
"express" => "the-fast",
"none" => "the-good",
"picked" => "the-bad",
"packed" => "the-ugly",
"shipped" => "the-dead",
"printed" => "printed",
_ => "question"
};
}
public static List<UserRoleAssignment> MapSaveAssignedRoles(RoleAssignment model)
{
return new List<UserRoleAssignment>()
{
new() { Name = "Admin", Assigned = model.Admin },
new() { Name = "Advisor", Assigned = model.Advisor },
new() { Name = "EDoc", Assigned = model.EDoc },
new() { Name = "EShop", Assigned = model.EShop },
new() { Name = "Management", Assigned = model.Management },
new() { Name = "Office", Assigned = model.Office },
new() { Name = "Supervisor", Assigned = model.Supervisor },
new() { Name = "Warehouse", Assigned = model.Warehouse }
};
}
public static RoleAssignment MapEditAssignedRoles(UserManagerEditView model)
{
var x = new RoleAssignment();
foreach (var role in model.AssignedRoles)
{
switch (role.Name.ToLower())
{
case "admin":
x.Admin = role.Assigned;
break;
case "advisor":
x.Advisor = role.Assigned;
break;
case "edoc":
x.EDoc = role.Assigned;
break;
case "eshop":
x.EShop = role.Assigned;
break;
case "management":
x.Management = role.Assigned;
break;
case "office":
x.Office = role.Assigned;
break;
case "supervisor":
x.Supervisor = role.Assigned;
break;
case "warehouse":
x.Warehouse = role.Assigned;
break;
}
}
return x;
}
}

View file

@ -157,61 +157,7 @@ public static class Utils
}).ToList();
}
public static List<UserRoleAssignment> MapSaveAssignedRoles(RoleAssignment model)
{
return new List<UserRoleAssignment>()
{
new() { Name = "Admin", Assigned = model.Admin },
new() { Name = "Advisor", Assigned = model.Advisor },
new() { Name = "EDoc", Assigned = model.EDoc },
new() { Name = "EShop", Assigned = model.EShop },
new() { Name = "Management", Assigned = model.Management },
new() { Name = "Office", Assigned = model.Office },
new() { Name = "Supervisor", Assigned = model.Supervisor },
new() { Name = "Warehouse", Assigned = model.Warehouse }
};
}
public static RoleAssignment MapEditAssignedRoles(UserManagerEditView model)
{
var x = new RoleAssignment();
foreach (var role in model.AssignedRoles)
{
switch (role.Name.ToLower())
{
case "admin":
x.Admin = role.Assigned;
break;
case "advisor":
x.Advisor = role.Assigned;
break;
case "edoc":
x.EDoc = role.Assigned;
break;
case "eshop":
x.EShop = role.Assigned;
break;
case "management":
x.Management = role.Assigned;
break;
case "office":
x.Office = role.Assigned;
break;
case "supervisor":
x.Supervisor = role.Assigned;
break;
case "warehouse":
x.Warehouse = role.Assigned;
break;
}
}
return x;
}
public static string StringToDigits(string digitString)
{
if (string.IsNullOrWhiteSpace(digitString))
@ -332,41 +278,4 @@ public static class Utils
{
return DateTime.Now.ToFileTimeUtc().GetHashCode();
}
public static string MapOrgState(int validVat)
{
return validVat == 0 ? "no-vat" : "the-good";
}
public static string MapVisitState(string dtNextVisit)
{
if (dtNextVisit is "0001-01-01" or "1970-01-01" or "2010-01-01" or "2020-01-01")
return "the-draw";
if (!DateTime.TryParse(dtNextVisit, out _))
return "the-draw";
var dtNow = DateTime.Now;
var dtNext = DateTime.Parse(dtNextVisit);
if (dtNow > dtNext)
return "the-ugly";
return dtNow > dtNext.AddDays(-14) ? "the-bad" : "the-good";
}
public static string MapProcessStatus(string processStatus)
{
return processStatus.ToLower() switch
{
"express" => "the-fast",
"none" => "the-good",
"picked" => "the-bad",
"packed" => "the-ugly",
"shipped" => "the-dead",
"printed" => "printed",
_ => "question"
};
}
}

View file

@ -30,11 +30,11 @@ public class NewUserForm
public bool LockoutEnabled { get; set; }
[Required(ErrorMessage = "AdgangsKode skal udfyldes")]
public string NewPassword { get; set; } = "";
[Compare(nameof(NewPassword), ErrorMessage = "Adgangskoder er ikke ens.")]
public string ConfirmPassword { get; set; } = "";
// [Required(ErrorMessage = "AdgangsKode skal udfyldes")]
// public string NewPassword { get; set; } = "";
//
// [Compare(nameof(NewPassword), ErrorMessage = "Adgangskoder er ikke ens.")]
// public string ConfirmPassword { get; set; } = "";
[MaxLength(20, ErrorMessage = "Der er afsat 20 tegn til telefon nummber")]
public string PhoneNumber { get; set; } = "";
@ -43,4 +43,5 @@ public class NewUserForm
public string SalesRep { get; set; } = "";
public List<UserRoleAssignment> AssignedRoles { get; set; } = new();
public PasswordInput PasswordInput { get; set; } = new();
}

View file

@ -18,8 +18,8 @@
<div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay">
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Pris Katalog</h5>
<div class="modal-header alert alert-info">
<h5 class="modal-title">Kunde liste</h5>
<button type="button" class="btn btn-danger" @onclick="@Hide" data-bs-dismiss="modal" aria-label="Luk"><i class="bi-x-lg"></i></button>
</div>
<div class="modal-body">

View file

@ -184,7 +184,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
/*
* display urgency of next visit
*/
_visitStateCss = Utils.MapVisitState($"{_nextVisit:yyyy-MM-dd}");
_visitStateCss = Mapper.MapVisitState($"{_nextVisit:yyyy-MM-dd}");
/*
* handle InfoDrawer.Company out of business case
*/

View file

@ -21,15 +21,47 @@
@page "/system/users/create"
<PageTitle>Opret Bruger - Administration</PageTitle>
<div class="card">
<div class="card-header bg-dark text-white">
<div class="mt-3 h3 card-title">
System Bruger Oprettelse
Opret Bruger
</div>
</div>
<div class="card-body">
<EditForm EditContext="FormContext" OnValidSubmit="PostNewUser">
<DataAnnotationsValidator/>
<div class="row mb-3 ps-3">
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="eshop" class="form-check-input" @bind-Value="AssignedRoles.EShop"/>
<label for="eshop" class="form-check-label">WebShop Kunde</label>
</div>
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="supervisor" class="form-check-input" @bind-Value="AssignedRoles.Supervisor"/>
<label for="supervisor" class="form-check-label">Supervisor</label>
</div>
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="advisor" class="form-check-input" @bind-Value="AssignedRoles.Advisor"/>
<label for="advisor" class="form-check-label">Sælger</label>
</div>
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="office" class="form-check-input" @bind-Value="AssignedRoles.Office"/>
<label for="office" class="form-check-label">Kontor</label>
</div>
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="warehouse" class="form-check-input" @bind-Value="AssignedRoles.Warehouse"/>
<label for="warehouse" class="form-check-label">Lager</label>
</div>
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="management" class="form-check-input" @bind-Value="AssignedRoles.Management"/>
<label for="management" class="form-check-label">Ledelse</label>
</div>
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="admin" class="form-check-input" @bind-Value="AssignedRoles.Admin"/>
<label for="admin" class="form-check-label">Administrator</label>
</div>
</div>
<div class="row g-3 mb-3">
@* firstName *@
<div class="col-sm-6">
@ -65,97 +97,88 @@
</div>
@* salesRep *@
<div class="col-sm-6">
<div class="form-floating">
<InputText id="salesRep" class="form-control" @bind-Value="UserForm.SalesRep" placeholder="Sælger"/>
<ValidationMessage For="@(() => UserForm.SalesRep)"></ValidationMessage>
<label for="salesRep">Sælger</label>
<div class="@(!UserForm.EShop ? "inno-display" : "inno-hidden")">
<div class="form-floating">
<InputText id="salesRep" class="form-control" @bind-Value="UserForm.SalesRep" placeholder="Sælger"/>
<ValidationMessage For="@(() => UserForm.SalesRep)"></ValidationMessage>
<label for="salesRep">Sælger</label>
</div>
</div>
</div>
@* countrycode *@
<div class="col-sm-6">
<div class="form-floating">
<InputSelect id="countryCode" class="form-control" @bind-Value="UserForm.CountryCode" placeholder="Landekode">
<option value="" disabled>Klik for valg</option>
<option value="" disabled>Vælg Land</option>
<option value="DK">Danmark</option>
<option value="NO">Norge</option>
<option value="SE">Sverige</option>
</InputSelect>
<ValidationMessage For="@(() => UserForm.CountryCode)"></ValidationMessage>
<label for="countryCode">Landekode</label>
<label for="countryCode">Lande</label>
</div>
</div>
<div class="col-sm-6">
<div class="form-floating">
<InputText id="newPassword" class="form-control" @bind-Value="@UserForm.PasswordInput.NewPassword" placeholder="Ny Adgangskode"/>
<ValidationMessage For="@(() => UserForm.PasswordInput.NewPassword)"></ValidationMessage>
<label for="newPassword">Ny Adgangskode</label>
</div>
</div>
<div class="col-sm-6">
<div class="form-floating">
<InputText id="verifyPassword" class="form-control" @bind-Value="@UserForm.PasswordInput.ConfirmPassword" placeholder="Gentag Adgangskode"/>
<ValidationMessage For="@(() => UserForm.PasswordInput.ConfirmPassword)"></ValidationMessage>
<label for="verifyPassword">Gentag Adgangskode</label>
</div>
</div>
</div>
<div class="row mb-3">
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="eshop" class="form-check-input" @bind-Value="AssignedRoles.EShop"/>
<label for="eshop" class="form-check-label">WebShop Kunde</label>
</div>
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="supervisor" class="form-check-input" @bind-Value="AssignedRoles.Supervisor"/>
<label for="supervisor" class="form-check-label">Supervisor</label>
</div>
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="advisor" class="form-check-input" @bind-Value="AssignedRoles.Advisor"/>
<label for="advisor" class="form-check-label">Sælger</label>
</div>
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="office" class="form-check-input" @bind-Value="AssignedRoles.Office"/>
<label for="office" class="form-check-label">Kontor</label>
</div>
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="warehouse" class="form-check-input" @bind-Value="AssignedRoles.Warehouse"/>
<label for="warehouse" class="form-check-label">Lager</label>
</div>
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="management" class="form-check-input" @bind-Value="AssignedRoles.Management"/>
<label for="management" class="form-check-label">Ledelse</label>
</div>
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="admin" class="form-check-input" @bind-Value="AssignedRoles.Admin"/>
<label for="admin" class="form-check-label">Administrator</label>
<div class="@(UserForm.EShop && !string.IsNullOrWhiteSpace(UserForm.CountryCode) ? "inno-display" : "inno-hidden")">
<div class="row mb-3">
<div class="col-sm-6">
@if (!string.IsNullOrWhiteSpace(_company.Name))
{
<table class="table">
<tr>
<th scope="col">Tilknyttet kunde</th>
</tr>
<tr>
<td>@_company.Account</td>
</tr>
<tr>
<td>@_company.Name</td>
</tr>
<tr>
<td>@_company.Phone</td>
</tr>
</table>
}
</div>
<div class="col-sm-6">
<button type="button" class="btn btn-primary" @onclick="@ShowCompanySearchOverlay">
Tilknyt kunde ...
</button>
</div>
</div>
</div>
<div class="row @(UserForm.EShop && !string.IsNullOrWhiteSpace(UserForm.CountryCode) ? "inno-display" : "inno-hidden")">
<div class="col-sm-10">
@_company.Name - @_company.Account - @_company.Phone
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-primary" @onclick="@ShowCompanySearchOverlay">
Tilknyt kunde ...
</button>
</div>
</div>
<div class="row mb-3">
<div class="col-sm-6">
<a class="btn btn-primary" href="/system/users"><i class="bi-back"></i> Tilbage</a>
</div>
<div class="col-sm-6 text-end">
<button type="submit" class="btn btn-primary" disabled="@ContextInvalid">Gem</button>
</div>
</div>
<div class="alert alert-info">
<h4>Password politik</h4>
<p>Mindst 10 tegn bestående af store og små bogstaver samt tal. Password generator <a href="https://pw.nix.dk">pw.nix.dk</a></p>
</div>
<div class="row mb-3">
<div class="col-sm-6">
<div class="form-floating">
<InputText id="newPasswd" class="form-control" @bind-Value="@PasswdInput.NewPassword" placeholder="Ny Adgangskode"/>
<ValidationMessage For="@(() => UserForm.NewPassword)"></ValidationMessage>
<label for="newPasswd">Ny Adgangskode</label>
</div>
</div>
<div class="col-sm-6">
<div class="form-floating">
<InputText id="verifyPasswd" class="form-control" @bind-Value="@PasswdInput.ConfirmPassword" placeholder="Gentag Adgangskode"/>
<ValidationMessage For="@(() => UserForm.ConfirmPassword)"></ValidationMessage>
<label for="verifyPasswd">Gentag Adgangskode</label>
</div>
<button type="submit" class="btn btn-primary" disabled="@_formInvalid">Gem</button>
</div>
</div>
</EditForm>
<div class="alert alert-info">
<h4>Password politik</h4>
<p>Mindst 10 tegn bestående af store og små bogstaver samt tal. Password generator <a href="https://pw.nix.dk">pw.nix.dk</a></p>
</div>
</div>
</div>
@ -165,4 +188,4 @@
<WorkingThreeDots/>
}
<CustomerSearchOverlay CountryCode="@UserForm.CountryCode" OnSelected="@OnSelectCompany" @ref="SearchOverlay" />
<CustomerSearchOverlay CountryCode="@UserForm.CountryCode" OnSelected="@OnSelectCompany" @ref="SearchOverlay"/>

View file

@ -41,9 +41,9 @@ public partial class SystemUserCreatePage : IDisposable
private NewUserForm UserForm { get; set; } = new();
private ManagerNewUserDto NewUserDto { get; set; } = new();
private EditContext FormContext { get; set; }
private bool ContextInvalid { get; set; } = true;
private bool _formInvalid = true;
private bool Working { get; set; } = true;
private bool ReadOnly { get; set; } = true;
private bool _readOnly;
private PasswordInput PasswdInput { get; set; } = new();
private RoleAssignment AssignedRoles { get; set; } = new();
@ -57,9 +57,8 @@ public partial class SystemUserCreatePage : IDisposable
Interceptor.RegisterBeforeSendEvent();
FormContext = new EditContext(UserForm);
FormContext.OnFieldChanged += ContextHandleFieldChanged;
FormContext.OnValidationStateChanged += ContextValidationChanged;
FormContext.OnValidationStateChanged += ContextValidationChanged!;
Working = false;
}
@ -77,7 +76,7 @@ public partial class SystemUserCreatePage : IDisposable
/*
* Make fields reaonly
*/
ReadOnly = true;
_readOnly = true;
/*
* Raise working flag
*/
@ -85,15 +84,15 @@ public partial class SystemUserCreatePage : IDisposable
/*
* ensure companyId is set correct
*/
UserForm.CompanyId = !UserForm.EShop ? "" : _company.CompanyId;
UserForm.CompanyId = UserForm.EShop ? _company.CompanyId : "";
/*
* Map RoleAssignment
*/
UserForm.AssignedRoles = Utils.MapSaveAssignedRoles(AssignedRoles);
UserForm.AssignedRoles = Mapper.MapSaveAssignedRoles(AssignedRoles);
/*
* Map form input to a model the backend expects
*/
NewUserDto = MapUtils.MapCreateUser(UserForm);
NewUserDto = Mapper.MapCreateUser(UserForm);
/*
* Send Post Request
*/
@ -142,7 +141,7 @@ public partial class SystemUserCreatePage : IDisposable
{
if (!Utils.IsValidPasswd(PasswdInput.NewPassword))
{
ContextInvalid = true;
_formInvalid = true;
return;
}
}
@ -163,7 +162,7 @@ public partial class SystemUserCreatePage : IDisposable
UserForm.EShop = false;
}
ContextInvalid = !FormContext.Validate();
_formInvalid = !FormContext.Validate();
StateHasChanged();
}
@ -173,17 +172,18 @@ public partial class SystemUserCreatePage : IDisposable
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ContextValidationChanged(object? sender, ValidationStateChangedEventArgs e)
private void ContextValidationChanged(object sender, ValidationStateChangedEventArgs e)
{
ContextInvalid = true;
_formInvalid = false;
FormContext.OnFieldChanged -= ContextHandleFieldChanged;
FormContext.OnValidationStateChanged -= ContextValidationChanged;
FormContext.OnValidationStateChanged -= ContextValidationChanged!;
FormContext = new EditContext(UserForm);
FormContext.OnFieldChanged += ContextHandleFieldChanged;
FormContext.OnValidationStateChanged += ContextValidationChanged;
FormContext.OnValidationStateChanged += ContextValidationChanged!;
}

View file

@ -65,7 +65,7 @@ public partial class SystemUserViewEditPage : IDisposable
UserInfo = await UserRepo.GetUserInfo(UserId);
AssignedRoles = Utils.MapEditAssignedRoles(UserInfo);
AssignedRoles = Mapper.MapEditAssignedRoles(UserInfo);
UserEditContext = new EditContext(UserInfo);
PasswdContext = new EditContext(Passwords);
@ -82,7 +82,7 @@ public partial class SystemUserViewEditPage : IDisposable
ReadOnly = true;
Working = true;
UserInfo.AssignedRoles = Utils.MapSaveAssignedRoles(AssignedRoles);
UserInfo.AssignedRoles = Mapper.MapSaveAssignedRoles(AssignedRoles);
Toaster.ShowInfo("Sender data til server ...");
await UserRepo.UpdateUserInfo(UserId, UserInfo);