360 lines
15 KiB
Plaintext
360 lines
15 KiB
Plaintext
@page "/"
|
|
@attribute [Authorize]
|
|
@inject OverzichtService Overzichten
|
|
@inject LegacyService NalatenschapService
|
|
@inject AdvertentieService Adverteren
|
|
@inject AccountService Accounts
|
|
@inject SamenvoegService Samenvoegen
|
|
@rendermode InteractiveServer
|
|
|
|
<PageTitle>MijnBesluit</PageTitle>
|
|
|
|
@* Het beginscherm, met dezelfde indeling als in de app: eerst wat er speelt, dan de tegels.
|
|
De aantallen staan achter de titel in plaats van op een regel eronder, zodat de tegels
|
|
laag blijven. *@
|
|
|
|
<AuthorizeView Context="auth">
|
|
<Authorized>
|
|
<h1>@Begroeting(auth.User.Naam())</h1>
|
|
|
|
@if (Fout is not null)
|
|
{
|
|
<div class="melding fout">@Fout</div>
|
|
}
|
|
|
|
@if (Melding is not null)
|
|
{
|
|
<div class="melding goed">@Melding</div>
|
|
}
|
|
|
|
@* Heeft iemand een profiel voor je aangemaakt op jouw adres? Dan staat die vraag hier,
|
|
bovenaan, tot je hem beantwoordt. Alleen jij kunt zeggen of dat over jou gaat;
|
|
koppelen op e-mailadres doet MijnBesluit niet. Zie docs/Identiteit.md. *@
|
|
@foreach (var aantekening in Aantekeningen)
|
|
{
|
|
<div class="kaart" style="margin-bottom:1rem">
|
|
<h2 style="margin-top:0">Ben jij dit?</h2>
|
|
<p style="margin-top:0">
|
|
<strong>@aantekening.Van</strong> heeft een profiel voor je aangemaakt op jouw
|
|
e-mailadres@(aantekening.Relatie is { Length: > 0 } r ? $", als {r.ToLowerInvariant()}" : "").
|
|
</p>
|
|
<p class="zacht" style="margin-top:0">
|
|
Ben jij dat, dan voegen we het bij je eigen profiel: wat hij over je heeft
|
|
ingevuld komt bij jou te staan, en vanaf dat moment bepaal jij wat er staat.
|
|
Ben jij het niet, dan blijft alles zoals het is en vragen we het niet nog eens.
|
|
</p>
|
|
<div class="knoppen">
|
|
<button class="knop vol" disabled="@Bezig"
|
|
@onclick="() => Overnemen(aantekening.PersoonId)">Ja, dat ben ik</button>
|
|
<button class="knop rustig" disabled="@Bezig"
|
|
@onclick="() => Afwijzen(aantekening.PersoonId)">Nee, dat ben ik niet</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
@if (Gegevens is { Regels.Count: > 0 })
|
|
{
|
|
<div class="stapel speelt">
|
|
@foreach (var regel in Gegevens.Regels)
|
|
{
|
|
<div class="regel @(regel.Soort == "overlijden" ? "let-op" : "")">
|
|
<span class="teken">@Teken(regel.Soort)</span>
|
|
<div class="groei">
|
|
<div>@regel.Tekst</div>
|
|
@if (regel.Datum is { } datum)
|
|
{
|
|
<div class="zacht">@Datums.MetDag(datum)</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@if (Gegevens.Regels.Any(r => r.Soort == "overlijden"))
|
|
{
|
|
<button class="knop" style="margin-bottom:1rem" disabled="@Bezig" @onclick="IkBenErNog">
|
|
Ik ben er nog
|
|
</button>
|
|
}
|
|
}
|
|
|
|
@* De advertentie staat hier en niet bovenaan: "wat er speelt" gaat voor. Iemand die net
|
|
leest dat er een overlijden op zijn naam is gemeld, hoort daar geen reclame boven te
|
|
zien. Zie docs/Adverteren.md. *@
|
|
@if (Reclame is not null)
|
|
{
|
|
<a class="advertentie" href="/advertentie/@Reclame.Id/uit"
|
|
target="_blank" rel="noopener noreferrer nofollow">
|
|
@if (Reclame.HeeftAfbeelding)
|
|
{
|
|
<img src="/advertentie/@Reclame.Id/afbeelding" alt="" />
|
|
}
|
|
<span class="groei">
|
|
<span class="merkje">Advertentie</span>
|
|
<span class="tekst">@Reclame.Tekst</span>
|
|
</span>
|
|
</a>
|
|
}
|
|
|
|
<div class="raster twee">
|
|
<a class="kaart klikbaar" href="/kluis">
|
|
<span class="groot">Mijn kluis <span class="aantal">@(Gegevens?.AantalKluis ?? 0)</span></span>
|
|
</a>
|
|
|
|
<a class="kaart klikbaar" href="/familie">
|
|
<span class="groot">Mijn mensen <span class="aantal">@(Gegevens?.AantalFamilie ?? 0)</span></span>
|
|
</a>
|
|
|
|
@* Twee richtingen, dus twee aantallen; die staan achter de titel in hetzelfde
|
|
rondje als de andere tegels, met hun naam erbij zodat je niet hoeft te raden
|
|
welke welke is. Zo past de tegel op één regel, even hoog als de andere drie. *@
|
|
<a class="kaart klikbaar" href="/momenten">
|
|
<span class="groot">
|
|
Momenten
|
|
<span class="aantal" title="@(Gegevens?.AantalVoorMij ?? 0) voor mij, @(Gegevens?.AantalVanMij ?? 0) van mij">
|
|
↓@(Gegevens?.AantalVoorMij ?? 0) · ↑@(Gegevens?.AantalVanMij ?? 0)
|
|
</span>
|
|
@if (Gegevens is { AantalNieuweBerichten: > 0 })
|
|
{
|
|
<span class="aantal nieuw">@Gegevens.AantalNieuweBerichten</span>
|
|
}
|
|
</span>
|
|
</a>
|
|
|
|
<a class="kaart klikbaar" href="/nalatenschap">
|
|
<span class="groot">Nalatenschap <span class="aantal">@(Gegevens?.AantalBeheerders ?? 0)</span></span>
|
|
</a>
|
|
</div>
|
|
|
|
@if (Gegevens is not null)
|
|
{
|
|
<details class="uitklap" style="margin-top:1.5rem">
|
|
<summary>Hoe ver vooruit wil je kijken?</summary>
|
|
<p>
|
|
Hierboven zie je wat er de komende tijd voor je klaarstaat. Zet het op 0 als je
|
|
liever verrast wordt.
|
|
</p>
|
|
<div class="rij">
|
|
<select @bind="Dagen" @bind:after="VooruitblikOpslaan" style="max-width:14rem">
|
|
<option value="0">Niets vooruit tonen</option>
|
|
<option value="7">7 dagen</option>
|
|
<option value="14">14 dagen</option>
|
|
<option value="30">30 dagen</option>
|
|
<option value="60">60 dagen</option>
|
|
</select>
|
|
</div>
|
|
</details>
|
|
}
|
|
|
|
@* Dezelfde uitleg als in de app en op de pagina /watismijnbesluit, maar hier als popup:
|
|
je hoeft dan niet weg van je overzicht en weer terug.
|
|
|
|
De privacyverklaring staat er om dezelfde reden bij, en op dezelfde plek als in de app.
|
|
Er is ook een pagina /privacy - die is er voor wie hem los wil kunnen delen en voor
|
|
Google Play, dat een adres wil dat je kunt aanklikken. Maar wie hier zit, hoort hem te
|
|
kunnen lezen zonder zijn overzicht kwijt te raken. De tekst zelf staat in
|
|
Privacytekst.razor, hetzelfde onderdeel dat /privacy en de app gebruiken. *@
|
|
<p style="margin-top:1rem">
|
|
<button type="button" class="alsLink" @onclick="() => Uitleg = true">Wat is MijnBesluit?</button>
|
|
<br />
|
|
<button type="button" class="alsLink" @onclick="() => Privacy = true">Privacyverklaring</button>
|
|
<br />
|
|
<button type="button" class="alsLink" @onclick="() => VersiehistorieOpen = true">Versiehistorie</button>
|
|
</p>
|
|
|
|
@if (Uitleg)
|
|
{
|
|
<Popup Titel="Wat is MijnBesluit?" Bevestigtekst="Sluiten" AlleenSluiten="true"
|
|
OpBevestigen="() => Uitleg = false" OpSluiten="() => Uitleg = false">
|
|
<Productuitleg />
|
|
</Popup>
|
|
}
|
|
|
|
@if (Privacy)
|
|
{
|
|
<Popup Titel="Privacy" Bevestigtekst="Sluiten" AlleenSluiten="true"
|
|
OpBevestigen="() => Privacy = false" OpSluiten="() => Privacy = false">
|
|
<Privacytekst />
|
|
</Popup>
|
|
}
|
|
|
|
@* Zelfde tekst als in de app: Versiehistorie.razor staat twee keer op schijf en een
|
|
zelfcontrole vergelijkt ze letterlijk. *@
|
|
@if (VersiehistorieOpen)
|
|
{
|
|
<Popup Titel="Versiehistorie" Bevestigtekst="Sluiten" AlleenSluiten="true"
|
|
OpBevestigen="() => VersiehistorieOpen = false" OpSluiten="() => VersiehistorieOpen = false">
|
|
<Versiehistorie />
|
|
</Popup>
|
|
}
|
|
|
|
<div class="kaart">
|
|
<h2>Waar is MijnBesluit voor?</h2>
|
|
<p class="zacht" style="margin-bottom:.8rem">
|
|
Voor alles wat je zou willen doorgeven maar wat nu alleen in jouw hoofd zit.
|
|
</p>
|
|
<ul class="zacht" style="padding-left:1.2rem;margin:0">
|
|
<li>
|
|
<strong>Je kluis</strong> — wachtwoorden, de pincode van je telefoon,
|
|
polissen, documenten, je uitvaartwensen. Alles versleuteld, en jij bepaalt per
|
|
onderdeel of het alleen voor jou is, pas na je overlijden vrijkomt, of op een
|
|
datum die je zelf kiest.
|
|
</li>
|
|
<li>
|
|
<strong>Je mensen</strong> — familie en vrienden die je toevoegt en
|
|
uitnodigt. Zolang iemand de uitnodiging niet heeft aangenomen, beheer jij dat
|
|
profiel; daarna is het van hem of haar.
|
|
</li>
|
|
<li>
|
|
<strong>Momenten</strong> — een tekst- of videobericht dat je klaarzet
|
|
voor iemand. Te bezorgen op een datum die jij kiest, of pas na je overlijden.
|
|
Een verjaardag die je niet meer meemaakt, of gewoon iets wat je nog wilt zeggen.
|
|
</li>
|
|
<li>
|
|
<strong>Je nalatenschap</strong> — wie er straks mag regelen wat er
|
|
geregeld moet worden. Die persoon krijgt pas toegang als je overlijden is
|
|
bevestigd door meerdere mensen én jij er zelf niet op hebt gereageerd.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</Authorized>
|
|
</AuthorizeView>
|
|
|
|
@code {
|
|
[CascadingParameter] private Task<AuthenticationState>? AuthState { get; set; }
|
|
|
|
private long _gebruikerId, _persoonId;
|
|
private Overzicht? Gegevens;
|
|
private int Dagen = 30;
|
|
|
|
/// <summary>Profielen die anderen op mijn adres hebben aangemaakt; alleen ik kan zeggen of ik dat ben.</summary>
|
|
private IReadOnlyList<AccountService.Aantekeningaanbod> Aantekeningen =
|
|
Array.Empty<AccountService.Aantekeningaanbod>();
|
|
|
|
/// <summary>Staat de uitleg open?</summary>
|
|
private bool Uitleg;
|
|
|
|
/// <summary>Staat de privacyverklaring open?</summary>
|
|
private bool Privacy;
|
|
private bool VersiehistorieOpen;
|
|
|
|
/// <summary>De advertentie voor deze keer, of null als er geen is.</summary>
|
|
private Campagne? Reclame;
|
|
private bool Bezig;
|
|
private string? Fout, Melding;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
if (AuthState is null) return;
|
|
var user = (await AuthState).User;
|
|
_gebruikerId = user.UserId() ?? 0;
|
|
_persoonId = user.PersonId() ?? 0;
|
|
|
|
await Laden();
|
|
}
|
|
|
|
private async Task Laden()
|
|
{
|
|
if (_gebruikerId == 0) return;
|
|
|
|
var uitkomst = await Overzichten.VoorAsync(_gebruikerId);
|
|
if (!uitkomst.Succeeded) { Fout = uitkomst.Error; return; }
|
|
|
|
Fout = null;
|
|
Gegevens = uitkomst.Value;
|
|
Dagen = Gegevens!.VooruitblikDagen;
|
|
|
|
// De keuze en het tellen horen bij elkaar: wat hier wordt uitgekozen komt ook echt in
|
|
// beeld. Eén advertentie per keer dat het overzicht wordt geopend; zie docs/Adverteren.md.
|
|
//
|
|
// Gaat er hier iets mis, dan hoort het overzicht er gewoon te staan. Reclame is het
|
|
// minst belangrijke op dit scherm.
|
|
try
|
|
{
|
|
Reclame = await Adverteren.KiesAsync();
|
|
if (Reclame is not null) await Adverteren.TelVertoningAsync(Reclame.Id);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
Reclame = null;
|
|
}
|
|
|
|
// Heeft iemand een profiel voor mij aangemaakt? Apart opgehaald, en een fout hier hoort
|
|
// het overzicht niet weg te houden: dit is een vraag die best een keer later mag komen.
|
|
try { Aantekeningen = await Accounts.AantekeningenOverMijAsync(_gebruikerId); }
|
|
catch (Exception) { Aantekeningen = Array.Empty<AccountService.Aantekeningaanbod>(); }
|
|
}
|
|
|
|
/// <summary>"Ja, dat ben ik." Daarna staat alles wat die ander over je had bij jou.</summary>
|
|
private async Task Overnemen(long persoonId)
|
|
{
|
|
Bezig = true;
|
|
try
|
|
{
|
|
var uitkomst = await Accounts.NeemAantekeningOverAsync(persoonId, _gebruikerId, Samenvoegen);
|
|
Fout = uitkomst.Succeeded ? null : uitkomst.Error;
|
|
Melding = uitkomst.Succeeded ? "Klaar. Het profiel staat nu bij jou." : null;
|
|
if (uitkomst.Succeeded) await Laden();
|
|
}
|
|
finally { Bezig = false; }
|
|
}
|
|
|
|
/// <summary>"Nee, dat ben ik niet." De vraag komt niet terug.</summary>
|
|
private async Task Afwijzen(long persoonId)
|
|
{
|
|
Bezig = true;
|
|
try
|
|
{
|
|
var uitkomst = await Accounts.WijsAantekeningAfAsync(persoonId, _gebruikerId);
|
|
Fout = uitkomst.Succeeded ? null : uitkomst.Error;
|
|
if (uitkomst.Succeeded)
|
|
Aantekeningen = Aantekeningen.Where(a => a.PersoonId != persoonId).ToList();
|
|
}
|
|
finally { Bezig = false; }
|
|
}
|
|
|
|
private async Task VooruitblikOpslaan()
|
|
{
|
|
Bezig = true;
|
|
try
|
|
{
|
|
var uitkomst = await Overzichten.VooruitblikAsync(_gebruikerId, Dagen);
|
|
if (!uitkomst.Succeeded) { Fout = uitkomst.Error; return; }
|
|
await Laden();
|
|
}
|
|
finally { Bezig = false; }
|
|
}
|
|
|
|
private async Task IkBenErNog()
|
|
{
|
|
Bezig = true;
|
|
try
|
|
{
|
|
var uitkomst = await NalatenschapService.ObjectAsync(_persoonId, _gebruikerId);
|
|
Melding = uitkomst.Succeeded ? "Genoteerd. De melding is ingetrokken." : null;
|
|
Fout = uitkomst.Succeeded ? null : uitkomst.Error;
|
|
if (uitkomst.Succeeded) await Laden();
|
|
}
|
|
finally { Bezig = false; }
|
|
}
|
|
|
|
private static string Teken(string soort) => soort switch
|
|
{
|
|
"beheerder" => "\U0001F33F", // blad: iemand beheert jouw nalatenschap
|
|
"beheer-voor" => "\U0001F91D", // handdruk: jij beheert die van een ander
|
|
"moment" => "✉", // envelop
|
|
"overlijden" => "⚠", // waarschuwing
|
|
_ => "•"
|
|
};
|
|
|
|
/// <summary>
|
|
/// "Dag Jonathan" als we de naam kennen, anders alleen "Welkom". Nooit het e-mailadres:
|
|
/// dat is geen naam, en het staat raar boven een scherm over je nalatenschap.
|
|
/// </summary>
|
|
private static string Begroeting(string naam)
|
|
{
|
|
var voornaam = naam.Split(' ', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
|
|
return string.IsNullOrWhiteSpace(voornaam) ? "Welkom" : $"Dag {voornaam}";
|
|
}
|
|
}
|