LearnMood/resources/views/orangtua/child-visualization.blade.php

863 lines
44 KiB
PHP

{{-- resources/views/orangtua/child-visualization.blade.php --}}
@extends('layouts.app')
@section('title', 'Perkembangan ' . ($child->name ?? 'Anak') . ' - LearnMood')
@section('content')
<div class="space-y-6 pb-20 md:pb-0">
<!-- Breadcrumb -->
<div class="flex items-center text-xs md:text-sm text-gray-500 overflow-x-auto pb-1">
<a href="{{ route('dashboard') }}" class="hover:text-blue-600 flex items-center gap-1 whitespace-nowrap">
<svg class="w-3 h-3 md:w-4 md:h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
</svg>
<span>Dashboard</span>
</a>
<span class="mx-1 md:mx-2 text-gray-300">/</span>
<a href="{{ route('orangtua.children') }}" class="hover:text-blue-600 whitespace-nowrap">
Anak-anak
</a>
<span class="mx-1 md:mx-2 text-gray-300">/</span>
<span class="text-gray-700 font-medium truncate max-w-[120px] md:max-w-none">{{ $child->name }}</span>
</div>
<!-- Header -->
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
<div class="flex items-center gap-3">
<div class="w-12 h-12 md:w-14 md:h-14 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-full flex items-center justify-center text-white font-bold text-xl md:text-2xl shadow-md">
{{ substr($child->name, 0, 1) }}
</div>
<div>
<h2 class="text-xl md:text-2xl font-bold text-gray-800">{{ $child->name }}</h2>
<p class="text-xs md:text-sm text-gray-500">Pantau aktivitas belajar anak Anda</p>
</div>
</div>
<!-- Filter Periode -->
<div class="flex bg-white rounded-lg border border-gray-200 p-1 shadow-sm w-full sm:w-auto">
<a href="{{ route('orangtua.child.visualization', ['childId' => $child->id, 'period' => 7]) }}"
class="flex-1 sm:flex-none px-3 md:px-4 py-1.5 md:py-2 text-xs md:text-sm rounded-md transition {{ $period == 7 ? 'bg-blue-600 text-white' : 'text-gray-600 hover:bg-gray-100' }}">
7H
</a>
<a href="{{ route('orangtua.child.visualization', ['childId' => $child->id, 'period' => 30]) }}"
class="flex-1 sm:flex-none px-3 md:px-4 py-1.5 md:py-2 text-xs md:text-sm rounded-md transition {{ $period == 30 ? 'bg-blue-600 text-white' : 'text-gray-600 hover:bg-gray-100' }}">
30H
</a>
<a href="{{ route('orangtua.child.visualization', ['childId' => $child->id, 'period' => 90]) }}"
class="flex-1 sm:flex-none px-3 md:px-4 py-1.5 md:py-2 text-xs md:text-sm rounded-md transition {{ $period == 90 ? 'bg-blue-600 text-white' : 'text-gray-600 hover:bg-gray-100' }}">
90H
</a>
</div>
</div>
@if(count($dates) > 0)
<!-- Info Anak dengan Konsistensi yang Lebih Baik -->
<div class="bg-gradient-to-r from-blue-600 to-indigo-600 p-4 md:p-5 rounded-xl text-white shadow-md">
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3">
<div class="flex items-center gap-3">
<div class="w-10 h-10 md:w-12 md:h-12 bg-white/20 rounded-full flex items-center justify-center text-xl md:text-2xl shrink-0 backdrop-blur-sm">
👤
</div>
<div>
<h3 class="text-base md:text-lg font-semibold">{{ $child->name }}</h3>
<p class="text-blue-100 text-xs md:text-sm">{{ $child->email }}</p>
</div>
</div>
<!-- Konsistensi dengan Progress Bar -->
<div class="flex items-center gap-3 bg-white/10 px-3 py-2 rounded-lg backdrop-blur-sm">
<div class="text-right">
<p class="text-xs text-blue-100">Konsistensi</p>
<p class="text-xl font-bold">{{ $stats['konsistensi'] ?? 0 }}%</p>
</div>
<div class="w-16 sm:w-24 bg-white/20 rounded-full h-2">
<div class="bg-white h-2 rounded-full" style="width: {{ min(100, $stats['konsistensi'] ?? 0) }}%"></div>
</div>
</div>
</div>
</div>
<!-- Statistik Cards dengan Desain Lebih Menarik -->
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3 md:gap-4">
<!-- Total Hari -->
<div class="bg-white p-4 rounded-xl border border-gray-100 shadow-sm hover:shadow-md transition">
<div class="flex items-start justify-between">
<div>
<p class="text-xs text-gray-500 mb-1">Total Hari Input</p>
<p class="text-2xl md:text-3xl font-bold text-gray-800">{{ $stats['total_hari'] }}</p>
<p class="text-xs text-gray-400 mt-1">dari {{ $period }} hari</p>
</div>
<div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
</div>
</div>
</div>
<!-- Rata-rata Durasi -->
<div class="bg-white p-4 rounded-xl border border-gray-100 shadow-sm hover:shadow-md transition">
<div class="flex items-start justify-between">
<div>
<p class="text-xs text-gray-500 mb-1">Rata-rata Durasi</p>
<p class="text-2xl md:text-3xl font-bold text-gray-800">{{ $stats['rata_durasi'] }}</p>
<p class="text-xs text-gray-400 mt-1">menit per hari</p>
</div>
<div class="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
</div>
</div>
<!-- Mood Terbanyak -->
<div class="bg-white p-4 rounded-xl border border-gray-100 shadow-sm hover:shadow-md transition">
<div class="flex items-start justify-between">
<div>
<p class="text-xs text-gray-500 mb-1">Mood Terbanyak</p>
<p class="text-xl md:text-2xl font-bold
@if($stats['mood_terbanyak'] == 'Bagus') text-green-600
@elseif($stats['mood_terbanyak'] == 'Lumayan') text-blue-600
@elseif($stats['mood_terbanyak'] == 'Biasa Saja') text-gray-600
@elseif($stats['mood_terbanyak'] == 'Cukup Jenuh') text-yellow-600
@elseif($stats['mood_terbanyak'] == 'Jenuh') text-red-600
@else text-gray-800 @endif">
{{ $stats['mood_terbanyak'] }}
</p>
<p class="text-xs text-gray-400 mt-1">paling sering muncul</p>
</div>
<div class="w-10 h-10 bg-yellow-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
</div>
</div>
</div>
<!-- Grafik Durasi Belajar -->
<div class="bg-white p-4 md:p-6 rounded-xl shadow-sm border border-gray-100">
<div class="flex items-center gap-2 mb-4">
<div class="bg-blue-100 p-1.5 md:p-2 rounded-lg">
<svg class="w-4 h-4 md:w-5 md:h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg>
</div>
<h3 class="text-sm md:text-base font-semibold text-gray-800">📈 Grafik Durasi Belajar</h3>
</div>
<div style="height: 250px;" class="relative">
<canvas id="durationChart"></canvas>
</div>
</div>
<!-- Setelah Grafik Durasi Belajar -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- 1. HEATMAP AKTIVITAS (Pola Harian) -->
<div class="bg-white p-4 md:p-6 rounded-xl shadow-sm border border-gray-100">
<div class="flex items-center gap-2 mb-4">
<div class="bg-red-100 p-1.5 md:p-2 rounded-lg">
<svg class="w-4 h-4 md:w-5 md:h-5 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
</svg>
</div>
<h3 class="text-sm md:text-base font-semibold text-gray-800">🔥 Heatmap Aktivitas 30 Hari</h3>
</div>
@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
<div class="grid grid-cols-7 gap-1 mb-2">
@foreach(['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'] as $day)
<div class="text-center text-[10px] font-medium text-gray-500">{{ $day }}</div>
@endforeach
</div>
<div class="grid grid-cols-7 gap-1">
@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
<div class="aspect-square {{ $bgColor }} rounded-sm hover:scale-110 transition-transform cursor-pointer relative group"
title="{{ Carbon\Carbon::parse($data['date'])->format('d M Y') }}: {{ $data['duration'] }} menit">
<div class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block z-10">
<div class="bg-gray-800 text-white text-xs rounded py-1 px-2 whitespace-nowrap">
{{ Carbon\Carbon::parse($data['date'])->format('d M') }}: {{ $data['duration'] }} menit
</div>
</div>
</div>
@endforeach
</div>
<div class="flex items-center justify-between mt-3 text-xs text-gray-500">
<div class="flex items-center gap-2">
<span class="w-3 h-3 bg-gray-100 rounded-sm"></span>
<span>Tidak belajar</span>
</div>
<div class="flex items-center gap-2">
<span class="w-3 h-3 bg-green-200 rounded-sm"></span>
<span>Ringan</span>
</div>
<div class="flex items-center gap-2">
<span class="w-3 h-3 bg-green-300 rounded-sm"></span>
<span>Sedang</span>
</div>
<div class="flex items-center gap-2">
<span class="w-3 h-3 bg-green-400 rounded-sm"></span>
<span>Intensif</span>
</div>
<div class="flex items-center gap-2">
<span class="w-3 h-3 bg-green-500 rounded-sm"></span>
<span>Sangat intensif</span>
</div>
</div>
</div>
<!-- 2. INSIGHT & ANALISIS (Ringkasan Cerdas) -->
<div class="bg-white p-4 md:p-6 rounded-xl shadow-sm border border-gray-100">
<div class="flex items-center gap-2 mb-4">
<div class="bg-purple-100 p-1.5 md:p-2 rounded-lg">
<svg class="w-4 h-4 md:w-5 md:h-5 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"></path>
</svg>
</div>
<h3 class="text-sm md:text-base font-semibold text-gray-800">💡 Insight & Analisis</h3>
</div>
@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
<div class="space-y-4">
<!-- Statistik Utama -->
<div class="grid grid-cols-2 gap-3">
<div class="bg-gradient-to-br from-blue-50 to-blue-100 p-3 rounded-lg">
<p class="text-xs text-blue-600 mb-1">Total Belajar</p>
<p class="text-xl font-bold text-blue-800">{{ $totalDuration }} <span class="text-sm font-normal">menit</span></p>
</div>
<div class="bg-gradient-to-br from-green-50 to-green-100 p-3 rounded-lg">
<p class="text-xs text-green-600 mb-1">Rata-rata</p>
<p class="text-xl font-bold text-green-800">{{ $avgDuration }} <span class="text-sm font-normal">mnt/hari</span></p>
</div>
</div>
<!-- Insight Cards -->
<div class="space-y-2">
<div class="flex items-center gap-3 p-3 bg-yellow-50 rounded-lg">
<div class="text-2xl"></div>
<div>
<p class="text-xs text-yellow-700">Hari paling produktif</p>
<p class="text-sm font-semibold text-gray-800">{{ $mostProductiveDay }}</p>
</div>
</div>
<div class="flex items-center gap-3 p-3 bg-purple-50 rounded-lg">
<div class="text-2xl">😊</div>
<div>
<p class="text-xs text-purple-700">Mood paling produktif</p>
<p class="text-sm font-semibold text-gray-800">{{ $mostProductiveMood }}</p>
</div>
</div>
<div class="flex items-center gap-3 p-3 bg-blue-50 rounded-lg">
<div class="text-2xl">{{ $trendIcon }}</div>
<div>
<p class="text-xs text-blue-700">Tren 2 hari terakhir</p>
<p class="text-sm font-semibold {{ $trendColor }}">{{ ucfirst($trend) }}</p>
</div>
</div>
</div>
<!-- Rekomendasi Personal -->
<div class="mt-4 p-3 bg-gradient-to-r from-indigo-50 to-purple-50 rounded-lg border border-indigo-100">
<p class="text-xs font-semibold text-indigo-700 mb-2">📝 Catatan untuk Orang Tua</p>
@if($totalDays == 0)
<p class="text-sm text-gray-600">Ajak {{ $child->name }} untuk mulai mencatat aktivitas belajar agar bisa dipantau perkembangannya.</p>
@elseif($avgDuration < 30)
<p class="text-sm text-gray-600">{{ $child->name }} belajar dengan durasi pendek. Coba motivasi untuk belajar lebih konsisten.</p>
@elseif($avgDuration < 60)
<p class="text-sm text-gray-600">Durasi belajar {{ $child->name }} cukup baik. Pertahankan konsistensi!</p>
@elseif($avgDuration < 120)
<p class="text-sm text-gray-600">Luar biasa! {{ $child->name }} sangat rajin belajar. Pastikan tetap ada waktu istirahat.</p>
@else
<p class="text-sm text-gray-600">{{ $child->name }} belajar sangat intensif. Perhatikan keseimbangan dengan istirahat.</p>
@endif
</div>
</div>
</div>
</div>
<!-- 3. TREN MOOD (Setelah grid di atas) -->
<div class="bg-white p-4 md:p-6 rounded-xl shadow-sm border border-gray-100">
<div class="flex items-center gap-2 mb-4">
<div class="bg-pink-100 p-1.5 md:p-2 rounded-lg">
<svg class="w-4 h-4 md:w-5 md:h-5 text-pink-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<h3 class="text-sm md:text-base font-semibold text-gray-800">📊 Tren Mood Mingguan</h3>
</div>
@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)
<div class="space-y-3">
@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
<div class="flex items-center gap-3">
<span class="text-xs font-medium text-gray-600 w-16">Minggu {{ substr($week['week'], -2) }}</span>
<div class="flex-1">
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="{{ $barColor }} h-2.5 rounded-full" style="width: {{ ($avgScore / 5) * 100 }}%"></div>
</div>
</div>
<div class="flex items-center gap-2">
<span class="text-xs font-semibold text-gray-800">{{ $avgScore }}</span>
<span class="text-xs text-gray-500">{{ $moodLabel }}</span>
</div>
</div>
@endforeach
</div>
@else
<p class="text-center text-gray-400 py-4">Belum cukup data untuk tren mood</p>
@endif
</div>
<!-- 4. STATISTIK KOMPARATIF (Setelah tabel riwayat) -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Perbandingan dengan target ideal -->
<div class="bg-white p-4 md:p-6 rounded-xl shadow-sm border border-gray-100">
<div class="flex items-center gap-2 mb-4">
<div class="bg-indigo-100 p-1.5 md:p-2 rounded-lg">
<svg class="w-4 h-4 md:w-5 md:h-5 text-indigo-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg>
</div>
<h3 class="text-sm md:text-base font-semibold text-gray-800">🎯 Perbandingan Target</h3>
</div>
@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
<div class="space-y-4">
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">Durasi vs Target (60 mnt/hari)</span>
<span class="font-medium {{ $percentToTarget >= 100 ? 'text-green-600' : 'text-yellow-600' }}">
{{ $actualPerDay }} / 60 mnt
</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-3">
<div class="{{ $percentToTarget >= 100 ? 'bg-green-500' : 'bg-yellow-500' }} h-3 rounded-full"
style="width: {{ min(100, $percentToTarget) }}%"></div>
</div>
<p class="text-xs text-gray-500 mt-1">{{ $percentToTarget }}% dari target</p>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">Konsistensi vs Target (80%)</span>
<span class="font-medium {{ $actualConsistency >= 80 ? 'text-green-600' : 'text-yellow-600' }}">
{{ $actualConsistency }}%
</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-3">
<div class="{{ $actualConsistency >= 80 ? 'bg-green-500' : 'bg-yellow-500' }} h-3 rounded-full"
style="width: {{ min(100, $actualConsistency) }}%"></div>
</div>
</div>
</div>
</div>
<!-- Rekomendasi Waktu Belajar -->
<div class="bg-white p-4 md:p-6 rounded-xl shadow-sm border border-gray-100">
<div class="flex items-center gap-2 mb-4">
<div class="bg-teal-100 p-1.5 md:p-2 rounded-lg">
<svg class="w-4 h-4 md:w-5 md:h-5 text-teal-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<h3 class="text-sm md:text-base font-semibold text-gray-800"> Rekomendasi Waktu Belajar</h3>
</div>
@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
<div class="space-y-3">
<div class="bg-blue-50 p-3 rounded-lg">
<p class="text-xs text-blue-700 mb-1">Waktu paling produktif</p>
<p class="text-lg font-bold text-blue-800">{{ $bestTimeRange }}</p>
</div>
<div class="bg-green-50 p-3 rounded-lg">
<p class="text-xs text-green-700 mb-1">Rekomendasi untuk minggu depan</p>
<p class="text-sm text-gray-700">
@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
</p>
</div>
</div>
</div>
</div>
<!-- Rata-rata Durasi per Mood -->
<div class="bg-white p-4 md:p-6 rounded-xl shadow-sm border border-gray-100">
<div class="flex items-center gap-2 mb-4">
<div class="bg-orange-100 p-1.5 md:p-2 rounded-lg">
<svg class="w-4 h-4 md:w-5 md:h-5 text-orange-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z"></path>
</svg>
</div>
<h3 class="text-sm md:text-base font-semibold text-gray-800">😊 Rata-rata Durasi per Mood</h3>
</div>
@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
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 gap-2 md:gap-3">
@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
<div class="text-center p-2 md:p-3 rounded-xl {{ $bgColors[$idx] }} border border-{{ $colors[$idx] }}-200 hover:shadow-md transition">
<div class="text-xl md:text-2xl mb-1">{{ $emojis[$idx] }}</div>
<p class="text-[10px] md:text-xs font-medium text-gray-600 truncate">{{ $mood }}</p>
<p class="text-base md:text-lg font-bold {{ $textColors[$idx] }}">{{ $avg }}</p>
<p class="text-[8px] md:text-xs text-gray-500">menit</p>
@if($count > 0)
<p class="text-[8px] md:text-xs text-gray-400 mt-0.5">{{ $count }}x</p>
@endif
</div>
@endforeach
</div>
</div>
<!-- Tabel Riwayat - Mobile Friendly dengan Desain Lebih Baik -->
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
<div class="px-4 md:px-6 py-3 md:py-4 border-b border-gray-100 bg-gradient-to-r from-blue-50 to-indigo-50">
<div class="flex items-center gap-2">
<div class="w-6 h-6 bg-blue-100 rounded-lg flex items-center justify-center">
<svg class="w-3 h-3 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path>
</svg>
</div>
<h3 class="text-sm md:text-base font-semibold text-gray-800">📋 Riwayat Aktivitas</h3>
</div>
</div>
{{-- Desktop Table View --}}
<div class="hidden md:block overflow-x-auto">
<table class="w-full">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Tanggal</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Durasi</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Mood</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Tidur</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Rekomendasi</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@forelse(array_reverse($dates) as $index => $date)
@php
$i = count($dates) - 1 - $index;
$category = $categories[$i] ?? null;
@endphp
<tr class="hover:bg-gray-50 transition-colors">
<td class="px-6 py-3 text-sm text-gray-800 whitespace-nowrap">{{ \Carbon\Carbon::parse($date)->format('d M Y') }}</td>
<td class="px-6 py-3 text-sm text-gray-800">{{ $durations[$i] }} menit</td>
<td class="px-6 py-3">
<span class="px-2 py-1 text-xs rounded-full
@if($moods[$i] == 'Bagus') bg-green-100 text-green-700
@elseif($moods[$i] == 'Lumayan') bg-blue-100 text-blue-700
@elseif($moods[$i] == 'Biasa Saja') bg-gray-100 text-gray-700
@elseif($moods[$i] == 'Cukup Jenuh') bg-yellow-100 text-yellow-700
@else bg-red-100 text-red-700 @endif">
{{ $moods[$i] }}
</span>
</td>
<td class="px-6 py-3 text-sm text-gray-800">{{ $sleep_hours[$i] ?? '7' }} jam</td>
<td class="px-6 py-3">
@if($category)
@php
$parentDisplay = match($category) {
'Ringan' => 'Belajar Ringan',
'Sedang' => 'Belajar Cukup',
'Intensif' => 'Belajar Lama',
default => $category
};
@endphp
<span class="px-2 py-1 text-xs rounded-full
@if($category == 'Ringan') bg-yellow-100 text-yellow-700
@elseif($category == 'Sedang') bg-green-100 text-green-700
@else bg-blue-100 text-blue-700 @endif">
{{ $parentDisplay }}
</span>
@else
<span class="text-xs text-gray-400">-</span>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-6 py-8 text-center text-gray-500">
Belum ada data aktivitas
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
{{-- Mobile Card View dengan Desain Lebih Baik --}}
<div class="md:hidden divide-y divide-gray-100">
@forelse(array_reverse($dates) as $index => $date)
@php
$i = count($dates) - 1 - $index;
$category = $categories[$i] ?? null;
@endphp
<div class="p-4 hover:bg-gray-50 transition-colors">
<div class="flex items-center justify-between mb-3">
<div class="flex items-center gap-2">
<span class="font-medium text-gray-800">{{ \Carbon\Carbon::parse($date)->format('d M Y') }}</span>
@if($index == 0)
<span class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded-full">Terbaru</span>
@endif
</div>
<span class="text-sm font-semibold text-blue-600">{{ $durations[$i] }} mnt</span>
</div>
<div class="grid grid-cols-3 gap-2">
<!-- Mood -->
<div class="bg-gray-50 p-2 rounded-lg">
<p class="text-[10px] text-gray-500 mb-1">Mood</p>
<div class="flex items-center gap-1">
<span class="text-sm">
@if($moods[$i] == 'Bagus') 😊
@elseif($moods[$i] == 'Lumayan') 🙂
@elseif($moods[$i] == 'Biasa Saja') 😐
@elseif($moods[$i] == 'Cukup Jenuh') 😕
@else 😫 @endif
</span>
<span class="text-xs font-medium
@if($moods[$i] == 'Bagus') text-green-600
@elseif($moods[$i] == 'Lumayan') text-blue-600
@elseif($moods[$i] == 'Biasa Saja') text-gray-600
@elseif($moods[$i] == 'Cukup Jenuh') text-yellow-600
@else text-red-600 @endif">
{{ $moods[$i] }}
</span>
</div>
</div>
<!-- Tidur -->
<div class="bg-gray-50 p-2 rounded-lg">
<p class="text-[10px] text-gray-500 mb-1">Tidur</p>
<p class="text-sm font-medium text-gray-800">
{{ $sleep_hours[$i] ?? '7' }} <span class="text-xs text-gray-500">jam</span>
</p>
</div>
<!-- Rekomendasi -->
<div class="bg-gray-50 p-2 rounded-lg">
<p class="text-[10px] text-gray-500 mb-1">Rekom</p>
@if($category)
@php
$parentDisplay = match($category) {
'Ringan' => 'Belajar Ringan',
'Sedang' => 'Belajar Cukup',
'Intensif' => 'Belajar Lama',
default => $category
};
@endphp
<span class="text-xs font-medium px-2 py-0.5 rounded-full inline-block
@if($category == 'Ringan') bg-yellow-100 text-yellow-700
@elseif($category == 'Sedang') bg-green-100 text-green-700
@else bg-blue-100 text-blue-700 @endif">
{{ $parentDisplay }}
</span>
@else
<span class="text-sm text-gray-400">-</span>
@endif
</div>
</div>
</div>
@empty
<div class="p-8 text-center text-gray-500">
<svg class="w-12 h-12 text-gray-300 mx-auto mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
<p>Belum ada data aktivitas</p>
</div>
@endforelse
</div>
</div>
@else
<!-- Empty State dengan Desain Lebih Menarik -->
<div class="bg-gradient-to-br from-gray-50 to-white p-8 md:p-12 rounded-xl border border-gray-200 text-center shadow-sm">
<div class="w-20 h-20 md:w-24 md:h-24 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-10 h-10 md:w-12 md:h-12 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
</div>
<h3 class="text-lg md:text-xl font-semibold text-gray-800 mb-2">Belum Ada Data</h3>
<p class="text-sm md:text-base text-gray-500 mb-4">{{ $child->name }} belum menginput aktivitas belajar</p>
<div class="bg-blue-50 p-3 rounded-lg inline-block">
<p class="text-xs text-blue-700">💡 Ingatkan anak untuk mulai mencatat aktivitas</p>
</div>
</div>
@endif
<!-- Tombol Kembali -->
<div class="flex justify-center">
<a href="{{ route('orangtua.children') }}"
class="flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition text-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
</svg>
Kembali ke Daftar Anak
</a>
</div>
</div>
@endsection
@push('scripts')
@if(count($dates) > 0)
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Format dates untuk tampilan lebih pendek
const dates = {!! json_encode($dates) !!};
const durations = {!! json_encode($durations) !!};
const formattedDates = dates.map(date => {
const d = new Date(date);
return d.toLocaleDateString('id-ID', { day: 'numeric', month: 'short' });
});
// Grafik Durasi
const ctx = document.getElementById('durationChart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: formattedDates,
datasets: [{
label: 'Durasi Belajar (menit)',
data: durations,
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
borderWidth: 3,
tension: 0.3,
fill: true,
pointBackgroundColor: '#3b82f6',
pointBorderColor: 'white',
pointBorderWidth: 2,
pointRadius: 4,
pointHoverRadius: 6
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
backgroundColor: '#1f2937',
callbacks: {
label: function(context) {
return context.raw + ' menit';
}
}
}
},
scales: {
y: {
beginAtZero: true,
grid: { color: '#e5e7eb' },
ticks: {
callback: function(value) {
return value + ' mnt';
}
}
},
x: {
grid: { display: false },
ticks: {
maxRotation: 45,
minRotation: 45,
font: { size: 10 }
}
}
}
}
});
});
</script>
@endif
@endpush