Refactor onboarding and verification workflows.

Adjusted interaction types and state filters to better streamline onboarding and verification processes. Updated UI labels, navigation, and modal dialogs to reflect new terminology and improve usability. Enhanced filtering logic and added new interaction types to support the revised process.
This commit is contained in:
Andre Beging
2025-03-27 17:12:28 +01:00
parent 572a35fd3f
commit 19796928e7
15 changed files with 148 additions and 91 deletions

View File

@@ -90,6 +90,15 @@ namespace FoodsharingSiegen.Contracts.Entity
Admin = 300
}
public enum ProspectStateFilter
{
OnBoarding = 10,
Verification = 20,
Completed = 30
}
/// <summary>
/// The user group enum
/// </summary>
@@ -190,6 +199,16 @@ namespace FoodsharingSiegen.Contracts.Entity
/// <summary>
/// The complete interaction type
/// </summary>
Complete = 70
Complete = 70,
/// <summary>
/// The StepInBriefing interaction type
/// </summary>
StepInBriefing = 80,
/// <summary>
/// The StepInBriefing interaction type
/// </summary>
ReleasedForVerification = 90
}
}

View File

@@ -21,7 +21,7 @@
<div style="white-space: nowrap;">
<span title="@interaction.User.Memo">@interaction.User.Name</span> (@interaction.Date.ToShortDateString())
@if ((Prospect is not { Complete: true } || interaction.Type == InteractionType.Complete) && AllowAddInteraction)
@if ((Prospect is not { Complete: true } || interaction.Type == InteractionType.Complete) && AllowInteraction)
{
<span>&nbsp;<a href=""><i class="fa-solid fa-square-xmark" @onclick="async () => await RemoveClick.InvokeAsync(interaction.Id)" @onclick:preventDefault></i></a></span>
}
@@ -35,7 +35,7 @@
}
}
@if (Prospect is not {Complete: true } && (Interactions.Count == 0 || Multiple) && AllowAddInteraction)
@if (Prospect is not {Complete: true } && (Interactions.Count == 0 || Multiple) && AllowInteraction)
{
if (Multiple) ButtonIconClass = "fa-solid fa-plus";
<div class="m-auto">

View File

@@ -20,7 +20,7 @@ namespace FoodsharingSiegen.Server.Controls
/// Gets or sets the value of the allow add interaction (ab)
/// </summary>
[Parameter]
public bool AllowAddInteraction { get; set; }
public bool AllowInteraction { get; set; }
/// <summary>
/// Gets or sets the value of the button text (ab)

View File

@@ -1,7 +1,4 @@
@using FoodsharingSiegen.Contracts.Entity
@using FoodsharingSiegen.Contracts.Helper
@using FoodsharingSiegen.Server.BaseClasses
@inherits FsBase
@inherits FsBase
@{
var divClass = $"{CssClass} pc-main";
@@ -37,7 +34,7 @@
<InteractionRow
Prospect="Prospect"
Type="InteractionType.Welcome"
AllowAddInteraction="@CurrentUser.IsInGroup(UserGroup.WelcomeTeam)"
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))"
AddClick="() => AddInteraction(InteractionType.Welcome)"
RemoveClick="@RemoveInteraction"
Caption="Begrüßung"
@@ -45,10 +42,21 @@
IconClass="fa-solid fa-handshake-simple">
</InteractionRow>
<InteractionRow
Prospect="Prospect"
Type="InteractionType.StepInBriefing"
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))"
AddClick="() => AddInteraction(InteractionType.StepInBriefing)"
RemoveClick="@RemoveInteraction"
Caption="Neulingstreffen"
ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-graduation-cap">
</InteractionRow>
<InteractionRow
Prospect="Prospect"
Type="InteractionType.EinAb"
AllowAddInteraction="@CurrentUser.IsInGroup(UserGroup.WelcomeTeam, UserGroup.StoreManager, UserGroup.Ambassador)"
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam, UserGroup.StoreManager, UserGroup.Ambassador))"
AddClick="() => AddInteraction(InteractionType.EinAb)"
RemoveClick="@RemoveInteraction"
Caption="Einführungen"
@@ -64,21 +72,37 @@
</td>
</tr>
<InteractionRow
Prospect="Prospect"
Type="InteractionType.ReleasedForVerification"
AllowInteraction="@(StateFilter == ProspectStateFilter.OnBoarding && CurrentUser.IsInGroup(UserGroup.WelcomeTeam))"
AddClick="() => AddInteraction(InteractionType.ReleasedForVerification)"
RemoveClick="@RemoveInteraction"
Caption="Freigabe zur Verifizierung"
ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-id-card">
</InteractionRow>
@if (CurrentUser.IsInGroup(UserGroup.Ambassador))
{
<InteractionRow
Prospect="Prospect"
Type="InteractionType.IdCheck"
AllowAddInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
AddClick="() => AddInteraction(InteractionType.IdCheck)"
RemoveClick="@RemoveInteraction"
Caption="Perso checken"
ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-magnifying-glass">
</InteractionRow>
}
@if (StateFilter > ProspectStateFilter.OnBoarding)
{
<InteractionRow
Prospect="Prospect"
Type="InteractionType.PrintPass"
AllowAddInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
AddClick="() => AddInteraction(InteractionType.PrintPass)"
RemoveClick="@RemoveInteraction"
Caption="FS-Ausweis (print)"
@@ -88,7 +112,7 @@
<InteractionRow
Prospect="Prospect"
AllowAddInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
Type="InteractionType.Verify"
AddClick="() => AddInteraction(InteractionType.Verify)"
RemoveClick="@RemoveInteraction"
@@ -105,7 +129,7 @@
<InteractionRow
Prospect="Prospect"
AllowAddInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
AllowInteraction="@CurrentUser.IsInGroup(UserGroup.Ambassador)"
Type="InteractionType.Complete"
AddClick="() => AddInteraction(InteractionType.Complete)"
RemoveClick="@RemoveInteraction"
@@ -113,6 +137,7 @@
ButtonIconClass="fa-solid fa-check"
IconClass="fa-solid fa-flag-checkered">
</InteractionRow>
}
</table>

View File

@@ -14,6 +14,8 @@ namespace FoodsharingSiegen.Server.Controls
[Parameter] public EventCallback<Guid> RemoveInteraction { get; set; }
[Parameter] public ProspectStateFilter StateFilter { get; set; }
[Parameter] public string? CssClass { get; set; }

View File

@@ -18,7 +18,7 @@
flex-grow: 1;
max-width: 480px;
border: 1px solid #533a20;
border-radius: 7px;
border-radius: 3px;
margin: 5px;
padding: 16px;
}

View File

@@ -53,7 +53,7 @@
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="ModalReference.Hide">Abbrechen</Button>
<Button Color="Color.Primary" Clicked="@AddInteraction">Speichern</Button>
<Button Color="Color.Primary" Clicked="@AddInteraction">OK</Button>
</ModalFooter>
</ModalContent>
</Modal>

View File

@@ -72,6 +72,14 @@ namespace FoodsharingSiegen.Server.Dialogs
_header = "Als fertig markieren";
_showInfo = true;
break;
case InteractionType.StepInBriefing:
_header = "Neulingstreffen absolviert";
break;
case InteractionType.ReleasedForVerification:
_header = "Zur Verifizierung freigegeben";
_showInfo = true;
_infoName = "Hinweis";
break;
}
Interaction = new Interaction

View File

@@ -4,8 +4,8 @@
@inherits FsBase
<PageTitle>@AppSettings.Title - Aktuelle Einarbeitungen</PageTitle>
<h2>Aktuelle Einarbeitungen</h2>
<PageTitle>@AppSettings.Title - Neue Foodsaver</PageTitle>
<h2>Neue Foodsaver</h2>
<Button
Color="Color.Primary"
@@ -30,7 +30,7 @@
{
<div class="row m-0">
<Repeater Items="@filterList">
<ProspectContainer Prospect="context" InteractionModal="InteractionModal" ProspectModal="ProspectModal" RemoveInteraction="RemoveInteraction"></ProspectContainer>
<ProspectContainer Prospect="context" InteractionModal="InteractionModal" ProspectModal="ProspectModal" RemoveInteraction="RemoveInteraction" StateFilter="ProspectStateFilter.OnBoarding"></ProspectContainer>
</Repeater>
</div>
}

View File

@@ -94,7 +94,7 @@ namespace FoodsharingSiegen.Server.Pages
{
var parameter = new GetProspectsParameter
{
CannotHaveInteractions = [InteractionType.Complete, InteractionType.Verify]
CannotHaveInteractions = [InteractionType.Complete, InteractionType.Verify, InteractionType.ReleasedForVerification]
};
var prospectsR = await ProspectService.GetProspectsAsync(parameter);
if (prospectsR.Success) ProspectList = prospectsR.Data;

View File

@@ -64,7 +64,7 @@ namespace FoodsharingSiegen.Server.Pages
/// </summary>
private async Task LoadProspects()
{
var parameter = new GetProspectsParameter { MustHaveInteractions = new() { InteractionType.Complete } };
var parameter = new GetProspectsParameter { MustHaveInteractions = [InteractionType.Complete] };
var prospectsR = await ProspectService.GetProspectsAsync(parameter);
if (prospectsR.Success) ProspectList = prospectsR.Data;

View File

@@ -2,9 +2,9 @@
@inherits FsBase
<PageTitle>@AppSettings.Title - Wartende Einarbeitungen</PageTitle>
<PageTitle>@AppSettings.Title - </PageTitle>
<h2>Wartende Einarbeitungen</h2>
<h2>Freischalten</h2>
@{
var filterList = ProspectList;
@@ -21,10 +21,9 @@
<TextEdit TextChanged="FilterText_Changed" Placeholder="Suchen..." Debounce="true" DebounceInterval="150" />
@if (filterList?.Any() == true)
{
<div class="text-center font-weight-bold">Bereits verifiziert, aber noch nicht abgeschlossen. Zum Beispiel, wenn noch der Druck-Ausweis fehlt o.ä.</div>
<div class="row m-0">
<Repeater Items="@filterList">
<ProspectContainer Prospect="context" InteractionModal="InteractionModal" ProspectModal="ProspectModal" RemoveInteraction="RemoveInteraction"></ProspectContainer>
<ProspectContainer Prospect="context" InteractionModal="InteractionModal" ProspectModal="ProspectModal" RemoveInteraction="RemoveInteraction" StateFilter="ProspectStateFilter.Verification"></ProspectContainer>
</Repeater>
</div>
}

View File

@@ -92,7 +92,7 @@ namespace FoodsharingSiegen.Server.Pages
var parameter = new GetProspectsParameter
{
CannotHaveInteractions = [InteractionType.Complete],
MustHaveInteractions = [InteractionType.Verify]
MustHaveInteractions = [InteractionType.ReleasedForVerification]
};
var prospectsR = await ProspectService.GetProspectsAsync(parameter);
if (prospectsR.Success) ProspectList = prospectsR.Data;

View File

@@ -4,50 +4,54 @@
Einarbeitungen<br />
@(AppSettings.SidebarTitle ?? AppSettings.Title)
</div>
<div class="row px-3">
<div class="col">
<div class="nav-item">
<NavLink class="nav-link justify-content-center" href="profile" Match="NavLinkMatch.All" title="Profil">
<span class="fas fa-user mr-1" aria-hidden="true" style="font-size: 1.4em;"></span>
</NavLink>
</div>
</div>
<div class="col">
<div class="nav-item">
<NavLink class="nav-link justify-content-center" href="logout" Match="NavLinkMatch.All" title="Ausloggen">
<span class="fa-solid fa-door-open mr-1" aria-hidden="true" style="font-size: 1.4em;"></span>
</NavLink>
</div>
</div>
<div class="d-flex px-3 mt-3 justify-content-center text-center font-weight-bold">
Hallo @CurrentUser.Name!
</div>
<hr/>
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="fas fa-user-plus mr-1" aria-hidden="true" style="font-size: 1.4em;"></span> Neue Foodsaver
<span class="fas fa-user-plus mr-2" aria-hidden="true" style="font-size: 1.4em;"></span> Einarbeiten
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="todo" Match="NavLinkMatch.All">
<span class="fas fa-user-clock mr-1" aria-hidden="true" style="font-size: 1.4em;"></span> ToDo
<span class="fas fa-user-pen mr-2" aria-hidden="true" style="font-size: 1.4em;"></span> Freischalten
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="done" Match="NavLinkMatch.All">
<span class="fas fa-user-shield mr-1" aria-hidden="true" style="font-size: 1.4em;"></span> Abgeschlossen
<span class="fas fa-user-check mr-2" aria-hidden="true" style="font-size: 1.4em;"></span> Fertig
</NavLink>
</div>
<hr/>
@if (CurrentUser.IsAdmin())
{
<div class="nav-item px-3 mt-3">
<div class="nav-item px-3">
<NavLink class="nav-link" href="users" Match="NavLinkMatch.All">
<span class="fas fa-users mr-1" aria-hidden="true" style="font-size: 1.4em;"></span> Benutzer
<span class="fas fa-users mr-2" aria-hidden="true" style="font-size: 1.4em;"></span> Benutzer
</NavLink>
</div>
}
<div class="nav-item px-3">
<NavLink class="nav-link" href="profile" Match="NavLinkMatch.All">
<span class="fas fa-user mr-2" aria-hidden="true" style="font-size: 1.4em;"></span> Profil
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="audit" Match="NavLinkMatch.All">
<span class="fa-solid fa-clock-rotate-left mr-1" aria-hidden="true" style="font-size: 1.4em;"></span> Aktivitäten
<span class="fa-solid fa-clock-rotate-left mr-2" aria-hidden="true" style="font-size: 1.4em;"></span> Aktivitäten
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="logout" Match="NavLinkMatch.All">
<span class="fa-solid fa-door-open mr-2" aria-hidden="true" style="font-size: 1.4em;"></span> Ausloggen
</NavLink>
</div>
</nav>

View File

@@ -7,6 +7,6 @@
}
},
"Settings": {
"Title": "Foodsharing Olpe-Wenden"
"Title": "Andres Superduperbezirk"
}
}