@extends('layouts.app')
@section('title', 'Report e statistiche · FranCoach')
@section('content')
@php
$periodLabels = ['week' => 'Settimana', 'month' => 'Mese', '90_days' => '90 giorni', '6_months' => '6 mesi', 'custom' => 'Personalizzato'];
// Prima voce nera (non gialla): come tratto di linea sottile su sfondo bianco
// il giallo fluorescente del brand avrebbe un contrasto reale di ~1,3:1.
$chartColors = ['#121212', '#2F80ED', '#27AE60', '#9B51E0', '#EB5757', '#F2C94C', '#56CCF2'];
$chart = fn (string $type, array $labels, array $datasets) => compact('type', 'labels', 'datasets');
$adherenceChart = $chart('doughnut', ['Completati', 'Saltati'], [['label' => 'Allenamenti', 'data' => [$summary['completed'], $summary['skipped']]]]);
$weightChart = $chart('line', collect($measurements['weight']['points'] ?? [])->pluck('date')->map(fn ($date) => \Illuminate\Support\Carbon::parse($date)->format('d/m'))->all(), [['label' => 'Peso (kg)', 'data' => collect($measurements['weight']['points'] ?? [])->pluck('value')->all()]]);
$compositionLabels = $measurements['composition']->flatMap(fn ($series) => $series['points']->pluck('date'))->unique()->sort()->values();
$compositionDatasets = $measurements['composition']->values()->map(fn ($series, $index) => ['label' => $series['name'].' ('.$series['unit'].')', 'data' => $compositionLabels->map(fn ($date) => $series['points']->firstWhere('date', $date)['value'] ?? null)->all(), 'borderColor' => $chartColors[$index % count($chartColors)]])->all();
$circumferenceLabels = $measurements['circumferences']->flatMap(fn ($series) => $series['points']->pluck('date'))->unique()->sort()->values();
$circumferenceDatasets = $measurements['circumferences']->values()->map(fn ($series, $index) => ['label' => $series['name'], 'data' => $circumferenceLabels->map(fn ($date) => $series['points']->firstWhere('date', $date)['value'] ?? null)->all(), 'borderColor' => $chartColors[$index % count($chartColors)]])->all();
$charts = [
['title' => 'Aderenza', 'description' => 'Allenamenti completati e saltati.', 'config' => $adherenceChart, 'empty' => ($summary['completed'] + $summary['skipped']) === 0],
['title' => 'Andamento peso', 'description' => 'Peso registrato nel periodo.', 'config' => $weightChart, 'empty' => empty($measurements['weight']['points'] ?? [])],
['title' => 'Composizione corporea', 'description' => 'Massa grassa, magra e muscolare.', 'config' => $chart('line', $compositionLabels->map(fn ($date) => \Illuminate\Support\Carbon::parse($date)->format('d/m'))->all(), $compositionDatasets), 'empty' => empty($compositionDatasets)],
['title' => 'Volume per gruppo muscolare', 'description' => 'Volume complessivo in chilogrammi.', 'config' => $chart('bar', $volumeByMuscle->pluck('label')->all(), [['label' => 'Volume (kg)', 'data' => $volumeByMuscle->pluck('value')->map(fn ($value) => round((float) $value, 1))->all()]]), 'empty' => $volumeByMuscle->isEmpty()],
['title' => 'Carichi', 'description' => 'Carico medio e massimo per data.', 'config' => $chart('line', $loadTrend->pluck('date')->map(fn ($date) => \Illuminate\Support\Carbon::parse($date)->format('d/m'))->all(), [['label' => 'Carico medio', 'data' => $loadTrend->pluck('average')->map(fn ($value) => round((float) $value, 1))->all()], ['label' => 'Carico massimo', 'data' => $loadTrend->pluck('maximum')->map(fn ($value) => round((float) $value, 1))->all(), 'borderColor' => '#2F80ED']]), 'empty' => $loadTrend->isEmpty()],
['title' => 'Allenamenti', 'description' => 'Completati e saltati nel tempo.', 'config' => $chart('bar', $trainingTrend->pluck('date')->map(fn ($date) => \Illuminate\Support\Carbon::parse($date)->format('d/m'))->all(), [['label' => 'Completati', 'data' => $trainingTrend->pluck('completed')->all()], ['label' => 'Saltati', 'data' => $trainingTrend->pluck('skipped')->all(), 'backgroundColor' => '#EB5757']]), 'empty' => $trainingTrend->isEmpty()],
['title' => 'Circonferenze', 'description' => 'Variazione delle misure corporee.', 'config' => $chart('line', $circumferenceLabels->map(fn ($date) => \Illuminate\Support\Carbon::parse($date)->format('d/m'))->all(), $circumferenceDatasets), 'empty' => empty($circumferenceDatasets)],
];
@endphp
{{ $from->format('d/m/Y') }} - {{ $to->format('d/m/Y') }}
{{ $item['description'] }}
| Misura | Iniziale | Ultima | Variazione |
|---|---|---|---|
| {{ $series['name'] }} | {{ $series['first'] }} {{ $series['unit'] }} | {{ $series['last'] }} {{ $series['unit'] }} | {{ $series['change'] !== null ? ($series['change'] > 0 ? '+' : '').$series['change'].' '.$series['unit'] : '—' }} |
| Nessuna misurazione. | |||
| Esercizio | Carico massimo |
|---|---|
| {{ $record->label ?: 'Esercizio' }} | {{ number_format((float) $record->value, 1, ',', '.') }} kg |
| Nessun record nel periodo. | |