update revisi
This commit is contained in:
parent
6e5f120cbd
commit
fe34628f50
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 73 KiB |
Binary file not shown.
|
|
@ -21,14 +21,14 @@ public function create()
|
||||||
{
|
{
|
||||||
$gurus = Guru::whereNull('user_id')->get(['id', 'nama_guru']);
|
$gurus = Guru::whereNull('user_id')->get(['id', 'nama_guru']);
|
||||||
$waliMurids = WaliMurid::whereNull('user_id')->get(['id', 'nama_wali']);
|
$waliMurids = WaliMurid::whereNull('user_id')->get(['id', 'nama_wali']);
|
||||||
|
|
||||||
return view('admin.akun.create', compact('gurus', 'waliMurids'));
|
return view('admin.akun.create', compact('gurus', 'waliMurids'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'role' => 'required|in:guru,wali_murid',
|
'role' => 'required|in:guru,wali_murid',
|
||||||
'user_guru_id' => 'required',
|
'user_guru_id' => 'required',
|
||||||
|
|
@ -43,22 +43,22 @@ public function store(Request $request)
|
||||||
$name = $data->nama_wali;
|
$name = $data->nama_wali;
|
||||||
$email = $data->email ?? strtolower(str_replace(' ', '', $data->nama_wali)) . '@paud.local';
|
$email = $data->email ?? strtolower(str_replace(' ', '', $data->nama_wali)) . '@paud.local';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (User::where('email', $email)->exists()) {
|
if (User::where('email', $email)->exists()) {
|
||||||
return back()->with('error', 'Email sudah digunakan untuk akun lain.');
|
return back()->with('error', 'Email sudah digunakan untuk akun lain.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::create([
|
$user = User::create([
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'email' => $email,
|
'email' => $email,
|
||||||
'password' => Hash::make('123456'),
|
'password' => Hash::make('123456'),
|
||||||
'role' => $request->role,
|
'role' => $request->role,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$data->update(['user_id' => $user->id]);
|
$data->update(['user_id' => $user->id]);
|
||||||
|
|
||||||
|
|
||||||
return redirect()->route('akun.index')->with('success', 'Akun berhasil dibuat!');
|
return redirect()->route('akun.index')->with('success', 'Akun berhasil dibuat!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,12 +67,12 @@ public function destroy(User $akun)
|
||||||
$akun->delete();
|
$akun->delete();
|
||||||
return redirect()->route('akun.index')->with('success', 'Akun berhasil dihapus.');
|
return redirect()->route('akun.index')->with('success', 'Akun berhasil dihapus.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(User $akun)
|
public function edit(User $akun)
|
||||||
{
|
{
|
||||||
return view('admin.akun.edit', compact('akun'));
|
return view('admin.akun.edit', compact('akun'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(Request $request, User $akun)
|
public function update(Request $request, User $akun)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
|
|
@ -80,22 +80,22 @@ public function update(Request $request, User $akun)
|
||||||
'email' => 'required|email|unique:users,email,' . $akun->id,
|
'email' => 'required|email|unique:users,email,' . $akun->id,
|
||||||
'role' => 'required|in:admin,guru,wali_murid',
|
'role' => 'required|in:admin,guru,wali_murid',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$akun->update([
|
$akun->update([
|
||||||
'name' => $request->name,
|
'name' => $request->name,
|
||||||
'email' => $request->email,
|
'email' => $request->email,
|
||||||
'role' => $request->role,
|
'role' => $request->role,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect()->route('akun.index')->with('success', 'Akun berhasil diperbarui.');
|
return redirect()->route('akun.index')->with('success', 'Akun berhasil diperbarui.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resetPassword(User $akun)
|
public function resetPassword(User $akun)
|
||||||
{
|
{
|
||||||
$akun->update([
|
$akun->update([
|
||||||
'password' => Hash::make('123456'),
|
'password' => Hash::make('123456'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect()->route('akun.index')->with('success', 'Password berhasil direset ke default (123456).');
|
return redirect()->route('akun.index')->with('success', 'Password berhasil direset ke default (123456).');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,74 +23,93 @@ public function create()
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
// 1. Validasi
|
// 1. Validasi
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'nama_guru' => 'required',
|
'nama_guru' => 'required',
|
||||||
'email' => 'required|email|unique:users,email',
|
'email' => 'required|email|unique:users,email',
|
||||||
'password' => 'required|min:6',
|
'password' => 'required|min:6',
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::transaction(function () use ($request) {
|
||||||
|
|
||||||
|
// A. SIMPAN KE TABEL USERS (Disini tempatnya Email & Password)
|
||||||
|
$user = User::create([
|
||||||
|
'name' => $request->nama_guru,
|
||||||
|
'email' => $request->email,
|
||||||
|
'password' => Hash::make($request->password),
|
||||||
|
'role' => 'guru',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
DB::transaction(function () use ($request) {
|
// B. SIMPAN KE TABEL GURU (HANYA DATA PROFIL)
|
||||||
|
Guru::create([
|
||||||
// A. SIMPAN KE TABEL USERS (Disini tempatnya Email & Password)
|
'user_id' => $user->id,
|
||||||
$user = User::create([
|
'nama_guru' => $request->nama_guru,
|
||||||
'name' => $request->nama_guru,
|
'nip' => $request->nip,
|
||||||
'email' => $request->email,
|
'jenis_guru' => $request->jenis_guru, // Pastikan kolom ini ada di tabel guru kamu
|
||||||
'password' => Hash::make($request->password),
|
'no_hp' => $request->no_hp,
|
||||||
'role' => 'guru',
|
'alamat' => $request->alamat,
|
||||||
]);
|
|
||||||
|
// ❌ JANGAN ADA baris 'email' => ... disini
|
||||||
// B. SIMPAN KE TABEL GURU (HANYA DATA PROFIL)
|
// ❌ JANGAN ADA baris 'password' => ... disini
|
||||||
Guru::create([
|
]);
|
||||||
'user_id' => $user->id,
|
|
||||||
'nama_guru' => $request->nama_guru,
|
});
|
||||||
'nip' => $request->nip,
|
|
||||||
'jenis_guru' => $request->jenis_guru, // Pastikan kolom ini ada di tabel guru kamu
|
return redirect()->route('guru.index')->with('success', 'Berhasil menambahkan Guru!');
|
||||||
'no_hp' => $request->no_hp,
|
}
|
||||||
'alamat' => $request->alamat,
|
|
||||||
|
|
||||||
// ❌ JANGAN ADA baris 'email' => ... disini
|
|
||||||
// ❌ JANGAN ADA baris 'password' => ... disini
|
|
||||||
]);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
return redirect()->route('guru.index')->with('success', 'Berhasil menambahkan Guru!');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit($id)
|
public function edit($id)
|
||||||
{
|
{
|
||||||
// PENTING: Tambahkan ->with('user') biar data email & nama akun ke-load
|
// PENTING: Tambahkan ->with('user') biar data email & nama akun ke-load
|
||||||
$guru = Guru::with('user')->findOrFail($id);
|
$guru = Guru::with('user')->findOrFail($id);
|
||||||
return view('admin.guru.edit', compact('guru'));
|
return view('admin.guru.edit', compact('guru'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id)
|
||||||
{
|
{
|
||||||
// Cari data guru
|
// Cari data guru
|
||||||
$guru = Guru::findOrFail($id);
|
$guru = Guru::findOrFail($id);
|
||||||
|
|
||||||
// 1. Validasi
|
// 1. Validasi
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'nama_guru' => 'required|string|max:255', // Harus nama_guru
|
'nama_guru' => 'required|string|max:255',
|
||||||
'email' => 'required|email',
|
'email' => 'required|email|unique:users,email,' . $guru->user_id,
|
||||||
'no_hp' => 'nullable|string',
|
'password' => 'nullable|min:6',
|
||||||
'jenis_guru' => 'required|string',
|
'no_hp' => 'nullable|string',
|
||||||
]);
|
'jenis_guru' => 'required|string',
|
||||||
|
'nip' => 'nullable|string',
|
||||||
// 2. Update Tabel Guru LANGSUNG
|
'alamat' => 'nullable|string',
|
||||||
// Kita abaikan tabel user dulu karena user_id kamu masih NULL
|
]);
|
||||||
$guru->update([
|
|
||||||
'nama_guru' => $request->nama_guru, // Masukkan ke kolom nama_guru
|
DB::transaction(function () use ($request, $guru) {
|
||||||
'email' => $request->email,
|
// Update User Login (jika ada)
|
||||||
'no_hp' => $request->no_hp,
|
if ($guru->user) {
|
||||||
'jenis_guru' => $request->jenis_guru,
|
$userData = [
|
||||||
]);
|
'name' => $request->nama_guru,
|
||||||
|
'email' => $request->email,
|
||||||
return redirect()->route('guru.index')->with('success', 'Data Guru berhasil diperbarui!');
|
];
|
||||||
|
|
||||||
|
if ($request->filled('password')) {
|
||||||
|
$userData['password'] = Hash::make($request->password);
|
||||||
|
}
|
||||||
|
|
||||||
|
$guru->user->update($userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update Tabel Guru LANGSUNG
|
||||||
|
$guru->update([
|
||||||
|
'nama_guru' => $request->nama_guru,
|
||||||
|
'no_hp' => $request->no_hp,
|
||||||
|
'jenis_guru' => $request->jenis_guru,
|
||||||
|
'nip' => $request->nip,
|
||||||
|
'alamat' => $request->alamat,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return redirect()->route('guru.index')->with('success', 'Data Guru berhasil diperbarui!');
|
||||||
|
}
|
||||||
|
|
||||||
public function destroy(Guru $guru)
|
public function destroy(Guru $guru)
|
||||||
{
|
{
|
||||||
$guru->delete();
|
$guru->delete();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Pengumuman;
|
use App\Models\Pengumuman;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class PengumumanController extends Controller
|
class PengumumanController extends Controller
|
||||||
|
|
@ -20,17 +21,33 @@ public function create()
|
||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
|
// 1. Validasi Input
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'judul' => 'required|string|max:255',
|
'judul' => 'required|string|max:255',
|
||||||
'isi' => 'required|string',
|
'isi' => 'required|string',
|
||||||
'tanggal_mulai' => 'nullable|date',
|
'tanggal_mulai' => 'nullable|date',
|
||||||
'tanggal_selesai' => 'nullable|date|after_or_equal:tanggal_mulai',
|
'tanggal_selesai' => 'nullable|date|after_or_equal:tanggal_mulai',
|
||||||
'status' => 'boolean',
|
'status' => 'boolean',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Pengumuman::create($request->all());
|
// 2. Simpan Pengumuman ke Database
|
||||||
|
$pengumuman = Pengumuman::create($request->all());
|
||||||
|
|
||||||
return redirect()->route('pengumuman.index')->with('success', 'Pengumuman berhasil ditambahkan.');
|
// 3. Ambil semua FCM token user yang tidak null (guru & wali murid)
|
||||||
|
$tokens = User::whereNotNull('fcm_token')->pluck('fcm_token')->toArray();
|
||||||
|
|
||||||
|
// 4. Trigger Broadcast Notifikasi FCM
|
||||||
|
if (count($tokens) > 0) {
|
||||||
|
$notifTitle = "Pengumuman Baru: " . $pengumuman->judul;
|
||||||
|
$notifBody = "Ada pengumuman baru dari sekolah, yuk cek sekarang!";
|
||||||
|
|
||||||
|
// Panggil method dari Controller dasar
|
||||||
|
$this->sendFCMNotification($notifTitle, $notifBody, $tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Redirect dengan pesan sukses
|
||||||
|
return redirect()->route('pengumuman.index')
|
||||||
|
->with('success', 'Pengumuman berhasil ditambahkan dan notifikasi telah dikirim.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(Pengumuman $pengumuman)
|
public function edit(Pengumuman $pengumuman)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ public function index()
|
||||||
{
|
{
|
||||||
// Ambil data penjemputan, urutkan dari yang paling baru (latest)
|
// Ambil data penjemputan, urutkan dari yang paling baru (latest)
|
||||||
$logs = Penjemputan::with('siswa')->latest('waktu_jemput')->get();
|
$logs = Penjemputan::with('siswa')->latest('waktu_jemput')->get();
|
||||||
|
|
||||||
// Kirim ke tampilan
|
// Kirim ke tampilan
|
||||||
return view('admin.penjemputan.index', compact('logs'));
|
return view('admin.penjemputan.index', compact('logs'));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,29 +13,29 @@ class PerkembanganController extends Controller
|
||||||
{
|
{
|
||||||
// Halaman Utama: Tampilkan Daftar Siswa
|
// Halaman Utama: Tampilkan Daftar Siswa
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
// PERBAIKAN: Ganti 'nama' menjadi 'nama_siswa'
|
// PERBAIKAN: Ganti 'nama' menjadi 'nama_siswa'
|
||||||
$siswas = Siswa::orderBy('nama_siswa', 'asc')->get();
|
$siswas = Siswa::orderBy('nama_siswa', 'asc')->get();
|
||||||
|
|
||||||
return view('admin.perkembangan.index', compact('siswas'));
|
return view('admin.perkembangan.index', compact('siswas'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Halaman Detail: Tampilkan Rapot (Gabungan 3 Tabel)
|
// Halaman Detail: Tampilkan Rapot (Gabungan 3 Tabel)
|
||||||
public function show($id)
|
public function show($id)
|
||||||
{
|
{
|
||||||
$siswa = Siswa::findOrFail($id);
|
$siswa = Siswa::findOrFail($id);
|
||||||
|
|
||||||
// 1. Ambil Data Rapot (Untuk Tabel Bawah)
|
// 1. Ambil Data Rapot (Untuk Tabel Bawah)
|
||||||
$rapots = \App\Models\Rapot::where('siswa_id', $id)->orderBy('created_at', 'desc')->get();
|
$rapots = \App\Models\Rapot::where('siswa_id', $id)->orderBy('created_at', 'desc')->get();
|
||||||
|
|
||||||
// 2. Ambil Data Harian (Untuk Tombol/Menu Atas) - SUDAH DIAKTIFKAN
|
// 2. Ambil Data Harian (Untuk Tombol/Menu Atas) - SUDAH DIAKTIFKAN
|
||||||
$anekdots = \App\Models\Anekdot::where('siswa_id', $id)->get();
|
$anekdots = \App\Models\Anekdot::where('siswa_id', $id)->get();
|
||||||
$karyas = \App\Models\HasilKarya::where('siswa_id', $id)->get();
|
$karyas = \App\Models\HasilKarya::where('siswa_id', $id)->get();
|
||||||
$ceklis = \App\Models\PenilaianCeklis::where('siswa_id', $id)->get();
|
$ceklis = \App\Models\PenilaianCeklis::where('siswa_id', $id)->get();
|
||||||
|
|
||||||
// Kirim semua variabel ke View
|
// Kirim semua variabel ke View
|
||||||
return view('admin.perkembangan.show', compact('siswa', 'rapots', 'anekdots', 'karyas', 'ceklis'));
|
return view('admin.perkembangan.show', compact('siswa', 'rapots', 'anekdots', 'karyas', 'ceklis'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Halaman Cetak (Opsional, logika sama dengan show)
|
// Halaman Cetak (Opsional, logika sama dengan show)
|
||||||
public function print($id)
|
public function print($id)
|
||||||
|
|
|
||||||
|
|
@ -25,31 +25,31 @@ public function create()
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'nis' => 'required|unique:siswas,nis',
|
'nis' => 'required|unique:siswas,nis',
|
||||||
'nisn' => 'nullable|string',
|
'nisn' => 'nullable|string',
|
||||||
'nama_siswa' => 'required|string|max:255',
|
'nama_siswa' => 'required|string|max:255',
|
||||||
'tempat_lahir' => 'required|string',
|
'tempat_lahir' => 'required|string',
|
||||||
'tanggal_lahir' => 'required|date',
|
'tanggal_lahir' => 'required|date',
|
||||||
'jenis_kelamin' => 'required|in:L,P',
|
'jenis_kelamin' => 'required|in:L,P',
|
||||||
'wali_murid_id' => 'required|exists:wali_murids,id',
|
'wali_murid_id' => 'required|exists:wali_murids,id',
|
||||||
|
|
||||||
// --- TAMBAHAN BARU: Validasi Titik Koordinat Peta ---
|
// --- TAMBAHAN BARU: Validasi Titik Koordinat Peta ---
|
||||||
'latitude' => 'nullable|string',
|
'latitude' => 'nullable|string',
|
||||||
'longitude' => 'nullable|string',
|
'longitude' => 'nullable|string',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Siswa::create([
|
Siswa::create([
|
||||||
'nis' => $request->nis,
|
'nis' => $request->nis,
|
||||||
'nisn' => $request->nisn,
|
'nisn' => $request->nisn,
|
||||||
'nama_siswa' => $request->nama_siswa,
|
'nama_siswa' => $request->nama_siswa,
|
||||||
'tempat_lahir' => $request->tempat_lahir,
|
'tempat_lahir' => $request->tempat_lahir,
|
||||||
'tanggal_lahir' => $request->tanggal_lahir,
|
'tanggal_lahir' => $request->tanggal_lahir,
|
||||||
'jenis_kelamin' => $request->jenis_kelamin,
|
'jenis_kelamin' => $request->jenis_kelamin,
|
||||||
'wali_murid_id' => $request->wali_murid_id,
|
'wali_murid_id' => $request->wali_murid_id,
|
||||||
|
|
||||||
// --- TAMBAHAN BARU: Simpan ke Database ---
|
// --- TAMBAHAN BARU: Simpan ke Database ---
|
||||||
'latitude' => $request->latitude,
|
'latitude' => $request->latitude,
|
||||||
'longitude' => $request->longitude,
|
'longitude' => $request->longitude,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect()->route('siswa.index')->with('success', 'Data Siswa berhasil ditambahkan.');
|
return redirect()->route('siswa.index')->with('success', 'Data Siswa berhasil ditambahkan.');
|
||||||
|
|
@ -67,31 +67,31 @@ public function update(Request $request, $id)
|
||||||
$siswa = Siswa::findOrFail($id);
|
$siswa = Siswa::findOrFail($id);
|
||||||
|
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'nis' => 'required|unique:siswas,nis,'.$id,
|
'nis' => 'required|unique:siswas,nis,' . $id,
|
||||||
'nisn' => 'nullable|string',
|
'nisn' => 'nullable|string',
|
||||||
'nama_siswa' => 'required|string|max:255',
|
'nama_siswa' => 'required|string|max:255',
|
||||||
'tempat_lahir' => 'required|string',
|
'tempat_lahir' => 'required|string',
|
||||||
'tanggal_lahir' => 'required|date',
|
'tanggal_lahir' => 'required|date',
|
||||||
'jenis_kelamin' => 'required|in:L,P',
|
'jenis_kelamin' => 'required|in:L,P',
|
||||||
'wali_murid_id' => 'required|exists:wali_murids,id',
|
'wali_murid_id' => 'required|exists:wali_murids,id',
|
||||||
|
|
||||||
// --- TAMBAHAN BARU: Validasi Titik Koordinat Peta ---
|
// --- TAMBAHAN BARU: Validasi Titik Koordinat Peta ---
|
||||||
'latitude' => 'nullable|string',
|
'latitude' => 'nullable|string',
|
||||||
'longitude' => 'nullable|string',
|
'longitude' => 'nullable|string',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$siswa->update([
|
$siswa->update([
|
||||||
'nis' => $request->nis,
|
'nis' => $request->nis,
|
||||||
'nisn' => $request->nisn,
|
'nisn' => $request->nisn,
|
||||||
'nama_siswa' => $request->nama_siswa,
|
'nama_siswa' => $request->nama_siswa,
|
||||||
'tempat_lahir' => $request->tempat_lahir,
|
'tempat_lahir' => $request->tempat_lahir,
|
||||||
'tanggal_lahir' => $request->tanggal_lahir,
|
'tanggal_lahir' => $request->tanggal_lahir,
|
||||||
'jenis_kelamin' => $request->jenis_kelamin,
|
'jenis_kelamin' => $request->jenis_kelamin,
|
||||||
'wali_murid_id' => $request->wali_murid_id,
|
'wali_murid_id' => $request->wali_murid_id,
|
||||||
|
|
||||||
// --- TAMBAHAN BARU: Update ke Database ---
|
// --- TAMBAHAN BARU: Update ke Database ---
|
||||||
'latitude' => $request->latitude,
|
'latitude' => $request->latitude,
|
||||||
'longitude' => $request->longitude,
|
'longitude' => $request->longitude,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect()->route('siswa.index')->with('success', 'Data Siswa berhasil diperbarui!');
|
return redirect()->route('siswa.index')->with('success', 'Data Siswa berhasil diperbarui!');
|
||||||
|
|
|
||||||
|
|
@ -4,53 +4,54 @@
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\WaliMurid;
|
use App\Models\WaliMurid;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class WaliMuridController extends Controller
|
class WaliMuridController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$walis = WaliMurid::with('user')->latest()->get();
|
$walis = WaliMurid::with('user')->latest()->get();
|
||||||
|
|
||||||
// PERBAIKAN DI SINI: Sesuaikan dengan nama folder 'wali'
|
// PERBAIKAN DI SINI: Sesuaikan dengan nama folder 'wali'
|
||||||
return view('admin.wali.index', compact('walis'));
|
return view('admin.wali.index', compact('walis'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
// PERBAIKAN DI SINI JUGA
|
$zonas = \App\Models\MasterZona::orderBy('kategori', 'desc')->get()->groupBy('kategori');
|
||||||
return view('admin.wali.create');
|
return view('admin.wali.create', compact('zonas'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'nama_wali' => 'required',
|
'nama_wali' => 'required',
|
||||||
'email' => 'required|email|unique:users,email',
|
'email' => 'required|email|unique:users,email',
|
||||||
'password' => 'required|min:6',
|
'password' => 'required|min:6',
|
||||||
'no_hp' => 'required',
|
'no_hp' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
DB::transaction(function () use ($request) {
|
DB::transaction(function () use ($request) {
|
||||||
|
|
||||||
// 1. Buat User Login
|
// 1. Buat User Login
|
||||||
$user = User::create([
|
$user = User::create([
|
||||||
'name' => $request->nama_wali,
|
'name' => $request->nama_wali,
|
||||||
'email' => $request->email,
|
'email' => $request->email,
|
||||||
'password' => Hash::make($request->password),
|
'password' => Hash::make($request->password),
|
||||||
'role' => 'wali_murid',
|
'role' => 'wali_murid',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 2. Buat Profil Wali
|
// 2. Buat Profil Wali
|
||||||
WaliMurid::create([
|
WaliMurid::create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'nama_wali' => $request->nama_wali,
|
'nama_wali' => $request->nama_wali,
|
||||||
'no_hp' => $request->no_hp,
|
'no_hp' => $request->no_hp,
|
||||||
'alamat' => $request->alamat,
|
'alamat' => $request->alamat,
|
||||||
'pekerjaan' => $request->pekerjaan,
|
'pekerjaan' => $request->pekerjaan,
|
||||||
|
'master_zona_id' => $request->master_zona_id,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -60,7 +61,8 @@ public function store(Request $request)
|
||||||
public function edit($id)
|
public function edit($id)
|
||||||
{
|
{
|
||||||
$data = WaliMurid::with('user')->findOrFail($id);
|
$data = WaliMurid::with('user')->findOrFail($id);
|
||||||
return view('admin.wali.edit', compact('data'));
|
$zonas = \App\Models\MasterZona::orderBy('kategori', 'desc')->get()->groupBy('kategori');
|
||||||
|
return view('admin.wali.edit', compact('data', 'zonas'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id)
|
||||||
|
|
@ -69,25 +71,33 @@ public function update(Request $request, $id)
|
||||||
|
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'nama_wali' => 'required',
|
'nama_wali' => 'required',
|
||||||
'email' => 'required|email|unique:users,email,' . $wali->user_id,
|
'email' => 'required|email|unique:users,email,' . $wali->user_id,
|
||||||
'no_hp' => 'required',
|
'password' => 'nullable|min:6',
|
||||||
|
'no_hp' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
DB::transaction(function () use ($request, $wali) {
|
DB::transaction(function () use ($request, $wali) {
|
||||||
|
|
||||||
// 1. Update User Login
|
// 1. Update User Login
|
||||||
if ($wali->user) {
|
if ($wali->user) {
|
||||||
$wali->user->update([
|
$userData = [
|
||||||
'name' => $request->nama_wali,
|
'name' => $request->nama_wali,
|
||||||
'email' => $request->email,
|
'email' => $request->email,
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
if ($request->filled('password')) {
|
||||||
|
$userData['password'] = Hash::make($request->password);
|
||||||
|
}
|
||||||
|
|
||||||
|
$wali->user->update($userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Update Profil Wali
|
// 2. Update Profil Wali
|
||||||
$wali->update([
|
$wali->update([
|
||||||
'nama_wali' => $request->nama_wali,
|
'nama_wali' => $request->nama_wali,
|
||||||
'no_hp' => $request->no_hp,
|
'no_hp' => $request->no_hp,
|
||||||
'alamat' => $request->alamat,
|
'alamat' => $request->alamat,
|
||||||
|
'master_zona_id' => $request->master_zona_id,
|
||||||
// 'pekerjaan' => $request->pekerjaan, // Form belum ada input pekerjaan
|
// 'pekerjaan' => $request->pekerjaan, // Form belum ada input pekerjaan
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -98,9 +108,9 @@ public function update(Request $request, $id)
|
||||||
public function destroy($id)
|
public function destroy($id)
|
||||||
{
|
{
|
||||||
$wali = WaliMurid::findOrFail($id);
|
$wali = WaliMurid::findOrFail($id);
|
||||||
|
|
||||||
if($wali->user) {
|
if ($wali->user) {
|
||||||
$wali->user->delete();
|
$wali->user->delete();
|
||||||
} else {
|
} else {
|
||||||
$wali->delete();
|
$wali->delete();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,4 +42,25 @@ public function logout()
|
||||||
Auth::logout();
|
Auth::logout();
|
||||||
return response()->json(['message' => 'Berhasil Logout']);
|
return response()->json(['message' => 'Berhasil Logout']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateFcmToken(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'fcm_token' => 'required|string'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$user = Auth::user();
|
||||||
|
if ($user) {
|
||||||
|
$user->update(['fcm_token' => $request->fcm_token]);
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'FCM Token updated successfully'
|
||||||
|
], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Unauthenticated'
|
||||||
|
], 401);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -212,9 +212,28 @@ public function scanJemput(Request $request)
|
||||||
'qr_code' => 'required',
|
'qr_code' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$qrCodeData = $request->qr_code;
|
||||||
|
$parts = explode('_', $qrCodeData);
|
||||||
|
$idSiswa = $parts[0];
|
||||||
|
|
||||||
|
if (count($parts) > 1) {
|
||||||
|
$qrDate = $parts[1];
|
||||||
|
if ($qrDate !== date('Y-m-d')) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'QR Code Kadaluarsa! Harap gunakan QR hari ini.'
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Format QR Code tidak valid atau Kadaluarsa!'
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
// Cari siswa berdasarkan qr_code (Biasanya NIS atau ID Siswa)
|
// Cari siswa berdasarkan qr_code (Biasanya NIS atau ID Siswa)
|
||||||
$siswa = Siswa::where('nis', $request->qr_code)
|
$siswa = Siswa::where('nis', $idSiswa)
|
||||||
->orWhere('id', $request->qr_code)
|
->orWhere('id', $idSiswa)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if (!$siswa) {
|
if (!$siswa) {
|
||||||
|
|
@ -224,18 +243,30 @@ public function scanJemput(Request $request)
|
||||||
], 404);
|
], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Catat Penjemputan
|
// Cek request untuk nama penjemput dan status
|
||||||
// Kita bisa atur default nama penjemput "Orang Tua/Wali"
|
$statusPenjemput = $request->status_penjemput ?? 'Orang Tua / Wali';
|
||||||
|
|
||||||
Penjemputan::create([
|
Penjemputan::create([
|
||||||
'siswa_id' => $siswa->id,
|
'siswa_id' => $siswa->id,
|
||||||
'nama_penjemput' => 'Orang Tua / Wali',
|
'nama_penjemput' => $statusPenjemput,
|
||||||
'status_hubungan' => 'Orang Tua',
|
'status_hubungan' => $statusPenjemput == 'Orang Tua' ? 'Orang Tua' : 'Diwakilkan',
|
||||||
'waktu_jemput' => now(),
|
'waktu_jemput' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// --- TRIGGER FCM NOTIFICATION KE WALI MURID ---
|
||||||
|
if ($siswa->waliMurid && $siswa->waliMurid->user && $siswa->waliMurid->user->fcm_token) {
|
||||||
|
$token = $siswa->waliMurid->user->fcm_token;
|
||||||
|
$namaAnak = $siswa->nama_siswa ?? $siswa->nama_lengkap ?? 'Ananda';
|
||||||
|
$this->sendFCMNotification(
|
||||||
|
"Penjemputan Berhasil",
|
||||||
|
"Ananda {$namaAnak} telah berhasil dijemput dan diverifikasi oleh Guru.",
|
||||||
|
[$token]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'message' => 'Berhasil mencatat penjemputan untuk ' . $siswa->nama_lengkap
|
'message' => 'Berhasil mencatat penjemputan untuk ' . ($siswa->nama_siswa ?? $siswa->nama_lengkap)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\MasterZona;
|
||||||
|
use App\Models\Siswa;
|
||||||
|
|
||||||
|
class HomeVisitController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Endpoint 1: Mendapatkan daftar zona, dikelompokkan berdasarkan kategori
|
||||||
|
*/
|
||||||
|
public function getZonasi()
|
||||||
|
{
|
||||||
|
// Mengambil semua data zona dan mengelompokkan berdasarkan field 'kategori'
|
||||||
|
$zonas = MasterZona::orderBy('kategori', 'desc')->get()->groupBy('kategori');
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Berhasil mengambil data zonasi',
|
||||||
|
'data' => $zonas
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint 2: Mendapatkan daftar siswa berdasarkan zona_id
|
||||||
|
*/
|
||||||
|
public function getSiswaByZona($zona_id)
|
||||||
|
{
|
||||||
|
// Query Siswa yang berelasi dengan wali_murid, dimana wali_murid.master_zona_id = $zona_id
|
||||||
|
$siswas = Siswa::with('wali_murid')
|
||||||
|
->whereHas('wali_murid', function ($query) use ($zona_id) {
|
||||||
|
$query->where('master_zona_id', $zona_id);
|
||||||
|
})
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Berhasil mengambil data siswa di zona tersebut',
|
||||||
|
'data' => $siswas
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -40,8 +40,14 @@ public function getDashboard(Request $request)
|
||||||
|
|
||||||
// 3. Pengumuman Aktif Terbaru
|
// 3. Pengumuman Aktif Terbaru
|
||||||
$pengumuman = Pengumuman::where('status', true)
|
$pengumuman = Pengumuman::where('status', true)
|
||||||
->where('tanggal_mulai', '<=', now())
|
->where(function ($query) {
|
||||||
->where('tanggal_selesai', '>=', now())
|
$query->whereNull('tanggal_mulai')
|
||||||
|
->orWhereDate('tanggal_mulai', '<=', now());
|
||||||
|
})
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereNull('tanggal_selesai')
|
||||||
|
->orWhereDate('tanggal_selesai', '>=', now());
|
||||||
|
})
|
||||||
->latest()
|
->latest()
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
|
@ -76,9 +82,21 @@ public function getDashboard(Request $request)
|
||||||
// Murni kalkulasi berdasarkan data riil, 0 jika kosong
|
// Murni kalkulasi berdasarkan data riil, 0 jika kosong
|
||||||
$percentage = $count > 0 ? round($totalScore / $count) : 0;
|
$percentage = $count > 0 ? round($totalScore / $count) : 0;
|
||||||
|
|
||||||
|
$predikat = "Perlu Bimbingan";
|
||||||
|
if ($percentage >= 76) $predikat = "Sangat Baik";
|
||||||
|
elseif ($percentage >= 51) $predikat = "Baik";
|
||||||
|
elseif ($percentage >= 26) $predikat = "Cukup";
|
||||||
|
|
||||||
|
$narasi = null;
|
||||||
|
if ($count > 0) {
|
||||||
|
$namaAnak = $siswa->nama_siswa ?? $siswa->nama_lengkap ?? 'Ananda';
|
||||||
|
$narasi = "Ananda {$namaAnak} telah menunjukkan perkembangan yang {$predikat} pada aspek {$aspek} dengan capaian {$percentage}%.";
|
||||||
|
}
|
||||||
|
|
||||||
$progressPerkembangan[] = [
|
$progressPerkembangan[] = [
|
||||||
'aspek' => $aspek,
|
'aspek' => $aspek,
|
||||||
'nilai' => $percentage
|
'nilai' => $percentage,
|
||||||
|
'narasi' => $narasi
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,62 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Kreait\Firebase\Factory;
|
||||||
|
use Kreait\Firebase\Messaging\CloudMessage;
|
||||||
|
use Kreait\Firebase\Messaging\Notification;
|
||||||
|
use Kreait\Firebase\Messaging\AndroidConfig;
|
||||||
|
|
||||||
abstract class Controller
|
abstract class Controller
|
||||||
{
|
{
|
||||||
//
|
public function sendFCMNotification($title, $body, $tokens)
|
||||||
|
{
|
||||||
|
$credentialsFilePath = storage_path('firebase-auth.json');
|
||||||
|
|
||||||
|
if (!file_exists($credentialsFilePath)) {
|
||||||
|
\Log::error("FCM Service Account file not found at: " . $credentialsFilePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$factory = (new Factory)->withServiceAccount($credentialsFilePath);
|
||||||
|
$messaging = $factory->createMessaging();
|
||||||
|
|
||||||
|
$responses = [];
|
||||||
|
|
||||||
|
foreach ($tokens as $fcmToken) {
|
||||||
|
$message = CloudMessage::withTarget('token', $fcmToken)
|
||||||
|
->withNotification(Notification::create($title, $body))
|
||||||
|
->withAndroidConfig(AndroidConfig::fromArray([
|
||||||
|
'priority' => 'high',
|
||||||
|
'notification' => [
|
||||||
|
'channel_id' => 'paud_notif_channel',
|
||||||
|
'sound' => 'default'
|
||||||
|
]
|
||||||
|
]));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = $messaging->send($message);
|
||||||
|
$responses[] = $result;
|
||||||
|
\Log::info("FCM Response for token {$fcmToken}: Sukses via Kreait. Result: " . json_encode($result));
|
||||||
|
} catch (\Kreait\Firebase\Exception\MessagingException $e) {
|
||||||
|
\Log::error("Kreait FCM Error for token {$fcmToken}: " . $e->getMessage());
|
||||||
|
// ERROR HANDLING TEGAS SEPERTI SEBELUMNYA
|
||||||
|
dd([
|
||||||
|
'STATUS' => 'ERROR_DITOLAK_GOOGLE',
|
||||||
|
'FCM_ERROR' => $e->getMessage(),
|
||||||
|
'FCM_ERROR_DETAILS' => $e->errors()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $responses;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("FCM System Error: " . $e->getMessage());
|
||||||
|
dd([
|
||||||
|
'STATUS' => 'FATAL_SYSTEM_ERROR',
|
||||||
|
'ERROR' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class MasterZona extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'master_zonas';
|
||||||
|
protected $fillable = ['nama_zona', 'kategori'];
|
||||||
|
}
|
||||||
|
|
@ -24,4 +24,9 @@ public function siswas()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Siswa::class, 'wali_id');
|
return $this->hasMany(Siswa::class, 'wali_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function zona()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(MasterZona::class, 'master_zona_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
"doctrine/dbal": "^4.4",
|
"doctrine/dbal": "^4.4",
|
||||||
|
"google/apiclient": "^2.19",
|
||||||
|
"kreait/firebase-php": "^7.24",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/sanctum": "^4.0",
|
"laravel/sanctum": "^4.0",
|
||||||
"laravel/tinker": "^2.10.1",
|
"laravel/tinker": "^2.10.1",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?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(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->text('fcm_token')->nullable()->after('remember_token');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('fcm_token');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?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(): void
|
||||||
|
{
|
||||||
|
Schema::create('master_zonas', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('nama_zona');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('master_zonas');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?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(): void
|
||||||
|
{
|
||||||
|
Schema::table('wali_murids', function (Blueprint $table) {
|
||||||
|
$table->foreignId('master_zona_id')->nullable()->constrained('master_zonas')->nullOnDelete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('wali_murids', function (Blueprint $table) {
|
||||||
|
$table->dropForeign(['master_zona_id']);
|
||||||
|
$table->dropColumn('master_zona_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?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(): void
|
||||||
|
{
|
||||||
|
Schema::table('master_zonas', function (Blueprint $table) {
|
||||||
|
$table->string('kategori')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('master_zonas', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('kategori');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class MasterZonaSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
\Illuminate\Support\Facades\Schema::disableForeignKeyConstraints();
|
||||||
|
\App\Models\MasterZona::truncate();
|
||||||
|
\Illuminate\Support\Facades\Schema::enableForeignKeyConstraints();
|
||||||
|
|
||||||
|
$kotaMadiun = [
|
||||||
|
'Kartoharjo', 'Manguharjo', 'Taman'
|
||||||
|
];
|
||||||
|
|
||||||
|
$kabupatenMadiun = [
|
||||||
|
'Balerejo', 'Dagangan', 'Dolopo', 'Geger', 'Gemarang', 'Jiwan', 'Kare', 'Kebonsari', 'Madiun', 'Mejayan', 'Pilangkenceng', 'Saradan', 'Sawahan', 'Wonoasri', 'Wungu'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($kotaMadiun as $zona) {
|
||||||
|
\App\Models\MasterZona::create(['nama_zona' => $zona, 'kategori' => 'Kota Madiun']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($kabupatenMadiun as $zona) {
|
||||||
|
\App\Models\MasterZona::create(['nama_zona' => $zona, 'kategori' => 'Kabupaten Madiun']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
|
@ -1,102 +1,103 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="bg-white p-6 rounded-lg shadow-md">
|
<div class="bg-white p-6 rounded-lg shadow-md">
|
||||||
<div class="flex justify-between items-center mb-4">
|
<div class="flex justify-between items-center mb-4">
|
||||||
<h1 class="text-xl font-semibold text-gray-700">🔐 Daftar Akun</h1>
|
<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>
|
<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>
|
</div>
|
||||||
|
|
||||||
@if(session('success'))
|
{{-- Script show/hide password --}}
|
||||||
<div class="bg-green-100 text-green-800 p-3 rounded mb-4">{{ session('success') }}</div>
|
<script>
|
||||||
@endif
|
document.querySelectorAll('.toggle-password').forEach(btn => {
|
||||||
@if(session('error'))
|
btn.addEventListener('click', function () {
|
||||||
<div class="bg-red-100 text-red-800 p-3 rounded mb-4">{{ session('error') }}</div>
|
const input = this.closest('div').querySelector('.password-field');
|
||||||
@endif
|
const icon = this.querySelector('i');
|
||||||
|
if (input.type === 'password') {
|
||||||
<table class="w-full border border-gray-200 rounded-lg text-sm">
|
input.type = 'text';
|
||||||
<thead class="bg-gray-100">
|
icon.classList.remove('fa-eye');
|
||||||
<tr>
|
icon.classList.add('fa-eye-slash');
|
||||||
<th class="p-3 border">#</th>
|
} else {
|
||||||
<th class="p-3 border">Nama</th>
|
input.type = 'password';
|
||||||
<th class="p-3 border">Email</th>
|
icon.classList.remove('fa-eye-slash');
|
||||||
<th class="p-3 border">Role</th>
|
icon.classList.add('fa-eye');
|
||||||
<th class="p-3 border">Password</th>
|
}
|
||||||
<th class="p-3 border text-center">Aksi</th>
|
});
|
||||||
</tr>
|
});
|
||||||
</thead>
|
</script>
|
||||||
<tbody>
|
@endsection
|
||||||
@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
|
|
||||||
|
|
@ -1,71 +1,81 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
||||||
<!-- Header Section -->
|
<!-- Header Section -->
|
||||||
<div class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
<div
|
||||||
<!-- Decorative inner pattern -->
|
class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
||||||
<div class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay"></div>
|
<!-- Decorative inner pattern -->
|
||||||
<div class="relative z-10">
|
<div
|
||||||
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay">
|
||||||
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i class="fas fa-chalkboard-teacher"></i></span> Data Guru
|
</div>
|
||||||
</h1>
|
<div class="relative z-10">
|
||||||
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Kelola informasi tenaga pengajar PAUD.</p>
|
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
||||||
|
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i
|
||||||
|
class="fas fa-chalkboard-teacher"></i></span> Data Guru
|
||||||
|
</h1>
|
||||||
|
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Kelola informasi tenaga pengajar PAUD.</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 md:mt-0 relative z-10">
|
||||||
|
<a href="{{ route('guru.create') }}"
|
||||||
|
class="inline-flex items-center gap-2 bg-white text-green-700 px-6 py-3 rounded-xl hover:bg-green-50 font-bold text-sm shadow-lg transition-all hover:-translate-y-1">
|
||||||
|
<i class="fas fa-plus"></i> Tambah Guru
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 md:mt-0 relative z-10">
|
|
||||||
<a href="{{ route('guru.create') }}" class="inline-flex items-center gap-2 bg-white text-green-700 px-6 py-3 rounded-xl hover:bg-green-50 font-bold text-sm shadow-lg transition-all hover:-translate-y-1">
|
|
||||||
<i class="fas fa-plus"></i> Tambah Guru
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6">
|
<div class="p-6">
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="w-full border-collapse">
|
<table class="w-full border-collapse">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-green-600 text-white text-left">
|
<tr class="bg-green-600 text-white text-left">
|
||||||
<th class="p-2">#</th>
|
<th class="p-2">#</th>
|
||||||
<th class="p-2">Nama Guru</th>
|
<th class="p-2">Nama Guru</th>
|
||||||
<th class="p-2">Email</th>
|
<th class="p-2">Email</th>
|
||||||
<th class="p-2">No HP</th>
|
<th class="p-2">No HP</th>
|
||||||
<th class="p-2">Jenis Guru</th>
|
<th class="p-2">Jenis Guru</th>
|
||||||
<th class="p-2">Aksi</th>
|
<th class="p-2">Aksi</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@forelse ($gurus as $i => $guru)
|
@forelse ($gurus as $i => $guru)
|
||||||
<tr class="border-b hover:bg-gray-50">
|
<tr class="border-b hover:bg-gray-50">
|
||||||
<td class="p-2">{{ $i + 1 }}</td>
|
<td class="p-2">{{ $i + 1 }}</td>
|
||||||
<td class="p-2 font-medium">{{ $guru->nama_guru ?? '-' }}</td>
|
<td class="p-2 font-medium">{{ $guru->nama_guru ?? '-' }}</td>
|
||||||
<td class="p-2">{{ $guru->email ?? '-' }}</td>
|
<td class="p-2">{{ $guru->email ?? '-' }}</td>
|
||||||
<td class="p-2">{{ $guru->no_hp ?? '-' }}</td>
|
<td class="p-2">{{ $guru->no_hp ?? '-' }}</td>
|
||||||
<td class="p-2">
|
<td class="p-2">
|
||||||
{{-- Logic tampilan badge --}}
|
{{-- Logic tampilan badge --}}
|
||||||
@if($guru->jenis_guru == 'guru_kelas')
|
@if($guru->jenis_guru == 'guru_kelas')
|
||||||
<span class="bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">Guru Kelas</span>
|
<span
|
||||||
@elseif($guru->jenis_guru == 'shadow_abk')
|
class="bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">Guru
|
||||||
<span class="bg-yellow-100 text-yellow-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">Shadow ABK</span>
|
Kelas</span>
|
||||||
@else
|
@elseif($guru->jenis_guru == 'shadow_abk')
|
||||||
-
|
<span
|
||||||
@endif
|
class="bg-yellow-100 text-yellow-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">Shadow
|
||||||
</td>
|
ABK</span>
|
||||||
<td class="p-2 space-x-2">
|
@else
|
||||||
<a href="{{ route('guru.edit', $guru->id) }}" class="text-blue-500 hover:underline">Edit</a>
|
-
|
||||||
<form action="{{ route('guru.destroy', $guru->id) }}" method="POST" class="inline" onsubmit="return confirm('Yakin hapus data ini?');">
|
@endif
|
||||||
@csrf
|
</td>
|
||||||
@method('DELETE')
|
<td class="p-2 space-x-2">
|
||||||
<button type="submit" class="text-red-500 hover:underline">Hapus</button>
|
<a href="{{ route('guru.edit', $guru->id) }}" class="text-blue-500 hover:underline">Edit</a>
|
||||||
</form>
|
<form action="{{ route('guru.destroy', $guru->id) }}" method="POST" class="inline"
|
||||||
</td>
|
onsubmit="return confirm('Yakin hapus data ini?');">
|
||||||
</tr>
|
@csrf
|
||||||
@empty
|
@method('DELETE')
|
||||||
<tr>
|
<button type="submit" class="text-red-500 hover:underline">Hapus</button>
|
||||||
<td colspan="6" class="text-center text-gray-500 py-4">Belum ada data guru</td>
|
</form>
|
||||||
</tr>
|
</td>
|
||||||
@endforelse
|
</tr>
|
||||||
</tbody>
|
@empty
|
||||||
</table>
|
<tr>
|
||||||
|
<td colspan="6" class="text-center text-gray-500 py-4">Belum ada data guru</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,62 +1,71 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
||||||
<!-- Header Section -->
|
<!-- Header Section -->
|
||||||
<div class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
<div
|
||||||
<!-- Decorative inner pattern -->
|
class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
||||||
<div class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay"></div>
|
<!-- Decorative inner pattern -->
|
||||||
<div class="relative z-10">
|
<div
|
||||||
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay">
|
||||||
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i class="fas fa-bullhorn"></i></span> Menu Pengumuman
|
</div>
|
||||||
</h1>
|
<div class="relative z-10">
|
||||||
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Kelola informasi dan pengumuman untuk seluruh pihak.</p>
|
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
||||||
|
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i
|
||||||
|
class="fas fa-bullhorn"></i></span> Menu Pengumuman
|
||||||
|
</h1>
|
||||||
|
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Kelola informasi dan pengumuman untuk seluruh
|
||||||
|
pihak.</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 md:mt-0 relative z-10">
|
||||||
|
<a href="{{ route('pengumuman.create') }}"
|
||||||
|
class="inline-flex items-center gap-2 bg-white text-green-700 px-6 py-3 rounded-xl hover:bg-green-50 font-bold text-sm shadow-lg transition-all hover:-translate-y-1">
|
||||||
|
<i class="fas fa-plus"></i> Tambah Pengumuman
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 md:mt-0 relative z-10">
|
|
||||||
<a href="{{ route('pengumuman.create') }}" class="inline-flex items-center gap-2 bg-white text-green-700 px-6 py-3 rounded-xl hover:bg-green-50 font-bold text-sm shadow-lg transition-all hover:-translate-y-1">
|
|
||||||
<i class="fas fa-plus"></i> Tambah Pengumuman
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6">
|
<div class="p-6">
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="w-full border-collapse">
|
<table class="w-full border-collapse">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-green-600 text-white">
|
<tr class="bg-green-600 text-white">
|
||||||
<th class="p-2">#</th>
|
<th class="p-2">#</th>
|
||||||
<th class="p-2">Judul</th>
|
<th class="p-2">Judul</th>
|
||||||
<th class="p-2">Tanggal</th>
|
<th class="p-2">Tanggal</th>
|
||||||
<th class="p-2">Status</th>
|
<th class="p-2">Status</th>
|
||||||
<th class="p-2">Aksi</th>
|
<th class="p-2">Aksi</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($pengumuman as $i => $p)
|
@foreach ($pengumuman as $i => $p)
|
||||||
<tr class="border-b hover:bg-gray-50">
|
<tr class="border-b hover:bg-gray-50">
|
||||||
<td class="p-2">{{ $i+1 }}</td>
|
<td class="p-2">{{ $i + 1 }}</td>
|
||||||
<td class="p-2 font-semibold">{{ $p->judul }}</td>
|
<td class="p-2 font-semibold">{{ $p->judul }}</td>
|
||||||
<td class="p-2">
|
<td class="p-2">
|
||||||
{{ $p->tanggal_mulai }} - {{ $p->tanggal_selesai }}
|
{{ $p->tanggal_mulai }} - {{ $p->tanggal_selesai }}
|
||||||
</td>
|
</td>
|
||||||
<td class="p-2">
|
<td class="p-2">
|
||||||
<span class="px-2 py-1 rounded text-white {{ $p->status ? 'bg-green-500' : 'bg-gray-400' }}">
|
<span
|
||||||
{{ $p->status ? 'Aktif' : 'Nonaktif' }}
|
class="px-2 py-1 rounded text-white {{ $p->status ? 'bg-green-500' : 'bg-gray-400' }}">
|
||||||
</span>
|
{{ $p->status ? 'Aktif' : 'Nonaktif' }}
|
||||||
</td>
|
</span>
|
||||||
<td class="p-2 flex gap-2">
|
</td>
|
||||||
<a href="{{ route('pengumuman.edit', $p->id) }}" class="bg-blue-500 text-white px-3 py-1 rounded hover:bg-blue-600">Edit</a>
|
<td class="p-2 flex gap-2">
|
||||||
<form action="{{ route('pengumuman.destroy', $p->id) }}" method="POST" onsubmit="return confirm('Yakin hapus?')">
|
<a href="{{ route('pengumuman.edit', $p->id) }}"
|
||||||
@csrf
|
class="bg-blue-500 text-white px-3 py-1 rounded hover:bg-blue-600">Edit</a>
|
||||||
@method('DELETE')
|
<form action="{{ route('pengumuman.destroy', $p->id) }}" method="POST"
|
||||||
<button class="bg-red-500 text-white px-3 py-1 rounded hover:bg-red-600">Hapus</button>
|
onsubmit="return confirm('Yakin hapus?')">
|
||||||
</form>
|
@csrf
|
||||||
</td>
|
@method('DELETE')
|
||||||
</tr>
|
<button class="bg-red-500 text-white px-3 py-1 rounded hover:bg-red-600">Hapus</button>
|
||||||
@endforeach
|
</form>
|
||||||
</tbody>
|
</td>
|
||||||
</table>
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endsection
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
|
|
@ -1,82 +1,96 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="bg-white shadow-md rounded-2xl p-6 border border-[#e1f0e8]">
|
<div class="bg-white shadow-md rounded-2xl p-6 border border-[#e1f0e8]">
|
||||||
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 border-b border-[#e1f0e8] pb-4">
|
<div
|
||||||
<div>
|
class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 border-b border-[#e1f0e8] pb-4">
|
||||||
<h1 class="text-2xl font-extrabold text-gray-800 flex items-center">
|
<div>
|
||||||
<span class="bg-green-100 text-green-700 p-2 rounded-xl mr-3"><i class="fas fa-bus"></i></span> Log Penjemputan
|
<h1 class="text-2xl font-extrabold text-gray-800 flex items-center">
|
||||||
</h1>
|
<span class="bg-green-100 text-green-700 p-2 rounded-xl mr-3"><i class="fas fa-bus"></i></span> Log
|
||||||
<p class="text-sm text-gray-500 mt-1 ml-12">Daftar riwayat penjemputan siswa (Real-time).</p>
|
Penjemputan
|
||||||
|
</h1>
|
||||||
|
<p class="text-sm text-gray-500 mt-1 ml-12">Daftar riwayat penjemputan siswa (Real-time).</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="mt-4 md:mt-0 flex items-center bg-green-50 text-green-800 px-4 py-2.5 rounded-xl font-bold text-sm border border-green-100 shadow-sm">
|
||||||
|
<i class="fas fa-calendar-day mr-2 text-green-500"></i> Hari Ini:
|
||||||
|
{{ $logs->where('waktu_jemput', '>=', now()->today())->count() }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4 md:mt-0 flex items-center bg-green-50 text-green-800 px-4 py-2.5 rounded-xl font-bold text-sm border border-green-100 shadow-sm">
|
|
||||||
<i class="fas fa-calendar-day mr-2 text-green-500"></i> Hari Ini: {{ $logs->where('waktu_jemput', '>=', now()->today())->count() }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="w-full text-left border-collapse">
|
<table class="w-full text-left border-collapse">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-gray-100 text-gray-600 uppercase text-xs tracking-wider border-b border-gray-200">
|
<tr class="bg-gray-100 text-gray-600 uppercase text-xs tracking-wider border-b border-gray-200">
|
||||||
<th class="p-4 font-bold">Waktu Jemput</th>
|
<th class="p-4 font-bold">Waktu Jemput</th>
|
||||||
<th class="p-4 font-bold">Nama Siswa</th>
|
<th class="p-4 font-bold">Nama Siswa</th>
|
||||||
<th class="p-4 font-bold">Nama Penjemput</th>
|
<th class="p-4 font-bold">Nama Penjemput</th>
|
||||||
<th class="p-4 font-bold text-center">Status Hubungan</th>
|
<th class="p-4 font-bold text-center">Status Hubungan</th>
|
||||||
<th class="p-4 font-bold text-center">Aksi</th>
|
<th class="p-4 font-bold text-center">Aksi</th>
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="divide-y divide-gray-50">
|
|
||||||
@forelse($logs as $log)
|
|
||||||
<tr class="hover:bg-green-50/50 transition duration-150 group">
|
|
||||||
<td class="p-4 whitespace-nowrap">
|
|
||||||
<div class="text-gray-800 font-semibold">
|
|
||||||
{{ \Carbon\Carbon::parse($log->waktu_jemput)->timezone('Asia/Jakarta')->format('H:i') }} WIB
|
|
||||||
</div>
|
|
||||||
<div class="text-xs text-gray-500">
|
|
||||||
{{ \Carbon\Carbon::parse($log->waktu_jemput)->timezone('Asia/Jakarta')->format('d M Y') }}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="p-4">
|
|
||||||
<div class="font-bold text-gray-800">{{ $log->siswa->nama_siswa ?? 'Siswa Terhapus' }}</div>
|
|
||||||
<div class="text-xs text-gray-500">NIS: {{ $log->siswa->nis ?? '-' }}</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="p-4 text-gray-700 font-medium">
|
|
||||||
{{ $log->nama_penjemput }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="p-4 text-center">
|
|
||||||
<span class="inline-block px-3 py-1 rounded-full text-xs font-bold bg-green-100 text-green-700 border border-green-200 shadow-sm">
|
|
||||||
{{ $log->status_hubungan }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="p-4 text-center">
|
|
||||||
<form action="{{ route('penjemputan.destroy', $log->id) }}" method="POST" onsubmit="return confirm('Hapus data log ini?');">
|
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit" class="text-gray-400 hover:text-red-500 transition-colors p-2 rounded-full hover:bg-red-50" title="Hapus Riwayat">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-50">
|
||||||
|
@forelse($logs as $log)
|
||||||
|
<tr class="hover:bg-green-50/50 transition duration-150 group">
|
||||||
|
<td class="p-4 whitespace-nowrap">
|
||||||
|
<div class="text-gray-800 font-semibold">
|
||||||
|
{{ \Carbon\Carbon::parse($log->waktu_jemput)->timezone('Asia/Jakarta')->format('H:i') }} WIB
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-500">
|
||||||
|
{{ \Carbon\Carbon::parse($log->waktu_jemput)->timezone('Asia/Jakarta')->format('d M Y') }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="p-4">
|
||||||
|
<div class="font-bold text-gray-800">{{ $log->siswa->nama_siswa ?? 'Siswa Terhapus' }}</div>
|
||||||
|
<div class="text-xs text-gray-500">NIS: {{ $log->siswa->nis ?? '-' }}</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="p-4 text-gray-700 font-medium">
|
||||||
|
{{ $log->nama_penjemput }}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="p-4 text-center">
|
||||||
|
<span
|
||||||
|
class="inline-block px-3 py-1 rounded-full text-xs font-bold bg-green-100 text-green-700 border border-green-200 shadow-sm">
|
||||||
|
{{ $log->status_hubungan }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="p-4 text-center">
|
||||||
|
<form action="{{ route('penjemputan.destroy', $log->id) }}" method="POST"
|
||||||
|
onsubmit="return confirm('Hapus data log ini?');">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="submit"
|
||||||
|
class="text-gray-400 hover:text-red-500 transition-colors p-2 rounded-full hover:bg-red-50"
|
||||||
|
title="Hapus Riwayat">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="5" class="p-10 text-center text-gray-400">
|
<td colspan="5" class="p-10 text-center text-gray-400">
|
||||||
<div class="flex flex-col items-center justify-center">
|
<div class="flex flex-col items-center justify-center">
|
||||||
<svg class="w-12 h-12 mb-3 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
<svg class="w-12 h-12 mb-3 text-gray-300" fill="none" stroke="currentColor"
|
||||||
<p class="text-sm">Belum ada data penjemputan hari ini.</p>
|
viewBox="0 0 24 24">
|
||||||
</div>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
</td>
|
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||||
</tr>
|
</svg>
|
||||||
|
<p class="text-sm">Belum ada data penjemputan hari ini.</p>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,72 +1,79 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
||||||
<!-- Header Section -->
|
<!-- Header Section -->
|
||||||
<div class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
<div
|
||||||
<!-- Decorative inner pattern -->
|
class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
||||||
<div class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay"></div>
|
<!-- Decorative inner pattern -->
|
||||||
<div class="relative z-10">
|
<div
|
||||||
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay">
|
||||||
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i class="fas fa-chart-line"></i></span> Laporan Perkembangan
|
</div>
|
||||||
</h1>
|
<div class="relative z-10">
|
||||||
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Pilih siswa untuk melihat Catatan Anekdot, Hasil Karya, dan Ceklis.</p>
|
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
||||||
|
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i
|
||||||
|
class="fas fa-chart-line"></i></span> Laporan Perkembangan
|
||||||
|
</h1>
|
||||||
|
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Pilih siswa untuk melihat Catatan Anekdot,
|
||||||
|
Hasil Karya, dan Ceklis.</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mt-6 md:mt-0 relative z-10 flex items-center bg-white text-green-800 px-5 py-3 rounded-xl font-bold text-sm shadow-lg">
|
||||||
|
<i class="fas fa-users mr-2 text-green-500"></i> Total Siswa: {{ $siswas->count() }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 md:mt-0 relative z-10 flex items-center bg-white text-green-800 px-5 py-3 rounded-xl font-bold text-sm shadow-lg">
|
|
||||||
<i class="fas fa-users mr-2 text-green-500"></i> Total Siswa: {{ $siswas->count() }}
|
<div class="p-6">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full border-collapse">
|
||||||
|
<thead class="bg-green-600 text-white">
|
||||||
|
<tr>
|
||||||
|
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">No</th>
|
||||||
|
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">NIS</th>
|
||||||
|
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">Nama Siswa</th>
|
||||||
|
<th class="py-3 px-4 text-center uppercase font-semibold text-sm">Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="text-gray-700">
|
||||||
|
@forelse($siswas as $index => $siswa)
|
||||||
|
<tr class="hover:bg-gray-100 border-b transition duration-150">
|
||||||
|
<td class="py-3 px-4">{{ $index + 1 }}</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4">
|
||||||
|
<span class="bg-gray-100 text-gray-600 py-1 px-2 rounded text-xs font-mono">
|
||||||
|
{{ $siswa->nis ?? '-' }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4 font-medium text-gray-900">
|
||||||
|
{{ $siswa->nama_siswa }}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4 text-center">
|
||||||
|
{{-- PERBAIKAN: Hapus 'admin.' jadi 'perkembangan.show' --}}
|
||||||
|
<a href="{{ route('perkembangan.show', $siswa->id) }}"
|
||||||
|
class="inline-flex items-center gap-1 border border-green-600 text-green-600 bg-white hover:bg-green-50 px-4 py-1.5 rounded-md text-sm font-medium transition duration-200 shadow-sm">
|
||||||
|
📂 Buka Rapot
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" class="text-center py-8 text-gray-500">
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<span class="text-4xl mb-2">📭</span>
|
||||||
|
<p>Belum ada data siswa.</p>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4 pb-6 text-center text-xs text-gray-400">
|
||||||
|
© {{ date('Y') }} PAUD Aisyiyah Monitoring System
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-6">
|
|
||||||
<div class="overflow-x-auto">
|
|
||||||
<table class="w-full border-collapse">
|
|
||||||
<thead class="bg-green-600 text-white">
|
|
||||||
<tr>
|
|
||||||
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">No</th>
|
|
||||||
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">NIS</th>
|
|
||||||
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">Nama Siswa</th>
|
|
||||||
<th class="py-3 px-4 text-center uppercase font-semibold text-sm">Aksi</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="text-gray-700">
|
|
||||||
@forelse($siswas as $index => $siswa)
|
|
||||||
<tr class="hover:bg-gray-100 border-b transition duration-150">
|
|
||||||
<td class="py-3 px-4">{{ $index + 1 }}</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4">
|
|
||||||
<span class="bg-gray-100 text-gray-600 py-1 px-2 rounded text-xs font-mono">
|
|
||||||
{{ $siswa->nis ?? '-' }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 font-medium text-gray-900">
|
|
||||||
{{ $siswa->nama_siswa }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-center">
|
|
||||||
{{-- PERBAIKAN: Hapus 'admin.' jadi 'perkembangan.show' --}}
|
|
||||||
<a href="{{ route('perkembangan.show', $siswa->id) }}" class="inline-flex items-center gap-1 border border-green-600 text-green-600 bg-white hover:bg-green-50 px-4 py-1.5 rounded-md text-sm font-medium transition duration-200 shadow-sm">
|
|
||||||
📂 Buka Rapot
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@empty
|
|
||||||
<tr>
|
|
||||||
<td colspan="4" class="text-center py-8 text-gray-500">
|
|
||||||
<div class="flex flex-col items-center">
|
|
||||||
<span class="text-4xl mb-2">📭</span>
|
|
||||||
<p>Belum ada data siswa.</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforelse
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4 pb-6 text-center text-xs text-gray-400">
|
|
||||||
© {{ date('Y') }} PAUD Aisyiyah Monitoring System
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,106 +1,117 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
||||||
<!-- Header Section -->
|
<!-- Header Section -->
|
||||||
<div class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
<div
|
||||||
<!-- Decorative inner pattern -->
|
class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
||||||
<div class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay"></div>
|
<!-- Decorative inner pattern -->
|
||||||
<div class="relative z-10">
|
<div
|
||||||
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay">
|
||||||
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i class="fas fa-child"></i></span> Data Peserta Didik
|
</div>
|
||||||
</h1>
|
<div class="relative z-10">
|
||||||
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Manajemen data peserta didik PAUD.</p>
|
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
||||||
|
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i
|
||||||
|
class="fas fa-child"></i></span> Data Peserta Didik
|
||||||
|
</h1>
|
||||||
|
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Manajemen data peserta didik PAUD.</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 md:mt-0 relative z-10">
|
||||||
|
<a href="{{ route('siswa.create') }}"
|
||||||
|
class="inline-flex items-center gap-2 bg-white text-green-700 px-6 py-3 rounded-xl hover:bg-green-50 font-bold text-sm shadow-lg transition-all hover:-translate-y-1">
|
||||||
|
<i class="fas fa-plus"></i> Tambah Siswa
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 md:mt-0 relative z-10">
|
|
||||||
<a href="{{ route('siswa.create') }}" class="inline-flex items-center gap-2 bg-white text-green-700 px-6 py-3 rounded-xl hover:bg-green-50 font-bold text-sm shadow-lg transition-all hover:-translate-y-1">
|
<div class="p-6">
|
||||||
<i class="fas fa-plus"></i> Tambah Siswa
|
|
||||||
</a>
|
@if(session('success'))
|
||||||
|
<div class="bg-green-50/50 border border-green-200 text-green-700 p-4 mb-6 rounded-xl flex items-center shadow-sm"
|
||||||
|
role="alert">
|
||||||
|
<i class="fas fa-check-circle mr-3 text-xl text-green-500"></i>
|
||||||
|
<p class="font-medium">{{ session('success') }}</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="min-w-full bg-white">
|
||||||
|
<thead class="bg-green-600 text-white">
|
||||||
|
<tr>
|
||||||
|
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">No</th>
|
||||||
|
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">NIS / NISN</th>
|
||||||
|
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">Nama Siswa</th>
|
||||||
|
<th class="py-3 px-4 text-center uppercase font-semibold text-sm">L/P</th>
|
||||||
|
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">TTL</th>
|
||||||
|
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">Wali Murid / Alamat</th>
|
||||||
|
<th class="py-3 px-4 text-center uppercase font-semibold text-sm">Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="text-gray-700">
|
||||||
|
@forelse($siswas as $index => $siswa)
|
||||||
|
<tr class="hover:bg-gray-100 border-b">
|
||||||
|
<td class="py-3 px-4">{{ $index + 1 }}</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4">
|
||||||
|
<div class="font-bold text-gray-700">{{ $siswa->nis ?? '-' }}</div>
|
||||||
|
<div class="text-xs text-gray-500">{{ $siswa->nisn ?? '-' }}</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4 font-medium">{{ $siswa->nama_siswa }}</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4 text-center">
|
||||||
|
<span
|
||||||
|
class="px-2 py-1 rounded text-xs font-bold {{ $siswa->jenis_kelamin == 'L' ? 'bg-blue-100 text-blue-800' : 'bg-pink-100 text-pink-800' }}">
|
||||||
|
{{ $siswa->jenis_kelamin }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4 text-sm">
|
||||||
|
{{ $siswa->tempat_lahir }}, {{ date('d-m-Y', strtotime($siswa->tanggal_lahir)) }}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4">
|
||||||
|
@if($siswa->wali_murid)
|
||||||
|
<div class="text-sm font-semibold text-gray-800">{{ $siswa->wali_murid->nama_wali }}</div>
|
||||||
|
{{-- Tampilkan Alamat dari Wali Murid --}}
|
||||||
|
<div class="text-xs text-gray-500 mt-1">🏠 {{ Str::limit($siswa->wali_murid->alamat, 30) }}
|
||||||
|
</div>
|
||||||
|
@if(!empty($siswa->wali_murid->no_hp) && $siswa->wali_murid->no_hp != '-')
|
||||||
|
<div class="text-xs text-gray-500">📞 {{ $siswa->wali_murid->no_hp }}</div>
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
|
<span class="text-red-500 text-xs italic bg-red-100 px-2 py-1 rounded">⚠️ Belum diset</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-3 px-4 text-center">
|
||||||
|
<div class="flex items-center justify-center gap-4">
|
||||||
|
<a href="{{ route('siswa.edit', $siswa->id) }}"
|
||||||
|
class="text-blue-500 hover:text-blue-700 hover:underline transition duration-150">
|
||||||
|
Edit
|
||||||
|
</a>
|
||||||
|
<form action="{{ route('siswa.destroy', $siswa->id) }}" method="POST"
|
||||||
|
onsubmit="return confirm('Yakin ingin menghapus data siswa ini?');" class="m-0">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="submit"
|
||||||
|
class="text-red-500 hover:text-red-700 hover:underline transition duration-150">
|
||||||
|
Hapus
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="7" class="text-center py-6 text-gray-500">
|
||||||
|
Belum ada data siswa.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-6">
|
|
||||||
|
|
||||||
@if(session('success'))
|
|
||||||
<div class="bg-green-50/50 border border-green-200 text-green-700 p-4 mb-6 rounded-xl flex items-center shadow-sm" role="alert">
|
|
||||||
<i class="fas fa-check-circle mr-3 text-xl text-green-500"></i>
|
|
||||||
<p class="font-medium">{{ session('success') }}</p>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
|
||||||
<table class="min-w-full bg-white">
|
|
||||||
<thead class="bg-green-600 text-white">
|
|
||||||
<tr>
|
|
||||||
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">No</th>
|
|
||||||
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">NIS / NISN</th>
|
|
||||||
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">Nama Siswa</th>
|
|
||||||
<th class="py-3 px-4 text-center uppercase font-semibold text-sm">L/P</th>
|
|
||||||
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">TTL</th>
|
|
||||||
<th class="py-3 px-4 text-left uppercase font-semibold text-sm">Wali Murid / Alamat</th>
|
|
||||||
<th class="py-3 px-4 text-center uppercase font-semibold text-sm">Aksi</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="text-gray-700">
|
|
||||||
@forelse($siswas as $index => $siswa)
|
|
||||||
<tr class="hover:bg-gray-100 border-b">
|
|
||||||
<td class="py-3 px-4">{{ $index + 1 }}</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4">
|
|
||||||
<div class="font-bold text-gray-700">{{ $siswa->nis ?? '-' }}</div>
|
|
||||||
<div class="text-xs text-gray-500">{{ $siswa->nisn ?? '-' }}</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 font-medium">{{ $siswa->nama_siswa }}</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-center">
|
|
||||||
<span class="px-2 py-1 rounded text-xs font-bold {{ $siswa->jenis_kelamin == 'L' ? 'bg-blue-100 text-blue-800' : 'bg-pink-100 text-pink-800' }}">
|
|
||||||
{{ $siswa->jenis_kelamin }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-sm">
|
|
||||||
{{ $siswa->tempat_lahir }}, {{ date('d-m-Y', strtotime($siswa->tanggal_lahir)) }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4">
|
|
||||||
@if($siswa->wali_murid)
|
|
||||||
<div class="text-sm font-semibold text-gray-800">{{ $siswa->wali_murid->nama_wali }}</div>
|
|
||||||
{{-- Tampilkan Alamat dari Wali Murid --}}
|
|
||||||
<div class="text-xs text-gray-500 mt-1">🏠 {{ Str::limit($siswa->wali_murid->alamat, 30) }}</div>
|
|
||||||
@if(!empty($siswa->wali_murid->no_hp) && $siswa->wali_murid->no_hp != '-')
|
|
||||||
<div class="text-xs text-gray-500">📞 {{ $siswa->wali_murid->no_hp }}</div>
|
|
||||||
@endif
|
|
||||||
@else
|
|
||||||
<span class="text-red-500 text-xs italic bg-red-100 px-2 py-1 rounded">⚠️ Belum diset</span>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-center">
|
|
||||||
<div class="flex items-center justify-center gap-4">
|
|
||||||
<a href="{{ route('siswa.edit', $siswa->id) }}" class="text-blue-500 hover:text-blue-700 hover:underline transition duration-150">
|
|
||||||
Edit
|
|
||||||
</a>
|
|
||||||
<form action="{{ route('siswa.destroy', $siswa->id) }}" method="POST" onsubmit="return confirm('Yakin ingin menghapus data siswa ini?');" class="m-0">
|
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit" class="text-red-500 hover:text-red-700 hover:underline transition duration-150">
|
|
||||||
Hapus
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@empty
|
|
||||||
<tr>
|
|
||||||
<td colspan="7" class="text-center py-6 text-gray-500">
|
|
||||||
Belum ada data siswa.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforelse
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -39,6 +39,22 @@
|
||||||
<label class="block text-gray-700 font-medium mb-1">Alamat Lengkap</label>
|
<label class="block text-gray-700 font-medium mb-1">Alamat Lengkap</label>
|
||||||
<textarea name="alamat" rows="2" class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none">{{ old('alamat') }}</textarea>
|
<textarea name="alamat" rows="2" class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none">{{ old('alamat') }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2 md:col-span-2">
|
||||||
|
<label class="block text-gray-700 font-medium mb-1">Zona Wilayah</label>
|
||||||
|
<select name="master_zona_id" class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none" required>
|
||||||
|
<option value="">-- Pilih Zona Wilayah --</option>
|
||||||
|
@foreach ($zonas as $kategori => $zonaGroup)
|
||||||
|
<optgroup label="{{ $kategori }}">
|
||||||
|
@foreach ($zonaGroup as $zona)
|
||||||
|
<option value="{{ $zona->id }}" {{ old('master_zona_id') == $zona->id ? 'selected' : '' }}>
|
||||||
|
{{ $zona->nama_zona }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</optgroup>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,90 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="bg-white shadow-md rounded-lg p-6 max-w-xl mx-auto mt-10">
|
<div class="bg-white shadow-md rounded-lg p-6 max-w-xl mx-auto mt-10">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h1 class="text-xl font-bold text-gray-700">✏️ Edit Wali Murid</h1>
|
<h1 class="text-xl font-bold text-gray-700">✏️ Edit Wali Murid</h1>
|
||||||
<a href="{{ route('wali-murid.index') }}" class="text-gray-500 hover:text-gray-700">← Kembali</a>
|
<a href="{{ route('wali-murid.index') }}" class="text-gray-500 hover:text-gray-700">← Kembali</a>
|
||||||
</div>
|
|
||||||
|
|
||||||
@if ($errors->any())
|
|
||||||
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4" role="alert">
|
|
||||||
<p class="font-bold">Gagal Menyimpan:</p>
|
|
||||||
<ul class="list-disc list-inside">
|
|
||||||
@foreach ($errors->all() as $error)
|
|
||||||
<li>{{ $error }}</li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
{{-- PERHATIKAN: DI SINI KITA PAKAI $data (BUKAN $wali_murid) --}}
|
|
||||||
<form action="{{ route('wali-murid.update', $data->id) }}" method="POST">
|
|
||||||
@csrf
|
|
||||||
@method('PUT')
|
|
||||||
|
|
||||||
<div class="mb-4">
|
|
||||||
<label class="block text-gray-700 font-medium mb-1">Nama Wali</label>
|
|
||||||
{{-- PERHATIKAN: value="{{ old('nama_wali', $data->nama_wali) }}" --}}
|
|
||||||
<input type="text" name="nama_wali"
|
|
||||||
value="{{ old('nama_wali', $data->nama_wali) }}"
|
|
||||||
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none"
|
|
||||||
required>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
@if ($errors->any())
|
||||||
<label class="block text-gray-700 font-medium mb-1">Email (Login)</label>
|
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4" role="alert">
|
||||||
<input type="email" name="email"
|
<p class="font-bold">Gagal Menyimpan:</p>
|
||||||
value="{{ old('email', $data->user?->email ?? '') }}"
|
<ul class="list-disc list-inside">
|
||||||
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none"
|
@foreach ($errors->all() as $error)
|
||||||
placeholder="Email belum didaftarkan">
|
<li>{{ $error }}</li>
|
||||||
</div>
|
@endforeach
|
||||||
|
</ul>
|
||||||
<div class="mb-4">
|
</div>
|
||||||
<label class="block text-gray-700 font-medium mb-1">No HP</label>
|
@endif
|
||||||
<input type="text" name="no_hp"
|
|
||||||
value="{{ old('no_hp', $data->no_hp) }}"
|
|
||||||
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-4">
|
{{-- PERHATIKAN: DI SINI KITA PAKAI $data (BUKAN $wali_murid) --}}
|
||||||
<label class="block text-gray-700 font-medium mb-1">Alamat</label>
|
<form action="{{ route('wali-murid.update', $data->id) }}" method="POST">
|
||||||
<textarea name="alamat" rows="3"
|
@csrf
|
||||||
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none">{{ old('alamat', $data->alamat) }}</textarea>
|
@method('PUT')
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-end mt-6 gap-3">
|
<div class="mb-4">
|
||||||
<button type="submit"
|
<label class="block text-gray-700 font-medium mb-1">Nama Wali</label>
|
||||||
|
{{-- PERHATIKAN: value="{{ old('nama_wali', $data->nama_wali) }}" --}}
|
||||||
|
<input type="text" name="nama_wali" value="{{ old('nama_wali', $data->nama_wali) }}"
|
||||||
|
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-gray-700 font-medium mb-1">No HP</label>
|
||||||
|
<input type="text" name="no_hp" value="{{ old('no_hp', $data->no_hp) }}"
|
||||||
|
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-gray-700 font-medium mb-1">Alamat</label>
|
||||||
|
<textarea name="alamat" rows="3"
|
||||||
|
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none">{{ old('alamat', $data->alamat) }}</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-gray-700 font-medium mb-1">Zona Wilayah</label>
|
||||||
|
<select name="master_zona_id" class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none" required>
|
||||||
|
<option value="">-- Pilih Zona Wilayah --</option>
|
||||||
|
@foreach ($zonas as $kategori => $zonaGroup)
|
||||||
|
<optgroup label="{{ $kategori }}">
|
||||||
|
@foreach ($zonaGroup as $zona)
|
||||||
|
<option value="{{ $zona->id }}" {{ old('master_zona_id', $data->master_zona_id) == $zona->id ? 'selected' : '' }}>
|
||||||
|
{{ $zona->nama_zona }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</optgroup>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-yellow-50 p-4 rounded-lg border border-yellow-200 mb-6 mt-4">
|
||||||
|
<h2 class="text-lg font-bold text-yellow-800 mb-2 flex items-center gap-2">🔐 Pengaturan Akun Login</h2>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label class="block text-gray-700 font-medium mb-1">Email Login</label>
|
||||||
|
<input type="email" name="email" value="{{ old('email', $data->user?->email ?? '') }}"
|
||||||
|
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-yellow-500 focus:outline-none"
|
||||||
|
placeholder="Email belum didaftarkan">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-gray-700 font-medium mb-1">Password Baru</label>
|
||||||
|
<input type="password" name="password"
|
||||||
|
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-yellow-500 focus:outline-none"
|
||||||
|
placeholder="Kosongkan jika tidak ganti">
|
||||||
|
<p class="text-xs text-gray-500 mt-1">*Isi hanya jika ingin mengganti password login.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-end mt-6 gap-3">
|
||||||
|
<button type="submit"
|
||||||
class="bg-green-600 text-white font-semibold px-6 py-2 rounded-lg hover:bg-green-700 transition duration-200 shadow-md">
|
class="bg-green-600 text-white font-semibold px-6 py-2 rounded-lg hover:bg-green-700 transition duration-200 shadow-md">
|
||||||
💾 Simpan Perubahan
|
💾 Simpan Perubahan
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,79 +1,89 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
<div class="bg-white shadow-md rounded-2xl border border-[#e1f0e8] overflow-hidden">
|
||||||
<!-- Header Section -->
|
<!-- Header Section -->
|
||||||
<div class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
<div
|
||||||
<!-- Decorative inner pattern -->
|
class="flex flex-col md:flex-row justify-between items-start md:items-center bg-gradient-to-br from-green-600 to-teal-700 p-8 shadow-inner relative overflow-hidden">
|
||||||
<div class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay"></div>
|
<!-- Decorative inner pattern -->
|
||||||
<div class="relative z-10">
|
<div
|
||||||
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
class="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10 mix-blend-overlay">
|
||||||
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i class="fas fa-users"></i></span> Data Wali Murid
|
</div>
|
||||||
</h1>
|
<div class="relative z-10">
|
||||||
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Kelola informasi orang tua / wali peserta didik.</p>
|
<h1 class="text-2xl font-extrabold text-white flex items-center drop-shadow">
|
||||||
</div>
|
<span class="bg-white/20 text-white p-2.5 rounded-xl mr-4 backdrop-blur-md"><i
|
||||||
<div class="mt-6 md:mt-0 relative z-10">
|
class="fas fa-users"></i></span> Data Wali Murid
|
||||||
<a href="{{ route('wali-murid.create') }}" class="inline-flex items-center gap-2 bg-white text-green-700 px-6 py-3 rounded-xl hover:bg-green-50 font-bold text-sm shadow-lg transition-all hover:-translate-y-1">
|
</h1>
|
||||||
<i class="fas fa-plus"></i> Tambah Wali
|
<p class="text-green-50 mt-2 ml-14 font-medium drop-shadow-sm">Kelola informasi orang tua / wali peserta
|
||||||
</a>
|
didik.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="mt-6 md:mt-0 relative z-10">
|
||||||
|
<a href="{{ route('wali-murid.create') }}"
|
||||||
<div class="p-6">
|
class="inline-flex items-center gap-2 bg-white text-green-700 px-6 py-3 rounded-xl hover:bg-green-50 font-bold text-sm shadow-lg transition-all hover:-translate-y-1">
|
||||||
{{-- Alert Merah untuk Error --}}
|
<i class="fas fa-plus"></i> Tambah Wali
|
||||||
@if(session('error'))
|
</a>
|
||||||
<div class="bg-red-50/50 border border-red-200 text-red-700 p-4 mb-6 rounded-xl flex items-center shadow-sm" role="alert">
|
|
||||||
<i class="fas fa-exclamation-circle mr-3 text-xl text-red-500"></i>
|
|
||||||
<div>
|
|
||||||
<strong class="font-bold block">Error!</strong>
|
|
||||||
<span>{{ session('error') }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
|
|
||||||
{{-- Alert Hijau untuk Sukses --}}
|
<div class="p-6">
|
||||||
@if(session('success'))
|
{{-- Alert Merah untuk Error --}}
|
||||||
<div class="bg-green-50/50 border border-green-200 text-green-700 p-4 mb-6 rounded-xl flex items-center shadow-sm" role="alert">
|
@if(session('error'))
|
||||||
<i class="fas fa-check-circle mr-3 text-xl text-green-500"></i>
|
<div class="bg-red-50/50 border border-red-200 text-red-700 p-4 mb-6 rounded-xl flex items-center shadow-sm"
|
||||||
<p class="font-medium">{{ session('success') }}</p>
|
role="alert">
|
||||||
</div>
|
<i class="fas fa-exclamation-circle mr-3 text-xl text-red-500"></i>
|
||||||
@endif
|
<div>
|
||||||
|
<strong class="font-bold block">Error!</strong>
|
||||||
|
<span>{{ session('error') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
{{-- Alert Hijau untuk Sukses --}}
|
||||||
<table class="w-full border-collapse">
|
@if(session('success'))
|
||||||
<thead>
|
<div class="bg-green-50/50 border border-green-200 text-green-700 p-4 mb-6 rounded-xl flex items-center shadow-sm"
|
||||||
<tr class="bg-green-600 text-white text-left">
|
role="alert">
|
||||||
<th class="p-2">No</th>
|
<i class="fas fa-check-circle mr-3 text-xl text-green-500"></i>
|
||||||
<th class="p-2">Nama Wali</th>
|
<p class="font-medium">{{ session('success') }}</p>
|
||||||
<th class="p-2">No HP</th>
|
</div>
|
||||||
<th class="p-2">Alamat</th>
|
@endif
|
||||||
<th class="p-2">Aksi</th>
|
|
||||||
</tr>
|
<div class="overflow-x-auto">
|
||||||
</thead>
|
<table class="w-full border-collapse">
|
||||||
<tbody>
|
<thead>
|
||||||
@forelse ($walis as $i => $wali)
|
<tr class="bg-green-600 text-white text-left">
|
||||||
<tr class="border-b hover:bg-gray-50">
|
<th class="p-2">No</th>
|
||||||
<td class="p-2">{{ $i + 1 }}</td>
|
<th class="p-2">Nama Wali</th>
|
||||||
<td class="p-2 font-medium">{{ $wali->nama_wali ?? '-' }}</td>
|
<th class="p-2">No HP</th>
|
||||||
<td class="p-2">{{ $wali->no_hp ?? '-' }}</td>
|
<th class="p-2">Alamat</th>
|
||||||
<td class="p-2 text-sm text-gray-600">{{ $wali->alamat ?? '-' }}</td>
|
<th class="p-2">Aksi</th>
|
||||||
<td class="p-2 space-x-2">
|
</tr>
|
||||||
<a href="{{ route('wali-murid.edit', $wali->id) }}" class="text-blue-500 hover:underline">Edit</a>
|
</thead>
|
||||||
<form action="{{ route('wali-murid.destroy', $wali->id) }}" method="POST" class="inline" onsubmit="return confirm('Yakin hapus?');">
|
<tbody>
|
||||||
@csrf
|
@forelse ($walis as $i => $wali)
|
||||||
@method('DELETE')
|
<tr class="border-b hover:bg-gray-50">
|
||||||
<button type="submit" class="text-red-500 hover:underline">Hapus</button>
|
<td class="p-2">{{ $i + 1 }}</td>
|
||||||
</form>
|
<td class="p-2 font-medium">{{ $wali->nama_wali ?? '-' }}</td>
|
||||||
</td>
|
<td class="p-2">{{ $wali->no_hp ?? '-' }}</td>
|
||||||
</tr>
|
<td class="p-2 text-sm text-gray-600">{{ $wali->alamat ?? '-' }}</td>
|
||||||
@empty
|
<td class="p-2 space-x-2">
|
||||||
<tr>
|
<a href="{{ route('wali-murid.edit', $wali->id) }}"
|
||||||
<td colspan="5" class="text-center text-gray-500 py-4">Belum ada data wali murid.</td>
|
class="text-blue-500 hover:underline">Edit</a>
|
||||||
</tr>
|
<form action="{{ route('wali-murid.destroy', $wali->id) }}" method="POST" class="inline"
|
||||||
@endforelse
|
onsubmit="return confirm('Yakin hapus?');">
|
||||||
</tbody>
|
@csrf
|
||||||
</table>
|
@method('DELETE')
|
||||||
|
<button type="submit" class="text-red-500 hover:underline">Hapus</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" class="text-center text-gray-500 py-4">Belum ada data wali murid.</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -31,16 +31,26 @@ class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-gree
|
||||||
required>
|
required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="bg-yellow-50 p-4 rounded-lg border border-yellow-200 mb-6 mt-4">
|
||||||
<label class="block text-gray-700 font-medium mb-1">Email (Login)</label>
|
<h2 class="text-lg font-bold text-yellow-800 mb-2 flex items-center gap-2">🔐 Pengaturan Akun Login</h2>
|
||||||
{{-- Gunakan $data->user --}}
|
|
||||||
<input type="email" name="email"
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
value="{{ old('email', $data->user?->email ?? '') }}"
|
<div>
|
||||||
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-green-500 focus:outline-none"
|
<label class="block text-gray-700 font-medium mb-1">Email Login</label>
|
||||||
placeholder="Email belum didaftarkan">
|
<input type="email" name="email"
|
||||||
|
value="{{ old('email', $data->user?->email ?? '') }}"
|
||||||
|
class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-yellow-500 focus:outline-none"
|
||||||
|
placeholder="Email belum didaftarkan">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-gray-700 font-medium mb-1">Password Baru</label>
|
||||||
|
<input type="password" name="password" class="w-full border border-gray-300 rounded-lg p-2 focus:ring-2 focus:ring-yellow-500 focus:outline-none" placeholder="Kosongkan jika tidak ingin ganti">
|
||||||
|
<p class="text-xs text-gray-500 mt-1">*Isi hanya jika ingin mengganti password login.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4 mt-4">
|
||||||
<label class="block text-gray-700 font-medium mb-1">No HP</label>
|
<label class="block text-gray-700 font-medium mb-1">No HP</label>
|
||||||
<input type="text" name="no_hp"
|
<input type="text" name="no_hp"
|
||||||
value="{{ old('no_hp', $data->no_hp) }}"
|
value="{{ old('no_hp', $data->no_hp) }}"
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@
|
||||||
<!-- Search Input with Icon -->
|
<!-- Search Input with Icon -->
|
||||||
<div class="relative hidden md:block">
|
<div class="relative hidden md:block">
|
||||||
<i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 text-sm"></i>
|
<i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 text-sm"></i>
|
||||||
<input type="text" placeholder="Cari..."
|
<input type="text" id="global-search" placeholder="Cari data di tabel..."
|
||||||
class="pl-10 pr-4 py-2 bg-gray-50/50 border border-gray-200 focus:bg-white rounded-xl w-64 text-sm transition-all focus:w-80 shadow-sm">
|
class="pl-10 pr-4 py-2 bg-gray-50/50 border border-gray-200 focus:bg-white rounded-xl w-64 text-sm transition-all focus:w-80 shadow-sm">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -224,4 +224,28 @@ class="pl-10 pr-4 py-2 bg-gray-50/50 border border-gray-200 focus:bg-white round
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const searchInput = document.getElementById('global-search');
|
||||||
|
if(searchInput) {
|
||||||
|
searchInput.addEventListener('input', function(e) {
|
||||||
|
const query = e.target.value.toLowerCase();
|
||||||
|
const rows = document.querySelectorAll('tbody tr');
|
||||||
|
|
||||||
|
rows.forEach(row => {
|
||||||
|
// Jangan sembunyikan baris "Belum ada data pesan"
|
||||||
|
if(row.querySelector('td[colspan]')) return;
|
||||||
|
|
||||||
|
const text = row.textContent.toLowerCase();
|
||||||
|
if(text.includes(query)) {
|
||||||
|
row.style.display = '';
|
||||||
|
} else {
|
||||||
|
row.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
use App\Http\Controllers\Api\GuruController;
|
use App\Http\Controllers\Api\GuruController;
|
||||||
use App\Http\Controllers\Api\PenjemputanController;
|
use App\Http\Controllers\Api\PenjemputanController;
|
||||||
use App\Http\Controllers\Api\AStarController;
|
use App\Http\Controllers\Api\AStarController;
|
||||||
|
use App\Http\Controllers\Api\HomeVisitController;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -37,6 +38,7 @@
|
||||||
// --- UMUM ---
|
// --- UMUM ---
|
||||||
Route::get('/siswa-saya', [SiswaController::class, 'index']); // Pindah ke sini biar bisa baca Auth::user()
|
Route::get('/siswa-saya', [SiswaController::class, 'index']); // Pindah ke sini biar bisa baca Auth::user()
|
||||||
Route::post('/logout', [AuthController::class, 'logout']);
|
Route::post('/logout', [AuthController::class, 'logout']);
|
||||||
|
Route::post('/update-fcm-token', [AuthController::class, 'updateFcmToken']);
|
||||||
Route::get('/user', function (Request $request) {
|
Route::get('/user', function (Request $request) {
|
||||||
return $request->user(); // Cek siapa yang login
|
return $request->user(); // Cek siapa yang login
|
||||||
});
|
});
|
||||||
|
|
@ -69,5 +71,9 @@
|
||||||
|
|
||||||
Route::get('/rute-astar', [AStarController::class, 'cariRute']);
|
Route::get('/rute-astar', [AStarController::class, 'cariRute']);
|
||||||
|
|
||||||
|
// RUTE HOME VISIT / ZONASI
|
||||||
|
Route::get('/zonasi', [HomeVisitController::class, 'getZonasi']);
|
||||||
|
Route::get('/home-visit/zona/{zona_id}', [HomeVisitController::class, 'getSiswaByZona']);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"type": "service_account",
|
||||||
|
"project_id": "simpaudkartoharjo",
|
||||||
|
"private_key_id": "d5856c1910f178842deff72bb591d8480181c6fc",
|
||||||
|
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDYK3IGvE4dnkiy\nOhLyBDZGXigJ3Eu3nqUCixbSs/tBvURF8YR1Wxxmadw7v/ozJNwy5/aHo1wdd0j+\nFrIv5JVhpAWuO7OIXvodtRKYONmyPj9B9ioV9yGsIYsqj3942etbfyUVDdOpwniO\nAQBnJanu4pg6yoAGXLAjo//AuUMI5b+3NUwcfCva1dZgrLvz+pWZclN8nwOx/npU\nXj7SoWveSQXBqnhJFm5TLlacj9OHVW4TWx7DoAC5ePpVvXJGGC7s8xUgdlRXyoPL\n6DrFZVHHYmrdzSSVtgp8Hr0v0iLiKu8y7v79uN7jOyxZkw9ukzwA025TCQxtifSr\n/vEO0l3xAgMBAAECggEAWOGgLEHPsqDqzhFPyd/OeydqugcwwMqDmWScGT10kUaj\nZEjWSDSSnE9phM2+L7o3qdyzgni6PslVo1eso0GO5Es/JLEac/dtSrqxbxJs/DtY\n4iO3kTmASFiwcmr3JDch7Qh9tEbvoSy7SdQCmOalFPppUj8B3dvNdpIPbewesnCX\naNLHx1FkokKnrBD8H9oqSj97q6DutDM8BZpn9xxvZd9vDgFH1PYLO8FM8m7GMR3p\nJEU0Xs1gk9DfC9CQGcmF4WSqY0CDtvC9fscIcLTNG83fp0/DO74Wb6r6RT4q1lFb\nifYBmTiOuQT9J7tMMGGhkPXyQYW6Nw18TyOphE67GwKBgQDuI4FfXot4EcRVU/Lp\nm2BzD8aNAFZcUF/vOGWGiKp2kTLiDCxwEXS01gZzre+MtEGXK+40QpztkVnaU6zN\nlcXZuNHFOXsDA4LLhR2LRC4bOWchH8usroorfzM0kDfFkPMiwY+k6LZQAL1IvKuF\nIsqRTcnpGDDXvvyXVBYbOqrWZwKBgQDoYh063eXL4HIlh/oCOD3Fhp5p9zd/dHzN\nCv2ODOcEQG3N43YLPHHf2mCSpv8Vcp17cV3aGgMYUEU2i7f6TpOX9VUpgLip8tEj\nOxZL4xN3GAy57MC2v1t3RBU58waYk1fOdqFlvwy7xxdCqU/zB8vvdjJ1vqIJnAsw\nICD087eB5wKBgHLGtB0mMWxui8Vgj8yeMc9jRBxDlFwr9QEUmoJMLnS1KOQgX+6n\nyys5mKR6qeGUI6Tb7JRNotsx2i/Lcpcn39M/LAO1358lOw4im4m7E8nVUep6K62P\n9lJenWxxMiBL65PN3RDrhKtsn86F+NlTWnTMHEv3d9sUVyQMyBbZoOtzAoGBAJPj\nvQ51oYU6deqEuwsml8lZfv+ZIWyvya0ETZFVjMAb8MWS+ND1ytLXu5YZSUVxB+BD\nqaLf4xBaJXItQQy/bRbMP0KGdP9TVN3DANGS1hR47cB1d7/V0HP6lDeo/o2jV8JB\npT2HdKcccSUvc34LfDINWtesVpse/8/E4rSBVkwJAoGAI00acL5ragdj1Sz/eTiU\nnvi4uOhRbcegDOnk3H1VYULoy2d6bvTfNObDnI2laWTIZluwBJ4WrBbDAGjNkL4d\nDHNO5ZgjyqtK+3LoSixEac+YKxTvmPLtmXgBExjHwQ5lSWG3VQyCbPYBmruZFLhE\nKb868a/RtMJm9f8P1WDkb/I=\n-----END PRIVATE KEY-----\n",
|
||||||
|
"client_email": "firebase-adminsdk-fbsvc@simpaudkartoharjo.iam.gserviceaccount.com",
|
||||||
|
"client_id": "106199666854739826761",
|
||||||
|
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
"token_uri": "https://oauth2.googleapis.com/token",
|
||||||
|
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||||
|
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40simpaudkartoharjo.iam.gserviceaccount.com",
|
||||||
|
"universe_domain": "googleapis.com"
|
||||||
|
}
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
a:3:{s:6:"_token";s:40:"vYUfuBlzhzFJwH2XXHUItujz2a2gJxSN3nu71JBO";s:9:"_previous";a:1:{s:3:"url";s:21:"http://127.0.0.1:8000";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
a:4:{s:6:"_token";s:40:"ocZHTeLJ29EH7CNr3zDNqY5dmsDthSoRJrHMTTx8";s:9:"_previous";a:1:{s:3:"url";s:32:"http://127.0.0.1:8000/pengumuman";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}s:50:"login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d";i:1;}
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
a:4:{s:6:"_token";s:40:"00mfxFm9DrbF1elsEluX9X6oWjH0R4XSNXCoGuB3";s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}s:9:"_previous";a:1:{s:3:"url";s:31:"http://127.0.0.1:8000/dashboard";}s:50:"login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d";i:1;}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
a:3:{s:6:"_token";s:40:"Wli1wb6syOPQUamEet6OVXObBcjjwOw1H8ICY0Ck";s:9:"_previous";a:1:{s:3:"url";s:27:"http://127.0.0.1:8000/login";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
|
|
||||||
BIN
vendor.zip
BIN
vendor.zip
Binary file not shown.
Loading…
Reference in New Issue