Eerste commit
This commit is contained in:
@@ -0,0 +1,338 @@
|
||||
@page "/beheer"
|
||||
@attribute [Authorize]
|
||||
@inject BeheerService Beheerkant
|
||||
@rendermode InteractiveServer
|
||||
|
||||
<PageTitle>Beheer - MijnBesluit</PageTitle>
|
||||
|
||||
@* De beheerpagina. Twee handelingen: een overlijden terugdraaien dat ten onrechte is bevestigd,
|
||||
en een samenvoeging terugdraaien die niet had gemoeten.
|
||||
|
||||
Zie BeheerService voor waarom er niet meer op staat. Kort: een beheerder kan geen kluis
|
||||
openen en kan niet op naam zoeken. *@
|
||||
|
||||
@if (!Magdit)
|
||||
{
|
||||
<h1>Niet gevonden</h1>
|
||||
<p class="zacht">Deze pagina bestaat niet, of hij is niet voor jou.</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h1>Beheer</h1>
|
||||
<p class="zacht">
|
||||
Hier draai je twee dingen terug die niemand anders kan: een overlijden dat ten onrechte
|
||||
is bevestigd, en een samenvoeging van twee profielen die niet had gemoeten. Voor het
|
||||
eerste is dit nodig als de bezwaarlink uit de waarschuwingsmail verlopen is; de
|
||||
betrokkene kan dan niet meer inloggen en heeft zelf geen weg terug.
|
||||
</p>
|
||||
|
||||
@* Adverteren heeft een eigen scherm: dat gaat niet over terugdraaien maar over betalingen
|
||||
afvinken en advertenties beoordelen, en daar hoor je dagelijks te komen in plaats van bij
|
||||
hoge uitzondering. *@
|
||||
<p><a href="/beheer/adverteren">Advertenties beheren ›</a></p>
|
||||
|
||||
@if (Melding is not null) { <div class="melding @MeldingSoort">@Melding</div> }
|
||||
|
||||
@* ------------------------------------------------------------ statistieken *@
|
||||
<div class="kaart">
|
||||
<h2 style="margin-top:0">Gebruik van MijnBesluit</h2>
|
||||
<p class="zacht" style="margin-top:0">
|
||||
Aantallen, niet inhoud: hier is niets van iemands kluis of berichten te zien. Bedoeld
|
||||
om de belasting in te schatten, niet om iemand te volgen.
|
||||
</p>
|
||||
|
||||
@if (Stats is null)
|
||||
{
|
||||
<p class="zacht" style="margin-bottom:0">Statistieken zijn hier niet beschikbaar.</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="statgrid">
|
||||
<div class="statcel">
|
||||
<span class="statgetal">@Stats.Profielen</span>
|
||||
<span class="statlabel">Profielen (@Stats.GeclaimdeProfielen geclaimd)</span>
|
||||
</div>
|
||||
<div class="statcel">
|
||||
<span class="statgetal">@Stats.Families</span>
|
||||
<span class="statlabel">Families</span>
|
||||
</div>
|
||||
<div class="statcel">
|
||||
<span class="statgetal">@Stats.KluisItems</span>
|
||||
<span class="statlabel">Kluisitems</span>
|
||||
</div>
|
||||
<div class="statcel">
|
||||
<span class="statgetal">@Stats.KluisBestanden</span>
|
||||
<span class="statlabel">Bijlagen</span>
|
||||
</div>
|
||||
<div class="statcel">
|
||||
<span class="statgetal">@Stats.Momenten</span>
|
||||
<span class="statlabel">Momenten (@Stats.BezorgdeMomenten bezorgd)</span>
|
||||
</div>
|
||||
<div class="statcel">
|
||||
<span class="statgetal">@Stats.Nalatenschapbeheerders</span>
|
||||
<span class="statlabel">Aangewezen beheerders</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Groeigrafiek Punten="Stats.GroeiPerDag" />
|
||||
|
||||
@if (Stats.ItemsPerCategorie.Count > 0)
|
||||
{
|
||||
<h3 style="margin-bottom:.6rem">Kluisitems per categorie</h3>
|
||||
<div class="stapel">
|
||||
@foreach (var (categorie, aantal) in Stats.ItemsPerCategorie.OrderByDescending(kv => kv.Value))
|
||||
{
|
||||
<div class="rij">
|
||||
<span class="zacht" style="min-width:140px">@Kluisweergave.Naam(categorie)</span>
|
||||
<div class="groei">
|
||||
<div class="voortgang">
|
||||
<span style="width:@(CategoriePercentage(aantal))%"></span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="zacht" style="min-width:2.5rem;text-align:right">@aantal</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="kaart">
|
||||
<h2 style="margin-top:0">Profiel opzoeken</h2>
|
||||
<div class="veld">
|
||||
<label for="adres">E-mailadres</label>
|
||||
<input id="adres" type="email" @bind="Adres" placeholder="het volledige adres" />
|
||||
<div class="uitleg">
|
||||
Alleen het volledige adres, niet een deel ervan en niet op naam. Je hoort al te
|
||||
weten wie je zoekt.
|
||||
</div>
|
||||
</div>
|
||||
<button class="knop" disabled="@Bezig" @onclick="Zoeken">Zoeken</button>
|
||||
</div>
|
||||
|
||||
@if (Gevonden is { } profiel)
|
||||
{
|
||||
<div class="kaart">
|
||||
<h2 style="margin-top:0">@profiel.DisplayName</h2>
|
||||
|
||||
<dl style="margin:0">
|
||||
<div class="rij" style="padding:.25rem 0">
|
||||
<span class="zacht" style="min-width:190px">E-mailadres</span>
|
||||
<span class="groei">@(profiel.Email ?? "onbekend")</span>
|
||||
</div>
|
||||
<div class="rij" style="padding:.25rem 0">
|
||||
<span class="zacht" style="min-width:190px">Eigen account</span>
|
||||
<span class="groei">@(profiel.IsGeclaimd ? "ja" : "nee, het profiel is nog niet geclaimd")</span>
|
||||
</div>
|
||||
<div class="rij" style="padding:.25rem 0">
|
||||
<span class="zacht" style="min-width:190px">Meldingen</span>
|
||||
<span class="groei">@profiel.Meldingen van @profiel.MeldingenNodig</span>
|
||||
</div>
|
||||
<div class="rij" style="padding:.25rem 0">
|
||||
<span class="zacht" style="min-width:190px">Stand</span>
|
||||
<span class="groei">@Stand(profiel.Stand)</span>
|
||||
</div>
|
||||
<div class="rij" style="padding:.25rem 0">
|
||||
<span class="zacht" style="min-width:190px">Kan inloggen</span>
|
||||
<span class="groei">@(profiel.AccountGeblokkeerd ? "nee, het account staat op overleden" : "ja")</span>
|
||||
</div>
|
||||
@if (profiel.OpgegaanIn is { } opgegaan)
|
||||
{
|
||||
<div class="rij" style="padding:.25rem 0">
|
||||
<span class="zacht" style="min-width:190px">Opgegaan in</span>
|
||||
<span class="groei">profiel @opgegaan</span>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
|
||||
@if (profiel.OverlijdenBevestigdOp is { } bevestigd)
|
||||
{
|
||||
<div class="melding let-op" style="margin-top:1rem">
|
||||
<p style="margin-top:0">
|
||||
Het overlijden is bevestigd op @Datums.Datum(bevestigd)@(
|
||||
profiel.Overlijdensdatum is { } datum ? $", met {Datums.Datum(datum)} als overlijdensdatum" : "").
|
||||
</p>
|
||||
<p>
|
||||
Terugdraaien betekent: alle meldingen vervallen, het account wordt weer
|
||||
actief, en de toegang die de nalatenschapsbeheerder had gekregen wordt
|
||||
ingetrokken.
|
||||
</p>
|
||||
|
||||
<div class="veld">
|
||||
<label for="reden">Waarom draai je dit terug?</label>
|
||||
<input id="reden" @bind="Reden" placeholder="bijvoorbeeld: telefonisch gesproken, leeft" />
|
||||
<div class="uitleg">Dit komt in het logboek te staan, bij jouw naam.</div>
|
||||
</div>
|
||||
|
||||
<button class="knop gevaar" disabled="@Bezig" @onclick="Herstellen">
|
||||
Overlijden terugdraaien
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="zacht" style="margin-bottom:0">
|
||||
Voor dit profiel is geen overlijden bevestigd. Er valt daar dus niets terug te draaien.
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
@* ------------------------------------------------------------ samenvoegingen *@
|
||||
<div class="kaart">
|
||||
<h2 style="margin-top:0">Samenvoegingen</h2>
|
||||
|
||||
@if (profiel.Samenvoegingen.Count == 0)
|
||||
{
|
||||
<p class="zacht" style="margin-bottom:0">
|
||||
Dit profiel is nooit samengevoegd. Let op: samenvoegingen van vóór 15 september
|
||||
2026 zijn niet vastgelegd en kunnen daarom ook niet worden teruggedraaid.
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="zacht" style="margin-top:0">
|
||||
Terugdraaien zet alles wat toen is verhuisd terug bij het profiel dat is
|
||||
opgegaan. Wat er ná die tijd bij het andere profiel is bijgekomen, blijft
|
||||
daar staan — dat is daar aangemaakt en hoort daar.
|
||||
</p>
|
||||
|
||||
<div class="stapel">
|
||||
@foreach (var samenvoeging in profiel.Samenvoegingen)
|
||||
{
|
||||
<div class="kaart compact">
|
||||
<div class="rij">
|
||||
<div class="groei">
|
||||
<span class="groot">
|
||||
@samenvoeging.DuplicaatNaam (@samenvoeging.DuplicaatPersonId)
|
||||
→ @samenvoeging.DoelNaam (@samenvoeging.DoelPersonId)
|
||||
</span>
|
||||
<div class="zacht">
|
||||
@Datums.DatumTijd(samenvoeging.SamengevoegdOp)
|
||||
· @samenvoeging.Stappen stap@(samenvoeging.Stappen == 1 ? "" : "pen")
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (samenvoeging.IsTeruggedraaid)
|
||||
{
|
||||
<span class="label">Teruggedraaid</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (!samenvoeging.IsTeruggedraaid)
|
||||
{
|
||||
<div class="veld" style="margin-top:.8rem">
|
||||
<label for="reden-@samenvoeging.Id">Waarom draai je dit terug?</label>
|
||||
<input id="reden-@samenvoeging.Id" @bind="Terugreden"
|
||||
placeholder="bijvoorbeeld: verkeerde uitnodiging aangenomen" />
|
||||
<div class="uitleg">Dit komt in het logboek te staan, bij jouw naam.</div>
|
||||
</div>
|
||||
|
||||
<button class="knop gevaar" disabled="@Bezig"
|
||||
@onclick="() => TerugdraaienAsync(samenvoeging.Id)">
|
||||
Samenvoeging terugdraaien
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
[CascadingParameter] private Task<AuthenticationState>? AuthState { get; set; }
|
||||
|
||||
private long _gebruikerId;
|
||||
private bool Magdit, Bezig;
|
||||
|
||||
private string Adres = "";
|
||||
private string Reden = "";
|
||||
private string Terugreden = "";
|
||||
private BeheerService.Profielbeeld? Gevonden;
|
||||
private string? Melding, MeldingSoort;
|
||||
private Statistieken? Stats;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (AuthState is null) return;
|
||||
_gebruikerId = (await AuthState).User.UserId() ?? 0;
|
||||
Magdit = await Beheerkant.IsBeheerderAsync(_gebruikerId);
|
||||
if (!Magdit) return;
|
||||
|
||||
var statistieken = await Beheerkant.StatistiekenAsync(_gebruikerId);
|
||||
if (statistieken.Succeeded) Stats = statistieken.Value;
|
||||
}
|
||||
|
||||
/// <summary>Breedte van de staaf voor deze categorie, ten opzichte van de grootste categorie.</summary>
|
||||
private int CategoriePercentage(int aantal)
|
||||
{
|
||||
var grootste = Stats!.ItemsPerCategorie.Values.Max();
|
||||
return grootste == 0 ? 0 : Math.Max(2, aantal * 100 / grootste);
|
||||
}
|
||||
|
||||
private async Task Zoeken()
|
||||
{
|
||||
Bezig = true;
|
||||
Melding = null;
|
||||
Gevonden = null;
|
||||
try
|
||||
{
|
||||
var resultaat = await Beheerkant.ZoekOpAdresAsync(Adres, _gebruikerId);
|
||||
if (resultaat.Succeeded) Gevonden = resultaat.Value;
|
||||
else { Melding = resultaat.Error; MeldingSoort = "fout"; }
|
||||
}
|
||||
finally { Bezig = false; }
|
||||
}
|
||||
|
||||
private async Task Herstellen()
|
||||
{
|
||||
if (Gevonden is not { } profiel) return;
|
||||
|
||||
Bezig = true;
|
||||
Melding = null;
|
||||
try
|
||||
{
|
||||
var resultaat = await Beheerkant.HerstelOverlijdenAsync(profiel.PersonId, _gebruikerId, Reden);
|
||||
if (!resultaat.Succeeded) { Melding = resultaat.Error; MeldingSoort = "fout"; return; }
|
||||
|
||||
Melding = $"Het overlijden van {profiel.DisplayName} is teruggedraaid. " +
|
||||
"Hij of zij kan weer inloggen, en de nalatenschapsbeheerder is zijn toegang kwijt.";
|
||||
MeldingSoort = "goed";
|
||||
Reden = "";
|
||||
|
||||
// Opnieuw ophalen, zodat het scherm laat zien wat er nu staat.
|
||||
var opnieuw = await Beheerkant.ZoekOpAdresAsync(Adres, _gebruikerId);
|
||||
Gevonden = opnieuw.Succeeded ? opnieuw.Value : null;
|
||||
}
|
||||
finally { Bezig = false; }
|
||||
}
|
||||
|
||||
private async Task TerugdraaienAsync(long samenvoegingId)
|
||||
{
|
||||
Bezig = true;
|
||||
Melding = null;
|
||||
try
|
||||
{
|
||||
var resultaat = await Beheerkant.TerugdraaienAsync(samenvoegingId, _gebruikerId, Terugreden);
|
||||
if (!resultaat.Succeeded) { Melding = resultaat.Error; MeldingSoort = "fout"; return; }
|
||||
|
||||
Melding = "De samenvoeging is teruggedraaid. De twee profielen staan weer los van elkaar.";
|
||||
MeldingSoort = "goed";
|
||||
Terugreden = "";
|
||||
|
||||
var opnieuw = await Beheerkant.ZoekOpAdresAsync(Adres, _gebruikerId);
|
||||
Gevonden = opnieuw.Succeeded ? opnieuw.Value : null;
|
||||
}
|
||||
finally { Bezig = false; }
|
||||
}
|
||||
|
||||
private static string Stand(DeathProcedureState stand) => stand switch
|
||||
{
|
||||
DeathProcedureState.Geen => "geen meldingen",
|
||||
DeathProcedureState.Lopend => "procedure loopt",
|
||||
DeathProcedureState.Betwist => "tegengesproken door de betrokkene",
|
||||
DeathProcedureState.Bevestigd => "overlijden bevestigd",
|
||||
_ => "onbekend"
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user