193 lines
4.7 KiB
PHP
193 lines
4.7 KiB
PHP
<?php
|
|
// app/Models/Recommendation.php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
class Recommendation extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
protected $fillable = [
|
|
'user_id',
|
|
'activity_log_id',
|
|
'category',
|
|
'recommended_minutes',
|
|
'notes',
|
|
'based_on',
|
|
'confidence',
|
|
'model_input',
|
|
'recommendation_date',
|
|
];
|
|
|
|
protected $casts = [
|
|
'model_input' => 'array',
|
|
'recommendation_date' => 'date',
|
|
'confidence' => 'float',
|
|
];
|
|
|
|
public function user()
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
public function activityLog()
|
|
{
|
|
return $this->belongsTo(ActivityLog::class);
|
|
}
|
|
|
|
public function getDisplayCategoryAttribute()
|
|
{
|
|
// Gunakan ID rekomendasi + tanggal sebagai seed untuk variasi
|
|
// Agar variasi tetap konsisten untuk rekomendasi yang sama
|
|
$seed = $this->id . $this->recommendation_date->format('Ymd');
|
|
|
|
return match($this->category) {
|
|
'Ringan' => $this->getRandomRingan($seed),
|
|
'Sedang' => $this->getRandomSedang($seed),
|
|
'Intensif' => $this->getRandomIntensif($seed),
|
|
default => $this->category
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Variasi untuk kategori RINGAN
|
|
*/
|
|
private function getRandomRingan($seed)
|
|
{
|
|
$variations = [
|
|
'🌱 Pemanasan aja dulu',
|
|
'😌 Santai aja',
|
|
'🦥 Selow bro',
|
|
'🌸 Mulai pelan-pelan',
|
|
'☕ Rehat bentar, belajar dikit'
|
|
];
|
|
|
|
return $variations[$seed % count($variations)];
|
|
}
|
|
|
|
/**
|
|
* Variasi untuk kategori SEDANG
|
|
*/
|
|
private function getRandomSedang($seed)
|
|
{
|
|
$variations = [
|
|
'📚 Konsisten',
|
|
'⭐ Ideal banget',
|
|
'👍 Belajar cukup',
|
|
'🎯 Tepat sasaran',
|
|
'⚖️ Seimbang'
|
|
];
|
|
|
|
return $variations[$seed % count($variations)];
|
|
}
|
|
|
|
/**
|
|
* Variasi untuk kategori INTENSIF
|
|
*/
|
|
private function getRandomIntensif($seed)
|
|
{
|
|
$variations = [
|
|
'🚀 Gas terus!',
|
|
'💪 Semangat 45',
|
|
'🔥 Maksimal',
|
|
'🏆 Juara hari ini',
|
|
'⚡ Fokus penuh'
|
|
];
|
|
|
|
return $variations[$seed % count($variations)];
|
|
}
|
|
|
|
/**
|
|
* Accessor untuk mendapatkan emoji berdasarkan kategori
|
|
*/
|
|
public function getCategoryEmojiAttribute()
|
|
{
|
|
return match($this->category) {
|
|
'Ringan' => '🌱',
|
|
'Sedang' => '📚',
|
|
'Intensif' => '🚀',
|
|
default => '📖'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* ACCESSOR: Untuk tampilan Orang Tua (formal & mudah dipahami)
|
|
*/
|
|
public function getParentDisplayCategoryAttribute()
|
|
{
|
|
return match($this->category) {
|
|
'Ringan' => 'Belajar Ringan',
|
|
'Sedang' => 'Belajar Cukup',
|
|
'Intensif' => 'Belajar Lama',
|
|
default => $this->category
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
* Accessor untuk warna badge (tetap berdasarkan kategori asli)
|
|
*/
|
|
public function getCategoryColorAttribute()
|
|
{
|
|
return match($this->category) {
|
|
'Ringan' => 'yellow',
|
|
'Sedang' => 'green',
|
|
'Intensif' => 'blue',
|
|
default => 'gray'
|
|
};
|
|
}
|
|
|
|
// Mapping kategori ke durasi
|
|
public static function getDurationByCategory($category)
|
|
{
|
|
return match($category) {
|
|
'Ringan' => 30,
|
|
'Sedang' => 45,
|
|
'Intensif' => 90,
|
|
default => 30,
|
|
};
|
|
}
|
|
|
|
// Mapping mood ke skor (sesuai proposal)
|
|
public static function getMoodScore($mood)
|
|
{
|
|
return match($mood) {
|
|
'Bagus' => 2.0,
|
|
'Lumayan' => 1.5,
|
|
'Biasa Saja' => 1.0,
|
|
'Cukup Jenuh' => 0.5,
|
|
'Jenuh' => 0.0,
|
|
default => 1.0,
|
|
};
|
|
}
|
|
|
|
// Mapping durasi ke skor
|
|
public static function getDurationScore($durationMinutes)
|
|
{
|
|
if ($durationMinutes > 60) return 2.0;
|
|
if ($durationMinutes >= 31) return 1.0;
|
|
return 0.0;
|
|
}
|
|
|
|
// Mapping tidur ke skor
|
|
public static function getSleepScore($sleepDuration)
|
|
{
|
|
return match($sleepDuration) {
|
|
'>7' => 2.0,
|
|
'4-7' => 1.0,
|
|
'<4' => 0.0,
|
|
default => 1.0,
|
|
};
|
|
}
|
|
|
|
// Hitung rekomendasi berdasarkan skor total
|
|
public static function calculateCategory($totalScore)
|
|
{
|
|
if ($totalScore > 4.5) return 'Intensif';
|
|
if ($totalScore > 3) return 'Sedang';
|
|
return 'Ringan';
|
|
}
|
|
} |