feat: use cash flow presentation in transaction histories

This commit is contained in:
Bastian Wagner
2026-08-01 20:58:22 +02:00
parent 239b157015
commit f2e6704943
15 changed files with 203 additions and 90 deletions

View File

@@ -43,9 +43,13 @@
><span>{{ activity.note || activity.type }}</span
><small>{{ activity.date | date: 'dd.MM.yyyy' }}</small>
</div>
<strong class="activity__amount" [class.negative]="displayAmount(activity) < 0">{{
displayAmount(activity) | currency: 'EUR'
}}</strong>
<strong>
<app-transaction-amount
[amount]="activity.amount"
[type]="activity.type"
[context]="activity.isTeamWalletTransaction ? 'team' : 'player'"
/>
</strong>
</article>
}
</div>

View File

@@ -44,12 +44,7 @@ h2 {
.balance-card--primary {
// background: var(--mat-sys-primary-container);
// color: var(--mat-sys-on-primary-container);
background: linear-gradient(
135deg,
#5ca34c 0%,
#4f8f46 55%,
#3f7f3c 100%
);
background: linear-gradient(135deg, #5ca34c 0%, #4f8f46 55%, #3f7f3c 100%);
color: #ffffff;
}
@@ -76,7 +71,6 @@ h2 {
border-radius: 14px;
background: var(--mat-sys-secondary-container);
color: var(--mat-sys-on-secondary-container);
}
.activity__copy {
display: flex;
@@ -90,12 +84,6 @@ h2 {
text-overflow: ellipsis;
white-space: nowrap;
}
.activity__amount {
color: var(--mat-sys-primary);
}
.activity__amount.negative {
color: var(--mat-sys-error);
}
.state {
min-height: 180px;
display: flex;

View File

@@ -43,11 +43,28 @@ describe('Overview', () => {
id: 1,
date: '2026-07-31',
amount: 12,
type: 'fine',
type: 'payment',
note: 'Beitrag',
playerName: 'Alex',
isTeamWalletTransaction: false,
},
{
id: 2,
date: '2026-07-30',
amount: 8,
type: 'expense',
note: 'Material',
isTeamWalletTransaction: true,
},
{
id: 3,
date: '2026-07-29',
amount: 5,
type: 'fine',
note: 'Training',
playerName: 'Bea',
isTeamWalletTransaction: false,
},
]);
await fixture.whenStable();
fixture.detectChanges();
@@ -55,7 +72,18 @@ describe('Overview', () => {
expect(fixture.nativeElement.textContent).toContain('125,00');
expect(fixture.nativeElement.textContent).toContain('Alex');
expect(fixture.nativeElement.textContent).toContain('Beitrag');
expect(fixture.nativeElement.textContent).toContain('-12,00');
const amounts = [
...fixture.nativeElement.querySelectorAll(
'app-transaction-amount [data-testid="transaction-amount"]',
),
] as HTMLElement[];
expect(amounts).toHaveLength(3);
expect(amounts[0].classList).toContain('inflow');
expect(amounts[1].classList).toContain('outflow');
expect(amounts[2].classList).toContain('neutral');
expect(
amounts.map((amount) => amount.querySelector('.transaction-amount__sign')?.textContent),
).toEqual(['+', '', '']);
routeParams.next(convertToParamMap({ id: '6' }));
TestBed.inject(HttpTestingController)

View File

@@ -9,7 +9,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { TeamStore } from '../../../core/team/team-store';
import { TransactionsApi } from '../../../core/team/transactions-api';
import { TeamActivity } from '../../../models/transaction.model';
import { signedTransactionAmount } from '../../../models/transaction-amount';
import { TransactionAmount } from '../../../shared/transaction-amount/transaction-amount';
import { of } from 'rxjs';
import { catchError, distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
@@ -17,7 +17,14 @@ registerLocaleData(localeDe);
@Component({
selector: 'app-overview',
imports: [CurrencyPipe, DatePipe, MatCardModule, MatIconModule, MatProgressSpinnerModule],
imports: [
CurrencyPipe,
DatePipe,
MatCardModule,
MatIconModule,
MatProgressSpinnerModule,
TransactionAmount,
],
providers: [{ provide: LOCALE_ID, useValue: 'de-DE' }],
templateUrl: './overview.html',
styleUrl: './overview.scss',
@@ -60,8 +67,4 @@ export class Overview {
protected activityIcon(activity: TeamActivity): string {
return activity.isTeamWalletTransaction ? 'account_balance' : 'person';
}
protected displayAmount(activity: TeamActivity): number {
return signedTransactionAmount(activity.amount, activity.type);
}
}