TKK_E32231477/routes/web.php

203 lines
8.9 KiB
PHP

<?php
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
Route::get('/', function () {
return view('home');
})->name('home');
Route::get('/home', function () {
return view('home');
})->name('home.page');
Route::get('/login', function () {
return view('login');
})->name('login');
// Halaman Register
Route::get('/register', function () {
return view('register');
})->name('register');
// Proses Register
Route::post('/register', function (\Illuminate\Http\Request $request) {
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:8|confirmed',
], [
'name.required' => 'Nama lengkap wajib diisi.',
'email.required' => 'Email wajib diisi.',
'email.email' => 'Format email tidak valid.',
'email.unique' => 'Email sudah terdaftar, gunakan email lain.',
'password.required' => 'Password wajib diisi.',
'password.min' => 'Password minimal 8 karakter.',
'password.confirmed' => 'Konfirmasi password tidak cocok.',
]);
\App\Models\User::create([
'name' => $request->name,
'email' => $request->email,
'password' => $request->password,
]);
return redirect()->route('login')->with('success', 'Akun berhasil dibuat! Silakan login dengan akun Anda.');
})->name('register.process');
// Route untuk proses login
Route::post('/login', function (Request $request) {
$request->validate([
'username' => 'required',
'password' => 'required',
]);
// Cek kredensial ke tabel users (kolom email = username)
$credentials = [
'email' => $request->input('username'),
'password' => $request->input('password'),
];
if (\Illuminate\Support\Facades\Auth::attempt($credentials, $request->boolean('remember'))) {
$request->session()->regenerate();
return redirect()->route('dashboard')->with('success', 'Login berhasil!');
}
return back()->with('error', 'Email atau password salah. Silakan coba lagi.')->withInput(['username' => $request->input('username')]);
})->name('login.process');
// Route untuk logout
Route::get('/logout', function () {
\Illuminate\Support\Facades\Auth::logout();
request()->session()->invalidate();
request()->session()->regenerateToken();
return redirect()->route('home')->with('success', 'Logout berhasil!');
})->name('logout');
// Group routes yang memerlukan login
Route::middleware(['auth'])->group(function () {
// Upload foto profil
Route::post('/profile/photo', function (\Illuminate\Http\Request $request) {
$request->validate([
'photo' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
], [
'photo.required' => 'Pilih foto terlebih dahulu.',
'photo.image' => 'File harus berupa gambar.',
'photo.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
'photo.max' => 'Ukuran foto maksimal 2MB.',
]);
$user = \Illuminate\Support\Facades\Auth::user();
// Hapus foto lama jika ada
if ($user->profile_photo) {
\Illuminate\Support\Facades\Storage::disk('public')->delete($user->profile_photo);
}
$path = $request->file('photo')->store('profile-photos', 'public');
$user->update(['profile_photo' => $path]);
return back()->with('success', 'Foto profil berhasil diperbarui.');
})->name('profile.photo.upload');
// Hapus foto profil
Route::delete('/profile/photo', function () {
$user = \Illuminate\Support\Facades\Auth::user();
if ($user->profile_photo) {
\Illuminate\Support\Facades\Storage::disk('public')->delete($user->profile_photo);
$user->update(['profile_photo' => null]);
}
return back()->with('success', 'Foto profil berhasil dihapus.');
})->name('profile.photo.delete');
Route::get('/dashboard', function () {
$totalSensor = \App\Models\Sensor::where('is_active', true)->count();
$sensorAktif = \App\Models\Sensor::where('status', 'active')->count();
$peringatanHariIni = \App\Models\Alert::whereDate('triggered_at', today())->count();
$alertAktif = \App\Models\Alert::where('status', 'active')->count();
$lastUpdate = \App\Models\ActivityLog::latest('event_time')->first()?->event_time;
// Alert terbaru untuk ditampilkan di dashboard
$alertTerbaru = \App\Models\Alert::with('device')
->where('status', 'active')
->orderBy('triggered_at', 'desc')
->limit(5)
->get();
// Deteksi sensor aktif dalam 30 detik terakhir
$pirAktif = \App\Models\PirReading::where('recorded_at', '>=', now()->subSeconds(30))
->where('motion_detected', true)->exists();
$vibAktif = \App\Models\VibrationReading::where('recorded_at', '>=', now()->subSeconds(30))
->where('is_abnormal', true)->exists();
// Reed Switch: cek DoorAccessReading (data dari ESP32 via /api/door-access/data)
$reedAktif = \App\Models\DoorAccessReading::where('recorded_at', '>=', now()->subSeconds(30))
->where('door_opened', true)->exists();
// Status device online — berdasarkan last_seen dalam 2 menit terakhir
$device = \App\Models\Device::orderBy('last_seen', 'desc')->first();
$sistemOnline = $device && $device->last_seen && $device->last_seen->diffInMinutes(now()) <= 2;
return view('dashboard', compact(
'totalSensor', 'sensorAktif', 'peringatanHariIni', 'alertAktif',
'lastUpdate', 'alertTerbaru', 'pirAktif', 'vibAktif', 'reedAktif',
'device', 'sistemOnline'
));
})->name('dashboard');
Route::get('/monitoring', function () {
// Ambil data terbaru dari tabel spesifik sensor
$pirLatest = \App\Models\PirReading::with('device')
->orderBy('recorded_at', 'desc')->first();
$vibrationLatest = \App\Models\VibrationReading::with('device')
->orderBy('recorded_at', 'desc')->first();
// Reed Switch: data dari ESP32 disimpan di DoorAccessReading via /api/door-access/data
$reedLatest = \App\Models\DoorAccessReading::with('device')
->orderBy('recorded_at', 'desc')->first();
// Ambil data sensor dari tabel sensors untuk info nama & status
$pirSensor = \App\Models\Sensor::where('type', 'pir')->first();
$vibrationSensor = \App\Models\Sensor::where('type', 'vibration')->first();
$reedSensor = \App\Models\Sensor::where('type', 'reed_switch')->first();
// Statistik 24 jam terakhir
$pirCount24h = \App\Models\PirReading::where('recorded_at', '>=', now()->subHours(24))
->where('motion_detected', true)->count();
$vibrationCount24h = \App\Models\VibrationReading::where('recorded_at', '>=', now()->subHours(24))
->where('is_abnormal', true)->count();
$reedCount24h = \App\Models\DoorAccessReading::where('recorded_at', '>=', now()->subHours(24))
->where('door_opened', true)->count();
// Riwayat 5 data terakhir tiap sensor
$pirHistory = \App\Models\PirReading::orderBy('recorded_at', 'desc')->limit(5)->get();
$vibrationHistory = \App\Models\VibrationReading::orderBy('recorded_at', 'desc')->limit(5)->get();
$reedHistory = \App\Models\DoorAccessReading::orderBy('recorded_at', 'desc')->limit(5)->get();
$device = \App\Models\Device::where('status', 'online')->first();
$lastUpdate = \App\Models\PirReading::orderBy('recorded_at', 'desc')->first()?->recorded_at;
return view('monitoring', compact(
'pirSensor', 'vibrationSensor', 'reedSensor',
'pirLatest', 'vibrationLatest', 'reedLatest',
'pirCount24h', 'vibrationCount24h', 'reedCount24h',
'pirHistory', 'vibrationHistory', 'reedHistory',
'device', 'lastUpdate'
));
})->name('monitoring');
Route::get('/log', function () {
$logs = \App\Models\ActivityLog::with(['device', 'sensor'])
->orderBy('event_time', 'desc')
->paginate(20);
$totalLog = \App\Models\ActivityLog::count();
$logHariIni = \App\Models\ActivityLog::whereDate('event_time', today())->count();
$logWarning = \App\Models\ActivityLog::where('severity', 'warning')->count();
$logCritical = \App\Models\ActivityLog::where('severity', 'critical')->count();
return view('log', compact('logs', 'totalLog', 'logHariIni', 'logWarning', 'logCritical'));
})->name('log');
Route::get('/device', function () {
return view('device');
})->name('device');
});