Merge branch 'kh-test'

This commit is contained in:
2025-11-20 11:38:54 +01:00
27 changed files with 1038 additions and 189 deletions

View File

@ -1,29 +1,60 @@
@using Oqtane.Modules.Controls
@using Oqtane
@using Oqtane.Modules.Controls
@using Oqtane.Themes.Controls
@using SZUAbsolventenverein.Module.EventRegistration.Services
@using SZUAbsolventenverein.Module.EventRegistration.Models
@using System.Text.RegularExpressions
@namespace SZUAbsolventenverein.Module.EventRegistration
@inherits ModuleBase
@inject IEventRegistrationService EventRegistrationService
@inject NavigationManager NavigationManager
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@inject IUserService UserService
@inject IProfileService ProfileService
@inject ISettingService SettingService
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="name" HelpText="Enter a name" ResourceKey="Name">Name: </Label>
<div class="col-sm-9">
<input id="name" class="form-control" @bind="@_name" required />
</div>
<h3>Anmeldung zum Event</h3>
<p>Willst du am Event (@_name) teilnehmen?</p>
<span class="mb-6">@_eventDate.ToLocalTime() - @_location</span>
<div>
@((MarkupString) _description)
</div>
@if (PageState.User != null) {
@if (Status != null)
{
<p class="mt-2"><strong>Status: </strong>
@if (Status == true)
{
<span class ="fontsizeInf">@Localizer["Zugesagt"]</span><br />
<p><button class="btn btn-danger" @onclick="Absage">@Localizer["Absagen"]</button></p>
} else
{
<span class="fontsizeInf"> @Localizer["Abgesagt"]</span><br />
<p><button class="btn btn-success" @onclick="Zusage">@Localizer["Zusagen"]</button></p>
}
</p>
} else {
<div class="buttons">
<button class="btn btn-success" @onclick="Zusage">@Localizer["Zusagen"]</button>
<button class="btn btn-danger" @onclick="Absage">@Localizer["Absagen"]</button>
</div>
}
} else
{
<p class="mt-3">Um dich für dieses Event zu registrieren, muss man sich zuerst anmelden.</p>
<div class="gap-2">
<Login />
<UserProfile ShowRegister="true" />
</div>
<button type="button" class="btn btn-success" @onclick="Save">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<br /><br />
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
}
@code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
public override string Actions => "Details";
@ -34,29 +65,88 @@
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
};
private ElementReference form;
private bool validated = false;
// private ElementReference form;
// private bool validated = false;
private int _id;
private string _name;
private string _createdby;
private DateTime _createdon;
private string _modifiedby;
private DateTime _modifiedon;
private string _description;
private DateTime _eventDate;
private string _location;
private Response _response;
private bool? Status;
private List<Profile> _profiles = new List<Profile>();
private Dictionary<string, string> _settings;
private async Task SendResponse(bool response)
{
if(ValidateProfiles()) {
if(_response == null)
{
_response = new Response();
_response.EventRegistrationId = _id;
_response.OwnerId = PageState.User.UserId;
_response.ModuleId = ModuleState.ModuleId;
_response.ResponseType = response;
_response = await EventRegistrationService.AddResponseAsync(_response);
} else
{
_response.ResponseType = response;
_response = await EventRegistrationService.UpdateResponseAsync(_response);
}
if(_response != null) Status = _response.ResponseType;
} else
{
var currentPathAndQuery = new Uri(NavigationManager.Uri).PathAndQuery;
var encodedReturnUrl = Uri.EscapeDataString(currentPathAndQuery);
var link = $"/profile?tab=Profile&returnurl={encodedReturnUrl}";
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], $"Vervollständige hier dein Profil mit deinem Jahrgang und deiner Fachrichtung: <a href=\"{link}\">Link zum Profil</a>"), MessageType.Warning);
}
}
private async void Zusage()
{
await SendResponse(true);
}
private async void Absage()
{
await SendResponse(false);
}
protected override async Task OnInitializedAsync()
{
try
{
if(PageState.User != null) {
_profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
var user = await UserService.GetUserAsync(PageState.User.UserId, PageState.Site.SiteId);
if (user != null)
{
_settings = user.Settings;
}
}
_id = Int32.Parse(PageState.QueryString["id"]);
Event EventRegistration = await EventRegistrationService.GetEventRegistrationAsync(_id, ModuleState.ModuleId);
if (EventRegistration != null)
Event currentEvent;
Response rsvp;
(currentEvent, rsvp) = await EventRegistrationService.GetEventDetails(_id, ModuleState.ModuleId);
if (currentEvent != null)
{
_name = EventRegistration.Name;
_createdby = EventRegistration.CreatedBy;
_createdon = EventRegistration.CreatedOn;
_modifiedby = EventRegistration.ModifiedBy;
_modifiedon = EventRegistration.ModifiedOn;
_name = currentEvent.Name;
_description = currentEvent.Description;
_eventDate = currentEvent.EventDate;
_location = currentEvent.Location;
}
if(rsvp != null)
{
_response = rsvp;
Status = rsvp.ResponseType;
}
}
catch (Exception ex)
@ -66,40 +156,45 @@
}
}
private async Task Save()
private bool ValidateProfiles()
{
try
foreach (Profile profile in _profiles)
{
validated = true;
var interop = new Oqtane.UI.Interop(JSRuntime);
if (await interop.FormValid(form))
var value = GetProfileValue(profile.Name, string.Empty);
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
{
if (PageState.Action == "Add")
{
Event EventRegistration = new Event();
EventRegistration.ModuleId = ModuleState.ModuleId;
EventRegistration.Name = _name;
EventRegistration = await EventRegistrationService.AddEventRegistrationAsync(EventRegistration);
await logger.LogInformation("EventRegistration Added {EventRegistration}", EventRegistration);
}
else
{
Event EventRegistration = await EventRegistrationService.GetEventRegistrationAsync(_id, ModuleState.ModuleId);
EventRegistration.Name = _name;
await EventRegistrationService.UpdateEventRegistrationAsync(EventRegistration);
await logger.LogInformation("EventRegistration Updated {EventRegistration}", EventRegistration);
}
NavigationManager.NavigateTo(NavigateUrl());
_settings = SettingService.SetSetting(_settings, profile.Name, profile.DefaultValue);
}
else
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{
AddModuleMessage(Localizer["Message.SaveValidation"], MessageType.Warning);
if (profile.IsRequired && string.IsNullOrEmpty(value))
{
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
return false;
}
if (!string.IsNullOrEmpty(profile.Validation))
{
Regex regex = new Regex(profile.Validation);
bool valid = regex.Match(value).Success;
if (!valid)
{
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
return false;
}
}
}
}
catch (Exception ex)
return true;
}
private string GetProfileValue(string SettingName, string DefaultValue)
{
string value = SettingService.GetSetting(_settings, SettingName, DefaultValue);
if (value.Contains("]"))
{
await logger.LogError(ex, "Error Saving EventRegistration {Error}", ex.Message);
AddModuleMessage(Localizer["Message.SaveError"], MessageType.Error);
value = value.Substring(value.IndexOf("]") + 1);
}
return value;
}
}

View File

@ -1,6 +1,7 @@
@using Oqtane.Modules.Controls
@using SZUAbsolventenverein.Module.EventRegistration.Services
@using SZUAbsolventenverein.Module.EventRegistration.Models
@using Microsoft.AspNetCore.Components.Forms
@namespace SZUAbsolventenverein.Module.EventRegistration
@inherits ModuleBase
@ -16,13 +17,30 @@
<input id="name" class="form-control" @bind="@_name" required />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="location" HelpText="Enter a Location" ResourceKey="Location">Location: </Label>
<div class="col-sm-9">
<input id="location" class="form-control" @bind="@_location" required />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="eventdate" HelpText="Enter a Date" ResourceKey="EventDate">EventDate: </Label>
<div class="col-sm-9">
<!--<input id="eventdate" class="form-control" @bind="@_eventDate" required />-->
<InputDate id="eventdate" class="form-control" @bind-Value="@_eventDate" Type="InputDateType.DateTimeLocal" />
</div>
</div>
<div class="mb-1 align-items-center">
<Label Class="" For="description" HelpText="Enter a description" ResourceKey="Description">Description: </Label>
<RichTextEditor @ref="@RichTextEditorHtml" Content="@_description" Placeholder="Enter a description"/>
</div>
</div>
<button type="button" class="btn btn-success" @onclick="Save">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<br /><br />
@if (PageState.Action == "Edit")
{
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
}
</form>
@ -38,11 +56,17 @@
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
};
private RichTextEditor RichTextEditorHtml;
private ElementReference form;
private bool validated = false;
private int _id;
private string _name;
private string _description;
private DateTime _eventDate = DateTime.Now;
private string _location;
private string _createdby;
private DateTime _createdon;
private string _modifiedby;
@ -55,10 +79,14 @@
if (PageState.Action == "Edit")
{
_id = Int32.Parse(PageState.QueryString["id"]);
Event EventRegistration = await EventRegistrationService.GetEventRegistrationAsync(_id, ModuleState.ModuleId);
Event EventRegistration = await EventRegistrationService.GetEventAsync(_id, ModuleState.ModuleId);
if (EventRegistration != null)
{
_name = EventRegistration.Name;
_description = EventRegistration.Description;
_eventDate = EventRegistration.EventDate.ToLocalTime();
_location = EventRegistration.Location;
_createdby = EventRegistration.CreatedBy;
_createdon = EventRegistration.CreatedOn;
_modifiedby = EventRegistration.ModifiedBy;
@ -79,6 +107,10 @@
{
validated = true;
var interop = new Oqtane.UI.Interop(JSRuntime);
string content = await RichTextEditorHtml.GetHtml();
content = Utilities.FormatContent(content, PageState.Alias, "save");
if (await interop.FormValid(form))
{
if (PageState.Action == "Add")
@ -86,14 +118,20 @@
Event EventRegistration = new Event();
EventRegistration.ModuleId = ModuleState.ModuleId;
EventRegistration.Name = _name;
EventRegistration = await EventRegistrationService.AddEventRegistrationAsync(EventRegistration);
EventRegistration.Description = content;
EventRegistration.EventDate = _eventDate.ToUniversalTime();
EventRegistration.Location = _location;
EventRegistration = await EventRegistrationService.AddEventAsync(EventRegistration);
await logger.LogInformation("EventRegistration Added {EventRegistration}", EventRegistration);
}
else
{
Event EventRegistration = await EventRegistrationService.GetEventRegistrationAsync(_id, ModuleState.ModuleId);
Event EventRegistration = await EventRegistrationService.GetEventAsync(_id, ModuleState.ModuleId);
EventRegistration.Name = _name;
await EventRegistrationService.UpdateEventRegistrationAsync(EventRegistration);
EventRegistration.Description = content;
EventRegistration.EventDate = _eventDate.ToUniversalTime();
EventRegistration.Location = _location;
await EventRegistrationService.UpdateEventAsync(EventRegistration);
await logger.LogInformation("EventRegistration Updated {EventRegistration}", EventRegistration);
}
NavigationManager.NavigateTo(NavigateUrl());

View File

@ -16,26 +16,38 @@ else
<ActionLink Action="Add" Security="SecurityAccessLevel.Edit" Text="Add Event" ResourceKey="Add" />
<br />
<br />
<p>@Status</p>
@if (@_EventRegistrations.Count != 0)
{
<Pager Items="@_EventRegistrations">
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th style="width: 1px;">&nbsp;</th>
</Header>
<Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.EventRegistrationId.ToString())" ResourceKey="Edit" /></td>
<td><ActionDialog Header="Delete EventRegistration" Message="Are You Sure You Wish To Delete This EventRegistration?" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" ResourceKey="Delete" Id="@context.EventRegistrationId.ToString()" /></td>
<td>@context.Name</td>
@* @if(UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize)) { *@
<td><ActionLink Action="Details" Parameters="@($"id=" + context.EventRegistrationId.ToString())" ResourceKey="Details"/></td>
@* } *@
</Row>
</Pager>
<div class="event-list">
<div class="event-list">
@foreach (var context in _EventRegistrations)
{
<div class="event-card">
<h3>@context.Name</h3>
<p><strong>@Localizer["Date"]:</strong> @context.EventDate.ToLocalTime()</p>
<p><strong>@Localizer["Location"]:</strong> @context.Location</p>
<div class="event-actions">
<ActionLink Action="Edit"
Parameters="@($"id={context.EventId}")"
ResourceKey="Edit" />
<ActionDialog Action="Delete"
Security="SecurityAccessLevel.Edit"
Class="btn btn-danger"
OnClick="@(async () => await Delete(context))"
ResourceKey="Delete"
Id="@context.EventId.ToString()" />
<ActionLink Action="Details"
Parameters="@($"id={context.EventId}")"
ResourceKey="Details" />
</div>
</div>
}
</div>
</div>
}
else
{
@ -44,8 +56,6 @@ else
}
@code {
private string Status;
public override List<Resource> Resources => new List<Resource>()
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
@ -58,7 +68,7 @@ else
{
try
{
_EventRegistrations = await EventRegistrationService.GetEventRegistrationsAsync(ModuleState.ModuleId);
_EventRegistrations = await EventRegistrationService.GetEventsAsync(ModuleState.ModuleId);
}
catch (Exception ex)
{
@ -71,9 +81,9 @@ else
{
try
{
await EventRegistrationService.DeleteEventRegistrationAsync(EventRegistration.EventRegistrationId, ModuleState.ModuleId);
await EventRegistrationService.DeleteEventAsync(EventRegistration.EventId, ModuleState.ModuleId);
await logger.LogInformation("EventRegistration Deleted {EventRegistration}", EventRegistration);
_EventRegistrations = await EventRegistrationService.GetEventRegistrationsAsync(ModuleState.ModuleId);
_EventRegistrations = await EventRegistrationService.GetEventsAsync(ModuleState.ModuleId);
StateHasChanged();
}
catch (Exception ex)
@ -82,15 +92,4 @@ else
AddModuleMessage(Localizer["Message.DeleteError"], MessageType.Error);
}
}
private async Task Accept(Event eventRegistration)
{
Status = ("EventRegistration Accepted " + eventRegistration.Name);
await logger.LogInformation("EventRegistration Accepted {EventRegistration}", eventRegistration);
}
private void Reject()
{
Status = "EventRegistration Rejected 1";
}
}

View File

@ -9,9 +9,9 @@ namespace SZUAbsolventenverein.Module.EventRegistration
{
Name = "EventRegistration",
Description = "A module to manage registration for events",
Version = "1.0.0",
Version = "1.0.17",
ServerManagerType = "SZUAbsolventenverein.Module.EventRegistration.Manager.EventRegistrationManager, SZUAbsolventenverein.Module.EventRegistration.Server.Oqtane",
ReleaseVersions = "1.0.0",
ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,1.0.5,1.0.6,1.0.7,1.0.8,1.0.9,1.0.10,1.0.11,1.0.12,1.0.13,1.0.14,1.0.15,1.0.16,1.0.17",
Dependencies = "SZUAbsolventenverein.Module.EventRegistration.Shared.Oqtane",
PackageName = "SZUAbsolventenverein.Module.EventRegistration"
};