12 Commits
ci ... dev

Author SHA1 Message Date
eed265776b Anmelde Button und status sichtbarer 2025-07-14 07:42:51 +02:00
f92c163e2c COSMETIC: Comment out unused vars, remove not released versions and update dependencies 2025-06-21 14:44:25 -07:00
106851fe94 Migrations Down Skript repariert, Eventregistrationservice import hinzugefügt 2025-06-21 00:31:32 +02:00
5f4794e42f Down Methode geschreiben für DropClumn von 3 Spalten 2025-06-16 10:59:54 +02:00
91f1121736 Merge branch 'dev' of https://git.kocoder.xyz/Diplomarbeit-Absolventenverein/Module.EventRegistration into dev 2025-06-16 09:10:08 +02:00
396e531b56 Migrations Down Skript repariert, Eventregistrationservice import hinzugefügt 2025-06-16 09:09:22 +02:00
29c93baa6d Event-Details: Erstellt von und bearbeitet von Felder gelöscht.
Closes: #12
Changed-Files: Details.razor
2025-06-02 12:45:46 +00:00
4f7e846661 New: Event und Response Export Methode
Changed: EventRegistrationManager.cs
Co-Author: Konstantin Hintermayer
2025-06-02 11:52:37 +02:00
f63681bce5 Update: Save DateTime's as UTC and parse to LocalTime at the client. 2025-05-30 23:54:11 +02:00
f280e49d96 Event: Add description, date and location.
Changed Files: Model >Event.cs & Client > Module > Edit.razor & Detail.razor
2025-05-30 23:39:32 +02:00
527f9aadc6 EventRegistrationService: Add Notifications on subscribe/unsubscribe.
Changed: EventRegistrationService.cs
Co-Author: Florian Edlmayer <florian.edlmayer@edu.szu.at>
2025-05-30 09:38:09 +02:00
287b932444 Event: Add Description, Date and Location Column.
Changed: 01000005_AddDescriptionDateTimeLocation.cs
Co-Author: Florian Edlmayer <florian.edlmayer@edu.szu.at>
2025-05-30 08:35:06 +02:00
14 changed files with 169 additions and 160 deletions

View File

@ -1,50 +0,0 @@
on:
push:
branches:
- main
- ci
pull_request:
branches:
- main
- ci
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout Module
uses: https://github.com/actions/checkout@v4
with:
path: Module.EventRegistration
- name: Checkout Oqtane
uses: https://github.com/actions/checkout@v4
with:
repository: Diplomarbeit-Absolventenverein/oqtane.framework
path: oqtane.framework
ref: v6.1.1
- name: Setup Dotnet SDK
uses: https://github.com/actions/setup-dotnet@v4
with:
dotnet-version: '9.x'
# - name: Setup NuGet
# uses: https://github.com/nuget/setup-nuget@v2
# with:
# nuget-api-key: ${{ secrets.NuGetAPIKey }}
# nuget-version: '5.x'
- name: Build Oqtane
run: dotnet build ./oqtane.framework/Oqtane.sln --configuration Debug
- name: Build Module
run: dotnet build ./Module.EventRegistration/SZUAbsolventenverein.Module.EventRegistration.sln --configuration Release
- name: Test
run: dotnet test ./Module.EventRegistration/SZUAbsolventenverein.Module.EventRegistration.sln --configuration Release --no-build
- name: Create Release
uses: akkuman/gitea-release-action@v1
env:
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
with:
body: "Test-release"
draft: true
files: |-
./**/*.nupkg
./*.nupkg

View File

@ -1,35 +0,0 @@
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
release:
types:
- published
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: https://github.com/actions/checkout@v4
- name: Verify commit exists in origin/main
run: |
git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/*
git branch --remote --contains | grep origin/main
- name: Set VERSION variable from tag
run: echo "VERSION=${GITEA_REF/refs\/tags\/v/}" >> $GITEA_ENV
- name: Setup Dotnet SDK
uses: https://github.com/actions/setup-dotnet@v4
- name: Build
run: dotnet build --configuration Release /p:Version=${VERSION}
- name: Test
run: dotnet test --configuration Release /p:Version=${VERSION} --no-build
- name: Pack
run: dotnet pack --configuration Release /p:Version=${VERSION} --no-build --output .
- uses: https://github.com/actions/upload-artifact@v4
with:
name: nuget
if-no-files-found: error
retention-days: 7
path: ./*.nupkg

View File

@ -11,31 +11,36 @@
<h3>Anmeldung zum Event</h3>
<p>Willst du am Event (@_name) teilnehmen?</p>
<span>@_eventDate - @_location</span>
<div>
<p>@_description</p>
</div>
@if (PageState.User != null) {
@if (Status != null)
{
<p class="mt-3"><strong>Status:</strong>
<p class="mt-3 Ueberschrift">
<strong>Status: </strong>
@if (Status == true)
{
@Localizer["Zusage"]
<button class="btn btn-danger" @onclick="Absage">@Localizer["Absagen"]</button>
<span class="Underline">@Localizer["Zugesagt"]</span>
<br /> <button class="btn mt-1 AbsageBtn" @onclick="Absage">@Localizer["Absagen"]</button>
} else
{
@Localizer["Absage"]
<button class="btn btn-success" @onclick="Zusage">@Localizer["Zusagen"]</button>
<span class="Underline">@Localizer["Abgesagt"]</span>
<br /> <button class="btn mt-1 ZusageBtn" @onclick="Zusage">@Localizer["Zusagen"]</button>
}
</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>
<button class="AbsageBtn" @onclick="Zusage">@Localizer["Zusagen"]</button>
<button class="ZusageBtn" @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> <Login />
<p class="mt-3">Um dich für dieses Event zu registrieren, muss man sich zuerst anmelden.</p> <Login /><Register />
}
@code {
@ -50,11 +55,15 @@
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 _description;
private DateTime _eventDate;
private string _location;
private string _createdby;
private DateTime _createdon;
private string _modifiedby;
@ -103,10 +112,13 @@
if (currentEvent != null)
{
_name = currentEvent.Name;
_description = currentEvent.Description;
_eventDate = currentEvent.EventDate.ToLocalTime();
_location = currentEvent.Location;
_createdby = currentEvent.CreatedBy;
_createdon = currentEvent.CreatedOn;
_createdon = currentEvent.CreatedOn.ToLocalTime();
_modifiedby = currentEvent.ModifiedBy;
_modifiedon = currentEvent.ModifiedOn;
_modifiedon = currentEvent.ModifiedOn.ToLocalTime();
}
if(rsvp != null)
@ -121,41 +133,4 @@
AddModuleMessage(Localizer["Message.LoadError"], MessageType.Error);
}
}
private async Task Save()
{
try
{
validated = true;
var interop = new Oqtane.UI.Interop(JSRuntime);
if (await interop.FormValid(form))
{
if (PageState.Action == "Add")
{
Event EventRegistration = new Event();
EventRegistration.ModuleId = ModuleState.ModuleId;
EventRegistration.Name = _name;
EventRegistration = await EventRegistrationService.AddEventAsync(EventRegistration);
await logger.LogInformation("EventRegistration Added {EventRegistration}", EventRegistration);
}
else
{
Event EventRegistration = await EventRegistrationService.GetEventAsync(_id, ModuleState.ModuleId);
EventRegistration.Name = _name;
await EventRegistrationService.UpdateEventAsync(EventRegistration);
await logger.LogInformation("EventRegistration Updated {EventRegistration}", EventRegistration);
}
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
AddModuleMessage(Localizer["Message.SaveValidation"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving EventRegistration {Error}", ex.Message);
AddModuleMessage(Localizer["Message.SaveError"], MessageType.Error);
}
}
}

View File

@ -16,13 +16,31 @@
<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="description" HelpText="Enter a description" ResourceKey="Description">Description: </Label>
<div class="col-sm-9">
<input id="description" class="form-control" @bind="@_description" 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 />
</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>
<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>
@ -43,6 +61,10 @@
private int _id;
private string _name;
private string _description;
private DateTime _eventDate;
private string _location;
private string _createdby;
private DateTime _createdon;
private string _modifiedby;
@ -59,6 +81,10 @@
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;
@ -86,6 +112,9 @@
Event EventRegistration = new Event();
EventRegistration.ModuleId = ModuleState.ModuleId;
EventRegistration.Name = _name;
EventRegistration.Description = _description;
EventRegistration.EventDate = _eventDate.ToUniversalTime();
EventRegistration.Location = _location;
EventRegistration = await EventRegistrationService.AddEventAsync(EventRegistration);
await logger.LogInformation("EventRegistration Added {EventRegistration}", EventRegistration);
}
@ -93,6 +122,9 @@
{
Event EventRegistration = await EventRegistrationService.GetEventAsync(_id, ModuleState.ModuleId);
EventRegistration.Name = _name;
EventRegistration.Description = _description;
EventRegistration.EventDate = _eventDate.ToUniversalTime();
EventRegistration.Location = _location;
await EventRegistrationService.UpdateEventAsync(EventRegistration);
await logger.LogInformation("EventRegistration Updated {EventRegistration}", EventRegistration);
}

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.5",
ServerManagerType = "SZUAbsolventenverein.Module.EventRegistration.Manager.EventRegistrationManager, SZUAbsolventenverein.Module.EventRegistration.Server.Oqtane",
ReleaseVersions = "1.0.0",
ReleaseVersions = "1.0.0,1.0.5",
Dependencies = "SZUAbsolventenverein.Module.EventRegistration.Shared.Oqtane",
PackageName = "SZUAbsolventenverein.Module.EventRegistration"
};

View File

@ -13,8 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.5" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.3" />
<PackageReference Include="System.Net.Http.Json" Version="9.0.3" />

View File

@ -1,9 +1,5 @@
TargetFramework=$1
ProjectName=$2
# chmod +x ../../oqtane.framework/Oqtane.Package/nuget.exe
# "../../oqtane.framework/Oqtane.Package/nuget.exe" pack %ProjectName%.nuspec -Properties targetframework=%TargetFramework%;projectname=%ProjectName%
# https://learn.microsoft.com/en-us/nuget/reference/dotnet-commands
dotnet pack SZUAbsolventenverein.Module.EventRegistration.Package.csproj --no-build
#cp -f "*.nupkg" "..\..\oqtane.framework\Oqtane.Server\Packages\"
"..\..\oqtane.framework\oqtane.package\nuget.exe" pack %ProjectName%.nuspec -Properties targetframework=%TargetFramework%;projectname=%ProjectName%
cp -f "*.nupkg" "..\..\oqtane.framework\Oqtane.Server\Packages\"

View File

@ -40,10 +40,19 @@ namespace SZUAbsolventenverein.Module.EventRegistration.Manager
{
// TODO: Export event Responses as well.
string content = "";
List<Models.Event> EventRegistrations = _EventRepository.GetEvents(module.ModuleId).ToList();
if (EventRegistrations != null)
List<object> exportData = new List<object>();
foreach (var events in _EventRepository.GetEvents(module.ModuleId))
{
content = JsonSerializer.Serialize(EventRegistrations);
var responses = _ResponseRepository.GetResponses(events.EventId, module.ModuleId);
exportData.Add(new
{
Event = events,
Responses = responses.ToList()
});
};
if (exportData != null)
{
content = JsonSerializer.Serialize(exportData);
}
return content;
}

View File

@ -26,10 +26,10 @@ namespace SZUAbsolventenverein.Module.EventRegistration.Migrations
protected override void Down(MigrationBuilder migrationBuilder)
{
var entityBuilder = new EventEntityBuilder(migrationBuilder, ActiveDatabase);
entityBuilder.Drop();
var entityBuilder2 = new EventResponseEntityBuilder(migrationBuilder, ActiveDatabase);
entityBuilder2.Drop();
var responseEB = new EventResponseEntityBuilder(migrationBuilder, ActiveDatabase);
responseEB.Drop();
var eventEB = new EventEntityBuilder(migrationBuilder, ActiveDatabase);
eventEB.Drop();
}
}
}

View File

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Databases.Interfaces;
using Oqtane.Migrations;
using System;
using SZUAbsolventenverein.Module.EventRegistration.Migrations.EntityBuilders;
using SZUAbsolventenverein.Module.EventRegistration.Repository;
namespace SZUAbsolventenverein.Module.EventRegistration.Migrations
{
[DbContext(typeof(EventRegistrationContext))]
[Migration("SZUAbsolventenverein.Module.EventRegistration.01.00.00.05")]
public class AddDescriptionDateTimeLocation : MultiDatabaseMigration
{
public AddDescriptionDateTimeLocation(IDatabase database) : base(database)
{
}
protected override void Up(MigrationBuilder migrationBuilder)
{
var entityBuilder = new EventEntityBuilder(migrationBuilder, ActiveDatabase);
entityBuilder.AddMaxStringColumn("Description", false, true, ""); // Contents for RichTextEditor
entityBuilder.AddDateTimeColumn("EventDate", false, new DateTime()); // DateTime for the event
entityBuilder.AddStringColumn("Location", 100, false, true, ""); // Location of the event
}
protected override void Down(MigrationBuilder migrationBuilder)
{
var entityBuilder = new EventEntityBuilder(migrationBuilder, ActiveDatabase);
entityBuilder.DropColumn("Description"); // RichTextEditor
entityBuilder.DropColumn("EventDate"); // DateTime
entityBuilder.DropColumn("Location"); // Location 0
}
}
}

View File

@ -19,10 +19,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.5" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.5" />
</ItemGroup>
<ItemGroup>

View File

@ -6,6 +6,7 @@ using Oqtane.Enums;
using Oqtane.Extensions;
using Oqtane.Infrastructure;
using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Security;
using Oqtane.Shared;
using SZUAbsolventenverein.Module.EventRegistration.Models;
@ -17,15 +18,19 @@ namespace SZUAbsolventenverein.Module.EventRegistration.Services
{
private readonly IEventRepository _EventRepository;
private readonly IResponseRepository _ResponseRepository;
private readonly INotificationRepository _NotificationRepository;
private readonly IUserRepository _UserRepository;
private readonly IUserPermissions _userPermissions;
private readonly ILogManager _logger;
private readonly IHttpContextAccessor _accessor;
private readonly Alias _alias;
public ServerEventRegistrationService(IEventRepository EventRepository, IResponseRepository ResponseRepository, IUserPermissions userPermissions, ITenantManager tenantManager, ILogManager logger, IHttpContextAccessor accessor)
public ServerEventRegistrationService(IEventRepository EventRepository, IResponseRepository ResponseRepository, INotificationRepository NotificationRepository, IUserRepository UserRepository, IUserPermissions userPermissions, ITenantManager tenantManager, ILogManager logger, IHttpContextAccessor accessor)
{
_EventRepository = EventRepository;
_ResponseRepository = ResponseRepository;
_NotificationRepository = NotificationRepository;
_UserRepository = UserRepository;
_userPermissions = userPermissions;
_logger = logger;
_accessor = accessor;
@ -52,6 +57,12 @@ namespace SZUAbsolventenverein.Module.EventRegistration.Services
if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, Response.ModuleId, PermissionNames.View))
{
Response = _ResponseRepository.AddResponse(Response);
Event currentEvent = _EventRepository.GetEvent(Response.EventRegistrationId);
string subject = Response.ResponseType ? $"Du bist erfolgreich für '{currentEvent.Name}' Registriert worden." : $"Du hast erfolgreich für '{currentEvent.Name}' abgesagt.";
string body = "Hier kann man die Infos des Events hineinpacken (HTML ist erlaubt)";
SendEventResponseNotification(subject, body);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "EventRegistration Added {NewEvent}", Response);
}
else
@ -68,6 +79,12 @@ namespace SZUAbsolventenverein.Module.EventRegistration.Services
if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, Response.ModuleId, PermissionNames.View))
{
Response = _ResponseRepository.UpdateResponse(Response);
Event currentEvent = _EventRepository.GetEvent(Response.EventRegistrationId);
string subject = Response.ResponseType ? $"Du bist erfolgreich für '{currentEvent.Name}' Registriert worden." : $"Du hast erfolgreich für '{currentEvent.Name}' abgesagt.";
string body = "Hier kann man die Infos des Events hineinpacken (HTML ist erlaubt)";
SendEventResponseNotification(subject, body);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "EventRegistration Added {NewEvent}", Response);
}
else
@ -211,7 +228,11 @@ namespace SZUAbsolventenverein.Module.EventRegistration.Services
}*/
private void SendEventResponseNotification(string subject, string body)
{
User user = _UserRepository.GetUser(_accessor.HttpContext.User.UserId());
Notification notification = new Notification(_alias.SiteId, user, subject, body);
_NotificationRepository.AddNotification(notification);
}
}
}

View File

@ -1 +1,23 @@
/* Module Custom Styles */
/* Module Custom Styles */
.AbsageBtn {
background-color: #e63946; /* sch<63>nes kr<6B>ftiges Rot */
color: white;
}
.AbsageBtn:hover {
background-color: #ae262f
}
.ZusageBtn {
background-color: #2a9d8f; /* angenehmes Gr<47>n */
color: white;
}
.ZusageBtn:hover {
background-color: #20776d
}
.Ueberschrift {
font-size: 1.5rem;
}
.Underline {
text-decoration: underline;
}

View File

@ -13,6 +13,10 @@ namespace SZUAbsolventenverein.Module.EventRegistration.Models
public int ModuleId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime EventDate { get; set; }
public string Location { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public string ModifiedBy { get; set; }