This commit is contained in:
ghozahimma65 2025-11-14 13:20:21 +07:00
parent ae2368c8f8
commit 7a1bbb020d
8 changed files with 335 additions and 20 deletions

View File

@ -0,0 +1,96 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Guru;
use App\Models\WaliMurid;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class AkunController extends Controller
{
public function index()
{
$users = User::whereIn('role', ['guru', 'wali_murid'])->get();
return view('admin.akun.index', compact('users'));
}
public function create()
{
$gurus = Guru::whereNull('user_id')->get(['id', 'nama_guru']);
$waliMurids = WaliMurid::whereNull('user_id')->get(['id', 'nama_wali']);
return view('admin.akun.create', compact('gurus', 'waliMurids'));
}
public function store(Request $request)
{
$request->validate([
'role' => 'required|in:guru,wali_murid',
'user_id' => 'required',
]);
if ($request->role == 'guru') {
$data = Guru::findOrFail($request->user_id);
$name = $data->nama_guru;
$email = $data->email ?? strtolower(str_replace(' ', '', $data->nama_guru)) . '@paud.local';
$data = WaliMurid::findOrFail($request->user_id);
$name = $data->nama_wali;
$email = $data->email ?? strtolower(str_replace(' ', '', $data->nama_wali)) . '@paud.local';
}
if (User::where('email', $email)->exists()) {
return back()->with('error', 'Email sudah digunakan untuk akun lain.');
}
$user = User::create([
'name' => $name,
'email' => $email,
'password' => Hash::make('123456'),
'role' => $request->role,
]);
$data->update(['user_id' => $user->id]);
return redirect()->route('akun.index')->with('success', 'Akun berhasil dibuat!');
}
public function destroy(User $akun)
{
$akun->delete();
return redirect()->route('akun.index')->with('success', 'Akun berhasil dihapus.');
}
public function edit(User $akun)
{
return view('admin.akun.edit', compact('akun'));
}
public function update(Request $request, User $akun)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email,' . $akun->id,
'role' => 'required|in:admin,guru,wali_murid',
]);
$akun->update([
'name' => $request->name,
'email' => $request->email,
'role' => $request->role,
]);
return redirect()->route('akun.index')->with('success', 'Akun berhasil diperbarui.');
}
public function resetPassword(User $akun)
{
$akun->update([
'password' => Hash::make('123456'),
]);
return redirect()->route('akun.index')->with('success', 'Password berhasil direset ke default (123456).');
}
}

View File

@ -8,12 +8,20 @@
class Guru extends Model
{
use HasFactory;
// kasih tahu Laravel kalau nama tabelnya "guru", bukan "gurus"
protected $table = 'guru';
protected $fillable = [
'nama_guru',
'email',
'nama',
'jenis_guru',
'no_hp',
'bidang',
'email',
'user_id',
];
public function user()
{
return $this->belongsTo(User::class);
}
}

View File

@ -13,14 +13,14 @@ class WaliMurid extends Model
protected $fillable = [
'nama_wali',
'email',
'no_hp',
'email',
'alamat',
'user_id',
];
// Tambahin relasi ke siswa
public function siswas()
public function user()
{
return $this->hasMany(Siswa::class, 'wali_id');
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,54 @@
@extends('layouts.app')
@section('content')
<div class="bg-white shadow-md rounded-lg p-6 max-w-lg mx-auto">
<h1 class="text-xl font-semibold text-gray-700 mb-4"> Tambah Akun</h1>
<form action="{{ route('akun.store') }}" method="POST">
@csrf
<div class="mb-4">
<label class="block text-gray-700 font-medium mb-1">Jenis Akun</label>
<select name="role" id="roleSelect" class="w-full border-gray-300 rounded-lg p-2">
<option value="guru">Guru</option>
<option value="wali_murid">Wali Murid</option>
</select>
</div>
<div id="guruSelect" class="mb-4">
<label class="block text-gray-700 font-medium mb-1">Pilih Guru</label>
<select name="user_id" class="w-full border-gray-300 rounded-lg p-2">
@foreach ($gurus as $guru)
<option value="{{ $guru->id }}">{{ $guru->nama_guru }}</option>
@endforeach
</select>
</div>
<div id="waliSelect" class="mb-4 hidden">
<label class="block text-gray-700 font-medium mb-1">Pilih Wali Murid</label>
<select name="user_id" class="w-full border-gray-300 rounded-lg p-2">
@foreach ($waliMurids as $wali)
<option value="{{ $wali->id }}">{{ $wali->nama_wali }}</option>
@endforeach
</select>
</div>
<div class="flex justify-end gap-3">
<a href="{{ route('akun.index') }}" class="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600">Batal</a>
<button type="submit" class="bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700">Simpan</button>
</div>
</form>
</div>
<script>
document.getElementById('roleSelect').addEventListener('change', function() {
if (this.value === 'guru') {
document.getElementById('guruSelect').classList.remove('hidden');
document.getElementById('waliSelect').classList.add('hidden');
} else {
document.getElementById('waliSelect').classList.remove('hidden');
document.getElementById('guruSelect').classList.add('hidden');
}
});
</script>
@endsection

View File

@ -0,0 +1,48 @@
@extends('layouts.app')
@section('content')
<div class="bg-white shadow-md rounded-lg p-6 max-w-lg mx-auto">
<h1 class="text-xl font-semibold text-gray-700 mb-4">✏️ Edit Akun</h1>
<form action="{{ route('akun.update', $akun->id) }}" method="POST">
@csrf
@method('PUT')
<!-- Nama -->
<div class="mb-4">
<label class="block text-gray-700 font-medium">Nama</label>
<input type="text" name="name"
value="{{ old('name', $akun->name) }}"
class="w-full border-gray-300 rounded-lg p-2 focus:ring-green-500 focus:border-green-500">
</div>
<!-- Email -->
<div class="mb-4">
<label class="block text-gray-700 font-medium">Email</label>
<input type="email" name="email"
value="{{ old('email', $akun->email) }}"
class="w-full border-gray-300 rounded-lg p-2 focus:ring-green-500 focus:border-green-500">
</div>
<!-- Role -->
<div class="mb-4">
<label class="block text-gray-700 font-medium">Role</label>
<select name="role" class="w-full border-gray-300 rounded-lg p-2 focus:ring-green-500 focus:border-green-500">
<option value="guru" {{ $akun->role == 'guru' ? 'selected' : '' }}>Guru</option>
<option value="wali_murid" {{ $akun->role == 'wali_murid' ? 'selected' : '' }}>Wali Murid</option>
<option value="admin" {{ $akun->role == 'admin' ? 'selected' : '' }}>Admin</option>
</select>
</div>
<!-- Tombol -->
<div class="flex justify-end gap-3">
<a href="{{ route('akun.index') }}"
class="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600">Batal</a>
<button type="submit"
class="bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700">
Simpan Perubahan
</button>
</div>
</form>
</div>
@endsection

View File

@ -0,0 +1,102 @@
@extends('layouts.app')
@section('content')
<div class="bg-white p-6 rounded-lg shadow-md">
<div class="flex justify-between items-center mb-4">
<h1 class="text-xl font-semibold text-gray-700">🔐 Daftar Akun</h1>
<a href="{{ route('akun.create') }}" class="bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700">+ Tambah Akun</a>
</div>
@if(session('success'))
<div class="bg-green-100 text-green-800 p-3 rounded mb-4">{{ session('success') }}</div>
@endif
@if(session('error'))
<div class="bg-red-100 text-red-800 p-3 rounded mb-4">{{ session('error') }}</div>
@endif
<table class="w-full border border-gray-200 rounded-lg text-sm">
<thead class="bg-gray-100">
<tr>
<th class="p-3 border">#</th>
<th class="p-3 border">Nama</th>
<th class="p-3 border">Email</th>
<th class="p-3 border">Role</th>
<th class="p-3 border">Password</th>
<th class="p-3 border text-center">Aksi</th>
</tr>
</thead>
<tbody>
@forelse ($users as $i => $user)
<tr class="hover:bg-gray-50">
<td class="p-3 border">{{ $i + 1 }}</td>
<td class="p-3 border">{{ $user->name }}</td>
<td class="p-3 border">{{ $user->email }}</td>
<td class="p-3 border text-center">
@if($user->role == 'guru')
<span class="text-blue-600 font-semibold">Guru</span>
@elseif($user->role == 'wali_murid')
<span class="text-purple-600 font-semibold">Wali Murid</span>
@else
<span class="text-gray-600">Admin</span>
@endif
</td>
{{-- Kolom password (disembunyikan tapi bisa dilihat) --}}
<td class="p-3 border text-center">
<div class="relative inline-block">
<input
type="password"
value="123456"
readonly
class="border rounded-lg px-2 py-1 text-center bg-gray-100 text-sm w-24 password-field"
>
<button type="button" class="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 toggle-password">
<i class="fas fa-eye"></i>
</button>
</div>
</td>
{{-- Tombol Aksi --}}
<td class="p-3 border text-center space-x-2">
<a href="{{ route('akun.edit', $user->id) }}" class="bg-blue-500 text-white px-3 py-1 rounded hover:bg-blue-600">Edit</a>
<form action="{{ route('akun.reset', $user->id) }}" method="POST" class="inline">
@csrf
<button type="submit" class="bg-yellow-500 text-white px-3 py-1 rounded hover:bg-yellow-600">Reset</button>
</form>
<form action="{{ route('akun.destroy', $user->id) }}" method="POST" onsubmit="return confirm('Yakin mau hapus akun ini?')" class="inline">
@csrf
@method('DELETE')
<button class="bg-red-500 text-white px-3 py-1 rounded hover:bg-red-600">Hapus</button>
</form>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center p-4 text-gray-500">Belum ada akun terdaftar.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
{{-- Script show/hide password --}}
<script>
document.querySelectorAll('.toggle-password').forEach(btn => {
btn.addEventListener('click', function() {
const input = this.closest('div').querySelector('.password-field');
const icon = this.querySelector('i');
if (input.type === 'password') {
input.type = 'text';
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
} else {
input.type = 'password';
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
}
});
});
</script>
@endsection

View File

@ -37,9 +37,12 @@
<div>
<p class="font-semibold uppercase text-xs mb-2">Menu Akun</p>
<ul class="ml-4 space-y-1">
<li><a href="#" class="block p-2 hover:bg-green-700 rounded">👨‍🏫 Guru</a></li>
<li><a href="#" class="block p-2 hover:bg-green-700 rounded">👪 Wali Murid</a></li>
<li><a href="#" class="block p-2 hover:bg-green-700 rounded">🧒 Peserta Didik</a></li>
<li>
<a href="{{ route('akun.index') }}"
class="block p-2 hover:bg-green-700 rounded">
👥 Manajemen Akun
</a>
</li>
</ul>
</div>

View File

@ -8,33 +8,37 @@
use App\Http\Controllers\Admin\SiswaController;
use App\Http\Controllers\Admin\PengumumanController;
use App\Http\Controllers\Admin\PerkembanganController;
use App\Http\Controllers\Admin\AkunController;
// Login routes
Route::get('/login', [AuthController::class, 'showLogin'])->name('login');
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
// Splash screen (halaman awal)
// Splash
Route::get('/', function () {
return view('splash');
});
// Hanya bisa diakses setelah login
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
Route::resource('pengumuman', \App\Http\Controllers\Admin\PengumumanController::class);
Route::prefix('admin')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
Route::resource('pengumuman', PengumumanController::class);
Route::prefix('admin')->group(function () {
Route::resource('guru', GuruController::class);
Route::resource('wali-murid', WaliMuridController::class);
Route::resource('siswa', SiswaController::class);
Route::middleware(['auth'])->group(function () {
Route::prefix('admin')->group(function () {
Route::get('/perkembangan', [PerkembanganController::class, 'index'])->name('admin.perkembangan.index');
Route::get('/perkembangan/{id}', [PerkembanganController::class, 'show'])->name('admin.perkembangan.show');
Route::get('/perkembangan/{id}/print', [PerkembanganController::class, 'print'])->name('admin.perkembangan.print');
// Akun
Route::resource('akun', AkunController::class);
Route::post('akun/{akun}/reset-password', [AkunController::class, 'resetPassword'])->name('akun.resetPassword');
});
});
});
});