pagination & search

This commit is contained in:
Savema 2026-03-26 10:11:42 +07:00
parent 2c9bf3307d
commit 01bf741a46
14 changed files with 422 additions and 182 deletions

View File

@ -10,10 +10,19 @@ class AnakController extends Controller
/**
* Display a listing of the resource.
*/
public function index()
public function index(Request $request)
{
$balita = Anak::latest()->get();
return view('balita.data-balita', compact('balita'));
// $balita = Anak::latest()->get();
$search = $request->search;
$balita = Anak::query()
->when($search, function ($query) use ($search) {
$query->where('nama', 'like', "%{$search}%");
})
->paginate(10);
return view('balita.data-balita', compact('balita', 'search'));
}
/**

View File

@ -4,6 +4,7 @@
use App\Models\Anak;
use App\Models\IbuHamil;
use App\Models\PengukuranBalita;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@ -13,18 +14,37 @@ class DashboardController extends Controller
{
public function index()
{
$total_ibu_hamil = IbuHamil::count();
$total_balita = Anak::count();
$total_petugas = User::count();
// 1. Hitung Total Data Statis
$total_balita = \App\Models\Anak::count();
$total_ibu_hamil = \App\Models\IbuHamil::count();
$total_petugas = \App\Models\User::count();
$grafik = IbuHamil::select(
DB::raw('MONTH(created_at) as bulan'),
DB::raw('count(*) as total')
)
->groupBy('bulan')
->orderBy('bulan')
->get();
// 2. Hitung Balita yang terdeteksi Stunting (Hasil Terakhir)
$total_stunting = \App\Models\PengukuranBalita::where('hasil', 'Stunting')->count();
return view('dashboard.index', compact( 'total_ibu_hamil', 'total_balita', 'total_petugas', 'grafik'));
// 3. Siapkan Data Grafik (6 Bulan Terakhir)
$label_bulan = [];
$grafik_balita = [];
$grafik_ibu = [];
for ($i = 5; $i >= 0; $i--) {
$bulan = now()->subMonths($i);
$label_bulan[] = $bulan->translatedFormat('M'); // Contoh: Jan, Feb, Mar
// Hitung jumlah pengukuran balita di bulan tersebut
$grafik_balita[] = \App\Models\PengukuranBalita::whereMonth('tanggal', $bulan->month)
->whereYear('tanggal', $bulan->year)
->count();
// Hitung jumlah pengukuran ibu hamil di bulan tersebut
$grafik_ibu[] = \App\Models\PengukuranIbuHamil::whereMonth('tanggal', $bulan->month)
->whereYear('tanggal', $bulan->year)
->count();
}
return view('dashboard.index', compact(
'total_balita', 'total_ibu_hamil', 'total_petugas',
'total_stunting', 'label_bulan', 'grafik_balita', 'grafik_ibu'
));
}
}

View File

@ -7,10 +7,17 @@
class EdukasiController extends Controller
{
public function index()
public function index(Request $request)
{
$t_edukasi = Edukasi::latest()->get();
return view('edukasi.edukasi', compact('t_edukasi'));
$search = $request->search;
$t_edukasi = Edukasi::query()
->when($search, function ($query) use ($search) {
$query->where('judul', 'like', "%{$search}%");
})
->paginate(10);
return view('edukasi.edukasi', compact('t_edukasi', 'search'));
}
/**

View File

@ -7,10 +7,17 @@
class IbuHamilController extends Controller
{
public function index()
public function index(Request $request)
{
$ibu_hamil = IbuHamil::latest()->get();
return view('ibu_hamil.data-ibuhamil', compact('ibu_hamil'));
$search = $request->search;
$ibu_hamil = IbuHamil::query()
->when($search, function ($query) use ($search) {
$query->where('nama', 'like', "%{$search}%");
})
->paginate(10);
return view('ibu_hamil.data-ibuhamil', compact('ibu_hamil', 'search'));
}
public function create()

View File

@ -11,14 +11,21 @@
class PengukuranBalitaController extends Controller
{
public function index()
public function index(Request $request)
{
$search = $request->search;
$p_balita = PengukuranBalita::with(['balita','petugas'])->get();
$p_balita = PengukuranBalita::with(['balita','petugas'])
->when($search, function ($query) use ($search) {
$query->whereHas('balita', function ($q) use ($search) {
$q->where('nama', 'like', "%{$search}%");
});
})
->paginate(10);
// $ibu->usia = Carbon::parse($ibu->tgl_lahir)->age;
// return $ibu;
return view('pengukuran_balita.data', compact('p_balita'));
return view('pengukuran_balita.data', compact('p_balita', 'search'));
}
public function create()

View File

@ -15,14 +15,21 @@
class PengukuranIbuHamilController extends Controller
{
public function index()
public function index(Request $request)
{
$search = $request->search;
$p_ibuhamil = PengukuranIbuHamil::with(['ibuHamil','petugas'])->get();
$p_ibuhamil = PengukuranIbuHamil::with(['ibuhamil','petugas'])
->when($search, function ($query) use ($search) {
$query->whereHas('ibuhamil', function ($q) use ($search) {
$q->where('nama', 'like', "%{$search}%");
});
})
->paginate(10);
// $ibu->usia = Carbon::parse($ibu->tgl_lahir)->age;
// return $ibu;
return view('pengukuran_ibuhamil.data', compact('p_ibuhamil'));
return view('pengukuran_ibuhamil.data', compact('p_ibuhamil', 'search'));
}
public function create()

View File

@ -7,9 +7,19 @@
class UsersController extends Controller
{
public function index()
public function index(Request $request)
{
$user = User::latest()->get();
$search = $request->search;
$user = User::query()
->when($search, function ($query) use ($search) {
$query->where('nama', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%")
->orWhere('no_hp', 'like', "%{$search}%")
->orWhere('role', 'like', "%{$search}%");
})
->paginate(10);
return view('users.users', compact('user'));
}

View File

@ -22,6 +22,18 @@
</a>
</div>
<form method="GET" action="{{ route('balita.index') }}" class="mb-3">
<div class="input-group" style="max-width: 300px;">
<input type="text" name="search" class="form-control" id="search"
placeholder="Cari nama..."
value="{{ request('search') }}">
<button class="btn btn-primary" type="submit">
<i class="bi bi-search"></i> Cari
</button>
</div>
</form>
<!-- Table -->
<div class="table-responsive">
<table class="table table-hover align-middle datatable">
@ -36,10 +48,10 @@
<th style="width: 15%" class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
<tbody id="balita-table">
@forelse ($balita as $index => $balitas)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ $balita->firstItem() + $index }}</td>
<td>{{ $balitas->nama }}</td>
<td>{{ $balitas->alamat }}</td>
<td>{{ $balitas->tgl_lahir }}</td>
@ -84,32 +96,33 @@ class="btn btn-sm btn-warning me-1" title="Edit">
</table>
</div>
{{-- <div class="card">
<div class="card-body">
<h5 class="card-title">Pagination with icon</h5>
<!-- Pagination with icons -->
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</nav><!-- End Pagination with icons -->
<div class="d-flex justify-content-center mt-3">
{{ $balita->withQueryString()->links() }}
</div>
</div>
</div> --}}
</div>
</div>
<script>
let delayTimer;
document.getElementById('search').addEventListener('keyup', function () {
clearTimeout(delayTimer);
let query = this.value;
delayTimer = setTimeout(() => {
fetch(`{{ route('balita.index') }}?search=` + query)
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let newTable = doc.querySelector('#balita-table').innerHTML;
document.getElementById('balita-table').innerHTML = newTable;
});
}, 300);
});
</script>
@endsection

View File

@ -5,119 +5,100 @@
@section('content')
<div class="pagetitle mb-4">
<h1 style="color: #9c3a5b;">Dashboard</h1>
<h1 style="color: #9c3a5b;">Dashboard Utama</h1>
</div>
<section class="section dashboard">
<div class="row g-4">
<!-- Balita -->
<div class="col-xl-4 col-md-6">
<div class="col-xl-3 col-md-6">
<div class="card info-card h-100 border-start border-danger border-4">
<div class="card-body">
<h5 class="card-title">Stunting <span>| Total</span></h5>
<div class="d-flex align-items-center">
<div class="card-icon rounded-circle d-flex align-items-center justify-content-center bg-danger text-white">
<i class="bi bi-exclamation-triangle"></i>
</div>
<div class="ps-3">
<h6 class="text-danger mb-0">{{ $total_stunting }}</h6>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card info-card h-100">
<div class="card-body">
<h5 class="card-title text-danger">
Balita <span>| Total</span>
</h5>
<h5 class="card-title">Balita <span>| Terdaftar</span></h5>
<div class="d-flex align-items-center">
<div class="card-icon rounded-circle d-flex align-items-center justify-content-center text-danger">
<div class="card-icon rounded-circle d-flex align-items-center justify-content-center bg-primary-light text-primary">
<i class="bi bi-emoji-laughing"></i>
</div>
<div class="ps-3">
<h6 class="text-danger mb-0">{{ $total_balita }}</h6>
<h6>{{ $total_balita }}</h6>
</div>
</div>
</div>
</div>
</div>
<!-- Balita Risiko Stunting -->
<div class="col-xl-4 col-md-6">
<div class="col-xl-3 col-md-6">
<div class="card info-card h-100">
<div class="card-body">
<h5 class="card-title text-danger">
Pengguna <span>| Total</span>
</h5>
<h5 class="card-title">Ibu Hamil <span>| Terdaftar</span></h5>
<div class="d-flex align-items-center">
<div class="card-icon rounded-circle d-flex align-items-center justify-content-center text-danger">
<i class="bi bi-person"></i>
</div>
<div class="ps-3">
<h6 class="text-danger mb-0">{{ $total_petugas }}</h6>
</div>
</div>
</div>
</div>
</div>
<!-- Ibu Hamil -->
<div class="col-xl-4 col-md-6">
<div class="card info-card h-100">
<div class="card-body">
<h5 class="card-title text-danger">
Ibu Hamil <span>| Total</span>
</h5>
<div class="d-flex align-items-center">
<div class="card-icon rounded-circle d-flex align-items-center justify-content-center text-danger">
<div class="card-icon rounded-circle d-flex align-items-center justify-content-center bg-success-light text-success">
<i class="bi bi-person-check"></i>
</div>
<div class="ps-3">
<h6 class="text-danger mb-0">{{ $total_ibu_hamil }}</h6>
<h6>{{ $total_ibu_hamil }}</h6>
</div>
</div>
</div>
</div>
</div>
<!-- Reports -->
<div class="col-12">
<div class="card">
<div class="filter">
<a class="icon" href="#" data-bs-toggle="dropdown"><i class="bi bi-three-dots"></i></a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
<li class="dropdown-header text-start">
<h6>Filter</h6>
</li>
<li><a class="dropdown-item" href="#">Today</a></li>
<li><a class="dropdown-item" href="#">This Month</a></li>
<li><a class="dropdown-item" href="#">This Year</a></li>
</ul>
</div>
<div class="col-xl-3 col-md-6">
<div class="card info-card h-100">
<div class="card-body">
<h5 class="card-title">Reports <span>/Today</span></h5>
<h5 class="card-title">Petugas <span>| Aktif</span></h5>
<div class="d-flex align-items-center">
<div class="card-icon rounded-circle d-flex align-items-center justify-content-center bg-info-light text-info">
<i class="bi bi-person"></i>
</div>
<div class="ps-3">
<h6>{{ $total_petugas }}</h6>
</div>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">Laporan Aktivitas Pengukuran <span>/6 Bulan Terakhir</span></h5>
<!-- Line Chart -->
<div id="reportsChart"></div>
<script>
document.addEventListener("DOMContentLoaded", () => {
new ApexCharts(document.querySelector("#reportsChart"), {
series: [{
name: 'Sales',
data: [31, 40, 28, 51, 42, 82, 56],
name: 'Pengukuran Balita',
data: @json($grafik_balita)
}, {
name: 'Revenue',
data: [11, 32, 45, 32, 34, 52, 41]
}, {
name: 'Customers',
data: [15, 11, 32, 18, 9, 24, 11]
name: 'Pengukuran Ibu Hamil',
data: @json($grafik_ibu)
}],
chart: {
height: 350,
type: 'area',
toolbar: {
show: false
toolbar: { show: false },
},
},
markers: {
size: 4
},
colors: ['#4154f1', '#2eca6a', '#ff771d'],
markers: { size: 4 },
colors: ['#9c3a5b', '#2eca6a'],
fill: {
type: "gradient",
gradient: {
@ -127,31 +108,23 @@
stops: [0, 90, 100]
}
},
dataLabels: {
enabled: false
},
dataLabels: { enabled: false },
stroke: {
curve: 'smooth',
width: 2
width: 3
},
xaxis: {
type: 'datetime',
categories: ["2018-09-19T00:00:00.000Z", "2018-09-19T01:30:00.000Z", "2018-09-19T02:30:00.000Z", "2018-09-19T03:30:00.000Z", "2018-09-19T04:30:00.000Z", "2018-09-19T05:30:00.000Z", "2018-09-19T06:30:00.000Z"]
categories: @json($label_bulan),
},
tooltip: {
x: {
format: 'dd/MM/yy HH:mm'
},
x: { format: 'dd/MM/yy' },
}
}).render();
});
</script>
<!-- End Line Chart -->
</div>
</div>
</div><!-- End Reports -->
</div>
</div>
</section>

View File

@ -22,6 +22,18 @@
</a>
</div>
<form method="GET" action="{{ route('edukasi.index') }}" class="mb-3">
<div class="input-group" style="max-width: 300px;">
<input type="text" name="search" class="form-control" id="search"
placeholder="Cari judul..."
value="{{ request('search') }}">
<button class="btn btn-primary" type="submit">
<i class="bi bi-search"></i> Cari
</button>
</div>
</form>
<!-- Table -->
<div class="table-responsive">
<table class="table table-hover align-middle datatable">
@ -35,10 +47,10 @@
<th style="width: 15%" class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
<tbody id="edukasi-table">
@forelse ($t_edukasi as $index => $t_edukasis)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ $t_edukasi->firstItem() + $index }}</td>
<td>{{ $t_edukasis->kategori }}</td>
<td>{{ $t_edukasis->judul }}</td>
<td>{{ $t_edukasis->konten }}</td>
@ -84,7 +96,33 @@ class="btn btn-sm btn-warning me-1" title="Edit">
</table>
</div>
<div class="d-flex justify-content-center mt-3">
{{ $t_edukasi->withQueryString()->links() }}
</div>
</div>
</div>
<script>
let delayTimer;
document.getElementById('search').addEventListener('keyup', function () {
clearTimeout(delayTimer);
let query = this.value;
delayTimer = setTimeout(() => {
fetch(`{{ route('edukasi.index') }}?search=` + query)
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let newTable = doc.querySelector('#edukasi-table').innerHTML;
document.getElementById('edukasi-table').innerHTML = newTable;
});
}, 300);
});
</script>
@endsection

View File

@ -22,6 +22,18 @@
</a>
</div>
<form method="GET" action="{{ route('ibu_hamil.index') }}" class="mb-3">
<div class="input-group" style="max-width: 300px;">
<input type="text" name="search" class="form-control" id="search"
placeholder="Cari nama..."
value="{{ request('search') }}">
<button class="btn btn-primary" type="submit">
<i class="bi bi-search"></i> Cari
</button>
</div>
</form>
<!-- Table -->
<div class="table-responsive">
<table class="table table-hover align-middle datatable">
@ -35,10 +47,10 @@
<th style="width: 15%" class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
<tbody id="ibu-hamil-table">
@forelse ($ibu_hamil as $index => $ibu_hamils)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ $ibu_hamil->firstItem() + $index }}</td>
<td>{{ $ibu_hamils->nama }}</td>
<td>{{ $ibu_hamils->tgl_lahir }}</td>
<td>{{ $ibu_hamils->alamat }}</td>
@ -78,7 +90,33 @@ class="btn btn-sm btn-warning me-1" title="Edit">
</table>
</div>
<div class="d-flex justify-content-center mt-3">
{{ $ibu_hamil->withQueryString()->links() }}
</div>
</div>
</div>
<script>
let delayTimer;
document.getElementById('search').addEventListener('keyup', function () {
clearTimeout(delayTimer);
let query = this.value;
delayTimer = setTimeout(() => {
fetch(`{{ route('ibu_hamil.index') }}?search=` + query)
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let newTable = doc.querySelector('#ibu-hamil-table').innerHTML;
document.getElementById('ibu-hamil-table').innerHTML = newTable;
});
}, 300);
});
</script>
@endsection

View File

@ -22,6 +22,18 @@
</a>
</div>
<form method="GET" action="{{ route('pengukuran_balita.index') }}" class="mb-3">
<div class="input-group" style="max-width: 300px;">
<input type="text" name="search" class="form-control" id="search"
placeholder="Cari nama..."
value="{{ request('search') }}">
<button class="btn btn-primary" type="submit">
<i class="bi bi-search"></i> Cari
</button>
</div>
</form>
<!-- Table -->
<div class="table-responsive">
<table class="table table-hover align-middle datatable">
@ -40,14 +52,14 @@
<th style="width: 15%" class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
<tbody id="pengukuran-balita-table">
@forelse ($p_balita as $index => $balita)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ $p_balita->firstItem() + $index }}</td>
<td>{{ $balita->petugas->nama ?? '-' }}</td>
<td>{{ $balita->tanggal }}</td>
<td>{{ $balita->balita->nama ?? '-' }}</td>
<td>{{ \Carbon\Carbon::parse($balita->balita->tgl_lahir)->age ?? '-' }}</td>
<td>{{ \Carbon\Carbon::parse($balita->balita->tgl_lahir)->diffInMonths(\Carbon\Carbon::parse($balita->tanggal)) }} Bulan</td>
<td>{{ $balita->berat_badan }}</td>
<td>{{ $balita->tinggi_badan }}</td>
<td>{{ $balita->lingkar_kepala }}</td>
@ -88,9 +100,32 @@ class="btn btn-sm btn-info"
</table>
</div>
<div class="d-flex justify-content-center mt-3">
{{ $p_balita->withQueryString()->links() }}
</div>
</div>
</div>
<script>
let delayTimer;
document.getElementById('search').addEventListener('keyup', function () {
clearTimeout(delayTimer);
let query = this.value;
delayTimer = setTimeout(() => {
fetch(`{{ route('pengukuran_balita.index') }}?search=` + query)
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let newTable = doc.querySelector('#pengukuran-balita-table').innerHTML;
document.getElementById('pengukuran-balita-table').innerHTML = newTable;
});
}, 300);
});
</script>
@endsection

View File

@ -22,6 +22,18 @@
</a>
</div>
<form method="GET" action="{{ route('pengukuran_ibu_hamil.index') }}" class="mb-3">
<div class="input-group" style="max-width: 300px;">
<input type="text" name="search" class="form-control" id="search"
placeholder="Cari nama..."
value="{{ request('search') }}">
<button class="btn btn-primary" type="submit">
<i class="bi bi-search"></i> Cari
</button>
</div>
</form>
<!-- Table -->
<div class="table-responsive">
<table class="table table-hover align-middle datatable">
@ -41,10 +53,10 @@
<th style="width: 15%" class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
<tbody id="pengukuran-ibuhamil-table">
@forelse ($p_ibuhamil as $index => $ibu)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ $p_ibuhamil->firstItem() + $index }}</td>
<td>{{ $ibu->petugas->nama ?? '-' }}</td>
<td>{{ $ibu->tanggal }}</td>
<td>{{ $ibu->ibuHamil->nama ?? '-' }}</td>
@ -90,7 +102,33 @@ class="btn btn-sm btn-info"
</table>
</div>
<div class="d-flex justify-content-center mt-3">
{{ $p_ibuhamil->withQueryString()->links() }}
</div>
</div>
</div>
<script>
let delayTimer;
document.getElementById('search').addEventListener('keyup', function () {
clearTimeout(delayTimer);
let query = this.value;
delayTimer = setTimeout(() => {
fetch(`{{ route('pengukuran_ibu_hamil.index') }}?search=` + query)
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let newTable = doc.querySelector('#pengukuran-ibuhamil-table').innerHTML;
document.getElementById('pengukuran-ibuhamil-table').innerHTML = newTable;
});
}, 300);
});
</script>
@endsection

View File

@ -22,9 +22,21 @@
</a>
</div>
<form method="GET" action="{{ route('users.index') }}" class="mb-3">
<div class="input-group" style="max-width: 300px;">
<input type="text" name="search" class="form-control" id="search"
placeholder="Cari nama, email, no HP..."
value="{{ request('search') }}">
<button class="btn btn-primary" type="submit">
<i class="bi bi-search"></i> Cari
</button>
</div>
</form>
<!-- Table -->
<div class="table-responsive">
<table class="table table-hover align-middle datatable">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr>
<th style="width: 5%">No</th>
@ -35,10 +47,10 @@
<th style="width: 15%" class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
<tbody id="user-table">
@forelse ($user as $index => $users)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ $user->firstItem() + $index }}</td>
<td>{{ $users->nama }}</td>
<td>{{ $users->no_hp }}</td>
<td>{{ $users->email }}</td>
@ -78,7 +90,33 @@ class="btn btn-sm btn-warning me-1" title="Edit">
</table>
</div>
<div class="d-flex justify-content-center mt-3">
{{ $user->withQueryString()->links() }}
</div>
</div>
</div>
<script>
let delayTimer;
document.getElementById('search').addEventListener('keyup', function () {
clearTimeout(delayTimer);
let query = this.value;
delayTimer = setTimeout(() => {
fetch(`{{ route('users.index') }}?search=` + query)
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let newTable = doc.querySelector('#user-table').innerHTML;
document.getElementById('user-table').innerHTML = newTable;
});
}, 300);
});
</script>
@endsection