feat: implementiert PDF-Generierung mit Hintergrundbild und Dokumentation
This commit is contained in:
@@ -76,13 +76,13 @@ else
|
||||
@foreach (var line in (_item.Description?.Replace("\t", " ").Split('\n') ?? Array.Empty<string>()))
|
||||
{
|
||||
<div class="hof-description-line">@line</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-wrap gap-3 mt-5 no-print">
|
||||
<button type="button" class="btn btn-primary btn-lg px-4 shadow-sm" @onclick="PrintPage">
|
||||
<i class="oi oi-print me-2"></i> Als PDF speichern
|
||||
<button type="button" class="btn btn-primary btn-lg px-4 shadow-sm" @onclick="ShowPdfPreview">
|
||||
<i class="oi oi-eye me-2"></i> PDF Vorschau
|
||||
</button>
|
||||
|
||||
@if (!string.IsNullOrEmpty(_item.Link))
|
||||
@@ -134,6 +134,28 @@ else
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if (_showPdfModal)
|
||||
{
|
||||
<div class="modal fade show" style="display: block; background: rgba(0,0,0,0.6); z-index: 1050;" tabindex="-1">
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered" style="max-width: 90vw; height: 90vh;">
|
||||
<div class="modal-content" style="height: 90vh;">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><i class="oi oi-document me-2"></i> PDF Vorschau</h5>
|
||||
<button type="button" class="btn-close" @onclick="ClosePdfPreview"></button>
|
||||
</div>
|
||||
<div class="modal-body p-0" style="flex: 1; overflow: hidden;">
|
||||
<iframe src="@_pdfPreviewUrl" style="width: 100%; height: 100%; border: none;"></iframe>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" @onclick="ClosePdfPreview">Schließen</button>
|
||||
<button type="button" class="btn btn-primary" @onclick="DownloadPdf">
|
||||
<i class="oi oi-data-transfer-download me-2"></i> Herunterladen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
<style>
|
||||
@@ -214,6 +236,8 @@ else
|
||||
|
||||
private bool _showReportModal = false;
|
||||
private string _reportReason = "";
|
||||
private bool _showPdfModal = false;
|
||||
private string _pdfPreviewUrl = "";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
@@ -239,9 +263,22 @@ else
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PrintPage()
|
||||
private void ShowPdfPreview()
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync("window.print");
|
||||
_pdfPreviewUrl = $"/api/HallOfFamePdf?moduleid={ModuleState.ModuleId}";
|
||||
_showPdfModal = true;
|
||||
}
|
||||
|
||||
private void ClosePdfPreview()
|
||||
{
|
||||
_showPdfModal = false;
|
||||
_pdfPreviewUrl = "";
|
||||
}
|
||||
|
||||
private async Task DownloadPdf()
|
||||
{
|
||||
var url = $"/api/HallOfFamePdf?moduleid={ModuleState.ModuleId}&download=true";
|
||||
await JSRuntime.InvokeVoidAsync("eval", $"var a = document.createElement('a'); a.href = '{url}'; a.download = 'HallOfFame.pdf'; document.body.appendChild(a); a.click(); document.body.removeChild(a);");
|
||||
}
|
||||
|
||||
private void ShowReportModal()
|
||||
|
||||
@@ -79,10 +79,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="button" class="btn btn-secondary me-2" @onclick="@(() => Save("Draft"))" disabled="@_uploading">Als Entwurf speichern</button>
|
||||
<button type="button" class="btn btn-primary" @onclick="@(() => Save("Published"))" disabled="@_uploading">Veröffentlichen</button>
|
||||
<NavLink class="btn btn-link ms-2" href="@NavigateUrl()">Abbrechen</NavLink>
|
||||
<div class="mt-4 d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<button type="button" class="btn btn-secondary me-2" @onclick="@(() => Save("Draft"))" disabled="@_uploading">Als Entwurf speichern</button>
|
||||
<button type="button" class="btn btn-primary" @onclick="@(() => Save("Published"))" disabled="@_uploading">Veröffentlichen</button>
|
||||
<NavLink class="btn btn-link ms-2" href="@NavigateUrl()">Abbrechen</NavLink>
|
||||
</div>
|
||||
@if (PageState.Action == "Edit")
|
||||
{
|
||||
<button type="button" class="btn btn-outline-danger" @onclick="DeleteEntry" disabled="@_uploading">
|
||||
<i class="oi oi-trash me-1"></i> Eintrag löschen
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
<br /><br />
|
||||
@@ -265,4 +273,18 @@
|
||||
AddModuleMessage(Localizer["Message.SaveError"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteEntry()
|
||||
{
|
||||
try
|
||||
{
|
||||
await HallOfFameService.DeleteHallOfFameAsync(_id, ModuleState.ModuleId);
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting HallOfFame {Error}", ex.Message);
|
||||
AddModuleMessage("Fehler beim Löschen des Eintrags.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,8 @@ else
|
||||
{
|
||||
try
|
||||
{
|
||||
_HallOfFames = await HallOfFameService.GetHallOfFamesAsync(ModuleState.ModuleId);
|
||||
var allEntries = await HallOfFameService.GetHallOfFamesAsync(ModuleState.ModuleId);
|
||||
_HallOfFames = allEntries.Where(i => i.Status == "Published").ToList();
|
||||
|
||||
if (PageState.User != null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user