import { Component, inject, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ParentApiService } from '../../core/parent-api.service'; import { I18nService } from '../../core/i18n.service'; import { ActivityView, MaterialView } from '../../core/models'; import { EmojiPickerComponent } from '../../shared/emoji-picker.component'; import { ColorPickerComponent } from '../../shared/color-picker.component'; /** Pestaña Materiales: catálogo de materiales y actividades (con su material). */ @Component({ selector: 'app-materials-tab', imports: [FormsModule, EmojiPickerComponent, ColorPickerComponent], template: `

Nuevo material

@for (m of materials(); track m.id) {
{{ m.icon }} {{ i18n.label(m.labelEs, m.labelCa) }}
} @empty {

{{ i18n.t('none') }}

}

Nueva actividad

@for (m of materials(); track m.id) { } @empty { Crea materiales primero ↑ }

Actividades

@for (a of activities(); track a.id) {
{{ a.icon }} {{ i18n.label(a.labelEs, a.labelCa) }} — {{ materialNames(a) }}
} @empty {

{{ i18n.t('none') }}

}
`, styles: [ ` .field { margin-bottom: var(--space-4); } .field__label { display: flex; align-items: center; gap: 6px; font-weight: 700; color: var(--text-1); margin-bottom: 6px; } .field__info { cursor: help; color: var(--text-4); font-size: 0.85rem; } .field__input { font-family: var(--font-body); font-size: 1rem; padding: 12px 14px; border: 2px solid var(--border-2); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-strong); width: 100%; box-sizing: border-box; } .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); } @media (max-width: 520px) { .grid2 { grid-template-columns: 1fr; } } .picker { display: flex; flex-wrap: wrap; gap: 8px; } `, ], }) export class MaterialsTabComponent { private readonly api = inject(ParentApiService); protected readonly i18n = inject(I18nService); protected readonly materialIcons = ['✏️', '📘', '📏', '🎵', '📓', '👕', '👟', '🧖', '💧', '📖', '📒', '🍎', '🎒', '🖍️', '✂️', '📐', '🧮', '🎨']; protected readonly activityIcons = ['🤸', '🎵', '📘', '📖', '🎨', '⚽', '🔬', '🧮', '🌍', '🎭', '💻', '🏃']; protected readonly materials = signal([]); protected readonly activities = signal([]); protected mIcon = ''; protected mEs = ''; protected mCa = ''; protected mColor = '#5B8DEF'; protected aIcon = ''; protected aEs = ''; protected aCa = ''; protected aColor = '#7FBF6B'; protected selectedMaterials = new Set(); constructor() { this.reload(); } private reload(): void { this.api.listMaterials().subscribe((l) => this.materials.set(l)); this.api.listActivities().subscribe((l) => this.activities.set(l)); } materialNames(a: ActivityView): string { const byId = new Map(this.materials().map((m) => [m.id, this.i18n.label(m.labelEs, m.labelCa)])); return a.materialIds.map((id) => byId.get(id) ?? '·').join(', ') || '—'; } toggleMaterial(id: number): void { if (this.selectedMaterials.has(id)) { this.selectedMaterials.delete(id); } else { this.selectedMaterials.add(id); } } addMaterial(): void { this.api .createMaterial({ labelEs: this.mEs, labelCa: this.mCa, icon: this.mIcon, color: this.mColor }) .subscribe(() => { this.mEs = this.mCa = this.mIcon = ''; this.reload(); }); } delMaterial(m: MaterialView): void { this.api.deleteMaterial(m.id).subscribe(() => this.reload()); } addActivity(): void { this.api .createActivity({ labelEs: this.aEs, labelCa: this.aCa, icon: this.aIcon, color: this.aColor, materialIds: [...this.selectedMaterials], }) .subscribe(() => { this.aEs = this.aCa = this.aIcon = ''; this.selectedMaterials.clear(); this.reload(); }); } delActivity(a: ActivityView): void { this.api.deleteActivity(a.id).subscribe(() => this.reload()); } }