validasi kelola tps
This commit is contained in:
parent
83ffa58000
commit
7100ed2342
|
|
@ -4,14 +4,17 @@
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\LokasiTps;
|
||||
use App\Models\AduanTps;
|
||||
use App\Models\Sampah;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$totalTps = \App\Models\LokasiTps::count();
|
||||
$totalAduan = \App\Models\AduanTps::count();
|
||||
$sampahTerbaru = \App\Models\Sampah::orderBy('created_at', 'desc')->first();
|
||||
$totalTps = LokasiTps::count();
|
||||
$totalAduan = AduanTps::count();
|
||||
$sampahTerbaru = Sampah::orderBy('created_at', 'desc')->first();
|
||||
|
||||
return view('admin.index', compact(
|
||||
'totalTps',
|
||||
|
|
@ -19,5 +22,4 @@ public function index()
|
|||
'sampahTerbaru'
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public function index()
|
|||
$tps = LokasiTps::with('kategori')
|
||||
->withCount('aduan')
|
||||
->get();
|
||||
|
||||
return view('admin.tps.index', compact('title', 'tps'));
|
||||
}
|
||||
|
||||
|
|
@ -23,53 +24,113 @@ public function create()
|
|||
{
|
||||
$title = 'Tambah TPS';
|
||||
$kategori = KategoriTps::all();
|
||||
|
||||
return view('admin.tps.create', compact('title', 'kategori'));
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| KONVERSI KOORDINAT (DECIMAL / DMS)
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
private function convertToDecimal($coordinate)
|
||||
{
|
||||
if (is_numeric($coordinate)) {
|
||||
return (float) $coordinate;
|
||||
}
|
||||
|
||||
$coordinate = html_entity_decode($coordinate);
|
||||
$coordinate = strtoupper(trim($coordinate));
|
||||
$coordinate = str_replace(
|
||||
['°', "'", '"'],
|
||||
[' ', ' ', ' '],
|
||||
$coordinate
|
||||
);
|
||||
preg_match('/([NSEW])/', $coordinate, $dirMatch);
|
||||
if (!$dirMatch) return null;
|
||||
$direction = $dirMatch[1];
|
||||
$coordinate = str_replace(['°', "'", '"'], [' ', ' ', ' '], $coordinate);
|
||||
|
||||
preg_match('/([NSEW])/', $coordinate, $dir);
|
||||
if (!$dir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
preg_match_all('/\d+(\.\d+)?/', $coordinate, $numbers);
|
||||
if (count($numbers[0]) < 3) return null;
|
||||
if (count($numbers[0]) < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
[$deg, $min, $sec] = array_map('floatval', $numbers[0]);
|
||||
$decimal = $deg + ($min / 60) + ($sec / 3600);
|
||||
if (in_array($direction, ['S', 'W'])) {
|
||||
|
||||
if (in_array($dir[1], ['S', 'W'])) {
|
||||
$decimal *= -1;
|
||||
}
|
||||
|
||||
return $decimal;
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| STORE (CREATE)
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
// VALIDASI DASAR + PESAN CUSTOM
|
||||
$request->validate(
|
||||
[
|
||||
'kategori_tps_id' => 'required|exists:kategori_tps,id_kategori_tps',
|
||||
'nama_tps' => 'required|string|max:255',
|
||||
'alamat_tps' => 'required|string|max:255',
|
||||
'status_tps' => 'required',
|
||||
'tahun_pembuatan' => 'required|numeric',
|
||||
'kapasitas_tps' => 'required',
|
||||
'status_tps' => 'required|in:Aktif,Tidak Aktif,Pembangunan',
|
||||
'tahun_pembuatan' => 'required|digits:4',
|
||||
'kapasitas_tps' => 'required|integer|min:1',
|
||||
'latitude' => 'required',
|
||||
'longitude' => 'required',
|
||||
'foto_tps' => 'nullable|image|mimes:jpg,jpeg,png|max:2048',
|
||||
]);
|
||||
],
|
||||
[
|
||||
'kategori_tps_id.required' => 'Kategori TPS wajib dipilih.',
|
||||
'kategori_tps_id.exists' => 'Kategori TPS tidak valid.',
|
||||
|
||||
'nama_tps.required' => 'Nama TPS wajib diisi.',
|
||||
'alamat_tps.required' => 'Alamat TPS wajib diisi.',
|
||||
|
||||
'status_tps.required' => 'Status TPS wajib dipilih.',
|
||||
'status_tps.in' => 'Status TPS tidak valid.',
|
||||
|
||||
'tahun_pembuatan.required' => 'Tahun pembuatan wajib diisi.',
|
||||
'tahun_pembuatan.digits' => 'Tahun pembuatan harus 4 digit (contoh: 2022).',
|
||||
|
||||
'kapasitas_tps.required' => 'Kapasitas TPS wajib diisi.',
|
||||
'kapasitas_tps.integer' => 'Kapasitas TPS harus berupa angka.',
|
||||
'kapasitas_tps.min' => 'Kapasitas TPS minimal 1.',
|
||||
|
||||
'latitude.required' => 'Latitude wajib diisi.',
|
||||
'longitude.required' => 'Longitude wajib diisi.',
|
||||
|
||||
'foto_tps.image' => 'Foto TPS harus berupa gambar.',
|
||||
'foto_tps.mimes' => 'Format foto TPS harus jpg, jpeg, atau png.',
|
||||
]
|
||||
);
|
||||
|
||||
// VALIDASI KOORDINAT (TIDAK DOBEL ERROR)
|
||||
$latitude = $this->convertToDecimal($request->latitude);
|
||||
$longitude = $this->convertToDecimal($request->longitude);
|
||||
if ($latitude === null || $longitude === null) {
|
||||
return back()->withErrors(['Koordinat tidak valid'])->withInput();
|
||||
|
||||
$errors = [];
|
||||
|
||||
if ($latitude === null || $latitude < -90 || $latitude > 90) {
|
||||
$errors['latitude'] = 'Latitude tidak valid. Contoh: -7.623 atau 7.623';
|
||||
}
|
||||
|
||||
if ($longitude === null || $longitude < -180 || $longitude > 180) {
|
||||
$errors['longitude'] = 'Longitude tidak valid. Contoh: 111.980 atau -111.980';
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
return back()->withErrors($errors)->withInput();
|
||||
}
|
||||
|
||||
// UPLOAD FOTO
|
||||
$foto = $request->hasFile('foto_tps')
|
||||
? $request->file('foto_tps')->store('foto-tps', 'public')
|
||||
: null;
|
||||
|
||||
LokasiTps::create([
|
||||
'kategori_tps_id' => $request->kategori_tps_id,
|
||||
'nama_tps' => $request->nama_tps,
|
||||
|
|
@ -81,38 +142,68 @@ public function store(Request $request)
|
|||
'longitude' => $longitude,
|
||||
'foto_tps' => $foto,
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.tps.index')
|
||||
->with('success', 'Data TPS berhasil ditambahkan');
|
||||
->with('success', 'Data TPS berhasil ditambahkan.');
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| EDIT
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$title = 'Edit TPS';
|
||||
$tps = LokasiTps::findOrFail($id);
|
||||
$kategori = KategoriTps::all();
|
||||
|
||||
return view('admin.tps.edit', compact('title', 'tps', 'kategori'));
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| UPDATE
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$tps = LokasiTps::findOrFail($id);
|
||||
$request->validate([
|
||||
|
||||
$request->validate(
|
||||
[
|
||||
'kategori_tps_id' => 'required|exists:kategori_tps,id_kategori_tps',
|
||||
'nama_tps' => 'required|string|max:255',
|
||||
'alamat_tps' => 'required|string|max:255',
|
||||
'status_tps' => 'required',
|
||||
'tahun_pembuatan' => 'required|numeric',
|
||||
'kapasitas_tps' => 'required',
|
||||
'status_tps' => 'required|in:Aktif,Tidak Aktif,Pembangunan',
|
||||
'tahun_pembuatan' => 'required|digits:4',
|
||||
'kapasitas_tps' => 'required|integer|min:1',
|
||||
'latitude' => 'required',
|
||||
'longitude' => 'required',
|
||||
'foto_tps' => 'nullable|image|mimes:jpg,jpeg,png|max:4096',
|
||||
]);
|
||||
],
|
||||
[
|
||||
'tahun_pembuatan.digits' => 'Tahun pembuatan harus 4 digit.',
|
||||
]
|
||||
);
|
||||
|
||||
$latitude = $this->convertToDecimal($request->latitude);
|
||||
$longitude = $this->convertToDecimal($request->longitude);
|
||||
if ($latitude === null || $longitude === null) {
|
||||
return back()
|
||||
->withErrors(['Koordinat tidak valid. Gunakan format Decimal atau DMS.'])
|
||||
->withInput();
|
||||
|
||||
$errors = [];
|
||||
|
||||
if ($latitude === null || $latitude < -90 || $latitude > 90) {
|
||||
$errors['latitude'] = 'Latitude tidak valid.';
|
||||
}
|
||||
|
||||
if ($longitude === null || $longitude < -180 || $longitude > 180) {
|
||||
$errors['longitude'] = 'Longitude tidak valid.';
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
return back()->withErrors($errors)->withInput();
|
||||
}
|
||||
|
||||
if ($request->hasFile('foto_tps')) {
|
||||
if ($tps->foto_tps) {
|
||||
Storage::disk('public')->delete($tps->foto_tps);
|
||||
|
|
@ -121,6 +212,7 @@ public function update(Request $request, $id)
|
|||
} else {
|
||||
$foto = $tps->foto_tps;
|
||||
}
|
||||
|
||||
$tps->update([
|
||||
'kategori_tps_id' => $request->kategori_tps_id,
|
||||
'nama_tps' => $request->nama_tps,
|
||||
|
|
@ -132,18 +224,27 @@ public function update(Request $request, $id)
|
|||
'longitude' => $longitude,
|
||||
'foto_tps' => $foto,
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.tps.index')
|
||||
->with('success', 'Data TPS berhasil diperbarui');
|
||||
->with('success', 'Data TPS berhasil diperbarui.');
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DELETE
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$tps = LokasiTps::findOrFail($id);
|
||||
|
||||
if ($tps->foto_tps) {
|
||||
Storage::disk('public')->delete($tps->foto_tps);
|
||||
}
|
||||
|
||||
$tps->delete();
|
||||
|
||||
return redirect()->route('admin.tps.index')
|
||||
->with('success', 'Data TPS berhasil dihapus');
|
||||
->with('success', 'Data TPS berhasil dihapus.');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,6 @@ public function destroy(Request $request): RedirectResponse
|
|||
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect('/index');
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ public function index()
|
|||
$sampah = Sampah::orderBy('tahun', 'desc')->first();
|
||||
$kategoriTps = KategoriTps::orderBy('id_kategori_tps')->get();
|
||||
$lokasiTps = LokasiTps::all();
|
||||
$jumlahTps = LokasiTps::where('kategori_tps_id', '3')->count();
|
||||
$jumlahTps3r = LokasiTps::where('kategori_tps_id', '5')->count();
|
||||
$jumlahTpa = LokasiTps::where('kategori_tps_id', '6')->count();
|
||||
|
||||
return view('user.index', compact('sampah', 'kategoriTps', 'lokasiTps'));
|
||||
return view('user.index', compact('sampah', 'kategoriTps', 'lokasiTps', 'jumlahTps', 'jumlahTps3r', 'jumlahTpa'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3068,3 +3068,120 @@ .btn-lokasi:focus:hover {
|
|||
color: var(--contrast-color);
|
||||
background: color-mix(in srgb, var(--accent-color), transparent 15%);
|
||||
}
|
||||
|
||||
/* ================================
|
||||
GEO STAT SECTION – FINAL VERSION
|
||||
================================ */
|
||||
|
||||
.geo-stat-section {
|
||||
position: relative;
|
||||
padding: 50px 0;
|
||||
background: #ffffff;
|
||||
color: #2f2f2f;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Badge kecil */
|
||||
.geo-badge {
|
||||
font-size: 13px;
|
||||
letter-spacing: 1px;
|
||||
color: var(--heading-color);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Judul utama */
|
||||
.geo-title {
|
||||
font-size: 38px;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
margin: 12px 0;
|
||||
color: var(--accent-color)
|
||||
}
|
||||
|
||||
/* Deskripsi */
|
||||
.geo-desc {
|
||||
font-size: 15px;
|
||||
color: #6b7280;
|
||||
max-width: 420px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ================================
|
||||
STATISTIK AREA
|
||||
================================ */
|
||||
|
||||
.geo-stats {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.geo-item {
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Icon box */
|
||||
.geo-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
margin: 0 auto 14px;
|
||||
background: rgba(11, 93, 59, 0.08);
|
||||
color: #0b5d3b;
|
||||
}
|
||||
|
||||
/* Variasi icon */
|
||||
.geo-icon.recycle {
|
||||
background: rgba(32, 201, 151, 0.18);
|
||||
color: #20c997;
|
||||
}
|
||||
|
||||
.geo-icon.location {
|
||||
background: rgba(255, 193, 7, 0.18);
|
||||
color: #f59f00;
|
||||
}
|
||||
|
||||
/* Angka statistik */
|
||||
.geo-item h3 {
|
||||
font-size: 46px;
|
||||
font-weight: 800;
|
||||
color: var(--heading-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Label bawah angka */
|
||||
.geo-item span {
|
||||
font-size: 14px;
|
||||
letter-spacing: .6px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
/* Garis pemisah */
|
||||
.geo-line {
|
||||
width: 2px;
|
||||
height: 110px;
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* ================================
|
||||
RESPONSIVE (AMAN MOBILE)
|
||||
================================ */
|
||||
@media (max-width: 768px) {
|
||||
.geo-stats {
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.geo-line {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.geo-title {
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
<tr>
|
||||
<th>TPS</th>
|
||||
<th>Nama Pelapor</th>
|
||||
{{-- <th>Alamat Pelapor</th> --}}
|
||||
<th>Tanggal Aduan</th>
|
||||
<th>Status</th>
|
||||
<th class="text-center">Aksi</th>
|
||||
|
|
@ -33,7 +32,6 @@
|
|||
<tbody>
|
||||
@forelse ($aduan as $item)
|
||||
<tr>
|
||||
<!-- TPS -->
|
||||
<td>
|
||||
<strong>
|
||||
{{ $item->lokasiTps->nama_tps ?? '-' }}
|
||||
|
|
@ -43,19 +41,10 @@
|
|||
{{ $item->lokasiTps->alamat_tps ?? '' }}
|
||||
</small>
|
||||
</td>
|
||||
|
||||
<!-- Pelapor -->
|
||||
<td>{{ $item->nama_pelapor }}</td>
|
||||
|
||||
<!-- Alamat -->
|
||||
{{-- <td>{{ $item->alamat_pelapor }}</td> --}}
|
||||
|
||||
<!-- Tanggal -->
|
||||
<td>
|
||||
{{ \Carbon\Carbon::parse($item->tanggal_aduan)->format('d M Y') }}
|
||||
</td>
|
||||
|
||||
<!-- Status -->
|
||||
<td>
|
||||
@if ($item->tanggapan_admin)
|
||||
<span class="badge badge-success">Ditanggapi</span>
|
||||
|
|
@ -63,8 +52,6 @@
|
|||
<span class="badge badge-danger">Belum</span>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
<!-- Aksi -->
|
||||
<td class="text-center">
|
||||
<a href="{{ route('admin.aduan.show', $item->id_aduan) }}"
|
||||
class="btn btn-warning btn-sm"
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
@section('content')
|
||||
<div class="content-wrapper">
|
||||
<div class="row">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12 grid-margin stretch-card">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Profil Admin</h4>
|
||||
|
||||
<h4 class="mb-4 card-title">Profil Admin</h4>
|
||||
|
||||
@if (session('success'))
|
||||
<div class="alert alert-success">
|
||||
|
|
@ -14,45 +15,87 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('admin.profil.update') }}" method="POST">
|
||||
<form action="{{ route('admin.profil.update') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
|
||||
<div class="row">
|
||||
|
||||
<!-- KIRI : FOTO -->
|
||||
<div class="text-center col-md-4 border-right">
|
||||
|
||||
<img
|
||||
src="{{ $admin->foto
|
||||
? asset('storage/foto-admin/' . $admin->foto)
|
||||
: asset('assets/admin/images/user.jpg') }}"
|
||||
class="mb-3 rounded-circle"
|
||||
width="160"
|
||||
height="160"
|
||||
style="object-fit: cover;"
|
||||
>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="file" name="foto" class="form-control-file">
|
||||
<small class="mt-2 text-muted d-block">
|
||||
JPG / PNG, maksimal 2MB
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- KANAN : FORM -->
|
||||
<div class="col-md-8">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Nama</label>
|
||||
<input type="text" name="name" class="form-control" value="{{ $admin->name }}"
|
||||
required>
|
||||
<input type="text" name="name"
|
||||
class="form-control"
|
||||
value="{{ $admin->name }}" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Username</label>
|
||||
<input type="text" name="username" class="form-control" value="{{ $admin->username }}"
|
||||
required>
|
||||
<input type="text" name="username"
|
||||
class="form-control"
|
||||
value="{{ $admin->username }}" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Role</label>
|
||||
<input type="text" class="form-control" value="{{ $admin->role }}" disabled>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
value="{{ $admin->role }}" disabled>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Password Baru (opsional)</label>
|
||||
<input type="password" name="password" class="form-control"
|
||||
<input type="password"
|
||||
name="password"
|
||||
class="form-control"
|
||||
placeholder="Kosongkan jika tidak diganti">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Konfirmasi Password</label>
|
||||
<input type="password" name="password_confirmation" class="form-control">
|
||||
<input type="password"
|
||||
name="password_confirmation"
|
||||
class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Simpan
|
||||
</button>
|
||||
<a href="{{ url()->previous() }}" class="btn btn-light ml-2">
|
||||
|
||||
<a href="{{ url()->previous() }}"
|
||||
class="ml-2 btn btn-light">
|
||||
Batal
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -9,85 +9,103 @@
|
|||
<h4 class="card-title">Tambah Data TPS</h4>
|
||||
<p class="card-description">Form tambah data TPS</p>
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<form action="{{ route('admin.tps.store') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
|
||||
<!-- NAMA TPS -->
|
||||
<div class="form-group">
|
||||
<label>Nama TPS</label>
|
||||
<input type="text" name="nama_tps" class="form-control" placeholder="Nama TPS" required>
|
||||
<input type="text" name="nama_tps" class="form-control"
|
||||
value="{{ old('nama_tps') }}"
|
||||
placeholder="Nama TPS">
|
||||
@error('nama_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- ALAMAT -->
|
||||
<div class="form-group">
|
||||
<label>Alamat</label>
|
||||
<input type="text" name="alamat_tps" class="form-control" placeholder="Alamat TPS"
|
||||
required>
|
||||
<input type="text" name="alamat_tps" class="form-control"
|
||||
value="{{ old('alamat_tps') }}"
|
||||
placeholder="Alamat TPS">
|
||||
@error('alamat_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Kecamatan</label>
|
||||
<input type="text" name="kecamatan" class="form-control" placeholder="Kecamatan TPS"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<!-- KATEGORI TPS -->
|
||||
<!-- KATEGORI -->
|
||||
<div class="form-group">
|
||||
<label>Kategori TPS</label>
|
||||
<select name="kategori_tps_id" class="form-control" required>
|
||||
<select name="kategori_tps_id" class="form-control">
|
||||
<option value="">Pilih Kategori</option>
|
||||
@foreach ($kategori as $item)
|
||||
<option value="{{ $item->id_kategori_tps }}">
|
||||
<option value="{{ $item->id_kategori_tps }}"
|
||||
{{ old('kategori_tps_id') == $item->id_kategori_tps ? 'selected' : '' }}>
|
||||
{{ $item->nama_kategori }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('kategori_tps_id')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- TAHUN -->
|
||||
<div class="form-group">
|
||||
<label>Tahun Pembuatan</label>
|
||||
<input type="number" name="tahun_pembuatan" class="form-control"
|
||||
placeholder="Tahun Pembuatan" required>
|
||||
value="{{ old('tahun_pembuatan') }}"
|
||||
placeholder="Contoh: 2022">
|
||||
@error('tahun_pembuatan')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- KAPASITAS -->
|
||||
<div class="form-group">
|
||||
<label>Kapasitas</label>
|
||||
<input type="text" name="kapasitas_tps" class="form-control" placeholder="Kapasitas TPS"
|
||||
required>
|
||||
<input type="text" name="kapasitas_tps" class="form-control"
|
||||
value="{{ old('kapasitas_tps') }}"
|
||||
placeholder="Kapasitas TPS">
|
||||
@error('kapasitas_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- STATUS -->
|
||||
<div class="form-group">
|
||||
<label>Status</label>
|
||||
<select name="status_tps" class="form-control" required>
|
||||
<option value="Aktif">Aktif</option>
|
||||
<option value="Non-Aktif">Tidak Aktif</option>
|
||||
<option value="Pembangunan">Pembangunan</option>
|
||||
<select name="status_tps" class="form-control">
|
||||
<option value="Aktif" {{ old('status_tps') == 'Aktif' ? 'selected' : '' }}>Aktif</option>
|
||||
<option value="Tidak Aktif" {{ old('status_tps') == 'Tidak Aktif' ? 'selected' : '' }}>Tidak Aktif</option>
|
||||
<option value="Pembangunan" {{ old('status_tps') == 'Pembangunan' ? 'selected' : '' }}>Pembangunan</option>
|
||||
</select>
|
||||
@error('status_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- LATITUDE -->
|
||||
<div class="form-group">
|
||||
<label>Latitude</label>
|
||||
<input type="text" name="latitude" class="form-control"
|
||||
placeholder="Contoh: 7°35'17.25"S" required>
|
||||
value="{{ old('latitude') }}"
|
||||
placeholder="Contoh: -7.623 atau 7°35'17.25"S">
|
||||
@error('latitude')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- LONGITUDE -->
|
||||
<div class="form-group">
|
||||
<label>Longitude</label>
|
||||
<input type="text" name="longitude" class="form-control"
|
||||
placeholder="Contoh: 111°55'0.97"E" required>
|
||||
value="{{ old('longitude') }}"
|
||||
placeholder="Contoh: 111.980 atau 111°55'0.97"E">
|
||||
@error('longitude')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- FOTO -->
|
||||
|
|
@ -105,6 +123,10 @@
|
|||
</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@error('foto_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<button type="submit" class="mr-2 btn btn-primary">Simpan</button>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
@php
|
||||
function decimalToDms($decimal, $type = 'lat')
|
||||
{
|
||||
if ($decimal === null || $decimal === '') return '';
|
||||
if ($decimal === null || $decimal === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$direction = $decimal >= 0
|
||||
? ($type === 'lat' ? 'N' : 'E')
|
||||
: ($type === 'lat' ? 'S' : 'W');
|
||||
$direction = $decimal >= 0 ? ($type === 'lat' ? 'N' : 'E') : ($type === 'lat' ? 'S' : 'W');
|
||||
|
||||
$decimal = abs($decimal);
|
||||
|
||||
|
|
@ -31,10 +31,8 @@ function decimalToDms($decimal, $type = 'lat')
|
|||
Form edit data Tempat Pembuangan Sampah
|
||||
</p>
|
||||
|
||||
<form action="{{ route('admin.tps.update', $tps->id_tps) }}"
|
||||
method="POST"
|
||||
enctype="multipart/form-data"
|
||||
class="forms-sample">
|
||||
<form action="{{ route('admin.tps.update', $tps->id_tps) }}" method="POST"
|
||||
enctype="multipart/form-data" class="forms-sample">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
|
|
@ -42,20 +40,20 @@ class="forms-sample">
|
|||
<div class="form-group">
|
||||
<label>Nama TPS</label>
|
||||
<input type="text" name="nama_tps" class="form-control"
|
||||
value="{{ old('nama_tps', $tps->nama_tps) }}" required>
|
||||
value="{{ old('nama_tps') ?? $tps->nama_tps }}" required>
|
||||
@error('nama_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
{{-- Alamat --}}
|
||||
<div class="form-group">
|
||||
<label>Alamat</label>
|
||||
<input type="text" name="alamat_tps" class="form-control"
|
||||
value="{{ old('alamat_tps', $tps->alamat_tps) }}" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Kecamatan</label>
|
||||
<input type="text" name="kecamatan" class="form-control"
|
||||
value="{{ old('kecamatan', $tps->kecamatan) }}" required>
|
||||
value="{{ old('alamat_tps') ?? $tps->alamat_tps }}" required>
|
||||
@error('alamat_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
{{-- Kategori TPS --}}
|
||||
|
|
@ -65,63 +63,81 @@ class="forms-sample">
|
|||
<option value="">-- Pilih Kategori --</option>
|
||||
@foreach ($kategori as $item)
|
||||
<option value="{{ $item->id_kategori_tps }}"
|
||||
{{ old('kategori_tps_id', $tps->kategori_tps_id) == $item->id_kategori_tps ? 'selected' : '' }}>
|
||||
{{ (old('kategori_tps_id') ?? $tps->kategori_tps_id) == $item->id_kategori_tps ? 'selected' : '' }}>
|
||||
{{ $item->nama_kategori }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('kategori_tps_id')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
{{-- Tahun Pembuatan --}}
|
||||
<div class="form-group">
|
||||
<label>Tahun Pembuatan</label>
|
||||
<input type="number" name="tahun_pembuatan" class="form-control"
|
||||
value="{{ old('tahun_pembuatan', $tps->tahun_pembuatan) }}" required>
|
||||
value="{{ old('tahun_pembuatan') ?? $tps->tahun_pembuatan }}" required>
|
||||
@error('tahun_pembuatan')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
{{-- Kapasitas TPS --}}
|
||||
<div class="form-group">
|
||||
<label>Kapasitas TPS</label>
|
||||
<input type="text" name="kapasitas_tps" class="form-control"
|
||||
value="{{ old('kapasitas_tps', $tps->kapasitas_tps) }}" required>
|
||||
<input type="number" name="kapasitas_tps" class="form-control"
|
||||
value="{{ old('kapasitas_tps') ?? $tps->kapasitas_tps }}" required>
|
||||
@error('kapasitas_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
{{-- Status TPS --}}
|
||||
<div class="form-group">
|
||||
<label>Status TPS</label>
|
||||
<select name="status_tps" class="form-control" required>
|
||||
<option value="Aktif" {{ old('status_tps', $tps->status_tps) == 'Aktif' ? 'selected' : '' }}>
|
||||
Aktif
|
||||
</option>
|
||||
<option value="Tidak Aktif" {{ old('status_tps', $tps->status_tps) == 'Tidak Aktif' ? 'selected' : '' }}>
|
||||
Tidak Aktif
|
||||
</option>
|
||||
<option value="Pembangunan" {{ old('status_tps', $tps->status_tps) == 'Pembangunan' ? 'selected' : '' }}>
|
||||
Pembangunan
|
||||
<option value="Aktif"
|
||||
{{ (old('status_tps') ?? $tps->status_tps) == 'Aktif' ? 'selected' : '' }}>Aktif
|
||||
</option>
|
||||
<option value="Tidak Aktif"
|
||||
{{ (old('status_tps') ?? $tps->status_tps) == 'Tidak Aktif' ? 'selected' : '' }}>
|
||||
Tidak Aktif</option>
|
||||
<option value="Pembangunan"
|
||||
{{ (old('status_tps') ?? $tps->status_tps) == 'Pembangunan' ? 'selected' : '' }}>
|
||||
Pembangunan</option>
|
||||
</select>
|
||||
@error('status_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
{{-- Latitude (DMS) --}}
|
||||
{{-- Latitude --}}
|
||||
<div class="form-group">
|
||||
<label>Latitude</label>
|
||||
<input type="text" name="latitude" class="form-control"
|
||||
placeholder="Contoh: 7°35'17.25"S"
|
||||
value="{{ old('latitude', decimalToDms($tps->latitude, 'lat')) }}" required>
|
||||
<input type="text" name="latitude" class="form-control" placeholder="Contoh: 7°35'17.25S"
|
||||
value="{{ old('latitude') ?? decimalToDms($tps->latitude, 'lat') }}" required>
|
||||
@error('latitude')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
{{-- Longitude (DMS) --}}
|
||||
{{-- Longitude --}}
|
||||
<div class="form-group">
|
||||
<label>Longitude</label>
|
||||
<input type="text" name="longitude" class="form-control"
|
||||
placeholder="Contoh: 111°55'0.97"E"
|
||||
value="{{ old('longitude', decimalToDms($tps->longitude, 'lng')) }}" required>
|
||||
placeholder="Contoh: 111°55'0.97E"
|
||||
value="{{ old('longitude') ?? decimalToDms($tps->longitude, 'lng') }}" required>
|
||||
@error('longitude')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
{{-- Foto TPS --}}
|
||||
<div class="form-group">
|
||||
<label>Foto TPS</label>
|
||||
<input type="file" name="foto_tps" class="file-upload-default">
|
||||
|
||||
<input type="file" name="foto_tps" id="foto_tps" class="file-upload-default">
|
||||
|
||||
<div class="input-group col-xs-12">
|
||||
<input type="text" class="form-control file-upload-info" disabled
|
||||
|
|
@ -133,23 +149,21 @@ class="forms-sample">
|
|||
</span>
|
||||
</div>
|
||||
|
||||
{{-- Foto Lama --}}
|
||||
@error('foto_tps')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
|
||||
@if ($tps->foto_tps)
|
||||
<div class="mt-2">
|
||||
<img src="{{ asset('storage/' . $tps->foto_tps) }}"
|
||||
width="250"
|
||||
<img src="{{ asset('storage/' . $tps->foto_tps) }}" width="250"
|
||||
class="img-thumbnail">
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Button --}}
|
||||
<button type="submit" class="mr-2 btn btn-primary">
|
||||
Simpan
|
||||
</button>
|
||||
<a href="{{ route('admin.tps.index') }}" class="btn btn-light">
|
||||
Batal
|
||||
</a>
|
||||
<button type="submit" class="mr-2 btn btn-primary">Simpan</button>
|
||||
<a href="{{ route('admin.tps.index') }}" class="btn btn-light">Batal</a>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -157,4 +171,22 @@ class="img-thumbnail">
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.querySelectorAll('.file-upload-browse').forEach(function(button) {
|
||||
button.addEventListener('click', function() {
|
||||
this.closest('.form-group')
|
||||
.querySelector('.file-upload-default')
|
||||
.click();
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.file-upload-default').forEach(function(input) {
|
||||
input.addEventListener('change', function() {
|
||||
const fileName = this.files[0]?.name || '';
|
||||
this.closest('.form-group')
|
||||
.querySelector('.file-upload-info')
|
||||
.value = fileName;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -1,67 +1,30 @@
|
|||
<?php
|
||||
public function create()
|
||||
{
|
||||
$title = 'Tambah Data Sampah';
|
||||
$users = User::all();
|
||||
return view('admin.sampah.create', compact('title', 'users'));
|
||||
}
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'tahun' => 'required|numeric',
|
||||
'total_sampah' => 'required|numeric',
|
||||
'total_kelola' => 'required|numeric',
|
||||
'total_daur_ulang' => 'required|numeric',
|
||||
]);
|
||||
$sisa_sampah = $request->total_sampah
|
||||
- ($request->total_kelola + $request->total_daur_ulang);
|
||||
Sampah::create([
|
||||
'user_id' => Auth::id(),
|
||||
'tahun' => $request->tahun,
|
||||
'total_sampah' => $request->total_sampah,
|
||||
'total_kelola' => $request->total_kelola,
|
||||
'total_daur_ulang' => $request->total_daur_ulang,
|
||||
'sisa_sampah' => $sisa_sampah,
|
||||
]);
|
||||
return redirect()->route('admin.sampah.index')
|
||||
->with('success', 'Data sampah berhasil ditambahkan');
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$title = 'Edit Data Sampah';
|
||||
$sampah = Sampah::findOrFail($id);
|
||||
$users = User::all();
|
||||
return view('admin.sampah.edit', compact('title', 'sampah', 'users'));
|
||||
}
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$sampah = Sampah::findOrFail($id);
|
||||
$request->validate([
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'tahun' => 'required|numeric',
|
||||
'total_sampah' => 'required|numeric',
|
||||
'total_kelola' => 'required|numeric',
|
||||
'total_daur_ulang' => 'required|numeric',
|
||||
]);
|
||||
$sisa_sampah = $request->total_sampah
|
||||
- ($request->total_kelola + $request->total_daur_ulang);
|
||||
$sampah->update([
|
||||
'user_id' => $request->user_id,
|
||||
'tahun' => $request->tahun,
|
||||
'total_sampah' => $request->total_sampah,
|
||||
'total_kelola' => $request->total_kelola,
|
||||
'total_daur_ulang' => $request->total_daur_ulang,
|
||||
'sisa_sampah' => $sisa_sampah,
|
||||
]);
|
||||
return redirect()->route('admin.sampah.index')
|
||||
->with('success', 'Data sampah berhasil diperbarui');
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$sampah = Sampah::findOrFail($id);
|
||||
$sampah->delete();
|
||||
return redirect()->route('admin.sampah.index')
|
||||
->with('success', 'Data sampah berhasil dihapus');
|
||||
}
|
||||
<tbody>
|
||||
@foreach ($kategori as $item)
|
||||
<tr>
|
||||
<td>{{ $item->nama_kategori }}</td>
|
||||
<td>
|
||||
@if ($item->foto_kategori)
|
||||
<img src="{{ asset('storage/' . $item->foto_kategori) }}" class="img-thumbnail" width="100">
|
||||
@else
|
||||
<span class="text-muted">-</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<div class="deskripsi-truncate-div">
|
||||
{{ $item->deskripsi ?? '-' }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{{ route('admin.kategori.edit', $item->id_kategori_tps) }}">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
</a>
|
||||
<form action="{{ route('admin.tps.destroy', $item->id_kategori_tps) }}" method="POST" class="form-hapus">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-danger btn-sm">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@
|
|||
<h1>Selamat Datang di <span>SIG TPS</span></h1>
|
||||
<p>Sistem Informasi Geografis Pemetaan Tempat Pembuangan Sampah di Kabupaten Nganjuk</p>
|
||||
<div class="d-flex">
|
||||
<a href="#about" class="btn-get-started scrollto">Lihat Peta</a>
|
||||
<!-- <a href="https://www.youtube.com/watch?v=Y7f98aduVJ8" class="glightbox btn-watch-video d-flex align-items-center"><i class="bi bi-play-circle"></i><span>Watch Video</span></a> -->
|
||||
<a href="{{ route('user.sig-tps') }}" class="btn-get-started scrollto">Lihat Peta</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -19,12 +18,11 @@
|
|||
<section id="featured-services" class="featured-services section">
|
||||
<div class="container">
|
||||
|
||||
<!-- Section Title -->
|
||||
<div class="text-center section-title" data-aos="fade-up">
|
||||
<h2>Timbulan Sampah</h2>
|
||||
<p>Data berikut menunjukkan total timbulan, pengelolaan, daur ulang, dan sisa sampah dalam <strong>ton per
|
||||
hari</strong>.</p>
|
||||
</div>
|
||||
<div class="container section-title" data-aos="fade-up">
|
||||
<h2>Sampah</h2>
|
||||
<p>Total sampah yang terkumpul di seluruh wilayah Kabupaten Nganjuk pada tahun
|
||||
{{ $sampah->tahun ?? 'Tahun Tidak Tersedia' }}</p>
|
||||
</div><!-- End Section Title -->
|
||||
|
||||
<div class="row gy-4">
|
||||
|
||||
|
|
@ -34,10 +32,10 @@
|
|||
<div class="icon">
|
||||
<i class="bi bi-trash2 icon"></i>
|
||||
</div>
|
||||
<h1>
|
||||
<h2>
|
||||
{{ number_format($sampah->total_sampah ?? 0, 2, ',', '.') }}
|
||||
</h1>
|
||||
<p><strong>Total Timbulan Sampah</strong></p>
|
||||
</h2>
|
||||
<p>Total Timbulan Sampah (ton)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -47,10 +45,10 @@
|
|||
<div class="icon">
|
||||
<i class="bi bi-gear icon"></i>
|
||||
</div>
|
||||
<h1>
|
||||
<h2>
|
||||
{{ number_format($sampah->total_kelola ?? 0, 2, ',', '.') }}
|
||||
</h1>
|
||||
<p><strong>Total Sampah Dikelola</strong></p>
|
||||
</h2>
|
||||
<p>Total Sampah Dikelola (ton)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -60,10 +58,10 @@
|
|||
<div class="icon">
|
||||
<i class="bi bi-recycle icon"></i>
|
||||
</div>
|
||||
<h1>
|
||||
<h2>
|
||||
{{ number_format($sampah->total_daur_ulang ?? 0, 2, ',', '.') }}
|
||||
</h1>
|
||||
<p><strong>Total Sampah Didaur Ulang</strong></p>
|
||||
</h2>
|
||||
<p>Total Sampah Didaur Ulang (ton)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -73,10 +71,10 @@
|
|||
<div class="icon">
|
||||
<i class="bi bi-exclamation-triangle icon"></i>
|
||||
</div>
|
||||
<h1>
|
||||
<h2>
|
||||
{{ number_format($sampah->sisa_sampah ?? 0, 2, ',', '.') }}
|
||||
</h1>
|
||||
<p><strong>Total Sisa Sampah</strong></p>
|
||||
</h2>
|
||||
<p>Total Sisa Sampah (ton)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -98,54 +96,40 @@
|
|||
</div><!-- End Section Title -->
|
||||
|
||||
<div class="container" data-aos="fade-up">
|
||||
|
||||
<div class="row g-4 g-lg-5" data-aos="fade-up" data-aos-delay="200">
|
||||
|
||||
<div class="col-lg-5">
|
||||
<div class="about-img">
|
||||
<img src="{{ asset('assets/user/img/tentang-lg.png') }}" class="img-fluid" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-7">
|
||||
<h3 class="pt-0 pt-lg-5">Sistem Informasi Geografis Tempat Pembuangan Sampah di Kabupaten Nganjuk</h3>
|
||||
|
||||
<!-- Tab Content -->
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="about-tab1">
|
||||
|
||||
<p class="fst-italic">Sistem Informasi Geografis yang menampilkan visualisasi lokasi Tempat
|
||||
Pembuangan Sampah di Kabupaten Nganjuk secara mudah, cepat, dan interaktif.</p>
|
||||
|
||||
<div class="mt-4 d-flex align-items-center">
|
||||
<i class="bi bi-check2"></i>
|
||||
<h4>Peta Interaktif Lokasi TPS</h4>
|
||||
</div>
|
||||
<p>Peta digital yang memudahkan pengguna menemukan lokasi TPS terdekat, lengkap dengan tampilan
|
||||
yang intuitif sehingga informasi dapat diakses dengan cepat dan jelas.</p>
|
||||
|
||||
<div class="mt-4 d-flex align-items-center">
|
||||
<i class="bi bi-check2"></i>
|
||||
<h4>Informasi TPS Lengkap</h4>
|
||||
</div>
|
||||
<p>Menyajikan berbagai informasi penting seperti kapasitas, kondisi, status, hingga jenis
|
||||
pengelolaan TPS, sehingga pengguna dapat memahami keadaan TPS secara menyeluruh.</p>
|
||||
|
||||
<div class="mt-4 d-flex align-items-center">
|
||||
<i class="bi bi-check2"></i>
|
||||
<h4>Layanan Aduan TPS</h4>
|
||||
</div>
|
||||
<p>Fitur yang memungkinkan masyarakat menyampaikan keluhan atau laporan terkait TPS dengan
|
||||
mudah, membantu pemerintah dalam memperbaiki serta meningkatkan pengelolaan sampah.</p>
|
||||
|
||||
</div><!-- End Tab 1 Content -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section><!-- /About Section -->
|
||||
|
|
@ -191,7 +175,6 @@
|
|||
<p>
|
||||
{{ explode('.', $item->deskripsi)[0] }}.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -201,266 +184,172 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- /Services Section -->
|
||||
|
||||
{{-- Leaflet CSS & JS --}}
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<section class="geo-stat-section">
|
||||
<div class="geo-bg"></div>
|
||||
|
||||
<style>
|
||||
/* =============================
|
||||
MAP SECTION
|
||||
============================= */
|
||||
#call-to-action.call-to-action {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
<div class="container position-relative" data-aos="fade-up" data-aos-delay="100">
|
||||
<div class="row align-items-center">
|
||||
|
||||
#call-to-action .container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.map-wrapper {
|
||||
width: 100%;
|
||||
max-width: 1100px;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#mapTPS {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.leaflet-popup-content-wrapper {
|
||||
border-radius: 14px !important;
|
||||
}
|
||||
|
||||
/* =============================
|
||||
FIX LEAFLET VS NAVBAR
|
||||
============================= */
|
||||
header,
|
||||
.navbar,
|
||||
#header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* paksa semua control leaflet turun dari navbar */
|
||||
.leaflet-top {
|
||||
top: 0px !important;
|
||||
/* SESUAIKAN TINGGI NAVBAR */
|
||||
z-index: 400 !important;
|
||||
}
|
||||
|
||||
.leaflet-bottom {
|
||||
bottom: 0px !important;
|
||||
}
|
||||
|
||||
/* =============================
|
||||
Legend
|
||||
============================= */
|
||||
.legend {
|
||||
background: white;
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
line-height: 18px;
|
||||
color: #333;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.legend i {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
float: left;
|
||||
margin-right: 8px;
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<section id="call-to-action" class="call-to-action section">
|
||||
|
||||
<!-- SECTION TITLE -->
|
||||
<div class="section-title" data-aos="fade-up">
|
||||
<h2>Peta Sebaran TPS</h2>
|
||||
<p>Sistem Informasi Geografis Tempat Pembuangan Sampah di Kabupaten Nganjuk</p>
|
||||
<!-- KIRI -->
|
||||
<div class="mb-4 col-lg-5 mb-lg-0">
|
||||
<span class="geo-badge">Statistik SIG TPS</span>
|
||||
<h2 class="geo-title">
|
||||
Pemetaan & Pengelolaan<br>
|
||||
Sampah Kabupaten Nganjuk
|
||||
</h2>
|
||||
<p class="geo-desc">
|
||||
Menampilkan jumlah fasilitas persampahan berbasis
|
||||
Sistem Informasi Geografis secara terintegrasi.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- KANAN -->
|
||||
<div class="col-lg-7">
|
||||
<div class="geo-stats">
|
||||
|
||||
<div class="geo-item">
|
||||
<div class="geo-icon">
|
||||
<i class="bi bi-trash"></i>
|
||||
</div>
|
||||
<h3 class="counter" data-target="{{ $jumlahTps }}">0</h3>
|
||||
<span>TPS</span>
|
||||
</div>
|
||||
|
||||
<div class="geo-line"></div>
|
||||
|
||||
<div class="geo-item">
|
||||
<div class="geo-icon recycle">
|
||||
<i class="bi bi-recycle"></i>
|
||||
</div>
|
||||
<h3 class="counter" data-target="{{ $jumlahTps3r }}">0</h3>
|
||||
<span>TPS 3R</span>
|
||||
</div>
|
||||
|
||||
<div class="geo-line"></div>
|
||||
|
||||
<div class="geo-item">
|
||||
<div class="geo-icon location">
|
||||
<i class="bi bi-geo-alt"></i>
|
||||
</div>
|
||||
<h3 class="counter" data-target="{{ $jumlahTpa }}">0</h3>
|
||||
<span>TPA</span>
|
||||
</div>
|
||||
|
||||
<!-- MAP -->
|
||||
<div class="container" data-aos="fade-up">
|
||||
<div class="map-wrapper">
|
||||
<div id="mapTPS"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
// =============================
|
||||
// INIT MAP
|
||||
// =============================
|
||||
var map = L.map('mapTPS', {
|
||||
zoomControl: true
|
||||
}).setView([-7.6078, 111.903], 12);
|
||||
<section id="faq" class="faq section">
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: "© OpenStreetMap contributors",
|
||||
maxZoom: 19
|
||||
}).addTo(map);
|
||||
<div class="container-fluid">
|
||||
|
||||
// =============================
|
||||
// ICON MARKER PER KATEGORI
|
||||
// =============================
|
||||
function markerIcon(color) {
|
||||
return new L.Icon({
|
||||
iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-${color}.png`,
|
||||
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
|
||||
iconSize: [25, 41],
|
||||
iconAnchor: [12, 41],
|
||||
popupAnchor: [1, -34],
|
||||
shadowSize: [41, 41]
|
||||
});
|
||||
}
|
||||
<div class="row gy-4 justify-content-center">
|
||||
|
||||
var iconTPS = markerIcon('green'); // TPS
|
||||
var iconTPS3R = markerIcon('blue'); // TPS 3R
|
||||
var iconTPA = markerIcon('red'); // TPA
|
||||
var iconDefault = markerIcon('black');
|
||||
<div class="order-2 col-lg-7 d-flex flex-column justify-content-center order-lg-1">
|
||||
|
||||
// =============================
|
||||
// DATA TPS DARI DATABASE
|
||||
// =============================
|
||||
var tpsData = @json($lokasiTps);
|
||||
|
||||
tpsData.forEach(function(tps) {
|
||||
if (tps.latitude && tps.longitude) {
|
||||
|
||||
let iconKategori = iconDefault;
|
||||
|
||||
// SESUAIKAN ID KATEGORI
|
||||
if (tps.kategori_tps_id == 3) {
|
||||
iconKategori = iconTPS;
|
||||
} else if (tps.kategori_tps_id == 5) {
|
||||
iconKategori = iconTPS3R;
|
||||
} else if (tps.kategori_tps_id == 6) {
|
||||
iconKategori = iconTPA;
|
||||
}
|
||||
|
||||
L.marker([tps.latitude, tps.longitude], {
|
||||
icon: iconKategori
|
||||
})
|
||||
.addTo(map)
|
||||
.bindPopup(`
|
||||
<div style="min-width:200px">
|
||||
<strong>${tps.nama_tps}</strong><br>
|
||||
${tps.alamat_tps ?? '-'}<br>
|
||||
<small>Status: ${tps.status_tps ?? '-'}</small>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
// =============================
|
||||
// LEGEND
|
||||
// =============================
|
||||
var legend = L.control({
|
||||
position: "bottomleft"
|
||||
});
|
||||
|
||||
legend.onAdd = function() {
|
||||
var div = L.DomUtil.create("div", "legend");
|
||||
div.innerHTML = `
|
||||
<strong>Kategori TPS</strong><br>
|
||||
<i style="background:#198754"></i> TPS<br>
|
||||
<i style="background:#0d6efd"></i> TPS 3R<br>
|
||||
<i style="background:#dc3545"></i> TPA
|
||||
`;
|
||||
return div;
|
||||
};
|
||||
|
||||
legend.addTo(map);
|
||||
</script>
|
||||
|
||||
|
||||
<!-- Aduan Section -->
|
||||
<section id="aduan" class="contact section">
|
||||
|
||||
<!-- Section Title -->
|
||||
<div class="container section-title" data-aos="fade-up">
|
||||
<h2>Aduan TPS</h2>
|
||||
<p>Laporkan permasalahan Tempat Pembuangan Sampah (TPS) di sekitar Anda</p>
|
||||
</div>
|
||||
<!-- End Section Title -->
|
||||
|
||||
<div class="container" data-aos="fade">
|
||||
<div class="row gy-4 gx-lg-5 align-items-center">
|
||||
|
||||
<!-- KIRI: INFO ADUAN -->
|
||||
<div class="col-lg-6">
|
||||
<div class="info">
|
||||
<h3>Temukan Masalah di TPS?</h3>
|
||||
<div class="text-center content px-xl-6" data-aos="fade-up" data-aos-delay="100">
|
||||
<h3><span>Pertanyaan yang Sering </span><strong>Diajukan</strong></h3>
|
||||
<p>
|
||||
Jika Anda menemukan TPS yang penuh, kotor, atau bermasalah,
|
||||
silakan laporkan agar dapat segera ditindaklanjuti oleh petugas.
|
||||
Berikut adalah beberapa pertanyaan yang sering diajukan oleh pengguna terkait
|
||||
informasi, fitur, dan layanan pada website.
|
||||
</p>
|
||||
|
||||
<div class="info-item d-flex">
|
||||
<i class="flex-shrink-0 bi bi-exclamation-triangle-fill"></i>
|
||||
<div>
|
||||
<h4>Cepat & Mudah</h4>
|
||||
<p>Aduan dapat dikirim hanya dalam beberapa langkah.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-item d-flex">
|
||||
<i class="flex-shrink-0 bi bi-geo-alt-fill"></i>
|
||||
<div>
|
||||
<h4>Berbasis Lokasi TPS</h4>
|
||||
<p>Pilih TPS langsung dari peta.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-container px-xl-5" data-aos="fade-up" data-aos-delay="200">
|
||||
|
||||
<div class="info-item d-flex">
|
||||
<i class="flex-shrink-0 bi bi-chat-dots-fill"></i>
|
||||
<div>
|
||||
<h4>Ditanggapi Admin</h4>
|
||||
<p>Aduan akan diproses oleh admin terkait.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- KANAN: CTA BUTTON -->
|
||||
<div class="text-center col-lg-6">
|
||||
<div class="p-4 shadow-sm card">
|
||||
<h4 class="mb-3">Ingin Mengajukan Aduan?</h4>
|
||||
<p class="mb-4">
|
||||
Klik tombol di bawah ini untuk memilih TPS dan mengisi form aduan.
|
||||
<!-- FAQ 1 -->
|
||||
<div class="faq-item faq-active">
|
||||
<i class="faq-icon bi bi-question-circle"></i>
|
||||
<h3>Apa tujuan utama website ini?</h3>
|
||||
<div class="faq-content">
|
||||
<p>
|
||||
Website ini bertujuan untuk menyediakan informasi yang akurat dan mudah diakses
|
||||
oleh masyarakat mengenai lokasi dan data Tempat Pembuangan Sampah (TPS). Dengan adanya
|
||||
website ini, diharapkan masyarakat dapat lebih memahami kondisi
|
||||
TPS serta mendukung pengelolaan lingkungan yang lebih baik.
|
||||
</p>
|
||||
|
||||
{{-- <a href="#map" class="mb-2 btn btn-outline-success w-100">
|
||||
<i class="bi bi-map-fill me-1"></i> Pilih TPS di Peta
|
||||
</a>
|
||||
|
||||
<p class="my-2 small text-muted">atau</p> --}}
|
||||
|
||||
<a href="{{ route('user.aduan', $tpsPertama->id ?? 1) }}" class="btn btn-danger w-100">
|
||||
<i class="bi bi-megaphone-fill me-1"></i> Laporkan Aduan
|
||||
</a>
|
||||
</div>
|
||||
<i class="faq-toggle bi bi-chevron-right"></i>
|
||||
</div><!-- End Faq item-->
|
||||
|
||||
<!-- FAQ 2 -->
|
||||
<div class="faq-item">
|
||||
<i class="faq-icon bi bi-question-circle"></i>
|
||||
<h3>Bagaimana cara melihat peta sebaran TPS?</h3>
|
||||
<div class="faq-content">
|
||||
<p>
|
||||
Peta sebaran TPS dapat dilihat melalui menu Sebaran TPS yang tersedia pada halaman utama
|
||||
website. Peta tersebut bersifat interaktif dan menampilkan lokasi TPS berdasarkan
|
||||
wilayah. Pengguna dapat mengklik setiap penanda lokasi untuk melihat detail informasi
|
||||
seperti alamat TPS dan keterangan tambahan lainnya.
|
||||
</p>
|
||||
{{-- <p>
|
||||
|
||||
</p> --}}
|
||||
</div>
|
||||
<i class="faq-toggle bi bi-chevron-right"></i>
|
||||
</div><!-- End Faq item-->
|
||||
|
||||
<!-- FAQ 3 -->
|
||||
<div class="faq-item">
|
||||
<i class="faq-icon bi bi-question-circle"></i>
|
||||
<h3>Bagaimana cara mengadukan permasalahan TPS?</h3>
|
||||
<div class="faq-content">
|
||||
<p>
|
||||
Pengaduan permasalahan TPS dapat dilakukan melalui menu Aduan TPS yang tersedia
|
||||
pada website dengan mengisi formulir yang telah disediakan. Laporan yang masuk akan
|
||||
diteruskan kepada pihak terkait untuk ditindaklanjuti
|
||||
guna meningkatkan kualitas pengelolaan TPS.
|
||||
</p>
|
||||
</div>
|
||||
<i class="faq-toggle bi bi-chevron-right"></i>
|
||||
</div><!-- End Faq item-->
|
||||
|
||||
<!-- FAQ 4 -->
|
||||
<div class="faq-item">
|
||||
<i class="faq-icon bi bi-question-circle"></i>
|
||||
<h3>Apakah website ini dapat diakses melalui perangkat mobile?</h3>
|
||||
<div class="faq-content">
|
||||
<p>
|
||||
Ya, website ini dirancang secara responsif sehingga dapat diakses melalui
|
||||
berbagai perangkat, termasuk smartphone dan tablet. Tampilan website akan menyesuaikan
|
||||
ukuran layar perangkat pengguna tanpa
|
||||
mengurangi fungsi dan informasi yang tersedia.
|
||||
</p>
|
||||
</div>
|
||||
<i class="faq-toggle bi bi-chevron-right"></i>
|
||||
</div><!-- End Faq item-->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.querySelectorAll(".counter").forEach(el => {
|
||||
const target = +el.dataset.target;
|
||||
let val = 0;
|
||||
|
||||
const step = () => {
|
||||
val += Math.ceil(target / 90);
|
||||
if (val < target) {
|
||||
el.textContent = val;
|
||||
requestAnimationFrame(step);
|
||||
} else {
|
||||
el.textContent = target;
|
||||
}
|
||||
};
|
||||
step();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</section>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@
|
|||
*/
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
return view('user.index');
|
||||
});
|
||||
|
||||
Route::get('/index', [IndexController::class, 'index'])->name('user.index');
|
||||
Route::get('/', [IndexController::class, 'index'])->name('user.index');
|
||||
Route::get('/about', [AboutController::class, 'index'])->name('user.about');
|
||||
Route::get('/about/{id}', [AboutController::class, 'show'])->name('user.about.kategori');
|
||||
|
||||
|
|
@ -37,16 +37,6 @@
|
|||
|
||||
Route::get('/kontak', [KontakController::class, 'index'])->name('user.kontak');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| ROUTE AUTH (LARAVEL BREEZE)
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Login : /login
|
||||
| Logout : /logout
|
||||
|
|
||||
*/
|
||||
|
||||
require __DIR__.'/auth.php';
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue