feat(back-end and front-end): calculator improvements

This commit is contained in:
2026-03-05 21:46:11 +01:00
parent 235fe7780d
commit 7a699d2adf
15 changed files with 206 additions and 172 deletions

View File

@@ -0,0 +1,25 @@
<div class="price-breakdown">
<div class="price-row" *ngFor="let row of visibleRows()">
<span>
<ng-container *ngIf="row.label; else translatedRowLabel">
{{ row.label }}
</ng-container>
<ng-template #translatedRowLabel>
{{ row.labelKey ? (row.labelKey | translate) : "" }}
</ng-template>
</span>
<span>{{ row.amount | currency: currency() }}</span>
</div>
<div class="price-total">
<span>
<ng-container *ngIf="totalLabel(); else translatedTotalLabel">
{{ totalLabel() }}
</ng-container>
<ng-template #translatedTotalLabel>
{{ totalLabelKey() ? (totalLabelKey() | translate) : "" }}
</ng-template>
</span>
<span>{{ total() | currency: currency() }}</span>
</div>
</div>

View File

@@ -0,0 +1,31 @@
.price-breakdown {
margin-top: var(--space-2);
margin-bottom: var(--space-4);
padding: var(--space-4);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: var(--color-neutral-100);
}
.price-row,
.price-total {
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--space-3);
}
.price-row {
color: var(--color-text);
font-size: 0.95rem;
margin-bottom: var(--space-2);
}
.price-total {
margin-top: var(--space-3);
padding-top: var(--space-3);
border-top: 2px solid var(--color-border);
font-size: 1.2rem;
font-weight: 700;
color: var(--color-text);
}

View File

@@ -0,0 +1,29 @@
import { CommonModule } from '@angular/common';
import { Component, computed, input } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
export interface PriceBreakdownRow {
label?: string;
labelKey?: string;
amount: number;
visible?: boolean;
}
@Component({
selector: 'app-price-breakdown',
standalone: true,
imports: [CommonModule, TranslateModule],
templateUrl: './price-breakdown.component.html',
styleUrl: './price-breakdown.component.scss',
})
export class PriceBreakdownComponent {
rows = input<PriceBreakdownRow[]>([]);
total = input.required<number>();
currency = input<string>('CHF');
totalLabel = input<string>('');
totalLabelKey = input<string>('');
visibleRows = computed(() =>
this.rows().filter((row) => row.visible === undefined || row.visible),
);
}