572 lines
32 KiB
PHP
572 lines
32 KiB
PHP
{{-- resources/views/siswa/visualization.blade.php --}}
|
|
@extends('layouts.app')
|
|
|
|
@section('title', 'Visualisasi Belajar - LearnMood')
|
|
|
|
@section('content')
|
|
<div class="space-y-6 pb-16 md:pb-0">
|
|
|
|
<!-- Header dengan Gradient -->
|
|
<div class="bg-gradient-to-r from-indigo-600 to-purple-600 rounded-2xl p-4 md:p-6 text-white shadow-lg">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<h2 class="text-xl md:text-2xl font-bold mb-2">Visualisasi Belajar</h2>
|
|
<p class="text-xs md:text-sm text-indigo-100">Lihat perkembangan dan pola belajarmu di sini</p>
|
|
</div>
|
|
<div class="hidden md:block">
|
|
<svg class="w-16 h-16 md:w-20 md:h-20 opacity-20" fill="currentColor" viewBox="0 0 24 24">
|
|
<path d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@if(count($dates) > 0)
|
|
<!-- Filter Periode -->
|
|
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
|
<p class="text-xs md:text-sm text-gray-500">
|
|
Menampilkan data {{ count($dates) }} hari terakhir
|
|
</p>
|
|
<div class="flex bg-white rounded-lg border border-gray-200 p-1 shadow-sm w-full sm:w-auto">
|
|
<a href="{{ route('siswa.visualization', ['period' => 7]) }}"
|
|
class="flex-1 sm:flex-none px-3 md:px-4 py-2 text-xs md:text-sm rounded-md transition {{ $period == 7 ? 'bg-indigo-600 text-white' : 'text-gray-600 hover:bg-gray-100' }}">
|
|
7 Hari
|
|
</a>
|
|
<a href="{{ route('siswa.visualization', ['period' => 30]) }}"
|
|
class="flex-1 sm:flex-none px-3 md:px-4 py-2 text-xs md:text-sm rounded-md transition {{ $period == 30 ? 'bg-indigo-600 text-white' : 'text-gray-600 hover:bg-gray-100' }}">
|
|
30 Hari
|
|
</a>
|
|
<a href="{{ route('siswa.visualization', ['period' => 90]) }}"
|
|
class="flex-1 sm:flex-none px-3 md:px-4 py-2 text-xs md:text-sm rounded-md transition {{ $period == 90 ? 'bg-indigo-600 text-white' : 'text-gray-600 hover:bg-gray-100' }}">
|
|
90 Hari
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistik Cards dengan Animasi -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-3 md:gap-4">
|
|
<!-- Total Hari -->
|
|
<div class="bg-white rounded-xl p-3 md:p-5 shadow-sm border border-gray-100 hover:shadow-md transition-all hover:-translate-y-1">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<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="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>
|
|
<span class="text-[10px] md:text-xs text-gray-400">Total Hari</span>
|
|
</div>
|
|
<p class="text-xl md:text-2xl font-bold text-gray-800">{{ $stats['total_hari'] }}</p>
|
|
<p class="text-[10px] md:text-xs text-gray-500 mt-1">dalam periode ini</p>
|
|
</div>
|
|
|
|
<!-- Rata-rata Durasi -->
|
|
<div class="bg-white rounded-xl p-3 md:p-5 shadow-sm border border-gray-100 hover:shadow-md transition-all hover:-translate-y-1">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<div class="bg-green-100 p-1.5 md:p-2 rounded-lg">
|
|
<svg class="w-4 h-4 md:w-5 md: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>
|
|
<span class="text-[10px] md:text-xs text-gray-400">Rata-rata</span>
|
|
</div>
|
|
<p class="text-xl md:text-2xl font-bold text-gray-800">{{ $stats['rata_durasi'] }} <span class="text-xs md:text-sm font-normal text-gray-500">mnt</span></p>
|
|
<p class="text-[10px] md:text-xs text-gray-500 mt-1">durasi belajar</p>
|
|
</div>
|
|
|
|
<!-- Mood Terbanyak -->
|
|
<div class="bg-white rounded-xl p-3 md:p-5 shadow-sm border border-gray-100 hover:shadow-md transition-all hover:-translate-y-1">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<div class="bg-yellow-100 p-1.5 md:p-2 rounded-lg">
|
|
<svg class="w-4 h-4 md:w-5 md: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>
|
|
<span class="text-[10px] md:text-xs text-gray-400">Mood</span>
|
|
</div>
|
|
<p class="text-base md:text-xl font-bold text-gray-800">{{ $stats['mood_terbanyak'] }}</p>
|
|
<p class="text-[10px] md:text-xs text-gray-500 mt-1">paling sering</p>
|
|
</div>
|
|
|
|
<!-- Rekomendasi Terbanyak -->
|
|
<div class="bg-white rounded-xl p-3 md:p-5 shadow-sm border border-gray-100 hover:shadow-md transition-all hover:-translate-y-1">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<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>
|
|
<span class="text-[10px] md:text-xs text-gray-400">Rekom</span>
|
|
</div>
|
|
<p class="text-base md:text-xl font-bold text-gray-800">{{ $stats['rekom_terbanyak'] }}</p>
|
|
<p class="text-[10px] md:text-xs text-gray-500 mt-1">paling sering</p>
|
|
</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-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">Grafik Durasi Belajar</h3>
|
|
</div>
|
|
<div style="height: 250px;" class="relative">
|
|
<canvas id="durationChart"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Grid 2 Kolom -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 md:gap-6">
|
|
<!-- Mood Distribution -->
|
|
<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-green-100 p-1.5 md:p-2 rounded-lg">
|
|
<svg class="w-4 h-4 md:w-5 md: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="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">Sebaran Mood</h3>
|
|
</div>
|
|
<div style="height: 200px;" class="relative">
|
|
<canvas id="moodChart"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Rekomendasi Distribution -->
|
|
<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">Sebaran Rekomendasi</h3>
|
|
</div>
|
|
<div style="height: 200px;" class="relative">
|
|
<canvas id="recommendationChart"></canvas>
|
|
</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 md:mb-6">
|
|
<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
|
|
// Definisi mood dan emoji
|
|
$moodList = [
|
|
'Bagus' => ['emoji' => '😊', 'color' => 'green', 'bg' => 'green'],
|
|
'Lumayan' => ['emoji' => '🙂', 'color' => 'blue', 'bg' => 'blue'],
|
|
'Biasa Saja' => ['emoji' => '😐', 'color' => 'gray', 'bg' => 'gray'],
|
|
'Cukup Jenuh' => ['emoji' => '😕', 'color' => 'yellow', 'bg' => 'yellow'],
|
|
'Jenuh' => ['emoji' => '😫', 'color' => 'red', 'bg' => 'red']
|
|
];
|
|
|
|
// Hitung rata-rata durasi per mood
|
|
$moodAverages = [];
|
|
foreach ($moodList as $mood => $data) {
|
|
$total = 0;
|
|
$count = 0;
|
|
|
|
foreach ($moods as $index => $m) {
|
|
if ($m == $mood) {
|
|
$total += $durations[$index] ?? 0;
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
$moodAverages[$mood] = [
|
|
'avg' => $count > 0 ? round($total / $count) : 0,
|
|
'count' => $count,
|
|
'emoji' => $data['emoji'],
|
|
'color' => $data['color'],
|
|
'bg' => $data['bg']
|
|
];
|
|
}
|
|
@endphp
|
|
|
|
<div class="grid grid-cols-2 md:grid-cols-5 gap-2 md:gap-3">
|
|
@foreach($moodAverages as $mood => $data)
|
|
<div class="text-center p-2 md:p-4 rounded-xl border border-{{ $data['bg'] }}-200 bg-{{ $data['bg'] }}-50 hover:shadow-md transition-all">
|
|
<div class="text-xl md:text-3xl mb-1 md:mb-2">{{ $data['emoji'] }}</div>
|
|
<p class="text-[10px] md:text-xs font-medium text-gray-600 mb-1 truncate">{{ $mood }}</p>
|
|
<p class="text-base md:text-2xl font-bold text-{{ $data['color'] }}-600">{{ $data['avg'] }}</p>
|
|
<p class="text-[8px] md:text-xs text-gray-500">menit</p>
|
|
<p class="text-[8px] md:text-xs text-gray-400 mt-0.5 md:mt-1">{{ $data['count'] }}x</p>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Insight Card -->
|
|
@php
|
|
$bestMood = array_keys($moodAverages, max($moodAverages))[0] ?? 'Bagus';
|
|
$bestAvg = $moodAverages[$bestMood]['avg'] ?? 0;
|
|
@endphp
|
|
<div class="bg-gradient-to-r from-indigo-500 to-purple-600 rounded-xl p-4 md:p-6 text-white shadow-lg">
|
|
<div class="flex items-start gap-3 md:gap-4">
|
|
<div class="bg-white/20 p-2 md:p-3 rounded-xl backdrop-blur-sm shrink-0">
|
|
<svg class="w-5 h-5 md:w-8 md:h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<h4 class="font-semibold text-sm md:text-lg mb-1">Insight Belajar</h4>
|
|
<p class="text-indigo-100 text-xs md:text-sm">
|
|
Kamu paling produktif saat mood <span class="font-bold">{{ $bestMood }}</span> dengan rata-rata
|
|
<span class="font-bold">{{ $bestAvg }} menit</span> belajar.
|
|
@if($bestAvg > 60)
|
|
Pertahankan semangat belajarmu! 🎉
|
|
@else
|
|
Ayo tingkatkan konsistensi belajarmu! 💪
|
|
@endif
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tabel Riwayat - Mobile Friendly -->
|
|
<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-gray-50 to-gray-100/50">
|
|
<div class="flex items-center gap-2">
|
|
<div class="bg-gray-200 p-1 md:p-1.5 rounded-lg">
|
|
<svg class="w-4 h-4 md:w-5 md:h-5 text-gray-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-semibold text-gray-600 uppercase">Tanggal</th>
|
|
<th class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Durasi</th>
|
|
<th class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Mood</th>
|
|
<th class="px-6 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Tidur</th>
|
|
<th class="px-6 py-3 text-left text-xs font-semibold text-gray-600 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; @endphp
|
|
<tr class="hover:bg-gray-50 transition-colors">
|
|
<td class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap">
|
|
<div class="flex items-center gap-2">
|
|
<span class="w-2 h-2 rounded-full
|
|
@if($moods[$i] == 'Bagus') bg-green-500
|
|
@elseif($moods[$i] == 'Lumayan') bg-blue-500
|
|
@elseif($moods[$i] == 'Biasa Saja') bg-gray-500
|
|
@elseif($moods[$i] == 'Cukup Jenuh') bg-yellow-500
|
|
@else bg-red-500 @endif">
|
|
</span>
|
|
{{ \Carbon\Carbon::parse($date)->format('d M Y') }}
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-800">
|
|
<span class="font-medium">{{ $durations[$i] }}</span> menit
|
|
</td>
|
|
<td class="px-6 py-4">
|
|
<span class="inline-flex items-center gap-1 px-3 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
|
|
@elseif($moods[$i] == 'Jenuh') bg-red-100 text-red-700
|
|
@endif">
|
|
@if($moods[$i] == 'Bagus') 😊
|
|
@elseif($moods[$i] == 'Lumayan') 🙂
|
|
@elseif($moods[$i] == 'Biasa Saja') 😐
|
|
@elseif($moods[$i] == 'Cukup Jenuh') 😕
|
|
@else 😫 @endif
|
|
{{ $moods[$i] }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-800">
|
|
@php
|
|
$sleepValue = $sleep_hours[$i] ?? $activity->sleep_duration ?? 7;
|
|
@endphp
|
|
<span class="font-medium">{{ is_numeric($sleepValue) ? number_format((float)$sleepValue, 1) : $sleepValue }}</span> jam
|
|
</td>
|
|
<td class="px-6 py-4">
|
|
@if(isset($categoriesDisplay[$i]) && $categoriesDisplay[$i] != 'Belum Ada')
|
|
<span class="inline-flex items-center gap-1 px-3 py-1 text-xs rounded-full
|
|
@if(isset($categoriesRaw[$i]) && $categoriesRaw[$i] == 'Ringan') bg-yellow-100 text-yellow-700
|
|
@elseif(isset($categoriesRaw[$i]) && $categoriesRaw[$i] == 'Sedang') bg-green-100 text-green-700
|
|
@elseif(isset($categoriesRaw[$i]) && $categoriesRaw[$i] == 'Intensif') bg-blue-100 text-blue-700
|
|
@endif">
|
|
{{ $categoriesDisplay[$i] }}
|
|
</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">
|
|
<p>Belum ada data aktivitas</p>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{{-- Mobile Card View --}}
|
|
<div class="md:hidden divide-y divide-gray-100">
|
|
@forelse(array_reverse($dates) as $index => $date)
|
|
@php $i = count($dates) - 1 - $index; @endphp
|
|
<div class="p-4 hover:bg-gray-50 transition-colors">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<div class="flex items-center gap-2">
|
|
<span class="w-2 h-2 rounded-full
|
|
@if($moods[$i] == 'Bagus') bg-green-500
|
|
@elseif($moods[$i] == 'Lumayan') bg-blue-500
|
|
@elseif($moods[$i] == 'Biasa Saja') bg-gray-500
|
|
@elseif($moods[$i] == 'Cukup Jenuh') bg-yellow-500
|
|
@else bg-red-500 @endif">
|
|
</span>
|
|
<span class="font-medium text-gray-800">{{ \Carbon\Carbon::parse($date)->format('d M Y') }}</span>
|
|
</div>
|
|
<span class="text-xs text-gray-500">{{ $durations[$i] }} menit</span>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-3 gap-2 text-xs">
|
|
<div class="bg-gray-50 p-2 rounded-lg text-center">
|
|
<span class="text-gray-500 block">Mood</span>
|
|
<span class="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">
|
|
@if($moods[$i] == 'Bagus') 😊
|
|
@elseif($moods[$i] == 'Lumayan') 🙂
|
|
@elseif($moods[$i] == 'Biasa Saja') 😐
|
|
@elseif($moods[$i] == 'Cukup Jenuh') 😕
|
|
@else 😫 @endif
|
|
{{ $moods[$i] }}
|
|
</span>
|
|
</div>
|
|
<div class="bg-gray-50 p-2 rounded-lg text-center">
|
|
<span class="text-gray-500 block">Tidur</span>
|
|
@php
|
|
$sleepValue = $sleep_hours[$i] ?? $activity->sleep_duration ?? 7;
|
|
@endphp
|
|
<span class="font-medium">{{ is_numeric($sleepValue) ? number_format((float)$sleepValue, 1) : $sleepValue }} j</span>
|
|
</div>
|
|
<div class="bg-gray-50 p-2 rounded-lg text-center">
|
|
<span class="text-gray-500 block">Rekom</span>
|
|
@if(isset($categoriesDisplay[$i]) && $categoriesDisplay[$i] != 'Belum Ada')
|
|
<span class="font-medium text-xs block
|
|
@if(isset($categoriesRaw[$i]) && $categoriesRaw[$i] == 'Ringan') text-yellow-600
|
|
@elseif(isset($categoriesRaw[$i]) && $categoriesRaw[$i] == 'Sedang') text-green-600
|
|
@elseif(isset($categoriesRaw[$i]) && $categoriesRaw[$i] == 'Intensif') text-blue-600
|
|
@endif">
|
|
{{ $categoriesDisplay[$i] }}
|
|
</span>
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div class="p-8 text-center text-gray-500">
|
|
<p>Belum ada data aktivitas</p>
|
|
</div>
|
|
@endforelse
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Export Buttons -->
|
|
<div class="flex flex-col sm:flex-row justify-end gap-3">
|
|
<button onclick="window.print()" class="flex items-center justify-center gap-2 px-4 py-2 bg-white border border-gray-200 rounded-lg hover:bg-gray-50 transition text-xs md: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="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"></path>
|
|
</svg>
|
|
<span class="hidden sm:inline">Print</span>
|
|
<span class="sm:hidden">Cetak</span>
|
|
</button>
|
|
<a href="{{ route('siswa.history') }}" class="flex items-center justify-center gap-2 px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition text-xs md: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="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>
|
|
<span class="hidden sm:inline">Lihat Semua Riwayat</span>
|
|
<span class="sm:hidden">Riwayat</span>
|
|
</a>
|
|
</div>
|
|
|
|
@else
|
|
<!-- Empty State dengan Desain Menarik -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
|
<div class="bg-gradient-to-r from-indigo-600 to-purple-600 p-6 md:p-8 text-center">
|
|
<div class="w-20 h-20 md:w-24 md:h-24 bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center mx-auto border-4 border-white/50">
|
|
<svg class="w-8 h-8 md:w-12 md:h-12 text-white" 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-xl md:text-2xl font-bold text-white mt-4">Belum Ada Data</h3>
|
|
<p class="text-indigo-100 text-sm md:text-base mt-2">Mulai input aktivitas belajarmu untuk melihat visualisasi</p>
|
|
</div>
|
|
|
|
<div class="p-4 md:p-8 text-center">
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 max-w-2xl mx-auto mb-6 md:mb-8">
|
|
<div class="text-center p-3 md:p-4">
|
|
<div class="w-10 h-10 md:w-12 md:h-12 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
|
|
<span class="text-blue-600 font-bold text-base md:text-xl">1</span>
|
|
</div>
|
|
<p class="text-xs md:text-sm text-gray-600">Klik <span class="font-semibold">"Input Sekarang"</span></p>
|
|
</div>
|
|
<div class="text-center p-3 md:p-4">
|
|
<div class="w-10 h-10 md:w-12 md:h-12 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
|
|
<span class="text-blue-600 font-bold text-base md:text-xl">2</span>
|
|
</div>
|
|
<p class="text-xs md:text-sm text-gray-600">Isi durasi, mood, tidur</p>
|
|
</div>
|
|
<div class="text-center p-3 md:p-4">
|
|
<div class="w-10 h-10 md:w-12 md:h-12 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
|
|
<span class="text-blue-600 font-bold text-base md:text-xl">3</span>
|
|
</div>
|
|
<p class="text-xs md:text-sm text-gray-600">Lihat grafik & analisis</p>
|
|
</div>
|
|
</div>
|
|
|
|
<a href="{{ route('siswa.input') }}" class="inline-flex items-center px-4 md:px-6 py-2 md:py-3 bg-gradient-to-r from-indigo-600 to-purple-600 text-white rounded-xl hover:from-indigo-700 hover:to-purple-700 transition shadow-lg text-sm md:text-base">
|
|
<svg class="w-4 h-4 md:w-5 md:h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
|
|
</svg>
|
|
Input Sekarang
|
|
</a>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</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() {
|
|
// Data dari controller
|
|
const dates = {!! json_encode($dates) !!};
|
|
const durations = {!! json_encode($durations) !!};
|
|
const moodDistribution = {!! json_encode($moodDistribution) !!};
|
|
|
|
// Format dates untuk tampilan lebih pendek
|
|
const formattedDates = dates.map(date => {
|
|
const d = new Date(date);
|
|
return d.toLocaleDateString('id-ID', { day: 'numeric', month: 'short' });
|
|
});
|
|
|
|
// Grafik Durasi (Line Chart)
|
|
const durCtx = document.getElementById('durationChart').getContext('2d');
|
|
new Chart(durCtx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: formattedDates,
|
|
datasets: [{
|
|
label: 'Durasi Belajar (menit)',
|
|
data: durations,
|
|
borderColor: '#6366f1',
|
|
backgroundColor: 'rgba(99, 102, 241, 0.1)',
|
|
borderWidth: 2,
|
|
tension: 0.3,
|
|
fill: true,
|
|
pointBackgroundColor: '#6366f1',
|
|
pointBorderColor: 'white',
|
|
pointBorderWidth: 1,
|
|
pointRadius: 3,
|
|
pointHoverRadius: 5
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: { display: false },
|
|
tooltip: { backgroundColor: '#1f2937' }
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
ticks: { callback: value => value + ' mnt' }
|
|
},
|
|
x: {
|
|
ticks: { maxRotation: 45, minRotation: 45 }
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Grafik Mood (Pie Chart)
|
|
const moodCtx = document.getElementById('moodChart').getContext('2d');
|
|
new Chart(moodCtx, {
|
|
type: 'doughnut',
|
|
data: {
|
|
labels: Object.keys(moodDistribution),
|
|
datasets: [{
|
|
data: Object.values(moodDistribution),
|
|
backgroundColor: ['#22c55e', '#3b82f6', '#9ca3af', '#eab308', '#ef4444'],
|
|
borderWidth: 0
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
cutout: '65%',
|
|
plugins: {
|
|
legend: {
|
|
position: 'bottom',
|
|
labels: { usePointStyle: true, font: { size: 10 } }
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Grafik Rekomendasi (Bar Chart)
|
|
const recCtx = document.getElementById('recommendationChart').getContext('2d');
|
|
new Chart(recCtx, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: ['Ringan', 'Sedang', 'Intensif'],
|
|
datasets: [{
|
|
data: [
|
|
{{ collect($categoriesRaw)->filter(fn($c) => $c == 'Ringan')->count() }},
|
|
{{ collect($categoriesRaw)->filter(fn($c) => $c == 'Sedang')->count() }},
|
|
{{ collect($categoriesRaw)->filter(fn($c) => $c == 'Intensif')->count() }}
|
|
],
|
|
backgroundColor: ['#eab308', '#22c55e', '#3b82f6'],
|
|
borderRadius: 6
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: { legend: { display: false } },
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
ticks: { stepSize: 1, callback: value => value + 'x' }
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
@endif
|
|
@endpush |