feat: Data Wali Murid diperkaya — relasi (Ayah/Ibu/Wali), email, status akun, perangkat & last active (fix $pending/$baruMingguIni)
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\ParentStudent;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
@@ -16,14 +17,18 @@ class WaliMuridController extends Controller
|
|||||||
{
|
{
|
||||||
$query = User::query()
|
$query = User::query()
|
||||||
->where('role', 'parent')
|
->where('role', 'parent')
|
||||||
->with(['parentStudents' => fn ($q) => $q->with('student:id,nisn,full_name,class_name')]);
|
->with([
|
||||||
|
'parentStudents' => fn ($q) => $q->with('student:id,nisn,full_name,class_name'),
|
||||||
|
'parentDevices',
|
||||||
|
]);
|
||||||
|
|
||||||
if ($request->filled('search')) {
|
if ($request->filled('search')) {
|
||||||
$search = $request->search;
|
$search = $request->search;
|
||||||
$query->where(function ($q) use ($search) {
|
$query->where(function ($q) use ($search) {
|
||||||
$q->where('name', 'like', "%{$search}%")
|
$q->where('name', 'like', "%{$search}%")
|
||||||
->orWhere('username', 'like', "%{$search}%")
|
->orWhere('username', 'like', "%{$search}%")
|
||||||
->orWhere('phone', 'like', "%{$search}%");
|
->orWhere('phone', 'like', "%{$search}%")
|
||||||
|
->orWhere('email', 'like', "%{$search}%");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +38,7 @@ class WaliMuridController extends Controller
|
|||||||
$totalAktif = User::where('role', 'parent')
|
$totalAktif = User::where('role', 'parent')
|
||||||
->whereHas('parentStudents', fn ($q) => $q->where('status', 'active'))
|
->whereHas('parentStudents', fn ($q) => $q->where('status', 'active'))
|
||||||
->count();
|
->count();
|
||||||
$pending = \App\Models\ParentStudent::where('status', 'pending')->count();
|
$pending = ParentStudent::where('status', 'pending')->count();
|
||||||
$baruMingguIni = User::where('role', 'parent')
|
$baruMingguIni = User::where('role', 'parent')
|
||||||
->where('created_at', '>=', now()->subDays(7))
|
->where('created_at', '>=', now()->subDays(7))
|
||||||
->count();
|
->count();
|
||||||
|
|||||||
@@ -146,6 +146,15 @@ class User extends Authenticatable
|
|||||||
return $this->hasMany(\App\Models\ParentStudent::class, 'user_id');
|
return $this->hasMany(\App\Models\ParentStudent::class, 'user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perangkat (HP/browser) yang pernah dipakai wali untuk FCM push.
|
||||||
|
*/
|
||||||
|
public function parentDevices()
|
||||||
|
{
|
||||||
|
return $this->hasMany(\App\Models\ParentDevice::class, 'user_id')
|
||||||
|
->orderByDesc('last_active_at');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anak-anak (siswa) milik akun wali, hanya yang statusnya aktif.
|
* Anak-anak (siswa) milik akun wali, hanya yang statusnya aktif.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -138,8 +138,9 @@
|
|||||||
<thead class="bg-gradient-to-r from-slate-50 to-blue-50/40">
|
<thead class="bg-gradient-to-r from-slate-50 to-blue-50/40">
|
||||||
<tr class="text-left text-[11px] font-bold text-slate-400 uppercase tracking-wider">
|
<tr class="text-left text-[11px] font-bold text-slate-400 uppercase tracking-wider">
|
||||||
<th class="px-6 py-3.5">Wali</th>
|
<th class="px-6 py-3.5">Wali</th>
|
||||||
<th class="px-6 py-3.5">Nomor HP</th>
|
<th class="px-6 py-3.5">Kontak</th>
|
||||||
<th class="px-6 py-3.5">Putra/Putri Tertaut</th>
|
<th class="px-6 py-3.5">Putra/Putri Tertaut</th>
|
||||||
|
<th class="px-6 py-3.5">Perangkat</th>
|
||||||
<th class="px-6 py-3.5">Terdaftar</th>
|
<th class="px-6 py-3.5">Terdaftar</th>
|
||||||
<th class="px-6 py-3.5 text-right">Aksi</th>
|
<th class="px-6 py-3.5 text-right">Aksi</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -155,16 +156,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="font-semibold text-sm text-gray-800">{{ $user->name }}</p>
|
<p class="font-semibold text-sm text-gray-800 flex items-center gap-2">
|
||||||
|
{{ $user->name }}
|
||||||
|
@php $relations = collect($user->parentStudents)->pluck('relation')->filter(); @endphp
|
||||||
|
@if($relations->contains('father'))
|
||||||
|
<span class="px-1.5 py-0.5 rounded-md bg-sky-50 border border-sky-100 text-sky-600 text-[9px] font-bold">AYAH</span>
|
||||||
|
@elseif($relations->contains('mother'))
|
||||||
|
<span class="px-1.5 py-0.5 rounded-md bg-pink-50 border border-pink-100 text-pink-600 text-[9px] font-bold">IBU</span>
|
||||||
|
@elseif($relations->contains('guardian'))
|
||||||
|
<span class="px-1.5 py-0.5 rounded-md bg-violet-50 border border-violet-100 text-violet-600 text-[9px] font-bold">WALI</span>
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
<p class="text-[11px] text-slate-400 font-mono">{{ $user->username }}</p>
|
<p class="text-[11px] text-slate-400 font-mono">{{ $user->username }}</p>
|
||||||
|
<span class="inline-flex items-center gap-1 mt-0.5 text-[10px] {{ $user->is_active ? 'text-emerald-500' : 'text-red-400' }}">
|
||||||
|
<span class="w-1.5 h-1.5 rounded-full {{ $user->is_active ? 'bg-emerald-500' : 'bg-red-400' }}"></span>
|
||||||
|
{{ $user->is_active ? 'Akun aktif' : 'Akun nonaktif' }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<span class="inline-flex items-center gap-1.5 text-sm text-slate-600">
|
<div class="flex flex-col gap-1.5 text-sm text-slate-600">
|
||||||
|
<span class="inline-flex items-center gap-1.5">
|
||||||
<i class="fa-solid fa-phone text-[11px] text-slate-300"></i>
|
<i class="fa-solid fa-phone text-[11px] text-slate-300"></i>
|
||||||
{{ $user->phone ?? '-' }}
|
{{ $user->phone ?? '-' }}
|
||||||
</span>
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1.5 text-xs {{ $user->email ? 'text-slate-500' : 'text-slate-300' }}">
|
||||||
|
<i class="fa-regular fa-envelope text-[11px]"></i>
|
||||||
|
{{ $user->email ?? 'tanpa email' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
@if($user->parentStudents->isEmpty())
|
@if($user->parentStudents->isEmpty())
|
||||||
@@ -197,6 +218,35 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
@if($user->parentDevices->isEmpty())
|
||||||
|
<span class="text-xs text-slate-400">Belum ada perangkat</span>
|
||||||
|
@else
|
||||||
|
<div class="flex flex-col gap-1.5">
|
||||||
|
@foreach($user->parentDevices as $device)
|
||||||
|
<span class="inline-flex items-center gap-2 text-xs">
|
||||||
|
@if($device->platform === 'android')
|
||||||
|
<span class="w-6 h-6 rounded-lg bg-gradient-to-br from-emerald-50 to-green-100 text-emerald-600 flex items-center justify-center">
|
||||||
|
<i class="fa-solid fa-mobile-screen text-[10px]"></i>
|
||||||
|
</span>
|
||||||
|
@elseif($device->platform === 'ios')
|
||||||
|
<span class="w-6 h-6 rounded-lg bg-gradient-to-br from-slate-100 to-slate-200 text-slate-500 flex items-center justify-center">
|
||||||
|
<i class="fa-brands fa-apple text-[10px]"></i>
|
||||||
|
</span>
|
||||||
|
@else
|
||||||
|
<span class="w-6 h-6 rounded-lg bg-gradient-to-br from-sky-50 to-blue-100 text-blue-500 flex items-center justify-center">
|
||||||
|
<i class="fa-solid fa-globe text-[10px]"></i>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
<div>
|
||||||
|
<p class="font-medium text-slate-600">{{ $device->device_name }}</p>
|
||||||
|
<p class="text-[10px] text-slate-400">aktif {{ $device->last_active_at?->diffForHumans() }}</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<span class="inline-flex items-center gap-1.5 text-xs text-slate-500">
|
<span class="inline-flex items-center gap-1.5 text-xs text-slate-500">
|
||||||
<i class="fa-regular fa-calendar text-slate-300"></i>
|
<i class="fa-regular fa-calendar text-slate-300"></i>
|
||||||
|
|||||||
Reference in New Issue
Block a user