78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { SCOREBOARD_TABS, ScoreboardTab } from './scoreboard.pure';
|
|
|
|
interface TabSpec {
|
|
id: ScoreboardTab;
|
|
label: string;
|
|
icon: string;
|
|
}
|
|
|
|
const TAB_SPECS: Readonly<Record<ScoreboardTab, { label: string; icon: string }>> = {
|
|
ranking: { label: 'RANKINGS', icon: '🏆' },
|
|
matrix: { label: 'MATRIX', icon: '▦' },
|
|
'event-log': { label: 'EVENT LOG', icon: '≡' },
|
|
graph: { label: 'SCORE GRAPH', icon: '📈' },
|
|
};
|
|
|
|
@Component({
|
|
selector: 'app-scoreboard-tabs',
|
|
standalone: true,
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
imports: [CommonModule],
|
|
styles: [`
|
|
:host { display: block; }
|
|
nav {
|
|
display: flex; gap: 10px; justify-content: center;
|
|
margin-bottom: 24px; flex-wrap: wrap;
|
|
}
|
|
button {
|
|
padding: 10px 20px;
|
|
background: #000000;
|
|
color: #aaaaee;
|
|
border: 2px solid #22222e;
|
|
cursor: pointer;
|
|
font-family: var(--font-mono);
|
|
font-weight: 800;
|
|
font-size: 0.85rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
display: flex; align-items: center; gap: 8px;
|
|
transition: all 0.15s ease;
|
|
}
|
|
button:hover:not(.active) {
|
|
border-color: var(--neon-purple);
|
|
color: #ffffff;
|
|
}
|
|
button.active {
|
|
background: var(--neon-red);
|
|
color: #000000;
|
|
border-color: var(--neon-red);
|
|
box-shadow: 0 0 15px rgba(255, 0, 51, 0.4);
|
|
}
|
|
`],
|
|
template: `
|
|
<nav data-testid="scoreboard-tabs">
|
|
<button
|
|
*ngFor="let t of tabs"
|
|
type="button"
|
|
[class.active]="t.id === active"
|
|
[attr.data-testid]="'scoreboard-tab-' + t.id"
|
|
(click)="select.emit(t.id)"
|
|
>
|
|
<span>{{ t.icon }}</span>
|
|
<span>{{ t.label }}</span>
|
|
</button>
|
|
</nav>
|
|
`,
|
|
})
|
|
export class ScoreboardTabsComponent {
|
|
@Input({ required: true }) active!: ScoreboardTab;
|
|
@Output() select = new EventEmitter<ScoreboardTab>();
|
|
|
|
readonly tabs: TabSpec[] = SCOREBOARD_TABS.map((id) => ({
|
|
id,
|
|
label: TAB_SPECS[id].label,
|
|
icon: TAB_SPECS[id].icon,
|
|
}));
|
|
} |