import {
Component,
ElementRef,
EventEmitter,
Input,
Output,
ViewChild,
computed,
inject,
signal,
} from '@angular/core';
import { I18nService } from '../../core/i18n.service';
import { TtsService } from '../../core/tts.service';
import { TaskView } from '../../core/models';
import { ToggleEvent } from './task-card.component';
/** Vista FOCO: una sola tarea a pantalla completa, clave para reducir carga en TDAH. */
@Component({
selector: 'app-focus-view',
imports: [],
template: `
@if (current(); as task) {
{{ task.icon }}
{{ i18n.label(task.labelEs, task.labelCa) }}
@for (t of tasks; track t.id; let i = $index) {
}
@if (ttsEnabled && tts.supported) {
}
}
`,
styles: [
`
.focus { display: flex; flex-direction: column; align-items: center; gap: var(--space-5); padding: var(--space-5) 0; }
.focus__nav { display: flex; align-items: center; gap: var(--space-5); }
.focus__stage { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); min-width: 260px; }
.hero {
width: var(--hero-size);
height: var(--hero-size);
border-radius: 44px;
display: flex;
align-items: center;
justify-content: center;
font-size: 120px;
background: color-mix(in srgb, var(--c) 16%, #fff);
border: 4px solid color-mix(in srgb, var(--c) 35%, #fff);
animation: floatY 3.5s ease-in-out infinite;
}
.hero--done { background: color-mix(in srgb, var(--c) 22%, #fff); border-color: var(--c); animation: pop 0.4s ease; }
.focus__label { margin: 0; font-size: 2rem; text-transform: uppercase; text-align: center; color: var(--text-strong); }
.navbtn {
all: unset; cursor: pointer; width: var(--touch-nav); height: var(--touch-nav);
border-radius: 50%; background: var(--surface); box-shadow: var(--shadow-btn);
display: flex; align-items: center; justify-content: center; font-size: 38px; color: var(--text-4);
}
.navbtn:disabled { opacity: 0.3; cursor: default; }
.dots { display: flex; gap: 10px; }
.dot { width: 14px; height: 14px; border-radius: 50%; background: var(--border-2); transition: background 0.2s, transform 0.2s; }
.dot--done { background: var(--accent-green); }
.dot--current { transform: scale(1.4); box-shadow: 0 0 0 3px var(--surface-softer); }
.focus__actions { display: flex; align-items: center; gap: var(--space-4); }
.bigbtn {
font-family: var(--font-display); font-weight: 700; font-size: 1.6rem; color: #fff;
border: 0; border-radius: 24px; padding: 18px 48px; min-height: 72px; cursor: pointer;
background: var(--accent-blue); transition: transform 0.12s;
}
.bigbtn--done { background: var(--accent-green); }
.bigbtn:active { transform: scale(0.97); }
.speakbtn { all: unset; cursor: pointer; font-size: 34px; }
.focus__foot { margin: 0; color: var(--text-2); font-family: var(--font-display); font-weight: 600; }
`,
],
})
export class FocusViewComponent {
@Input() set tasksInput(value: TaskView[]) {
this.tasks = value;
if (this.index() >= value.length) {
this.index.set(Math.max(0, value.length - 1));
}
}
@Input() ttsEnabled = true;
@Output() toggle = new EventEmitter();
@ViewChild('doneBtn') private doneBtn?: ElementRef;
protected tasks: TaskView[] = [];
protected readonly index = signal(0);
protected readonly i18n = inject(I18nService);
protected readonly tts = inject(TtsService);
protected readonly current = computed(() => this.tasks[this.index()] ?? null);
protected readonly remaining = computed(() => this.tasks.filter((t) => !t.done).length);
protected readonly nextLabel = computed(() => {
const nextTask = this.tasks[this.index() + 1];
return nextTask ? this.i18n.label(nextTask.labelEs, nextTask.labelCa) : 'โ';
});
prev(): void {
this.index.update((i) => Math.max(0, i - 1));
}
next(): void {
this.index.update((i) => Math.min(this.tasks.length - 1, i + 1));
}
emitToggle(): void {
const task = this.current();
if (!task) {
return;
}
const rect = this.doneBtn?.nativeElement.getBoundingClientRect();
this.toggle.emit({
taskId: task.id,
x: rect ? rect.left + rect.width / 2 : window.innerWidth / 2,
y: rect ? rect.top : window.innerHeight / 2,
});
}
speak(task: TaskView): void {
this.tts.speak(this.i18n.label(task.labelEs, task.labelCa), this.i18n.lang());
}
}