login guru (undone)
This commit is contained in:
parent
e1f4801551
commit
a71d652e8d
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Guru;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Mengajar;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$guru = Auth::guard('guru')->user();
|
||||
|
||||
// Hitung total kelas yang diajar
|
||||
$totalKelas = Mengajar::where('nip', $guru->nip)
|
||||
->distinct('id_kelas')
|
||||
->count('id_kelas');
|
||||
|
||||
// Hitung total mapel yang diajar
|
||||
$totalMapel = Mengajar::where('nip', $guru->nip)
|
||||
->distinct('id_mapel')
|
||||
->count('id_mapel');
|
||||
|
||||
// Hitung total siswa yang diajar (lewat kelas)
|
||||
$totalSiswa = Mengajar::where('nip', $guru->nip)
|
||||
->with('kelas.siswa')
|
||||
->get()
|
||||
->pluck('kelas.siswa')
|
||||
->flatten()
|
||||
->unique('nisn')
|
||||
->count();
|
||||
|
||||
return view('guru.dashboard', compact('totalKelas', 'totalMapel', 'totalSiswa'));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Guru;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Guru;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class GuruController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Guru::query();
|
||||
|
||||
// SEARCH
|
||||
if ($request->has('search')) {
|
||||
$search = $request->search;
|
||||
$query->where('nama', 'like', "%$search%")
|
||||
->orWhere('nip', 'like', "%$search%");
|
||||
}
|
||||
|
||||
// SHOW PER PAGE
|
||||
$perPage = $request->get('perPage', 10);
|
||||
|
||||
$gurus = $query->paginate($perPage)->appends($request->all());
|
||||
|
||||
return view('guru.guru.index', compact('gurus'));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Guru;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Kelas;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class KelasController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Kelas::query();
|
||||
|
||||
// SEARCH
|
||||
if ($request->has('search')) {
|
||||
$search = $request->search;
|
||||
$query->where('nama_kelas', 'like', "%$search%")
|
||||
->orWhere('id_kelas', 'like', "%$search%");
|
||||
}
|
||||
|
||||
// SHOW PER PAGE
|
||||
$perPage = $request->get('perPage', 10);
|
||||
|
||||
$kelass = $query->paginate($perPage)->appends($request->all());
|
||||
|
||||
return view('guru.kelas.index', compact('kelass'));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
// ============================================================
|
||||
// FILE 1: app/Http/Controllers/Guru/LoginController.php
|
||||
// ============================================================
|
||||
|
||||
namespace App\Http\Controllers\Guru;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('auth.login-guru');
|
||||
}
|
||||
|
||||
public function loginGuru(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'nip' => 'required',
|
||||
'password' => 'required',
|
||||
]);
|
||||
|
||||
$credentials = $request->only('nip', 'password');
|
||||
|
||||
if (Auth::guard('guru')->attempt($credentials)) {
|
||||
$request->session()->regenerate();
|
||||
|
||||
return redirect()->intended(route('guru.dashboard'));
|
||||
}
|
||||
|
||||
return back()->withErrors([
|
||||
'nip' => 'NIP atau password salah'
|
||||
])->withInput($request->except('password'));
|
||||
}
|
||||
|
||||
public function logout(Request $request)
|
||||
{
|
||||
Auth::guard('guru')->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect()->route('guru.login');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Guru;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class ProfilController extends Controller
|
||||
{
|
||||
public function show()
|
||||
{
|
||||
$guru = Auth::guard('guru')->user();
|
||||
return view('guru.profil.show', compact('guru'));
|
||||
}
|
||||
|
||||
public function update(Request $request)
|
||||
{
|
||||
$guru = Auth::guard('guru')->user();
|
||||
|
||||
$validated = $request->validate([
|
||||
'nama' => 'required|string|max:100',
|
||||
'password' => 'nullable|string|min:6|confirmed',
|
||||
], [
|
||||
'nama.required' => 'Nama wajib diisi',
|
||||
'password.min' => 'Password minimal 6 karakter',
|
||||
'password.confirmed' => 'Konfirmasi password tidak cocok',
|
||||
]);
|
||||
|
||||
$guru->nama = $validated['nama'];
|
||||
|
||||
if ($request->filled('password')) {
|
||||
$guru->password = Hash::make($validated['password']);
|
||||
}
|
||||
|
||||
$guru->save();
|
||||
|
||||
return redirect()->route('guru.profil.show')
|
||||
->with('success', 'Profil berhasil diupdate!');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Guru;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Siswa;
|
||||
use App\Models\Kelas;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SiswaController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Siswa::with('kelas');
|
||||
|
||||
// SEARCH
|
||||
if ($request->has('search')) {
|
||||
$search = $request->search;
|
||||
$query->where('nama', 'like', "%$search%")
|
||||
->orWhere('nisn', 'like', "%$search%");
|
||||
}
|
||||
|
||||
// FILTER BY KELAS
|
||||
if ($request->has('filter_kelas') && $request->filter_kelas != '') {
|
||||
$query->where('id_kelas', $request->filter_kelas);
|
||||
}
|
||||
|
||||
// SHOW PER PAGE
|
||||
$perPage = $request->get('perPage', 10);
|
||||
|
||||
$siswas = $query->paginate($perPage)->appends($request->all());
|
||||
|
||||
// Ambil semua kelas untuk dropdown filter
|
||||
$kelass = Kelas::orderBy('tingkat')->orderBy('nama_kelas')->get();
|
||||
|
||||
return view('guru.siswa.index', compact('siswas', 'kelass'));
|
||||
}
|
||||
}
|
||||
|
|
@ -9,18 +9,21 @@ class Authenticate extends Middleware
|
|||
/**
|
||||
* Tentukan ke mana redirect jika user belum login.
|
||||
*/
|
||||
protected function redirectTo($request): ?string
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
// Cek guard admin dulu
|
||||
if ($request->is('admin/*')) {
|
||||
return route('admin.login');
|
||||
}
|
||||
|
||||
// Default kalau bukan admin (misalnya guru/siswa)
|
||||
return route('login');
|
||||
protected function redirectTo($request): ?string{
|
||||
if (! $request->expectsJson()) {
|
||||
// Admin
|
||||
if ($request->is('admin/*')) {
|
||||
return route('admin.login');
|
||||
}
|
||||
|
||||
return null;
|
||||
// Guru
|
||||
if ($request->is('guru/*')) {
|
||||
return route('guru.login');
|
||||
}
|
||||
|
||||
// Default
|
||||
return route('login');
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Guru extends Model
|
||||
class Guru extends Authenticatable
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'gurus';
|
||||
|
||||
protected $primaryKey = 'nip';
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected $fillable = [
|
||||
|
|
@ -23,4 +23,10 @@ class Guru extends Model
|
|||
protected $hidden = [
|
||||
'password',
|
||||
];
|
||||
|
||||
// Relasi ke Mengajar
|
||||
public function mengajars()
|
||||
{
|
||||
return $this->hasMany(Mengajar::class, 'nip', 'nip');
|
||||
}
|
||||
}
|
||||
|
|
@ -46,11 +46,11 @@
|
|||
],
|
||||
'guru' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'guru',
|
||||
'provider' => 'gurus',
|
||||
],
|
||||
'siswa' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'siswa',
|
||||
'provider' => 'siswas',
|
||||
],
|
||||
],
|
||||
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
'driver' => 'eloquent',
|
||||
'model' => App\Models\Admin::class,
|
||||
],
|
||||
'guru' => [
|
||||
'gurus' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => App\Models\Guru::class,
|
||||
],
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@
|
|||
<h1 class="fw-bold text-primary mb-4">Selamat Datang di Website Kami</h1>
|
||||
<p class="mb-4">Ini halaman landing sederhana. Silakan pilih login sesuai role kamu.</p>
|
||||
<a href="{{ route('admin.login') }}" class="btn btn-primary">Login Admin</a>
|
||||
<a href="{{ route('guru.login') }}" class="btn btn-primary">Login Guru</a>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
← Kembali ke Landing Page
|
||||
</a>
|
||||
|
||||
<form method="POST" action="{{ route('login.guru') }}">
|
||||
<form method="POST" action="{{ route('guru.login.submit') }}">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">NIP</label>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
@extends('guru.layouts.app')
|
||||
|
||||
@section('title', 'Dashboard Guru')
|
||||
|
||||
@section('content')
|
||||
<div class="container mt-5">
|
||||
<h1 class="mb-4 fw-bold text-primary">Dashboard Guru</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="card text-center shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5>Total Guru</h5>
|
||||
<p class="fs-3 fw-bold text-success">12</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="card text-center shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5>Total Siswa</h5>
|
||||
<p class="fs-3 fw-bold text-primary">230</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
@extends('guru.layouts.app')
|
||||
|
||||
@section('title', 'Daftar Guru')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.page-title {
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 10px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.custom-card {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
border: 2px solid #e5e5e5;
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
background: #bae6fd;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
background: #bae6fd;
|
||||
border-radius: 30px;
|
||||
padding: 6px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.search-box input {
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.per-page-select {
|
||||
border-radius: 10px;
|
||||
padding: 5px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.badge-info {
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
padding: 5px 12px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3 class="page-title">DAFTAR GURU</h3>
|
||||
|
||||
<div class="custom-card">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
|
||||
<div class="badge-info">
|
||||
📖 Mode Hanya Lihat (Read Only)
|
||||
</div>
|
||||
|
||||
<form method="GET">
|
||||
<div class="search-box">
|
||||
<input type="text" name="search" placeholder="Cari" value="{{ request('search') }}">
|
||||
<button style="border:none;background:none">
|
||||
<img src="{{ asset('images/icon/main/search.png') }}" width="18">
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<form method="GET" class="mb-2">
|
||||
<span>Tampilkan</span>
|
||||
|
||||
<select name="perPage" onchange="this.form.submit()" class="per-page-select">
|
||||
<option value="10" {{ request('perPage') == 10 ? 'selected' : '' }}>10</option>
|
||||
<option value="25" {{ request('perPage') == 25 ? 'selected' : '' }}>25</option>
|
||||
<option value="50" {{ request('perPage') == 50 ? 'selected' : '' }}>50</option>
|
||||
</select>
|
||||
|
||||
<span>data</span>
|
||||
|
||||
<input type="hidden" name="search" value="{{ request('search') }}">
|
||||
</form>
|
||||
|
||||
<table class="table text-center align-middle">
|
||||
<thead class="table-header">
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>NIP</th>
|
||||
<th>Nama Guru</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@forelse($gurus as $index => $guru)
|
||||
<tr>
|
||||
<td>{{ $gurus->firstItem() + $index }}</td>
|
||||
<td>{{ $guru->nip }}</td>
|
||||
<td>{{ $guru->nama }}</td>
|
||||
</tr>
|
||||
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="3">Belum ada data guru</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
{{ $gurus->links() }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
@extends('guru.layouts.app')
|
||||
|
||||
@section('title', 'Daftar Kelas')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.page-title {
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 10px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.custom-card {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
border: 2px solid #e5e5e5;
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
background: #bae6fd;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
background: #bae6fd;
|
||||
border-radius: 30px;
|
||||
padding: 6px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.search-box input {
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.per-page-select {
|
||||
border-radius: 10px;
|
||||
padding: 5px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.badge-info {
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
padding: 5px 12px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3 class="page-title">DAFTAR KELAS</h3>
|
||||
|
||||
<div class="custom-card">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
|
||||
<div class="badge-info">
|
||||
📖 Mode Hanya Lihat (Read Only)
|
||||
</div>
|
||||
|
||||
<form method="GET">
|
||||
<div class="search-box">
|
||||
<input type="text" name="search" placeholder="Cari" value="{{ request('search') }}">
|
||||
<button style="border:none;background:none">
|
||||
<img src="{{ asset('images/icon/main/search.png') }}" width="18">
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<form method="GET" class="mb-2">
|
||||
<span>Tampilkan</span>
|
||||
|
||||
<select name="perPage" onchange="this.form.submit()" class="per-page-select">
|
||||
<option value="10" {{ request('perPage') == 10 ? 'selected' : '' }}>10</option>
|
||||
<option value="25" {{ request('perPage') == 25 ? 'selected' : '' }}>25</option>
|
||||
<option value="50" {{ request('perPage') == 50 ? 'selected' : '' }}>50</option>
|
||||
</select>
|
||||
|
||||
<span>data</span>
|
||||
|
||||
<input type="hidden" name="search" value="{{ request('search') }}">
|
||||
</form>
|
||||
|
||||
<table class="table text-center align-middle">
|
||||
<thead class="table-header">
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>ID Kelas</th>
|
||||
<th>Nama Kelas</th>
|
||||
<th>Tingkat</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@forelse($kelass as $index => $kelas)
|
||||
<tr>
|
||||
<td>{{ $kelass->firstItem() + $index }}</td>
|
||||
<td>{{ $kelas->id_kelas }}</td>
|
||||
<td>{{ $kelas->nama_kelas }}</td>
|
||||
<td>{{ $kelas->tingkat }}</td>
|
||||
</tr>
|
||||
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="4">Belum ada data kelas</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
{{ $kelass->links() }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
<?php?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>@yield('title', 'Panel Guru')</title>
|
||||
|
||||
<!-- Fonts & Bootstrap -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
background-color: #f8f9fa;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* WRAPPER */
|
||||
.guru-wrapper {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* SIDEBAR */
|
||||
.sidebar {
|
||||
width: 260px;
|
||||
background: #ffffff;
|
||||
border-right: 2px solid #e0f2fe;
|
||||
padding: 30px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar-logo {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.sidebar-logo img {
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 18px;
|
||||
margin-bottom: 12px;
|
||||
border-radius: 12px;
|
||||
color: #64748b;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.sidebar-link:hover {
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
}
|
||||
|
||||
.sidebar-link.active {
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.sidebar-logout button {
|
||||
width: 100%;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #ef4444;
|
||||
font-weight: 600;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* MAIN */
|
||||
.main {
|
||||
flex: 1;
|
||||
background: #f0f9ff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* TOPBAR */
|
||||
.topbar {
|
||||
background: #0284c7;
|
||||
margin: 20px;
|
||||
padding: 16px 24px;
|
||||
border-radius: 16px;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.topbar-left {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.topbar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.topbar-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* CONTENT */
|
||||
.content {
|
||||
padding: 20px 30px;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="guru-wrapper">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-logo">
|
||||
<img src="{{ asset('images/logo/logosmk.png') }}" alt="Logo SMK">
|
||||
</div>
|
||||
|
||||
<nav class="sidebar-menu">
|
||||
|
||||
<a href="{{ route('guru.dashboard') }}"
|
||||
class="sidebar-link {{ request()->routeIs('guru.dashboard') ? 'active' : '' }}">
|
||||
<img src="{{ asset('images/icon/sidebar/home.png') }}" class="sidebar-icon" alt="">
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ route('guru.guru.index') }}"
|
||||
class="sidebar-link {{ request()->routeIs('guru.guru.*') ? 'active' : '' }}">
|
||||
<img src="{{ asset('images/icon/sidebar/guru.png') }}" class="sidebar-icon" alt="">
|
||||
<span>Daftar Guru</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ route('guru.kelas.index') }}"
|
||||
class="sidebar-link {{ request()->routeIs('guru.kelas.*') ? 'active' : '' }}">
|
||||
<img src="{{ asset('images/icon/sidebar/kelas.png') }}" class="sidebar-icon" alt="">
|
||||
<span>Daftar Kelas</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ route('guru.siswa.index') }}"
|
||||
class="sidebar-link {{ request()->routeIs('guru.siswa.*') ? 'active' : '' }}">
|
||||
<img src="{{ asset('images/icon/sidebar/siswa.png') }}" class="sidebar-icon" alt="">
|
||||
<span>Daftar Siswa</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ route('guru.profil.show') }}"
|
||||
class="sidebar-link {{ request()->routeIs('guru.profil.*') ? 'active' : '' }}">
|
||||
<img src="{{ asset('images/icon/sidebar/profil.png') }}" class="sidebar-icon" alt="">
|
||||
<span>Profil Saya</span>
|
||||
</a>
|
||||
|
||||
</nav>
|
||||
|
||||
<form action="{{ route('guru.logout') }}" method="POST" class="sidebar-logout">
|
||||
@csrf
|
||||
<button type="submit">Logout</button>
|
||||
</form>
|
||||
</aside>
|
||||
|
||||
<!-- MAIN -->
|
||||
<div class="main">
|
||||
|
||||
<!-- TOPBAR -->
|
||||
<header class="topbar">
|
||||
<div class="topbar-left">
|
||||
👋 Hai, {{ Auth::guard('guru')->user()->nama ?? 'Guru' }}
|
||||
</div>
|
||||
|
||||
<div class="topbar-right">
|
||||
<img src="{{ asset('images/icon/sidebar/notif.png') }}" class="topbar-icon" alt="Notification">
|
||||
<img src="{{ asset('images/icon/sidebar/profil.png') }}" class="topbar-icon" alt="Profile">
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- CONTENT -->
|
||||
<main class="content">
|
||||
@yield('content')
|
||||
</main>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
<?php
|
||||
// ============================================================
|
||||
// FILE 10: resources/views/guru/dashboard.blade.php
|
||||
// ============================================================
|
||||
?>
|
||||
|
||||
@extends('guru.layouts.app')
|
||||
|
||||
@section('title', 'Dashboard Guru')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.page-title {
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
padding: 25px;
|
||||
border: 2px solid #e0f2fe;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stats-number {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
color: #0284c7;
|
||||
}
|
||||
|
||||
.stats-label {
|
||||
font-size: 16px;
|
||||
color: #64748b;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.welcome-card {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
border: 2px solid #e0f2fe;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3 class="page-title">DASHBOARD GURU</h3>
|
||||
|
||||
<div class="welcome-card">
|
||||
<h4>Selamat Datang, {{ Auth::guard('guru')->user()->nama }}! 👨🏫</h4>
|
||||
<p class="text-muted mb-0">NIP: {{ Auth::guard('guru')->user()->nip }}</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="stats-card">
|
||||
<div class="stats-number">{{ $totalKelas }}</div>
|
||||
<div class="stats-label">Total Kelas Diampu</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="stats-card">
|
||||
<div class="stats-number">{{ $totalMapel }}</div>
|
||||
<div class="stats-label">Total Mata Pelajaran</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="stats-card">
|
||||
<div class="stats-number">{{ $totalSiswa }}</div>
|
||||
<div class="stats-label">Total Siswa Diajar</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
@extends('guru.layouts.app')
|
||||
|
||||
@section('title', 'Profil Saya')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.page-title {
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 20px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.custom-card {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
border: 2px solid #e0f2fe;
|
||||
padding: 30px;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3 class="page-title">PROFIL SAYA</h3>
|
||||
|
||||
<div class="custom-card">
|
||||
|
||||
{{-- Alert Success --}}
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
{{ session('success') }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('guru.profil.update') }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">NIP</label>
|
||||
<input type="text" class="form-control bg-light" value="{{ $guru->nip }}" disabled>
|
||||
<small class="text-muted">NIP tidak dapat diubah</small>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Nama Lengkap <span class="text-danger">*</span></label>
|
||||
<input type="text" name="nama" class="form-control @error('nama') is-invalid @enderror"
|
||||
value="{{ old('nama', $guru->nama) }}" required>
|
||||
@error('nama')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Password Baru</label>
|
||||
<input type="password" name="password" class="form-control @error('password') is-invalid @enderror"
|
||||
placeholder="Kosongkan jika tidak ingin mengubah">
|
||||
@error('password')
|
||||
<small class="text-danger">{{ $message }}</small>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Konfirmasi Password Baru</label>
|
||||
<input type="password" name="password_confirmation" class="form-control"
|
||||
placeholder="Ulangi password baru">
|
||||
<small class="text-muted">Isi hanya jika ingin mengubah password</small>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end mt-4">
|
||||
<button type="submit" class="btn btn-primary px-4">
|
||||
💾 Simpan Perubahan
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
@extends('guru.layouts.app')
|
||||
|
||||
@section('title', 'Daftar Siswa')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.page-title {
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 10px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.custom-card {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
border: 2px solid #e5e5e5;
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
background: #bae6fd;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
background: #bae6fd;
|
||||
border-radius: 30px;
|
||||
padding: 6px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.search-box input {
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.per-page-select, .filter-select {
|
||||
border-radius: 10px;
|
||||
padding: 5px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.badge-info {
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
padding: 5px 12px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3 class="page-title">DAFTAR SISWA</h3>
|
||||
|
||||
<div class="custom-card">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
|
||||
<div class="badge-info">
|
||||
📖 Mode Hanya Lihat (Read Only)
|
||||
</div>
|
||||
|
||||
<form method="GET">
|
||||
<div class="search-box">
|
||||
<input type="text" name="search" placeholder="Cari" value="{{ request('search') }}">
|
||||
<button style="border:none;background:none">
|
||||
<img src="{{ asset('images/icon/main/search.png') }}" width="18">
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<form method="GET" class="mb-2">
|
||||
<span>Tampilkan</span>
|
||||
|
||||
<select name="perPage" onchange="this.form.submit()" class="per-page-select">
|
||||
<option value="10" {{ request('perPage') == 10 ? 'selected' : '' }}>10</option>
|
||||
<option value="25" {{ request('perPage') == 25 ? 'selected' : '' }}>25</option>
|
||||
<option value="50" {{ request('perPage') == 50 ? 'selected' : '' }}>50</option>
|
||||
</select>
|
||||
|
||||
<span>data</span>
|
||||
|
||||
<span class="ms-3">Filter Kelas</span>
|
||||
|
||||
<select name="filter_kelas" onchange="this.form.submit()" class="filter-select">
|
||||
<option value="">Semua Kelas</option>
|
||||
@foreach($kelass as $kelas)
|
||||
<option value="{{ $kelas->id_kelas }}"
|
||||
{{ request('filter_kelas') == $kelas->id_kelas ? 'selected' : '' }}>
|
||||
{{ $kelas->tingkat }} - {{ $kelas->nama_kelas }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<input type="hidden" name="search" value="{{ request('search') }}">
|
||||
</form>
|
||||
|
||||
<table class="table text-center align-middle">
|
||||
<thead class="table-header">
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>NISN</th>
|
||||
<th>Nama</th>
|
||||
<th>Tempat Lahir</th>
|
||||
<th>Tanggal Lahir</th>
|
||||
<th>Kelas</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@forelse($siswas as $index => $siswa)
|
||||
<tr>
|
||||
<td>{{ $siswas->firstItem() + $index }}</td>
|
||||
<td>{{ $siswa->nisn }}</td>
|
||||
<td>{{ $siswa->nama }}</td>
|
||||
<td>{{ $siswa->tempat_lahir }}</td>
|
||||
<td>{{ \Carbon\Carbon::parse($siswa->tanggal_lahir)->format('d M Y') }}</td>
|
||||
<td>{{ $siswa->kelas->tingkat }} - {{ $siswa->kelas->nama_kelas }}</td>
|
||||
</tr>
|
||||
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6">Belum ada data siswa</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
{{ $siswas->links() }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -11,12 +11,14 @@
|
|||
use App\Http\Controllers\Admin\SiswaController;
|
||||
use App\Http\Controllers\Admin\MapelController;
|
||||
|
||||
// use App\Http\Controllers\GuruController;
|
||||
// use App\Http\Controllers\SiswaController;
|
||||
// use App\Http\Controllers\KelasController;
|
||||
// use App\Http\Controllers\MapelController;
|
||||
use App\Http\Controllers\ChallengeController;
|
||||
use App\Http\Controllers\LeaderboardController;
|
||||
use App\Http\Controllers\Guru\GuruLoginController;
|
||||
use App\Http\Controllers\Guru\DashboardController;
|
||||
use App\Http\Controllers\Guru\GuruGuruController;
|
||||
use App\Http\Controllers\Guru\GuruSiswaController;
|
||||
use App\Http\Controllers\Guru\GuruKelasController;
|
||||
use App\Http\Controllers\Guru\GuruMapelController;
|
||||
use App\Http\Controllers\Guru\GuruLeaderboardController;
|
||||
use App\Http\Controllers\Guru\GuruProfilController;
|
||||
|
||||
// ====================
|
||||
// LANDING PAGE
|
||||
|
|
@ -117,12 +119,27 @@
|
|||
// =======================================================
|
||||
// GURU AREA
|
||||
// =======================================================
|
||||
Route::middleware(['auth:guru'])->group(function () {
|
||||
Route::get('/guru/dashboard', function () {
|
||||
return view('guru.dashboard');
|
||||
})->name('guru.dashboard');
|
||||
});
|
||||
Route::middleware(['auth:guru'])->prefix('guru')->name('guru.')->group(function () {
|
||||
|
||||
Route::get('/dashboard', [DashboardController::class, 'index'])
|
||||
->name('dashboard');
|
||||
|
||||
// Daftar Guru (Read Only)
|
||||
Route::get('/daftar-guru', [GuruGuruController::class, 'index'])->name('guru.index');
|
||||
|
||||
// Daftar Kelas (Read Only)
|
||||
Route::get('/daftar-kelas', [GuruKelasController::class, 'index'])->name('kelas.index');
|
||||
|
||||
// Daftar Siswa (Read Only)
|
||||
Route::get('/daftar-siswa', [GuruSiswaController::class, 'index'])->name('siswa.index');
|
||||
|
||||
// Profil (Edit)
|
||||
Route::get('/profil', [GuruProfilController::class, 'show'])->name('profil.show');
|
||||
Route::put('/profil', [GuruProfilController::class, 'update'])->name('profil.update');
|
||||
|
||||
// LOGOUT GURU
|
||||
Route::post('/logout', [GuruLoginController::class, 'logout'])->name('logout');
|
||||
});
|
||||
|
||||
// =======================================================
|
||||
// SISWA AREA
|
||||
|
|
|
|||
Loading…
Reference in New Issue