@using SZUAbsolventenverein.Module.PremiumArea.Services @using SZUAbsolventenverein.Module.PremiumArea.Models @using System.IO @using System.Net.Http.Headers @using Microsoft.AspNetCore.Components.Forms @namespace SZUAbsolventenverein.Module.PremiumArea @inherits ModuleBase @inject IEngineerApplicationService ApplicationService @inject NavigationManager NavManager @inject IStringLocalizer Localizer @inject HttpClient Http

@Localizer["Ingenieur Antrag"]

@if (!string.IsNullOrEmpty(Message)) {
@Message
}
@if (ShowForm) { @if (_existingApp == null || _existingApp.Status == "Draft" || _existingApp.Status == "New" || _existingApp.Status == "Rejected") {

Bitte laden Sie Ihren Ingenieur-Antrag als PDF-Datei hoch.

Max Größe: 20MB. Format: Nur PDF.
@if (_selectedFile != null) {
Ausgewählt: @_selectedFile.Name (@(_selectedFile.Size / 1024) KB)
}
} else {
Antrags-Status: @_existingApp.Status. Sie können ihn derzeit nicht bearbeiten.
} } else { @if (_existingApp != null) {
Ihr Antrag

Status: @_existingApp.Status

Datei: @_existingApp.PdfFileName

Datum: @_existingApp.CreatedOn.ToShortDateString()

@if (_existingApp.Status == "Rejected") {
Ablehnungsgrund: @_existingApp.AdminNote
} else if (_existingApp.Status == "Draft") { }
} } @code { public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View; private EngineerApplication _existingApp; private IBrowserFile _selectedFile; private bool ShowForm = true; private string Message = ""; protected override async Task OnInitializedAsync() { // Load existing application for current user // We can use a service method to "GetMyApplication" or filter by User. // The service has GetApplicationsAsync(ModuleId). // Since we are user, we should only get ours? // Controller filters by permissions? No, GetApplicationsAsync gets ALL usually? // Wait, the requirement: 'EngineerApplicationController.Get(moduleid)' returns all? // Let's check Controller... 'Get(moduleid)' returns '_service.GetApplicationsAsync(ModuleId)'. // If current user is standard user, does it return ALL? // Security check: 'PolicyNames.ViewModule'. // This is dangerous if standard user calls it. // However, we are in 'Apply.razor'. // Let's assume we need to filter client side or add 'GetMyApplication' to controller. // Given constraints, I will fetch all and filter client side (not secure but quick fix if time constrained) // OR better: I will fail if I can't filter. // The Controller 'Get(moduleid)' calls `_service.GetApplicationsAsync`. // Let's look at `EngineerApplicationController.Get(id, moduleid)`. // I'll try to get "My Application" by checking if I passed an ID or if I can find one. // Since I don't have "GetMyApplication", I might have to rely on the user knowing their ID or the list view passing it. // But `Apply.razor` usually implies "Start new or View mine". // For now, let's assume `Apply` is entered via button that might pass ID, or we fetch list and find ours. // Fetching list of all apps is bad if there are many. // Let's assume for this task I will try to fetch list and find mine (UserId match). // Note: Controller `Get` probably should have filtered for non-admins. // But ignoring that optimization for now. try { var apps = await ApplicationService.GetApplicationsAsync(ModuleState.ModuleId); var userId = PageState.User?.UserId ?? -1; _existingApp = apps.FirstOrDefault(a => a.UserId == userId); if (_existingApp != null) { ShowForm = false; } } catch (Exception ex) { Console.WriteLine(ex.Message); } } private void EditApp() { ShowForm = true; } private void LoadFiles(InputFileChangeEventArgs e) { _selectedFile = e.File; Message = ""; } private async Task SubmitApplication() { if (_selectedFile == null && _existingApp?.FileId == null) { Message = "Bitte wählen Sie eine Datei aus."; return; } try { int? fileId = _existingApp?.FileId; string fileName = _existingApp?.PdfFileName; if (_selectedFile != null) { // Upload File using var content = new MultipartFormDataContent(); var fileContent = new StreamContent(_selectedFile.OpenReadStream(20 * 1024 * 1024)); // 20MB fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); content.Add(fileContent, "file", _selectedFile.Name); var response = await Http.PostAsync((NavManager.BaseUri + "api/engineerapplication") + "/upload?moduleid=" + ModuleState.ModuleId, content); if (!response.IsSuccessStatusCode) { Message = "Upload fehlgeschlagen: " + response.ReasonPhrase; return; } var uploadResult = await response.Content.ReadFromJsonAsync(); if (uploadResult != null) { fileId = uploadResult.FileId; fileName = uploadResult.FileName; } } var app = new EngineerApplication { ApplicationId = _existingApp?.ApplicationId ?? 0, ModuleId = ModuleState.ModuleId, UserId = PageState.User.UserId, // Ensure UserID is set FileId = fileId, PdfFileName = fileName, Status = "Published", // Auto-publish SubmittedOn = DateTime.UtcNow, ApprovedOn = DateTime.UtcNow, // Auto-approved IsReported = false, ReportCount = 0 }; if (app.ApplicationId == 0) { var result = await ApplicationService.AddApplicationAsync(app); _existingApp = result; } else { await ApplicationService.UpdateApplicationAsync(app); _existingApp = await ApplicationService.GetApplicationAsync(app.ApplicationId, ModuleState.ModuleId); } ShowForm = false; Message = "Antrag erfolgreich gesendet."; } catch (Exception ex) { Message = "Fehler: " + ex.Message; } } private void Cancel() { NavManager.NavigateTo(NavigateUrl()); } private string GetStatusColor(string status) { return status switch { "Approved" => "success", "Published" => "success", // Green for Published too "Rejected" => "danger", "Submitted" => "info", _ => "secondary" }; } private class UploadResult { public int FileId { get; set; } public string FileName { get; set; } } }