MIF_E31221353/routes/web.php

297 lines
14 KiB
PHP

<?php
// Route khusus untuk akses gambar selfie jika public/storage bermasalah
require __DIR__.'/selfie.php';
use App\Http\Controllers\NotificationController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\RegisterController;
use App\Http\Controllers\PasswordResetController;
use App\Http\Controllers\AbsensiController;
use App\Http\Controllers\AdminAbsensiController;
use App\Http\Controllers\AdminCutiController;
use App\Http\Controllers\AdminBarangRusakController;
use App\Http\Controllers\AdminUserController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Storage;
Route::get('/', function () {
return auth()->check()
? redirect()->route('dashboard')
: redirect()->route('login');
});
// -------------------------
// Routes untuk GUEST (belum login)
// -------------------------
Route::middleware('guest')->group(function () {
// Verifikasi Email OTP
Route::get('/verify-email', [\App\Http\Controllers\EmailVerificationController::class, 'showForm'])->name('verification.form');
Route::post('/verify-email', [\App\Http\Controllers\EmailVerificationController::class, 'verify'])->name('verification.verify');
Route::get('/login', [AuthController::class, 'showLogin'])->name('login');
Route::post('/login', [AuthController::class, 'login'])->name('login.post');
// Register
Route::get('/register', [RegisterController::class, 'show'])->name('register');
Route::post('/register', [RegisterController::class, 'store'])->name('register.post');
// Password Reset (OTP flow)
Route::get('/forgot-password', [PasswordResetController::class, 'requestForm'])->name('password.request');
Route::post('/forgot-password', [PasswordResetController::class, 'email'])->name('password.email');
Route::get('/forgot-password/verify', [PasswordResetController::class, 'otpVerifyForm'])->name('password.otp.verify.form');
Route::post('/forgot-password/verify', [PasswordResetController::class, 'otpVerify'])->name('password.otp.verify');
Route::get('/reset-password', [PasswordResetController::class, 'resetForm'])->name('password.reset');
Route::get('/reset-password/{token}', [PasswordResetController::class, 'resetFormWithToken'])->name('password.reset.token');
Route::post('/reset-password', [PasswordResetController::class, 'update'])->name('password.update');
});
// -------------------------
// Routes untuk USER LOGIN
// -------------------------
Route::middleware('auth')->group(function () {
// Notifikasi user
Route::get('/absensi', [AbsensiController::class, 'indexUser'])->name('user.absensi');
Route::get('/absensi/{attendance}/edit', [AbsensiController::class, 'edit'])
->name('absensi.edit')
->whereNumber('attendance');
Route::put('/absensi/{attendance}', [AbsensiController::class, 'update'])
->name('absensi.update')
->whereNumber('attendance');
Route::post('/absensi/sakit', [AbsensiController::class, 'markSick'])->name('absensi.markSick');
Route::post('/absensi/izin', [AbsensiController::class, 'markIzin'])->name('absensi.markIzin');
Route::get('/notifications', [NotificationController::class, 'index'])->name('notifications.index');
Route::post('/notifications/{id}/read', [NotificationController::class, 'markAsRead'])->name('notifications.read');
Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
// Dashboard redirect → beda sesuai role
Route::get('/dashboard', function () {
$user = auth()->user();
if ($user->role === 'admin' || $user->role === 'atasan') {
return redirect()->route('admin.absensi.index');
}
// default: user biasa
return redirect()->route('user.absensi');
})->name('dashboard');
// -------------------------
// ABSENSI
// -------------------------
Route::get('/absensi/export', [AbsensiController::class, 'exportCsv'])->name('absensi.exportCsv');
Route::post('/absensi/clock-in', [AbsensiController::class, 'clockIn'])->name('absensi.clockIn');
Route::post('/absensi/clock-out', [AbsensiController::class, 'clockOut'])->name('absensi.clockOut');
// -------------------------
// BARANG RUSAK
// -------------------------
Route::get('/barang-rusak', function () {
if (! Schema::hasTable('barang_rusak')) {
return view('barang-rusak.index', [
'title' => 'Barang Rusak',
'items' => collect(),
'error' => 'Tabel `barang_rusak` tidak ditemukan. Silakan jalankan migrasi atau buat tabel di database.'
]);
}
$items = DB::table('barang_rusak')
->leftJoin('users', 'users.id', '=', 'barang_rusak.user_id')
->where('barang_rusak.user_id', auth()->id())
->select([
'barang_rusak.id',
'barang_rusak.tanggal',
'barang_rusak.lokasi',
'barang_rusak.kerusakan',
'barang_rusak.keterangan',
'barang_rusak.admin_note',
'barang_rusak.status',
'barang_rusak.created_at',
'barang_rusak.updated_at',
'users.name as user_name',
])
->orderByDesc('barang_rusak.tanggal')
->orderByDesc('barang_rusak.id')
->get();
return view('barang-rusak.index', [
'title' => 'Barang Rusak',
'items' => $items,
]);
})->name('barang-rusak.index');
Route::post('/barang-rusak', function (Request $request) {
$validated = $request->validate([
'tanggal' => ['required', 'date'],
'lokasi' => ['required', 'string'],
'kerusakan' => ['required', 'array', 'min:1'],
'kerusakan.*' => ['string'],
'keterangan' => ['nullable', 'string'],
]);
if (! Schema::hasTable('barang_rusak')) {
return redirect()->route('barang-rusak.index')->with('error', 'Tabel `barang_rusak` tidak ditemukan. Silakan jalankan migrasi.');
}
DB::table('barang_rusak')->insert([
'user_id' => auth()->id(),
'tanggal' => $validated['tanggal'],
'lokasi' => $validated['lokasi'],
'kerusakan' => json_encode(array_values((array)$validated['kerusakan'])),
'keterangan' => $validated['keterangan'] ?? null,
'status' => 'dilaporkan',
'created_at' => now(),
'updated_at' => now(),
]);
return redirect()->route('barang-rusak.index')->with('success', 'Laporan barang rusak berhasil disimpan.');
})->name('barang-rusak.store');
// -------------------------
// CUTI (pengajuan cuti)
// -------------------------
Route::get('/cuti', function () {
if (!Schema::hasTable('cuti')) {
return view('cuti.form', [
'title' => 'Pengajuan Cuti',
'list' => collect(),
'error' => 'Tabel cuti belum ada. Jalankan migrasi terlebih dulu.',
]);
}
$list = DB::table('cuti')
->where('user_id', auth()->id())
->orderByDesc('created_at')
->get();
return view('cuti.form', [
'title' => 'Pengajuan Cuti',
'list' => $list,
]);
})->name('cuti.form');
Route::post('/cuti', function (Request $request) {
$validated = $request->validate([
'tanggal_mulai' => ['required', 'date'],
'tanggal_selesai' => ['required', 'date', 'after_or_equal:tanggal_mulai'],
'jenis' => ['required', 'string'],
'alasan' => ['required', 'string'],
]);
if (!Schema::hasTable('cuti')) {
return redirect()->route('cuti.form')->with('error', 'Tabel cuti belum ada. Jalankan migrasi.');
}
DB::table('cuti')->insert([
'user_id' => auth()->id(),
'tanggal_mulai' => $validated['tanggal_mulai'],
'tanggal_selesai' => $validated['tanggal_selesai'],
'jenis' => $validated['jenis'],
'alasan' => $validated['alasan'],
'status' => 'menunggu',
'created_at' => now(),
'updated_at' => now(),
]);
return redirect()->route('cuti.form')->with('success', 'Pengajuan cuti berhasil dikirim.');
})->name('cuti.store');
// -------------------------
// PROFILE
// -------------------------
Route::get('/profile', function () {
$user = auth()->user();
return view('profile.index', [
'title' => 'Profil',
'user' => $user,
]);
})->name('profile.index');
Route::post('/profile', function (Request $request) {
$user = auth()->user();
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'username' => ['nullable', 'string', 'max:255', 'unique:users,username,' . $user->id],
'email' => ['required', 'email', 'max:255', 'unique:users,email,' . $user->id],
'password' => ['nullable', 'min:6'],
'phone' => ['nullable', 'string', 'max:50'],
'address' => ['nullable', 'string'],
'avatar' => ['nullable', 'image', 'max:2048'],
]);
$data = [
'name' => $validated['name'],
'email' => $validated['email'],
];
if (array_key_exists('username', $validated)) {
$data['username'] = $validated['username'];
}
if (array_key_exists('phone', $validated)) {
$data['phone'] = $validated['phone'];
}
if (array_key_exists('address', $validated)) {
$data['address'] = $validated['address'];
}
if (!empty($validated['password'] ?? null)) {
$data['password'] = bcrypt($validated['password']);
}
if ($request->hasFile('avatar')) {
$path = $request->file('avatar')->store('avatars', 'public');
$data['avatar_path'] = $path;
}
DB::table('users')->where('id', $user->id)->update($data);
return redirect()->route('profile.index')->with('success', 'Profil berhasil diperbarui.');
})->name('profile.update');
// -------------------------
// ADMIN / ATASAN
// -------------------------
Route::middleware('role:admin,atasan')->group(function () {
Route::get('/admin', function () { return redirect()->route('admin.absensi.index'); });
Route::get('/admin/users/{user}', [AdminUserController::class, 'show'])->name('admin.users.show');
// Rute untuk manajemen pengguna
Route::prefix('admin/users')->group(function () {
Route::get('/', [AdminUserController::class, 'index'])->name('admin.users.index');
Route::get('/{user}', [AdminUserController::class, 'show'])->name('admin.users.show');
Route::delete('/{user}', [AdminUserController::class, 'destroy'])->name('admin.users.destroy');
Route::patch('/{user}/attendance-toggle', [AdminUserController::class, 'toggleAttendance'])->name('admin.users.attendance-toggle');
Route::post('/attendance/enable-all', [AdminUserController::class, 'enableAllAttendance'])->name('admin.users.attendance.enable-all');
Route::post('/attendance/disable-all', [AdminUserController::class, 'disableAllAttendance'])->name('admin.users.attendance.disable-all');
});
Route::get('/admin/absensi', [AdminAbsensiController::class, 'index'])->name('admin.absensi.index');
Route::delete('/admin/absensi/{attendance}', [AdminAbsensiController::class, 'destroy'])->name('admin.absensi.destroy');
Route::post('/admin/absensi/{attendance}/jobdesk', [AdminAbsensiController::class, 'assignJobdesk'])->name('admin.absensi.jobdesk');
Route::get('/admin/barang-rusak', [AdminBarangRusakController::class, 'index'])->name('admin.barang_rusak.index');
Route::delete('/admin/barang-rusak/{barangRusak}', [AdminBarangRusakController::class, 'destroy'])->name('admin.barang_rusak.destroy');
Route::post('/admin/barang-rusak/{barangRusak}', [AdminBarangRusakController::class, 'update'])->name('admin.barang_rusak.update');
Route::get('/admin/cuti', [AdminCutiController::class, 'index'])->name('admin.cuti.index');
Route::post('/admin/cuti/{id}', [AdminCutiController::class, 'updateStatus'])->name('admin.cuti.update');
// Notifikasi Admin
Route::get('/admin/notifications', [\App\Http\Controllers\AdminNotificationController::class, 'index'])->name('admin.notifications.index');
Route::get('/admin/notifications/create', [\App\Http\Controllers\AdminNotificationController::class, 'create'])->name('admin.notifications.create');
Route::post('/admin/notifications', [\App\Http\Controllers\AdminNotificationController::class, 'store'])->name('admin.notifications.store');
Route::get('/admin/users/{user}', [AdminUserController::class, 'show'])
->name('admin.users.show');
Route::patch('/admin/users/{user}/attendance-toggle', [AdminUserController::class, 'toggleAttendance'])
->name('admin.users.attendance-toggle');
Route::patch('/admin/users/{user}/approval-toggle', [AdminUserController::class, 'toggleApproval'])
->name('admin.users.approval-toggle');
Route::post('/admin/users/attendance-enable-all', [AdminUserController::class, 'enableAllAttendance'])
->name('admin.users.attendance.enable-all');
Route::post('/admin/users/attendance-disable-all', [AdminUserController::class, 'disableAllAttendance'])
->name('admin.users.attendance.disable-all');
});
// Temporary route without middleware for testing
Route::get('/admin-test/barang-rusak', [\App\Http\Controllers\AdminBarangRusakController::class, 'index'])->name('admin.barang_rusak.test');
});