Re-skins the app's layout on top of the CIBG Huisstijl theme (previous commit) so it
matches designsystem.cibg.nl, not just its colour tokens — magenta ("robijn") header,
horizontal nav, and the CIBG component markup for forms/wizards/dashboard.
- Header: logo block + robijn titlebar (breadcrumb + user menu) + grey horizontal nav
(4 links) replacing the dashboard side-nav; breadcrumb restyled for the titlebar
(no background of its own — CIBG's global `header nav` rule otherwise bleeds a grey
fill into it, fixed by scoping an override inside BreadcrumbComponent).
- Forms: form-field/radio-group/checkbox rebuilt on CIBG's horizontal `form-group row`
/ `form-check.styled` markup (label col-md-4, control col-md-8); same input() APIs.
- Wizards: stepper rebuilt as the CIBG "stappenindicator" (numbered circles, visited
steps clickable for back-nav, title merged in); wizard-shell adopts the CIBG
procesnavigatie button row. Back-navigation wired into all three wizard machines
(registratie-wizard already had it; added `GaNaarStap` to intake/herregistratie
machines, pure + spec'd).
- New shared/ui molecules: confirmation (animated bevestiging checkmark, replaces
plain alerts on submit), review-section (controlestap sections with "Wijzigen"),
application-list/application-link (CIBG "aanvragen" rows, replace the dashboard's
card grid and aanvraag-block).
- Cleanup: delete side-nav and now-unused styles.scss utilities (.app-overview,
.app-form-panel, .app-card-grid); correct design-tokens.mdx (it referenced tokens
that no longer exist) and document the CIBG-value token bridge.
Verified: build/lint/check:tokens green, 178 tests pass (4 new GaNaarStap cases), and
manually driven end-to-end (dashboard, a full herregistratie submission through to the
confirmation screen, mobile width, keyboard focus).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
72 lines
3.3 KiB
TypeScript
72 lines
3.3 KiB
TypeScript
import { Component, computed, input, output } from '@angular/core';
|
|
import { ButtonComponent } from '@shared/ui/button/button.component';
|
|
import { ApplicationLinkComponent } from '@shared/ui/application-link/application-link.component';
|
|
import { Aanvraag, AanvraagType } from '@registratie/domain/aanvraag';
|
|
import { blockActions } from '@registratie/domain/block-actions';
|
|
|
|
const TYPE_LABELS: Record<AanvraagType, string> = {
|
|
registratie: $localize`:@@aanvraagBlock.type.registratie:Inschrijving`,
|
|
herregistratie: $localize`:@@aanvraagBlock.type.herregistratie:Herregistratie`,
|
|
intake: $localize`:@@aanvraagBlock.type.intake:Herregistratie-intake`,
|
|
};
|
|
|
|
/** Organism: one application on the dashboard's "Mijn aanvragen" list, rendered as
|
|
a CIBG Huisstijl "aanvragen" row (application-link). Which text/actions it shows
|
|
is driven by the pure `blockActions(status)` and the status tag; the block only
|
|
renders. Only a resumable Concept is clickable — a resolved status has nothing
|
|
to navigate to, so it renders as a plain (non-anchor) row. */
|
|
@Component({
|
|
selector: 'app-aanvraag-block',
|
|
imports: [ButtonComponent, ApplicationLinkComponent],
|
|
// display:contents — see application-link.component.ts (keeps <li> a direct <ul> child).
|
|
styles: [`:host{display:contents}`],
|
|
template: `
|
|
<app-application-link
|
|
[heading]="typeLabel()"
|
|
[status]="statusText()"
|
|
[subtitle]="subtitle()"
|
|
[cta]="actions().includes('resume') ? verderGaan : ''"
|
|
[clickable]="actions().includes('resume')"
|
|
(activate)="resume.emit()">
|
|
@if (actions().includes('cancel')) {
|
|
<div applicationActions>
|
|
<app-button variant="subtle" (click)="cancel.emit()" i18n="@@aanvraagBlock.annuleren">Annuleren</app-button>
|
|
</div>
|
|
}
|
|
</app-application-link>
|
|
`,
|
|
})
|
|
export class AanvraagBlockComponent {
|
|
aanvraag = input.required<Aanvraag>();
|
|
|
|
resume = output<void>();
|
|
cancel = output<void>();
|
|
|
|
protected readonly verderGaan = $localize`:@@aanvraagBlock.verderGaan:Verder gaan`;
|
|
|
|
protected typeLabel = computed(() => TYPE_LABELS[this.aanvraag().type]);
|
|
protected actions = computed(() => blockActions(this.aanvraag().status));
|
|
|
|
// Status-tag → row text (the UI's mapping, not a domain rule).
|
|
protected statusText = computed(() => {
|
|
const s = this.aanvraag().status;
|
|
switch (s.tag) {
|
|
case 'Concept': return $localize`:@@aanvraagBlock.stap:Stap ${s.stepIndex + 1}:index: van ${s.stepCount}:count:`;
|
|
case 'InBehandeling': return $localize`:@@aanvraagBlock.inBehandeling:Referentie ${s.referentie}:ref: · ingediend op ${formatNL(this.aanvraag().submittedAt)}:datum:`;
|
|
case 'Goedgekeurd': return $localize`:@@aanvraagBlock.goedgekeurd:Referentie ${s.referentie}:ref:`;
|
|
case 'Afgewezen': return $localize`:@@aanvraagBlock.afgewezen:Referentie ${s.referentie}:ref:`;
|
|
}
|
|
});
|
|
// Secondary note under the status line, when there's one to show.
|
|
protected subtitle = computed(() => {
|
|
const s = this.aanvraag().status;
|
|
if (s.tag === 'InBehandeling' && s.manual) return $localize`:@@aanvraagBlock.manual:Uw aanvraag wordt handmatig beoordeeld in de backoffice.`;
|
|
if (s.tag === 'Afgewezen') return s.reden;
|
|
return '';
|
|
});
|
|
}
|
|
|
|
function formatNL(iso?: string): string {
|
|
return iso ? new Date(iso).toLocaleDateString('nl-NL', { day: 'numeric', month: 'long', year: 'numeric' }) : '';
|
|
}
|