This commit is contained in:
2026-01-23 09:57:52 +01:00
commit 831badd188
136 changed files with 7705 additions and 0 deletions

View File

@ -0,0 +1,208 @@
@page "/"
<PageTitle>Home</PageTitle>
@page "/ballooning"
@using System.Text.Json
@using PdfMarker.Models
@using PdfMarker.Services
@inject PdfStorageService PdfStorage
@inject HttpClient Http
@inject IJSRuntime JS
@rendermode InteractiveServer
@*<RadzenSplitter Style="height: calc(100vh - 60px)">*@
<RadzenSplitter Style="height: 100vh">
<!-- SINISTRA -->
<RadzenSplitterPane Size="35%" Min="300px">
<RadzenCard Style="height:100%; display:flex; flex-direction:column;">
<!-- CONTENUTO SCROLLABILE -->
<div style="flex:1; overflow-y:auto; padding: 1rem;">
<h3>Documento</h3>
<RadzenUpload
ChooseText="Carica PDF"
Accept=".pdf"
Auto="true"
Url="/api/upload/pdf"
Progress="@OnUploadProgress"
Complete="@OnUploadComplete"
Style="width:100%" />
@if (pdf != null)
{
<h4 class="mt-3">Pallini</h4>
<RadzenButton
Icon="add_circle"
Text="Aggiungi pallino"
Click="@AddBalloon"
Style="margin-bottom:10px" />
<RadzenDataList Data="@balloons" TItem="BalloonVm">
<Template Context="b">
<div class="d-flex justify-content-between align-items-center mb-2">
<span>Pallino @b.Number - @b.Description</span>
<RadzenButton
Icon="delete"
ButtonStyle="ButtonStyle.Danger"
Size="ButtonSize.Small"
Click="@(() => RemoveBalloon(b))" />
</div>
</Template>
</RadzenDataList>
}
</div>
</RadzenCard>
</RadzenSplitterPane>
<!-- DESTRA -->
<RadzenSplitterPane>
<RadzenCard Style="height:100%">
<h3>Preview PDF</h3>
@if (pdf == null)
{
<p>Nessun documento caricato</p>
}
else
{
@*<iframe
src="@pdf?.PreviewUrl"
style="width:100%; height:100%; border:none;">
</iframe>
<canvas id="balloonCanvas"
width="100%"
height="100%"
style="
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
pointer-events:auto;
">
</canvas>*@
<div style="position:relative; height:100%; width:100%;">
<iframe
src="@pdf?.PreviewUrl"
style="width:100%; height:100%; border:none;">
</iframe>
<canvas id="balloonCanvas"
style="
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
pointer-events:auto;">
</canvas>
</div>
}
</RadzenCard>
</RadzenSplitterPane>
</RadzenSplitter>
@code {
UploadedPdf? pdf;
List<BalloonVm> balloons = new();
private ElementReference pdfPreview;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await JS.InvokeVoidAsync("balloonCanvas.resizeToIframe");
await DrawBalloons();
}
void OnUploadProgress(UploadProgressArgs args)
{
// opzionale
}
async Task OnUploadComplete(UploadCompleteEventArgs args)
{
var json = JsonSerializer.Deserialize<UploadedPdf>(args.RawResponse, new JsonSerializerOptions(){PropertyNameCaseInsensitive = true});
// 1⃣ Recupero risposta upload
var uploadResult = JsonSerializer.Deserialize<UploadResult>(
args.RawResponse,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
pdf = new UploadedPdf
{
FileName = json.File,
PreviewUrl = $"/uploads/{json.File}?v={DateTime.UtcNow.Ticks}"
};
// 2⃣ Chiamata API di process
var response = await Http.PostAsJsonAsync(
"/api/ballooning/process",
new AutoBalloonRequest
{
FileName = json.File
});
if (!response.IsSuccessStatusCode)
{
// TODO: gestione errore (toast/log)
return;
}
var autoResult = await response.Content
.ReadFromJsonAsync<AutoBalloonResult>();
// 3⃣ Aggiorna stato UI
balloons = autoResult?.Balloons ?? new();
// 4⃣ Disegno pallini
await DrawBalloons();
StateHasChanged();
/*var json = JsonSerializer.Deserialize<UploadedPdf>(args.RawResponse, new JsonSerializerOptions(){PropertyNameCaseInsensitive = true});
pdf = new UploadedPdf
{
FileName = json.File,
PreviewUrl = $"/uploads/{json.File}"
};
StateHasChanged();*/
}
void AddBalloon()
{
balloons.Add(new BalloonVm
{
Number = balloons.Count + 1
});
}
void RemoveBalloon(BalloonVm balloon)
{
balloons.Remove(balloon);
}
async Task DrawBalloons()
{
if (balloons == null || balloons.Count == 0)
{
await JS.InvokeVoidAsync("balloonCanvas.clear");
return;
}
var payload = balloons.Select(b => new
{
number = b.Number,
x = b.X,
y = b.Y,
selected = b.Selected
});
await JS.InvokeVoidAsync("balloonCanvas.draw", payload);
}
}