add song reporting

This commit is contained in:
2026-03-15 22:23:11 +01:00
parent e4f829d0c8
commit 67884e4638
24 changed files with 644 additions and 36 deletions

View File

@@ -0,0 +1,3 @@
<span [class]="'badge ' + type">
<ng-content></ng-content>
</span>

View File

@@ -0,0 +1,35 @@
.badge {
display: inline-flex;
align-items: center;
min-height: 1.75rem;
padding: 0 10px;
border-radius: 999px;
font-size: 0.85rem;
font-weight: 600;
line-height: 1;
border: 1px solid transparent;
&.ok {
background: #e6f6ea;
border-color: #9ad1a7;
color: #1f6b34;
}
&.warn {
background: #fff4db;
border-color: #f2cf7a;
color: #8a5a00;
}
&.error {
background: #fdeaea;
border-color: #efb2b2;
color: #9b2c2c;
}
&.none {
background: #eef1f4;
border-color: #c7d0d9;
color: #4f5f6f;
}
}

View File

@@ -0,0 +1,28 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {BadgeComponent} from './badge.component';
describe('BadgeComponent', () => {
let component: BadgeComponent;
let fixture: ComponentFixture<BadgeComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [BadgeComponent],
}).compileComponents();
fixture = TestBed.createComponent(BadgeComponent);
component = fixture.componentInstance;
});
it('create an instance', () => {
void expect(component).toBeTruthy();
});
it('should apply the configured type class', () => {
component.type = 'error';
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('.badge')?.className).toContain('error');
});
});

View File

@@ -0,0 +1,13 @@
import {Component, Input} from '@angular/core';
export type BadgeType = 'ok' | 'warn' | 'error' | 'none';
@Component({
selector: 'app-badge',
templateUrl: './badge.component.html',
styleUrls: ['./badge.component.less'],
standalone: true,
})
export class BadgeComponent {
@Input() public type: BadgeType = 'none';
}

View File

@@ -0,0 +1,15 @@
import {PublishedTypePipe} from './published-type.pipe';
describe('PublishedTypePipe', () => {
it('create an instance', () => {
const pipe = new PublishedTypePipe();
void expect(pipe).toBeTruthy();
});
it('should translate publication state', () => {
const pipe = new PublishedTypePipe();
expect(pipe.transform(true)).toBe('veröffentlicht');
expect(pipe.transform(false)).toBe('unveröffentlicht');
});
});

View File

@@ -0,0 +1,10 @@
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'publishedType',
})
export class PublishedTypePipe implements PipeTransform {
public transform(published: boolean): string {
return published ? 'veröffentlicht' : 'unveröffentlicht';
}
}

View File

@@ -0,0 +1,17 @@
import {ReportedTypePipe} from './reported-type.pipe';
describe('ReportedTypePipe', () => {
it('create an instance', () => {
const pipe = new ReportedTypePipe();
void expect(pipe).toBeTruthy();
});
it('should translate report states', () => {
const pipe = new ReportedTypePipe();
expect(pipe.transform('pending')).toBe('nicht gemeldet');
expect(pipe.transform('reported')).toBe('gemeldet');
expect(pipe.transform('not-required')).toBe('Meldung nicht notwendig');
expect(pipe.transform(null)).toBe('');
});
});

View File

@@ -0,0 +1,20 @@
import {Pipe, PipeTransform} from '@angular/core';
import {ReportedType} from '../../../modules/shows/services/show';
@Pipe({
name: 'reportedType',
})
export class ReportedTypePipe implements PipeTransform {
public transform(reportedType: ReportedType): string {
switch (reportedType) {
case 'pending':
return 'nicht gemeldet';
case 'reported':
return 'gemeldet';
case 'not-required':
return 'Meldung nicht notwendig';
default:
return '';
}
}
}