🔥 Heatmap Aktivitas 30 Hari
@php
// Generate data untuk 30 hari terakhir
$heatmapData = [];
$maxDuration = max($durations) ?: 1;
for ($i = 29; $i >= 0; $i--) {
$date = Carbon\Carbon::today()->subDays($i);
$dateStr = $date->format('Y-m-d');
$dayName = $date->format('D');
// Cari aktivitas di tanggal ini
$found = false;
$duration = 0;
foreach ($activities as $activity) {
if ($activity->activity_date->format('Y-m-d') == $dateStr) {
$found = true;
$duration = $activity->duration_minutes;
break;
}
}
$heatmapData[] = [
'date' => $dateStr,
'day' => $dayName,
'has_activity' => $found,
'duration' => $duration,
'intensity' => $found ? round(($duration / $maxDuration) * 100) : 0
];
}
@endphp
@foreach(['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'] as $day)
{{ $day }}
@endforeach
@foreach($heatmapData as $data)
@php
$intensity = $data['intensity'];
if ($intensity == 0) {
$bgColor = 'bg-gray-100';
} elseif ($intensity < 25) {
$bgColor = 'bg-green-200';
} elseif ($intensity < 50) {
$bgColor = 'bg-green-300';
} elseif ($intensity < 75) {
$bgColor = 'bg-green-400';
} else {
$bgColor = 'bg-green-500';
}
@endphp
@endforeach
Tidak belajar
Ringan
Sedang
Intensif
Sangat intensif
@php
// Hitung berbagai insight
$totalDays = count($activities);
$totalDuration = array_sum($durations);
$avgDuration = $totalDays > 0 ? round($totalDuration / $totalDays) : 0;
// Hari paling produktif
$dayProductivity = [];
foreach ($activities as $activity) {
$day = $activity->activity_date->format('l');
$dayProductivity[$day] = ($dayProductivity[$day] ?? 0) + $activity->duration_minutes;
}
arsort($dayProductivity);
$mostProductiveDay = array_key_first($dayProductivity) ?? '-';
// Mood yang paling produktif
$moodProductivity = [];
foreach ($activities as $activity) {
$moodProductivity[$activity->mood] = ($moodProductivity[$activity->mood] ?? 0) + $activity->duration_minutes;
}
arsort($moodProductivity);
$mostProductiveMood = array_key_first($moodProductivity) ?? '-';
// Tren (meningkat/menurun)
$recentAvg = 0;
$previousAvg = 0;
if (count($activities) >= 4) {
$recent = array_slice($durations, -2);
$previous = array_slice($durations, -4, 2);
$recentAvg = count($recent) > 0 ? array_sum($recent) / count($recent) : 0;
$previousAvg = count($previous) > 0 ? array_sum($previous) / count($previous) : 0;
}
$trend = $recentAvg > $previousAvg ? 'meningkat' : ($recentAvg < $previousAvg ? 'menurun' : 'stabil');
$trendColor = $trend == 'meningkat' ? 'text-green-600' : ($trend == 'menurun' ? 'text-red-600' : 'text-yellow-600');
$trendIcon = $trend == 'meningkat' ? '📈' : ($trend == 'menurun' ? '📉' : '📊');
@endphp
Total Belajar
{{ $totalDuration }} menit
Rata-rata
{{ $avgDuration }} mnt/hari
⭐
Hari paling produktif
{{ $mostProductiveDay }}
😊
Mood paling produktif
{{ $mostProductiveMood }}
{{ $trendIcon }}
Tren 2 hari terakhir
{{ ucfirst($trend) }}
📝 Catatan untuk Orang Tua
@if($totalDays == 0)
Ajak {{ $child->name }} untuk mulai mencatat aktivitas belajar agar bisa dipantau perkembangannya.
@elseif($avgDuration < 30)
{{ $child->name }} belajar dengan durasi pendek. Coba motivasi untuk belajar lebih konsisten.
@elseif($avgDuration < 60)
Durasi belajar {{ $child->name }} cukup baik. Pertahankan konsistensi!
@elseif($avgDuration < 120)
Luar biasa! {{ $child->name }} sangat rajin belajar. Pastikan tetap ada waktu istirahat.
@else
{{ $child->name }} belajar sangat intensif. Perhatikan keseimbangan dengan istirahat.
@endif
@php
// Kelompokkan mood per minggu
$weeklyMood = [];
foreach ($activities as $activity) {
$week = $activity->activity_date->format('W');
$year = $activity->activity_date->format('Y');
$weekKey = $year . '-W' . $week;
if (!isset($weeklyMood[$weekKey])) {
$weeklyMood[$weekKey] = [
'week' => $weekKey,
'moods' => [],
'count' => 0,
'avg_score' => 0
];
}
// Konversi mood ke skor
$score = match($activity->mood) {
'Bagus' => 5,
'Lumayan' => 4,
'Biasa Saja' => 3,
'Cukup Jenuh' => 2,
'Jenuh' => 1,
default => 3
};
$weeklyMood[$weekKey]['moods'][] = $activity->mood;
$weeklyMood[$weekKey]['count']++;
$weeklyMood[$weekKey]['avg_score'] =
(($weeklyMood[$weekKey]['avg_score'] * ($weeklyMood[$weekKey]['count'] - 1)) + $score)
/ $weeklyMood[$weekKey]['count'];
}
// Ambil 5 minggu terakhir
$weeklyMood = array_slice($weeklyMood, -5);
@endphp
@if(count($weeklyMood) > 0)
@foreach($weeklyMood as $week)
@php
$avgScore = round($week['avg_score'], 1);
$moodLabel = match(true) {
$avgScore >= 4.5 => 'Sangat Baik',
$avgScore >= 3.5 => 'Baik',
$avgScore >= 2.5 => 'Cukup',
$avgScore >= 1.5 => 'Kurang',
default => 'Buruk'
};
$barColor = match(true) {
$avgScore >= 4.5 => 'bg-green-500',
$avgScore >= 3.5 => 'bg-green-400',
$avgScore >= 2.5 => 'bg-yellow-400',
$avgScore >= 1.5 => 'bg-orange-400',
default => 'bg-red-400'
};
@endphp
Minggu {{ substr($week['week'], -2) }}
{{ $avgScore }}
{{ $moodLabel }}
@endforeach
@else
Belum cukup data untuk tren mood
@endif
@php
// Target ideal: 60 menit per hari
$targetPerDay = 60;
$actualPerDay = $avgDuration;
$percentToTarget = round(($actualPerDay / $targetPerDay) * 100);
// Target konsistensi: 80%
$targetConsistency = 80;
$actualConsistency = $stats['konsistensi'] ?? 0;
@endphp
Durasi vs Target (60 mnt/hari)
{{ $actualPerDay }} / 60 mnt
{{ $percentToTarget }}% dari target
Konsistensi vs Target (80%)
{{ $actualConsistency }}%
⏰ Rekomendasi Waktu Belajar
@php
// Analisis waktu belajar berdasarkan data
$bestTimes = [];
foreach ($activities as $activity) {
if (isset($activity->start_time)) {
$hour = (int) substr($activity->start_time, 0, 2);
$range = floor($hour / 4) * 4;
$timeRange = $range . ':00 - ' . ($range + 4) . ':00';
$bestTimes[$timeRange] = ($bestTimes[$timeRange] ?? 0) + $activity->duration_minutes;
}
}
arsort($bestTimes);
$bestTimeRange = array_key_first($bestTimes) ?? 'Belum ada data';
@endphp
Waktu paling produktif
{{ $bestTimeRange }}
Rekomendasi untuk minggu depan
@if($avgDuration < 30)
Coba tingkatkan durasi secara bertahap. Mulai dengan target 45 menit per hari.
@elseif($avgDuration < 60)
Pertahankan durasi saat ini. Fokus pada konsistensi.
@else
Durasi sudah baik. Pastikan ada jeda istirahat setiap 45 menit.
@endif
😊 Rata-rata Durasi per Mood
@php
$moodList = ['Bagus', 'Lumayan', 'Biasa Saja', 'Cukup Jenuh', 'Jenuh'];
$colors = ['green', 'blue', 'gray', 'yellow', 'red'];
$bgColors = ['bg-green-50', 'bg-blue-50', 'bg-gray-50', 'bg-yellow-50', 'bg-red-50'];
$textColors = ['text-green-700', 'text-blue-700', 'text-gray-700', 'text-yellow-700', 'text-red-700'];
$emojis = ['😊', '🙂', '😐', '😕', '😫'];
@endphp
@foreach($moodList as $idx => $mood)
@php
$total = 0;
$count = 0;
foreach($moods as $i => $m) {
if($m == $mood) {
$total += $durations[$i];
$count++;
}
}
$avg = $count > 0 ? round($total / $count) : 0;
@endphp
{{ $emojis[$idx] }}
{{ $mood }}
{{ $avg }}
menit
@if($count > 0)
{{ $count }}x
@endif
@endforeach
{{-- Desktop Table View --}}
| Tanggal |
Durasi |
Mood |
Tidur |
Rekomendasi |
@forelse(array_reverse($dates) as $index => $date)
@php
$i = count($dates) - 1 - $index;
$category = $categories[$i] ?? null;
@endphp
| {{ \Carbon\Carbon::parse($date)->format('d M Y') }} |
{{ $durations[$i] }} menit |
{{ $moods[$i] }}
|
{{ $sleep_hours[$i] ?? '7' }} jam |
@if($category)
@php
$parentDisplay = match($category) {
'Ringan' => 'Belajar Ringan',
'Sedang' => 'Belajar Cukup',
'Intensif' => 'Belajar Lama',
default => $category
};
@endphp
{{ $parentDisplay }}
@else
-
@endif
|
@empty
|
Belum ada data aktivitas
|
@endforelse
{{-- Mobile Card View dengan Desain Lebih Baik --}}
@forelse(array_reverse($dates) as $index => $date)
@php
$i = count($dates) - 1 - $index;
$category = $categories[$i] ?? null;
@endphp
{{ \Carbon\Carbon::parse($date)->format('d M Y') }}
@if($index == 0)
Terbaru
@endif
{{ $durations[$i] }} mnt
Mood
@if($moods[$i] == 'Bagus') 😊
@elseif($moods[$i] == 'Lumayan') 🙂
@elseif($moods[$i] == 'Biasa Saja') 😐
@elseif($moods[$i] == 'Cukup Jenuh') 😕
@else 😫 @endif
{{ $moods[$i] }}
Tidur
{{ $sleep_hours[$i] ?? '7' }} jam
Rekom
@if($category)
@php
$parentDisplay = match($category) {
'Ringan' => 'Belajar Ringan',
'Sedang' => 'Belajar Cukup',
'Intensif' => 'Belajar Lama',
default => $category
};
@endphp
{{ $parentDisplay }}
@else
-
@endif
@empty
@endforelse
Belum Ada Data
{{ $child->name }} belum menginput aktivitas belajar
💡 Ingatkan anak untuk mulai mencatat aktivitas