Add project files.

This commit is contained in:
OlgunR
2026-05-21 14:35:02 +02:00
parent b315aead20
commit dc551c2313
106 changed files with 303666 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
@page
<h2 class="content-block">About</h2>
<p class="content-block dx-card responsive-paddings">Use this area to provide additional information.</p>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace DXApp.TemplateKitProject.Pages
{
public class AboutModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,9 @@
@page
<h2 class="content-block">An error occurred while the server was processing your request.</h2>
<div class="content-block dx-card responsive-paddings">
To display detailed information about the error, set the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong> and restart the app.
<br /><br />
<strong>The Development environment should not be enabled for deployed applications</strong> because it provides users access to exceptions that can contain sensitive information.
</div>

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace DXApp.TemplateKitProject.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,28 @@
@page
@using DXApp.TemplateKitProject.Models
<h2 class="content-block">Home</h2>
@(Html.DevExtreme().DataGrid<SampleOrder>()
.ElementAttr(new { @class = "dx-card wide-card" })
.DataSource(d => d.Mvc().Controller("SampleData").LoadAction("Get").Key("OrderID"))
.ShowBorders(false)
.FilterRow(f => f.Visible(true))
.FocusedRowEnabled(true)
.FocusedRowIndex(0)
.ColumnAutoWidth(true)
.ColumnHidingEnabled(true)
.Columns(columns => {
columns.AddFor(m => m.OrderID);
columns.AddFor(m => m.OrderDate);
columns.AddFor(m => m.CustomerName);
columns.AddFor(m => m.ShipCountry);
columns.AddFor(m => m.ShipCity);
})
.Paging(p => p.PageSize(10))
.Pager(p => p
.ShowPageSizeSelector(true)
.AllowedPageSizes(new[] { 5, 10, 20 })
.ShowInfo(true)
)
)

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace DXApp.TemplateKitProject.Pages
{
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -0,0 +1,67 @@
@page
@model DXApp.TemplateKitProject.Pages.Invoices.UploadModel
@{
ViewData["Title"] = "PDF/A Upload";
}
<h2>PDF/A Rechnung hochladen</h2>
<form method="post" enctype="multipart/form-data">
<div class="mb-3">
<label asp-for="PdfFile" class="form-label">PDF/A-Datei auswählen</label>
<input asp-for="PdfFile" type="file" class="form-control" accept=".pdf" />
<span asp-validation-for="PdfFile" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Hochladen &amp; Analysieren</button>
</form>
@if (Model.ExtractionDone)
{
<hr />
<h4>Ergebnis</h4>
@if (!string.IsNullOrEmpty(Model.ErrorMessage))
{
<div class="alert alert-danger">@Model.ErrorMessage</div>
}
else if (Model.Result == null || !Model.Result.HasAttachments)
{
<div class="alert alert-warning">Keine Anhänge in der PDF gefunden.</div>
}
else
{
<div class="alert @(Model.Result.HasZugferdXml ? "alert-success" : "alert-warning")">
@if (Model.Result.HasZugferdXml)
{
<strong>✔ ZUGFeRD/Factur-X XML gefunden:</strong>
<span>@Model.Result.ZugferdXmlAttachment!.OriginalFileName</span>
}
else
{
<strong>⚠ Kein ZUGFeRD-XML gefunden.</strong>
}
</div>
<table class="table table-sm table-bordered">
<thead class="table-light">
<tr>
<th>Dateiname</th>
<th>Größe</th>
<th>ZUGFeRD?</th>
<th>Gespeichert unter</th>
</tr>
</thead>
<tbody>
@foreach (var a in Model.Result.Attachments)
{
<tr class="@(a.IsZugferdXml ? "table-success" : "")">
<td>@a.OriginalFileName</td>
<td>@($"{a.FileSizeBytes:N0}") Bytes</td>
<td>@(a.IsZugferdXml ? "✔ Ja" : "Nein")</td>
<td><small class="text-muted">@a.SavedFilePath</small></td>
</tr>
}
</tbody>
</table>
}
}

View File

@@ -0,0 +1,51 @@
using DXApp.TemplateKitProject.Models;
using DXApp.TemplateKitProject.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace DXApp.TemplateKitProject.Pages.Invoices;
public class UploadModel(
PdfAttachmentExtractorService extractor,
ILogger<UploadModel> logger) : PageModel
{
[BindProperty]
public IFormFile? PdfFile { get; set; }
public PdfExtractionResult? Result { get; private set; }
public bool ExtractionDone { get; private set; }
public string? ErrorMessage { get; private set; }
public void OnGet()
{ }
public async Task<IActionResult> OnPostAsync()
{
if (PdfFile is null || PdfFile.Length == 0)
{
ModelState.AddModelError(nameof(PdfFile), "Bitte eine PDF-Datei auswählen.");
return Page();
}
if (!PdfFile.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
{
ModelState.AddModelError(nameof(PdfFile), "Nur PDF-Dateien sind erlaubt.");
return Page();
}
ExtractionDone = true;
try
{
await using var stream = PdfFile.OpenReadStream();
Result = extractor.ExtractAttachments(stream, PdfFile.FileName);
}
catch (Exception ex)
{
logger.LogError(ex, "Fehler beim Verarbeiten der Datei '{FileName}'.", PdfFile.FileName);
ErrorMessage = $"Fehler beim Verarbeiten der Datei: {ex.Message}";
}
return Page();
}
}

View File

@@ -0,0 +1,203 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DXApp.TemplateKitProject</title>
@* Custom theme with a color swatch *@
@* Docs: https://js.devexpress.com/DevExtreme/Guide/Themes_and_Styles/Predefined_Themes/#Color_Swatches *@
<link href="~/css/devextreme/dx.fluent.blue.light.css" rel="stylesheet" />
<link rel="stylesheet" href="~/css/Site.css" />
<script src="~/js/devextreme/jquery.js"></script>
<script src="~/js/devextreme/dx.all.js"></script>
<script src="~/js/devextreme/aspnet/dx.aspnet.mvc.js"></script>
<script src="~/js/devextreme/aspnet/dx.aspnet.data.js"></script>
</head>
<body class="dx-viewport">
<div id="app-side-nav-outer-toolbar">
<div class="layout-header">
@(Html.DevExtreme().Toolbar()
.Items(items => {
items.Add()
.Widget(w => w
.Button()
.Icon("menu")
.OnClick("DevExtremeAspNetCoreAppMatRazorPages.onMenuButtonClick")
)
.Location(ToolbarItemLocation.Before)
.CssClass("menu-button");
items.Add()
.Html("<div>DXApp.TemplateKitProject</div>")
.Location(ToolbarItemLocation.Before)
.CssClass("header-title");
})
)
</div>
<div class="layout-body layout-body-hidden">
@(Html.DevExtreme().Drawer()
.ID("layout-drawer")
.Position(DrawerPosition.Left)
.Opened(new JS("DevExtremeAspNetCoreAppMatRazorPages.restoreDrawerOpened()"))
.Content(@<text>
<div id="layout-drawer-scrollview" class="with-footer">
<div class="content">
@RenderBody()
</div>
<div>
<div class="content-footer">
<div id="footer">
Copyright (c) 2000-@DateTime.Now.Year Developer Express Inc.
<br />
All trademarks or registered trademarks are property of their respective owners.
</div>
</div>
</div>
</div>
</text>)
.Template(new TemplateName("navigation-menu"))
)
</div>
</div>
@using(Html.DevExtreme().NamedTemplate("navigation-menu")) {
<div class="menu-container dx-swatch-additional">
@functions{
string GetUrl(string pageName) => Url.Page(pageName);
string GetCurrentUrl() => Url.Page(ViewContext.RouteData.Values["page"].ToString());
bool IsCurrentUrl(string pageName) => GetUrl(pageName) == GetCurrentUrl();
}
@(Html.DevExtreme().TreeView()
.Items(items =>
{
items.Add()
.Text("Home")
.Icon("home")
.Option("path", GetUrl("/Index"))
.Selected(IsCurrentUrl("/Index"));
items.Add()
.Text("About")
.Icon("info")
.Option("path", GetUrl("/About"))
.Selected(IsCurrentUrl("/About"));
})
.ExpandEvent(TreeViewExpandEvent.Click)
.SelectionMode(NavSelectionMode.Single)
.SelectedExpr("selected")
.FocusStateEnabled(false)
.Width(250)
.OnItemClick("DevExtremeAspNetCoreAppMatRazorPages.onTreeViewItemClick")
)
</div>
}
<script>
var DevExtremeAspNetCoreAppMatRazorPages = (function() {
var DRAWER_OPENED_KEY = "DevExtremeAspNetCoreAppMatRazorPages-drawer-opened";
var breakpoints = {
xSmallMedia: window.matchMedia("(max-width: 599.99px)"),
smallMedia: window.matchMedia("(min-width: 600px) and (max-width: 959.99px)"),
mediumMedia: window.matchMedia("(min-width: 960px) and (max-width: 1279.99px)"),
largeMedia: window.matchMedia("(min-width: 1280px)")
};
function getDrawer() {
return $("#layout-drawer").dxDrawer("instance");
}
function restoreDrawerOpened() {
var isLarge = breakpoints.largeMedia.matches;
if(!isLarge)
return false;
var state = sessionStorage.getItem(DRAWER_OPENED_KEY);
if(state === null)
return isLarge;
return state === "true";
}
function saveDrawerOpened() {
sessionStorage.setItem(DRAWER_OPENED_KEY, getDrawer().option("opened"));
}
function updateDrawer() {
var isXSmall = breakpoints.xSmallMedia.matches,
isLarge = breakpoints.largeMedia.matches;
getDrawer().option({
openedStateMode: isLarge ? "shrink" : "overlap",
revealMode: isXSmall ? "slide" : "expand",
minSize: isXSmall ? 0 : 60,
shading: !isLarge,
});
}
function init() {
$("#layout-drawer-scrollview").dxScrollView({ direction: "vertical" });
$.each(breakpoints, function(_, size) {
size.addListener(function(e) {
if(e.matches)
updateDrawer();
});
});
updateDrawer();
$('.layout-body').removeClass('layout-body-hidden');
}
function navigate(url, delay) {
if(url)
setTimeout(function() { location.href = url }, delay);
}
function onMenuButtonClick() {
getDrawer().toggle();
saveDrawerOpened();
}
function onTreeViewItemClick(e) {
var drawer = getDrawer();
var savedOpened = restoreDrawerOpened();
var actualOpened = drawer.option("opened");
if(!actualOpened) {
drawer.show();
} else {
var willHide = !savedOpened || !breakpoints.largeMedia.matches;
var willNavigate = !e.itemData.selected;
if(willHide)
drawer.hide();
if(willNavigate)
navigate(e.itemData.path, willHide ? 400 : 0);
}
}
return {
init: init,
restoreDrawerOpened: restoreDrawerOpened,
onMenuButtonClick: onMenuButtonClick,
onTreeViewItemClick: onTreeViewItemClick
};
})();
document.addEventListener("DOMContentLoaded", function documentReady() {
this.removeEventListener("DOMContentLoaded", documentReady);
DevExtremeAspNetCoreAppMatRazorPages.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,4 @@
@using DXApp.TemplateKitProject
@namespace DXApp.TemplateKitProject.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using DevExtreme.AspNet.Mvc

View File

@@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}