This commit is contained in:
rahmagustin 2026-03-05 06:31:41 +07:00
parent 4baa427ae3
commit e0119a4ff0
31 changed files with 107 additions and 428 deletions

View File

@ -17,9 +17,13 @@ public function index()
public function show($id) public function show($id)
{ {
// Ambil kategori berdasarkan id // Ambil kategori berdasarkan id
$kategori = \App\Models\KategoriTps::findOrFail($id); $kategori = KategoriTps::findOrFail($id);
// Ambil semua kategori untuk sidebar
$kategoriTps = KategoriTps::all();
$title = 'Tentang ' . $kategori->nama_kategori; $title = 'Tentang ' . $kategori->nama_kategori;
return view('user.about-tps', compact('title', 'kategori')); return view('user.about-tps', compact('title', 'kategori', 'kategoriTps'));
} }
} }

View File

@ -1,46 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function index()
{
return view('admin.login');
}
public function process(Request $request)
{
$credentials = $request->validate([
'username' => 'required',
'password' => 'required'
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
// pastikan admin
if (Auth::user()->role !== 'admin') {
Auth::logout();
return back()->with('error', 'Anda bukan admin');
}
return redirect()->route('admin.dashboard');
}
return back()->with('error', 'Username atau password salah');
}
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('user.index');
}
}

View File

@ -35,6 +35,18 @@ public function create()
====================================================== */ ====================================================== */
public function store(Request $request) public function store(Request $request)
{ {
// ===============================
// KONVERSI FORMAT INDONESIA
// ===============================
$request->merge([
'total_sampah' => $this->convertToDecimal($request->total_sampah),
'total_kelola' => $this->convertToDecimal($request->total_kelola),
'total_daur_ulang' => $this->convertToDecimal($request->total_daur_ulang),
]);
// ===============================
// VALIDASI
// ===============================
$validator = Validator::make( $validator = Validator::make(
$request->all(), $request->all(),
[ [
@ -45,7 +57,7 @@ public function store(Request $request)
], ],
[ [
'tahun.required' => 'Tahun wajib diisi.', 'tahun.required' => 'Tahun wajib diisi.',
'tahun.digits' => 'Tahun harus 4 digit (contoh: 2023).', 'tahun.digits' => 'Tahun harus 4 digit (contoh: 2024).',
'total_sampah.required' => 'Total sampah wajib diisi.', 'total_sampah.required' => 'Total sampah wajib diisi.',
'total_sampah.numeric' => 'Total sampah harus berupa angka.', 'total_sampah.numeric' => 'Total sampah harus berupa angka.',
@ -65,7 +77,9 @@ public function store(Request $request)
return back()->withErrors($validator)->withInput(); return back()->withErrors($validator)->withInput();
} }
// VALIDASI LOGIKA DATA // ===============================
// VALIDASI LOGIKA
// ===============================
if (($request->total_kelola + $request->total_daur_ulang) > $request->total_sampah) { if (($request->total_kelola + $request->total_daur_ulang) > $request->total_sampah) {
return back() return back()
->withErrors([ ->withErrors([
@ -74,9 +88,15 @@ public function store(Request $request)
->withInput(); ->withInput();
} }
// ===============================
// HITUNG SISA
// ===============================
$sisa_sampah = $request->total_sampah $sisa_sampah = $request->total_sampah
- ($request->total_kelola + $request->total_daur_ulang); - ($request->total_kelola + $request->total_daur_ulang);
// ===============================
// SIMPAN DATA
// ===============================
Sampah::create([ Sampah::create([
'user_id' => Auth::id(), 'user_id' => Auth::id(),
'tahun' => $request->tahun, 'tahun' => $request->tahun,
@ -90,6 +110,9 @@ public function store(Request $request)
->with('success', 'Data sampah berhasil ditambahkan.'); ->with('success', 'Data sampah berhasil ditambahkan.');
} }
/* ======================================================
EDIT
====================================================== */
public function edit($id) public function edit($id)
{ {
$title = 'Edit Data Sampah'; $title = 'Edit Data Sampah';
@ -100,12 +123,24 @@ public function edit($id)
} }
/* ====================================================== /* ======================================================
UPDATE (EDIT DATA) UPDATE
====================================================== */ ====================================================== */
public function update(Request $request, $id) public function update(Request $request, $id)
{ {
$sampah = Sampah::findOrFail($id); $sampah = Sampah::findOrFail($id);
// ===============================
// KONVERSI FORMAT INDONESIA
// ===============================
$request->merge([
'total_sampah' => $this->convertToDecimal($request->total_sampah),
'total_kelola' => $this->convertToDecimal($request->total_kelola),
'total_daur_ulang' => $this->convertToDecimal($request->total_daur_ulang),
]);
// ===============================
// VALIDASI
// ===============================
$validator = Validator::make( $validator = Validator::make(
$request->all(), $request->all(),
[ [
@ -137,7 +172,9 @@ public function update(Request $request, $id)
return back()->withErrors($validator)->withInput(); return back()->withErrors($validator)->withInput();
} }
// VALIDASI LOGIKA DATA // ===============================
// VALIDASI LOGIKA
// ===============================
if (($request->total_kelola + $request->total_daur_ulang) > $request->total_sampah) { if (($request->total_kelola + $request->total_daur_ulang) > $request->total_sampah) {
return back() return back()
->withErrors([ ->withErrors([
@ -146,9 +183,15 @@ public function update(Request $request, $id)
->withInput(); ->withInput();
} }
// ===============================
// HITUNG SISA
// ===============================
$sisa_sampah = $request->total_sampah $sisa_sampah = $request->total_sampah
- ($request->total_kelola + $request->total_daur_ulang); - ($request->total_kelola + $request->total_daur_ulang);
// ===============================
// UPDATE DATA
// ===============================
$sampah->update([ $sampah->update([
'user_id' => $request->user_id, 'user_id' => $request->user_id,
'tahun' => $request->tahun, 'tahun' => $request->tahun,
@ -170,4 +213,17 @@ public function destroy($id)
return redirect()->route('admin.sampah.index') return redirect()->route('admin.sampah.index')
->with('success', 'Data sampah berhasil dihapus.'); ->with('success', 'Data sampah berhasil dihapus.');
} }
/* ======================================================
HELPER KONVERSI FORMAT INDONESIA
====================================================== */
private function convertToDecimal($value)
{
if (!$value) {
return 0;
}
// hapus titik ribuan lalu ubah koma jadi titik
return str_replace(',', '.', str_replace('.', '', $value));
}
} }

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
class ConfirmablePasswordController extends Controller
{
/**
* Show the confirm password view.
*/
public function show(): View
{
return view('auth.confirm-password');
}
/**
* Confirm the user's password.
*/
public function store(Request $request): RedirectResponse
{
if (! Auth::guard('web')->validate([
'email' => $request->user()->email,
'password' => $request->password,
])) {
throw ValidationException::withMessages([
'password' => __('auth.password'),
]);
}
$request->session()->put('auth.password_confirmed_at', time());
return redirect()->intended(route('dashboard', absolute: false));
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class EmailVerificationNotificationController extends Controller
{
/**
* Send a new email verification notification.
*/
public function store(Request $request): RedirectResponse
{
if ($request->user()->hasVerifiedEmail()) {
return redirect()->intended(route('dashboard', absolute: false));
}
$request->user()->sendEmailVerificationNotification();
return back()->with('status', 'verification-link-sent');
}
}

View File

@ -1,21 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class EmailVerificationPromptController extends Controller
{
/**
* Display the email verification prompt.
*/
public function __invoke(Request $request): RedirectResponse|View
{
return $request->user()->hasVerifiedEmail()
? redirect()->intended(route('dashboard', absolute: false))
: view('auth.verify-email');
}
}

View File

@ -1,62 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules;
use Illuminate\View\View;
class NewPasswordController extends Controller
{
/**
* Display the password reset view.
*/
public function create(Request $request): View
{
return view('auth.reset-password', ['request' => $request]);
}
/**
* Handle an incoming new password request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'token' => ['required'],
'email' => ['required', 'email'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function (User $user) use ($request) {
$user->forceFill([
'password' => Hash::make($request->password),
'remember_token' => Str::random(60),
])->save();
event(new PasswordReset($user));
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $status == Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;
class PasswordController extends Controller
{
/**
* Update the user's password.
*/
public function update(Request $request): RedirectResponse
{
$validated = $request->validateWithBag('updatePassword', [
'current_password' => ['required', 'current_password'],
'password' => ['required', Password::defaults(), 'confirmed'],
]);
$request->user()->update([
'password' => Hash::make($validated['password']),
]);
return back()->with('status', 'password-updated');
}
}

View File

@ -1,44 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Illuminate\View\View;
class PasswordResetLinkController extends Controller
{
/**
* Display the password reset link request view.
*/
public function create(): View
{
return view('auth.forgot-password');
}
/**
* Handle an incoming password reset link request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'email' => ['required', 'email'],
]);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$status = Password::sendResetLink(
$request->only('email')
);
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}

View File

@ -1,50 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;
use Illuminate\View\View;
class RegisteredUserController extends Controller
{
/**
* Display the registration view.
*/
public function create(): View
{
return view('auth.register');
}
/**
* Handle an incoming registration request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(route('dashboard', absolute: false));
}
}

View File

@ -1,27 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\Verified;
use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Http\RedirectResponse;
class VerifyEmailController extends Controller
{
/**
* Mark the authenticated user's email address as verified.
*/
public function __invoke(EmailVerificationRequest $request): RedirectResponse
{
if ($request->user()->hasVerifiedEmail()) {
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
}
}

View File

@ -14,9 +14,9 @@ public function index()
$sampah = Sampah::orderBy('tahun', 'desc')->first(); $sampah = Sampah::orderBy('tahun', 'desc')->first();
$kategoriTps = KategoriTps::orderBy('id_kategori_tps')->get(); $kategoriTps = KategoriTps::orderBy('id_kategori_tps')->get();
$lokasiTps = LokasiTps::all(); $lokasiTps = LokasiTps::all();
$jumlahTps = LokasiTps::where('kategori_tps_id', '3')->count(); $jumlahTps = LokasiTps::where('kategori_tps_id', '1')->count();
$jumlahTps3r = LokasiTps::where('kategori_tps_id', '5')->count(); $jumlahTps3r = LokasiTps::where('kategori_tps_id', '2')->count();
$jumlahTpa = LokasiTps::where('kategori_tps_id', '6')->count(); $jumlahTpa = LokasiTps::where('kategori_tps_id', '3')->count();
return view('user.index', compact('sampah', 'kategoriTps', 'lokasiTps', 'jumlahTps', 'jumlahTps3r', 'jumlahTpa')); return view('user.index', compact('sampah', 'kategoriTps', 'lokasiTps', 'jumlahTps', 'jumlahTps3r', 'jumlahTpa'));
} }

View File

@ -1,30 +0,0 @@
<?php
namespace App\Http\Requests;
use App\Models\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class ProfileUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'string',
'lowercase',
'email',
'max:255',
Rule::unique(User::class)->ignore($this->user()->id),
],
];
}
}

View File

@ -21,7 +21,8 @@ public function register(): void
*/ */
public function boot(): void public function boot(): void
{ {
// Share semua kategori TPS ke semua view View::composer('user.template', function ($view) {
View::share('kategoriTps', KategoriTps::all()); $view->with('kategoriTps', KategoriTps::all());
});
} }
} }

View File

@ -8,14 +8,14 @@
public function up() public function up()
{ {
Schema::table('aduan_tps', function (Blueprint $table) { Schema::table('aduan_tps', function (Blueprint $table) {
$table->dropColumn('alamat');
}); });
} }
public function down() public function down()
{ {
Schema::table('aduan_tps', function (Blueprint $table) { Schema::table('aduan_tps', function (Blueprint $table) {
$table->string('alamat', 255)->after('alamat_pelapor');
}); });
} }
}; };

View File

@ -0,0 +1,25 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::table('kategori_tps', function (Blueprint $table) {
$table->string('kepanjangan_kategori')->after('nama_kategori');
});
}
public function down()
{
Schema::table('kategori_tps', function (Blueprint $table) {
$table->dropColumn('kepanjangan_kategori');
});
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 720 KiB

View File

@ -234,7 +234,7 @@ .header .logo {
} }
.header .logo img { .header .logo img {
max-height: 60px; max-height: 50px;
margin: auto; margin: auto;
transform: scale(1.4); transform: scale(1.4);
transform-origin: left center; transform-origin: left center;

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -30,7 +30,7 @@ class="form-control @error('tahun') is-invalid @enderror"
<div class="form-group"> <div class="form-group">
<label>Total Sampah</label> <label>Total Sampah</label>
<div class="input-group"> <div class="input-group">
<input type="number" step="0.01" name="total_sampah" <input type="text" step="0.01" name="total_sampah"
id="total_sampah" id="total_sampah"
class="form-control @error('total_sampah') is-invalid @enderror" class="form-control @error('total_sampah') is-invalid @enderror"
value="{{ old('total_sampah') }}" value="{{ old('total_sampah') }}"
@ -47,7 +47,7 @@ class="form-control @error('total_sampah') is-invalid @enderror"
<div class="form-group"> <div class="form-group">
<label>Total Sampah Dikelola</label> <label>Total Sampah Dikelola</label>
<div class="input-group"> <div class="input-group">
<input type="number" step="0.01" name="total_kelola" <input type="text" step="0.01" name="total_kelola"
id="total_kelola" id="total_kelola"
class="form-control @error('total_kelola') is-invalid @enderror" class="form-control @error('total_kelola') is-invalid @enderror"
value="{{ old('total_kelola') }}" value="{{ old('total_kelola') }}"
@ -64,7 +64,7 @@ class="form-control @error('total_kelola') is-invalid @enderror"
<div class="form-group"> <div class="form-group">
<label>Total Sampah Daur Ulang</label> <label>Total Sampah Daur Ulang</label>
<div class="input-group"> <div class="input-group">
<input type="number" step="0.01" name="total_daur_ulang" <input type="text" step="0.01" name="total_daur_ulang"
id="total_daur_ulang" id="total_daur_ulang"
class="form-control @error('total_daur_ulang') is-invalid @enderror" class="form-control @error('total_daur_ulang') is-invalid @enderror"
value="{{ old('total_daur_ulang') }}" value="{{ old('total_daur_ulang') }}"
@ -81,7 +81,7 @@ class="form-control @error('total_daur_ulang') is-invalid @enderror"
<div class="form-group"> <div class="form-group">
<label>Sisa Sampah</label> <label>Sisa Sampah</label>
<div class="input-group"> <div class="input-group">
<input type="number" step="0.01" name="sisa_sampah" <input type="text" step="0.01" name="sisa_sampah"
id="sisa_sampah" id="sisa_sampah"
class="form-control" readonly> class="form-control" readonly>
<div class="input-group-append"> <div class="input-group-append">

View File

@ -19,7 +19,7 @@
<!-- inject:css --> <!-- inject:css -->
<link rel="stylesheet" href="{{ asset('assets/admin/css/vertical-layout-light/style.css') }}"> <link rel="stylesheet" href="{{ asset('assets/admin/css/vertical-layout-light/style.css') }}">
<!-- endinject --> <!-- endinject -->
<link rel="shortcut icon" href="{{ asset('assets/admin/images/icon-mini.png') }}" /> <link rel="shortcut icon" href="{{ asset('assets/admin/images/icn.png') }}" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">

View File

@ -117,8 +117,8 @@ function icon(color) {
if (!tps.latitude || !tps.longitude) return; if (!tps.latitude || !tps.longitude) return;
let iconUse = iconTPS; let iconUse = iconTPS;
if (tps.kategori_tps_id == 5) iconUse = iconTPS3R; if (tps.kategori_tps_id == 2) iconUse = iconTPS3R;
if (tps.kategori_tps_id == 6) iconUse = iconTPA; if (tps.kategori_tps_id == 3) iconUse = iconTPA;
let marker = L.marker([tps.latitude, tps.longitude], { icon: iconUse }) let marker = L.marker([tps.latitude, tps.longitude], { icon: iconUse })
.bindPopup(` .bindPopup(`

View File

@ -12,47 +12,13 @@
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::middleware('guest')->group(function () { Route::middleware('guest')->group(function () {
Route::get('register', [RegisteredUserController::class, 'create'])
->name('register');
Route::post('register', [RegisteredUserController::class, 'store']);
Route::get('login', [AuthenticatedSessionController::class, 'create']) Route::get('login', [AuthenticatedSessionController::class, 'create'])
->name('login'); ->name('login');
Route::post('login', [AuthenticatedSessionController::class, 'store']); Route::post('login', [AuthenticatedSessionController::class, 'store']);
Route::get('forgot-password', [PasswordResetLinkController::class, 'create'])
->name('password.request');
Route::post('forgot-password', [PasswordResetLinkController::class, 'store'])
->name('password.email');
Route::get('reset-password/{token}', [NewPasswordController::class, 'create'])
->name('password.reset');
Route::post('reset-password', [NewPasswordController::class, 'store'])
->name('password.store');
}); });
Route::middleware('auth')->group(function () { Route::middleware('auth')->group(function () {
Route::get('verify-email', EmailVerificationPromptController::class)
->name('verification.notice');
Route::get('verify-email/{id}/{hash}', VerifyEmailController::class)
->middleware(['signed', 'throttle:6,1'])
->name('verification.verify');
Route::post('email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
->middleware('throttle:6,1')
->name('verification.send');
Route::get('confirm-password', [ConfirmablePasswordController::class, 'show'])
->name('password.confirm');
Route::post('confirm-password', [ConfirmablePasswordController::class, 'store']);
Route::put('password', [PasswordController::class, 'update'])->name('password.update');
Route::post('logout', [AuthenticatedSessionController::class, 'destroy']) Route::post('logout', [AuthenticatedSessionController::class, 'destroy'])
->name('logout'); ->name('logout');