feat(hoy): vista previa de mañana en el kiosko del niño

Botón "Mañana ›" en la cabecera: muestra el día siguiente en solo
lectura para preparar la mochila la noche antes. La vista se calcula al
vuelo desde las plantillas SIN materializar DailyTask (los cambios del
panel de esa noche siguen entrando al generarse el día de verdad), con
ids sintéticos negativos no accionables, sin temporizador ni progreso.
Banner "Así será mañana" y estados vacíos propios. Test de integración:
la vista previa no persiste tareas del día siguiente.
This commit is contained in:
Jaume Garriga Maestre
2026-07-12 22:37:39 +02:00
parent 4eccee9b05
commit e5385f7ddd
8 changed files with 205 additions and 16 deletions

View File

@@ -59,6 +59,8 @@ export class HomeComponent implements OnInit {
protected readonly coins = signal<FlyingCoin[]>([]);
protected readonly celebrating = signal(false);
protected readonly lastEarned = signal(0);
/** true mientras se muestra la vista previa (solo lectura) de mañana. */
protected readonly viewingTomorrow = signal(false);
private childId!: number;
private coinSeq = 0;
@@ -69,14 +71,18 @@ export class HomeComponent implements OnInit {
return t ? [...t.morning, ...t.afternoon] : [];
});
/** Fecha de hoy formateada en el idioma activo. */
/** Fecha mostrada (hoy o mañana, según la vista) formateada en el idioma activo. */
protected readonly dateLabel = computed(() => {
const locale = this.i18n.lang() === 'CA' ? 'ca-ES' : 'es-ES';
const date = new Date();
if (this.viewingTomorrow()) {
date.setDate(date.getDate() + 1);
}
return new Intl.DateTimeFormat(locale, {
weekday: 'long',
day: 'numeric',
month: 'long',
}).format(new Date());
}).format(date);
});
ngOnInit(): void {
@@ -107,8 +113,25 @@ export class HomeComponent implements OnInit {
this.api.updateSettings(this.childId, { viewMode: mode }).subscribe();
}
/** Alterna entre hoy y la vista previa (solo lectura) de mañana. */
toggleDay(): void {
if (this.viewingTomorrow()) {
this.viewingTomorrow.set(false);
this.load();
return;
}
this.api.getTomorrow(this.childId).subscribe((data) => {
this.today.set(data);
this.viewingTomorrow.set(true);
});
}
/** Marca/desmarca una tarea y aplica el feedback (monedas, sonido, celebración). */
onToggle(ev: ToggleEvent): void {
// La vista de mañana es solo lectura: mirar, no marcar.
if (this.viewingTomorrow()) {
return;
}
this.api.toggleTask(ev.taskId).subscribe((result) => {
const current = this.today();
if (!current) {