diff --git a/app/Http/Controllers/Admin/AnekdotController.php b/app/Http/Controllers/Admin/AnekdotController.php new file mode 100644 index 0000000..0ed0470 --- /dev/null +++ b/app/Http/Controllers/Admin/AnekdotController.php @@ -0,0 +1,52 @@ +validate([ + 'tanggal' => 'required|date', + 'waktu' => 'required|string|max:50', + 'tempat' => 'required|string|max:255', + 'uraian_kejadian' => 'required|string', + 'analisis_capaian' => 'nullable|string', + 'foto' => 'nullable|image|mimes:jpg,jpeg,png|max:2048', + ]); + + // 2. Ambil data mentah lalu tambahkan manual + $data = $request->all(); + $data['siswa_id'] = $siswa_id; + $data['guru_id'] = auth()->id(); + $data['kejadian_teramati'] = $request->uraian_kejadian; // ISI PAKSA + + // 3. Upload foto + if ($request->hasFile('foto')) { + $data['foto'] = $request->file('foto')->store('anekdot', 'public'); + } + + // 4. Simpan (Akan berhasil jika Model sudah diupdate fillable-nya) + Anekdot::create($data); + + return redirect() + ->route('perkembangan.show', $siswa_id) + ->with('success', 'Catatan anekdot berhasil disimpan!'); + } +} diff --git a/app/Http/Controllers/Admin/GuruController.php b/app/Http/Controllers/Admin/GuruController.php index cccee96..ea8be8c 100644 --- a/app/Http/Controllers/Admin/GuruController.php +++ b/app/Http/Controllers/Admin/GuruController.php @@ -4,7 +4,10 @@ use App\Http\Controllers\Controller; use App\Models\Guru; +use App\Models\User; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Hash; class GuruController extends Controller { @@ -20,19 +23,41 @@ public function create() } public function store(Request $request) - { - // Validasi disesuaikan dengan kolom database - $request->validate([ - 'nama_guru' => 'required|string|max:100', - 'email' => 'nullable|email|max:100', - 'no_hp' => 'nullable|string|max:20', - 'jenis_guru' => 'required|in:guru_kelas,shadow_abk', // UBAH 'bidang' JADI 'jenis_guru' - ]); - - Guru::create($request->all()); - - return redirect()->route('guru.index')->with('success', 'Data guru berhasil ditambahkan.'); - } + { + // 1. Validasi + $request->validate([ + 'nama_guru' => 'required', + 'email' => 'required|email|unique:users,email', + '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', + ]); + + // B. SIMPAN KE TABEL GURU (HANYA DATA PROFIL) + 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 + '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) { diff --git a/app/Http/Controllers/Admin/HasilKaryaController.php b/app/Http/Controllers/Admin/HasilKaryaController.php new file mode 100644 index 0000000..02c1e9a --- /dev/null +++ b/app/Http/Controllers/Admin/HasilKaryaController.php @@ -0,0 +1,43 @@ +validate([ + 'tanggal' => 'required|date', + 'foto' => 'required|image|max:2048', // Foto wajib ada untuk hasil karya + 'deskripsi_foto' => 'required', // Sesuai nama kolom di DB kamu + 'analisis_capaian' => 'nullable', + ]); + + $data = $request->all(); + $data['siswa_id'] = $siswa_id; + $data['guru_id'] = auth()->id(); + + if ($request->hasFile('foto')) { + $file = $request->file('foto'); + $filename = time() . '_' . $file->getClientOriginalName(); + $file->storeAs('public/hasil_karya', $filename); + $data['foto'] = $filename; + } + + HasilKarya::create($data); + + return redirect()->route('perkembangan.show', $siswa_id) + ->with('success', 'Hasil Karya berhasil diupload!'); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Admin/PenilaianCeklisController.php b/app/Http/Controllers/Admin/PenilaianCeklisController.php new file mode 100644 index 0000000..d36ce39 --- /dev/null +++ b/app/Http/Controllers/Admin/PenilaianCeklisController.php @@ -0,0 +1,37 @@ +validate([ + 'tanggal' => 'required|date', + 'indikator' => 'required|string', + 'hasil' => 'required|in:BB,MB,BSH,BSB', // Validasi 'hasil' + 'keterangan' => 'nullable|string', + ]); + + $data = $request->all(); + $data['siswa_id'] = $siswa_id; + $data['guru_id'] = auth()->id(); + + PenilaianCeklis::create($data); + + return redirect()->route('perkembangan.show', $siswa_id) + ->with('success', 'Data penilaian ceklis berhasil disimpan!'); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Admin/RapotController.php b/app/Http/Controllers/Admin/RapotController.php index 9e73e22..b220f06 100644 --- a/app/Http/Controllers/Admin/RapotController.php +++ b/app/Http/Controllers/Admin/RapotController.php @@ -10,71 +10,61 @@ class RapotController extends Controller { public function create($siswa_id) - { - $siswa = \App\Models\Siswa::findOrFail($siswa_id); - - // PERBAIKAN: Ambil data dari Model 'Guru', bukan 'User' - // Kita ambil semua guru, diurutkan berdasarkan nama - $gurus = \App\Models\Guru::orderBy('nama_guru', 'asc')->get(); - - return view('admin.rapot.create', compact('siswa', 'gurus')); - } + { + $siswa = Siswa::findOrFail($siswa_id); + return view('admin.rapot.create', compact('siswa')); + } - // 2. SIMPAN DATA RAPOT KE DATABASE public function store(Request $request, $siswa_id) - { - $request->validate([ - 'semester' => 'required', - 'tahun_ajaran' => 'required', - 'tanggal_rapot' => 'required|date', - 'nama_guru' => 'required', - 'nama_kepala_sekolah' => 'required', - ]); - - Rapot::create([ - 'siswa_id' => $siswa_id, - 'semester' => $request->semester, - 'tahun_ajaran' => $request->tahun_ajaran, - 'tanggal_rapot' => $request->tanggal_rapot, - - // Urutan A-E Sesuai PDF - 'narasi_aik' => $request->narasi_aik, - 'narasi_nilai_agama' => $request->narasi_nilai_agama, - 'narasi_jati_diri' => $request->narasi_jati_diri, - 'narasi_literasi' => $request->narasi_literasi, - 'narasi_kokurikuler' => $request->narasi_kokurikuler, // Kolom Baru - - // Fisik & Kehadiran - 'tinggi_badan' => $request->tinggi_badan, - 'berat_badan' => $request->berat_badan, - 'lingkar_kepala' => $request->lingkar_kepala, - 'lingkar_lengan' => $request->lingkar_lengan, - 'sakit' => $request->sakit ?? 0, - 'izin' => $request->izin ?? 0, - 'alpha' => $request->alpha ?? 0, - - // Refleksi & TTD - 'refleksi_orang_tua' => $request->refleksi_orang_tua, - 'nama_guru' => $request->nama_guru, - 'nama_kepala_sekolah' => $request->nama_kepala_sekolah, - 'nbm_kepala_sekolah' => $request->nbm_kepala_sekolah, - ]); - - return redirect()->route('perkembangan.show', $siswa_id) - ->with('success', 'Rapot berhasil dibuat!'); - } + { + $request->validate([ + 'tahun_ajaran' => 'required', + 'semester' => 'required', + 'tanggal_rapot' => 'required|date', + 'narasi_agama' => 'required', + 'narasi_budi_pekerti' => 'required', + 'narasi_jati_diri' => 'required', + 'narasi_literasi' => 'required', + 'narasi_kokurikuler' => 'required', // E Wajib + ]); + + Rapot::create([ + 'siswa_id' => $siswa_id, + 'tahun_ajaran' => $request->tahun_ajaran, + 'semester' => $request->semester, + 'tanggal_rapot' => $request->tanggal_rapot, + + // Narasi A-E + 'narasi_agama' => $request->narasi_agama, + 'narasi_budi_pekerti' => $request->narasi_budi_pekerti, + 'narasi_jati_diri' => $request->narasi_jati_diri, + 'narasi_literasi' => $request->narasi_literasi, + 'narasi_kokurikuler' => $request->narasi_kokurikuler, + + // TTD & Refleksi + 'refleksi_orang_tua' => $request->refleksi_orang_tua, + 'nama_guru' => $request->nama_guru, + 'nipy_guru' => $request->nipy_guru, + 'nama_kepala_sekolah' => $request->nama_kepala_sekolah, + 'nipy_kepala_sekolah' => $request->nipy_kepala_sekolah, + + // Fisik + 'tinggi_badan' => $request->tinggi_badan, + 'berat_badan' => $request->berat_badan, + 'lingkar_kepala' => $request->lingkar_kepala, + 'sakit' => $request->sakit ?? 0, + 'izin' => $request->izin ?? 0, + 'alpha' => $request->alpha ?? 0, + ]); + + return redirect()->route('perkembangan.show', $siswa_id)->with('success', 'Rapot Berhasil Dibuat!'); + } - // 3. LIHAT DETAIL RAPOT (PREVIEW SEBELUM CETAK) public function show($id) { $rapot = Rapot::with('siswa')->findOrFail($id); return view('admin.rapot.show', compact('rapot')); } - - // 4. CETAK PDF (Nanti kita bahas fitur ini) - public function print($id) - { - $rapot = Rapot::with('siswa')->findOrFail($id); - return view('admin.rapot.print', compact('rapot')); - } + + // Edit & Update bisa menyesuaikan strukturnya sama dengan Store } \ No newline at end of file diff --git a/app/Http/Controllers/Admin/WaliMuridController.php b/app/Http/Controllers/Admin/WaliMuridController.php index 70f2822..e244289 100644 --- a/app/Http/Controllers/Admin/WaliMuridController.php +++ b/app/Http/Controllers/Admin/WaliMuridController.php @@ -4,85 +4,69 @@ use App\Http\Controllers\Controller; use App\Models\WaliMurid; +use App\Models\User; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\DB; class WaliMuridController extends Controller { public function index() { - $walis = WaliMurid::latest()->get(); - return view('admin.wali.index', compact('walis')); + $walis = WaliMurid::with('user')->latest()->get(); + + // PERBAIKAN DI SINI: Sesuaikan dengan nama folder 'wali' + return view('admin.wali.index', compact('walis')); } public function create() { + // PERBAIKAN DI SINI JUGA return view('admin.wali.create'); } public function store(Request $request) { $request->validate([ - 'nama_wali' => 'required|string|max:100', - 'no_hp' => 'nullable|string|max:20', - 'alamat' => 'nullable|string', + 'nama_wali' => 'required', + 'email' => 'required|email|unique:users,email', + 'password' => 'required|min:6', + 'no_hp' => 'required', ]); - WaliMurid::create($request->all()); - - return redirect()->route('wali-murid.index')->with('success', 'Data Wali Murid berhasil ditambahkan.'); - } - - public function edit($id) - { - // Kita pakai nama variable $data biar netral dan pasti beda - $data = WaliMurid::with('user')->findOrFail($id); + DB::transaction(function () use ($request) { - // Kirim ke view dengan nama 'data' - return view('admin.wali.edit', compact('data')); - } - - public function update(Request $request, $id) - { - $data = WaliMurid::findOrFail($id); - - $request->validate([ - 'nama_wali' => 'required|string|max:255', - // Cek email unik kecuali user ini ($data->user_id) - 'email' => 'nullable|email|unique:users,email,' . ($data->user_id ?? 0), - 'no_hp' => 'nullable|string', - 'alamat' => 'nullable|string', + // 1. Buat User Login + $user = User::create([ + 'name' => $request->nama_wali, + 'email' => $request->email, + 'password' => Hash::make($request->password), + 'role' => 'wali_murid', ]); - - // 1. Update User (Jika ada) - if ($data->user) { - $data->user->update([ - 'name' => $request->nama_wali, - 'email' => $request->email, - ]); - } - - // 2. Update Data Wali - $data->update([ + + // 2. Buat Profil Wali + WaliMurid::create([ + 'user_id' => $user->id, 'nama_wali' => $request->nama_wali, 'no_hp' => $request->no_hp, - 'alamat' => $request->alamat, + 'alamat' => $request->alamat, + 'pekerjaan' => $request->pekerjaan, ]); - - return redirect()->route('wali-murid.index')->with('success', 'Data Wali Murid berhasil diperbarui!'); - } - - // --- DELETE (Perbaikan Hapus User juga) --- - public function destroy($id) - { - $waliMurid = WaliMurid::findOrFail($id); - - // Hapus akun loginnya juga biar bersih - if ($waliMurid->user) { - $waliMurid->user->delete(); - } - - $waliMurid->delete(); - - return redirect()->route('wali-murid.index')->with('success', 'Data Wali Murid berhasil dihapus!'); + }); + + return redirect()->route('wali-murid.index')->with('success', 'Berhasil! Akun Wali Murid siap digunakan.'); + } + + public function destroy($id) + { + $wali = WaliMurid::findOrFail($id); + + if($wali->user) { + $wali->user->delete(); + } else { + $wali->delete(); } + + return redirect()->route('wali-murid.index')->with('success', 'Data Wali Murid berhasil dihapus'); + } } \ No newline at end of file diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index 2f65b08..20761dd 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -12,26 +12,36 @@ public function showLogin() return view('auth.login'); } - public function login(Request $request) -{ - $credentials = $request->only('email', 'password'); - - if (Auth::guard('web')->attempt($credentials)) { - $request->session()->regenerate(); - return redirect()->intended('/dashboard');on()->regenerate(); - - // cek role di sini - if (Auth::user()->role === 'admin') { - return redirect()->intended('/dashboard'); - } else { - Auth::logout(); - return back()->with('error', 'Hanya admin yang bisa login di website.'); + public function login(Request $request) + { + // 1. Ambil input email & password + $credentials = $request->only('email', 'password'); + + // 2. Coba Login + if (Auth::guard('web')->attempt($credentials)) { + $request->session()->regenerate(); + + // --- πŸ›‘οΈ SATPAM (LOGIKA BLOKIR) --- + + // Cek Role User yang baru saja login + $user = Auth::user(); + + // Jika role-nya 'wali_murid', TOLAK! + if ($user->role === 'wali_murid') { + Auth::logout(); // Logout paksa + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return back()->with('error', 'Maaf, Wali Murid hanya bisa login lewat Aplikasi Android!'); + } + + // Jika Admin ATAU Guru, lolos ke Dashboard + return redirect()->intended('/dashboard'); + } + + // 3. Kalau email atau password salah + return back()->with('error', 'Username atau password salah!'); } - } - - // kalau email atau password salah - return back()->with('error', 'Username atau password salah!'); -} public function logout(Request $request) { Auth::logout(); diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 21d6566..6ad73ed 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -5,20 +5,34 @@ use Illuminate\Http\Request; use App\Models\Guru; use App\Models\Siswa; -use App\Models\WaliMurid; -use App\Models\Kelas; +use App\Models\Kelas; // Pastikan model ini ada use App\Models\Pengumuman; class DashboardController extends Controller { public function index() { - $pengumuman = Pengumuman::orderBy('created_at', 'desc')->first(); - $aktivitas = [ - (object)['deskripsi' => 'Admin menambahkan data guru', 'created_at' => now()], - (object)['deskripsi' => 'Admin membuat pengumuman baru', 'created_at' => now()->subHour()], - ]; + // 1. STATISTIK + $totalSiswa = Siswa::count(); + $totalGuru = Guru::count(); + // Cek dulu tabel kelas ada atau belum, kalau belum kasih 0 + $totalKelas = \Schema::hasTable('kelas') ? Kelas::count() : 0; - return view('dashboard', compact('pengumuman','aktivitas')); -} + // 2. PENGUMUMAN (Ambil 3 Terbaru yang Statusnya Aktif/1) + $pengumuman = Pengumuman::where('status', 1) + ->orderBy('created_at', 'desc') + ->take(3) + ->get(); + + // 3. SISWA BARU (Untuk Tabel) + $siswaBaru = Siswa::latest()->take(5)->get(); + + return view('dashboard', compact( + 'totalSiswa', + 'totalGuru', + 'totalKelas', + 'pengumuman', + 'siswaBaru' + )); + } } \ No newline at end of file diff --git a/app/Models/Anekdot.php b/app/Models/Anekdot.php index a75e511..7f4eb9c 100644 --- a/app/Models/Anekdot.php +++ b/app/Models/Anekdot.php @@ -2,9 +2,24 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Anekdot extends Model { - // + use HasFactory; + + protected $table = "anekdots"; // Pastikan nama tabelnya sesuai + + protected $fillable = [ + 'siswa_id', + 'guru_id', + 'tanggal', + 'waktu', + 'tempat', + 'uraian_kejadian', + 'kejadian_teramati', // TAMBAHKAN INI + 'analisis_capaian', + 'foto', + ]; } diff --git a/app/Models/Guru.php b/app/Models/Guru.php index 540fb63..0e08546 100644 --- a/app/Models/Guru.php +++ b/app/Models/Guru.php @@ -9,15 +9,13 @@ class Guru extends Model { use HasFactory; - protected $table = 'guru'; // Sesuai DB kamu + protected $table = 'guru'; // βœ… Sudah Benar (Sesuai tabelmu) - protected $fillable = [ - 'nama_guru', // SEBELUMNYA 'nama' (SALAH), HARUS 'nama_guru' - 'jenis_guru', // SEBELUMNYA 'jenis_guru' (SUDAH BENAR TAPI INPUT FORM SALAH) - 'no_hp', - 'email', - 'user_id', - ]; + // ❌ HAPUS variable $fillable yang lama + + // βœ… PAKAI INI SAJA (Jurus Anti Ribet) + // Artinya: Izinkan semua data masuk ke database + protected $guarded = []; public function user() { diff --git a/app/Models/HasilKarya.php b/app/Models/HasilKarya.php index fed5174..f6aeeb7 100644 --- a/app/Models/HasilKarya.php +++ b/app/Models/HasilKarya.php @@ -2,9 +2,21 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class HasilKarya extends Model { - // + use HasFactory; + + protected $table = "hasil_karyas"; // Pastikan nama tabelnya sesuai + + protected $fillable = [ + 'siswa_id', + 'guru_id', + 'tanggal', + 'foto', + 'deskripsi_foto', // Pastikan ini sama persis dengan DB + 'analisis_capaian' + ]; } diff --git a/app/Models/Pengumuman.php b/app/Models/Pengumuman.php index 7cc4ee4..5565d9c 100644 --- a/app/Models/Pengumuman.php +++ b/app/Models/Pengumuman.php @@ -9,7 +9,8 @@ class Pengumuman extends Model { use HasFactory; - protected $table = 'pengumuman'; // <- perbaikan disini + // Karena nama tabelnya 'pengumuman' (bukan pengumumans) + protected $table = 'pengumuman'; protected $fillable = [ 'judul', @@ -18,5 +19,11 @@ class Pengumuman extends Model 'tanggal_selesai', 'status', ]; -} + // Casting agar tanggal otomatis jadi Carbon (bisa diformat tgl-bln-thn) + protected $casts = [ + 'tanggal_mulai' => 'date', + 'tanggal_selesai' => 'date', + 'status' => 'boolean', + ]; +} \ No newline at end of file diff --git a/app/Models/PenilaianCeklis.php b/app/Models/PenilaianCeklis.php index ea87cf3..319e16f 100644 --- a/app/Models/PenilaianCeklis.php +++ b/app/Models/PenilaianCeklis.php @@ -2,9 +2,27 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class PenilaianCeklis extends Model { - // -} + use HasFactory; + + // Arahkan ke nama tabel yang benar + protected $table = 'penilaian_ceklis'; + + protected $fillable = [ + 'siswa_id', + 'guru_id', + 'indikator', // Sekarang sudah jadi teks + 'tanggal', + 'hasil', // Ingat, di database kamu namanya 'hasil' + 'keterangan' + ]; + + public function siswa() + { + return $this->belongsTo(Siswa::class); + } +} \ No newline at end of file diff --git a/app/Models/Rapot.php b/app/Models/Rapot.php index a8c6006..848c5b6 100644 --- a/app/Models/Rapot.php +++ b/app/Models/Rapot.php @@ -9,10 +9,29 @@ class Rapot extends Model { use HasFactory; - // Ini kuncinya biar semua kolom bisa diisi - protected $guarded = []; + protected $fillable = [ + 'siswa_id', 'tahun_ajaran', 'semester', 'tanggal_rapot', + + // NARASI A-E (Sesuai PDF) + 'narasi_agama', // A. AIK + 'narasi_budi_pekerti', // B. Budi Pekerti + 'narasi_jati_diri', // C. Jati Diri + 'narasi_literasi', // D. Literasi + 'narasi_kokurikuler', // E. Kokurikuler (Panjang) + + // REFLEKSI & TTD + 'refleksi_orang_tua', + 'nama_guru', 'nipy_guru', + 'nama_kepala_sekolah', 'nipy_kepala_sekolah', + + // FISIK & KEHADIRAN + 'tinggi_badan', 'berat_badan', 'lingkar_kepala', + 'sakit', 'izin', 'alpha', + + // SISA (Biarkan p5 ada jika nanti butuh) + 'p5_tema', 'p5_judul', 'p5_narasi' + ]; - // Relasi balik ke Siswa public function siswa() { return $this->belongsTo(Siswa::class); diff --git a/app/Models/Siswa.php b/app/Models/Siswa.php index 398c1ee..59fb849 100644 --- a/app/Models/Siswa.php +++ b/app/Models/Siswa.php @@ -17,4 +17,19 @@ public function wali_murid() { return $this->belongsTo(WaliMurid::class, 'wali_murid_id'); } + + public function anekdots() + { + return $this->hasMany(Anekdot::class, 'siswa_id'); + } + + public function hasilKaryas() + { + return $this->hasMany(HasilKarya::class, 'siswa_id'); + } + + public function penilaianCeklis() + { + return $this->hasMany(PenilaianCeklis::class, 'siswa_id'); + } } \ No newline at end of file diff --git a/app/Models/User.php b/app/Models/User.php index 0ca6c6e..8435cf9 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -10,17 +10,16 @@ class User extends Authenticatable { + use HasApiTokens, HasFactory, Notifiable; /** - * The attributes that are mass assignable. - * - * @var array + * GANTI FILLABLE DENGAN GUARDED + * Agar kolom 'role' bisa diisi oleh Controller */ - protected $fillable = [ - 'name', - 'email', - 'password', - ]; + // protected $fillable = [ ... ]; <-- HAPUS ATAU KOMENTAR INI + + // βœ… PAKAI INI (Jurus Open Gate): + protected $guarded = []; /** * The attributes that should be hidden for serialization. @@ -55,4 +54,4 @@ protected function casts(): array 'password' => 'hashed', ]; } -} +} \ No newline at end of file diff --git a/app/Models/WaliMurid.php b/app/Models/WaliMurid.php index 328fed4..9ee426c 100644 --- a/app/Models/WaliMurid.php +++ b/app/Models/WaliMurid.php @@ -9,22 +9,17 @@ class WaliMurid extends Model { use HasFactory; - protected $table = 'wali_murids'; // Default laravel biasanya plural + // Nama tabel di database kamu (Sesuai screenshot) + protected $table = 'wali_murids'; - protected $fillable = [ - 'user_id', - 'nama_wali', // Pastikan kolom di DB 'nama_wali', bukan 'nama' - 'no_hp', - 'alamat', - 'pekerjaan', // Opsional, jaga-jaga kalau butuh - ]; + // βœ… JURUS OPEN GATE: Izinkan semua data masuk (Alamat, Pekerjaan, dll) + protected $guarded = []; public function user() { return $this->belongsTo(User::class); } - // Relasi ke Siswa (Satu wali bisa punya banyak anak) public function siswas() { return $this->hasMany(Siswa::class, 'wali_id'); diff --git a/database/migrations/2024_01_01_000000_create_siswas_table_create_siswas_table.php b/database/migrations/2024_01_01_000000_create_siswas_table_create_siswas_table.php index c57d100..c302a44 100644 --- a/database/migrations/2024_01_01_000000_create_siswas_table_create_siswas_table.php +++ b/database/migrations/2024_01_01_000000_create_siswas_table_create_siswas_table.php @@ -11,7 +11,7 @@ public function up() Schema::create('siswas', function (Blueprint $table) { $table->id(); $table->string('nis')->nullable(); - $table->string('nama'); + $table->string('nama_siswa'); $table->enum('jenis_kelamin', ['L', 'P'])->nullable(); $table->date('tanggal_lahir')->nullable(); diff --git a/database/migrations/2025_09_17_031831_add_role_to_users_table.php b/database/migrations/2025_09_17_031831_add_role_to_users_table.php index b69df2f..d7c1785 100644 --- a/database/migrations/2025_09_17_031831_add_role_to_users_table.php +++ b/database/migrations/2025_09_17_031831_add_role_to_users_table.php @@ -9,21 +9,18 @@ /** * Run the migrations. */ - public function up(): void -{ - Schema::table('users', function (Blueprint $table) { - $table->enum('role', ['admin','guru','wali'])->default('wali'); - $table->string('phone')->nullable(); - }); -} - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('users', function (Blueprint $table) { - // - }); - } + public function up() + { + Schema::table('users', function (Blueprint $table) { + // Defaultnya 'admin' biar aman, atau 'guru' + $table->string('role')->default('guru')->after('email'); + }); + } + + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('role'); + }); + } }; diff --git a/database/migrations/2026_02_08_135848_create_penilaian_ceklis_table.php b/database/migrations/2026_02_08_135848_create_penilaian_ceklis_table.php index bde540a..b67aa88 100644 --- a/database/migrations/2026_02_08_135848_create_penilaian_ceklis_table.php +++ b/database/migrations/2026_02_08_135848_create_penilaian_ceklis_table.php @@ -6,28 +6,29 @@ return new class extends Migration { - /** - * Run the migrations. - */ - public function up() - { - Schema::create('penilaian_ceklis', function (Blueprint $table) { - $table->id(); - $table->foreignId('siswa_id')->constrained('siswas')->onDelete('cascade'); - $table->foreignId('guru_id')->constrained('users')->onDelete('cascade'); - $table->foreignId('indikator_id')->constrained('indikators')->onDelete('cascade'); - $table->date('tanggal'); - $table->enum('hasil', ['BSB', 'BSH', 'MB', 'BB']); // Skala Penilaian - $table->text('keterangan')->nullable(); - $table->timestamps(); - }); - } + public function up(): void + { + // Kita gunakan nama tabel sesuai file kamu: 'penilaian_ceklis' + Schema::create('penilaian_ceklis', function (Blueprint $table) { + $table->id(); + $table->foreignId('siswa_id')->constrained('siswas')->onDelete('cascade'); + $table->foreignId('guru_id')->constrained('users')->onDelete('cascade'); + + // UBAH INI: Dari ID jadi Text supaya bisa copy-paste dari Word + $table->text('indikator'); + + $table->date('tanggal'); + + // Sesuai screenshot kamu, namanya 'hasil' bukan 'skala' + $table->enum('hasil', ['BSB', 'BSH', 'MB', 'BB']); + + $table->text('keterangan')->nullable(); + $table->timestamps(); + }); + } - /** - * Reverse the migrations. - */ public function down(): void { Schema::dropIfExists('penilaian_ceklis'); } -}; +}; \ No newline at end of file diff --git a/database/migrations/2026_02_09_141001_add_foto_to_anekdots_and_hasil_karyas.php b/database/migrations/2026_02_09_141001_add_foto_to_anekdots_and_hasil_karyas.php new file mode 100644 index 0000000..9a6a964 --- /dev/null +++ b/database/migrations/2026_02_09_141001_add_foto_to_anekdots_and_hasil_karyas.php @@ -0,0 +1,50 @@ +string('foto')->nullable(); + }); + } + } + + // Cek tabel hasil_karyas + if (Schema::hasTable('hasil_karyas')) { + if (!Schema::hasColumn('hasil_karyas', 'foto')) { + Schema::table('hasil_karyas', function (Blueprint $table) { + $table->string('foto')->nullable(); + }); + } + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('anekdots', function (Blueprint $table) { + if (Schema::hasColumn('anekdots', 'foto')) { + $table->dropColumn('foto'); + } + }); + + Schema::table('hasil_karyas', function (Blueprint $table) { + if (Schema::hasColumn('hasil_karyas', 'foto')) { + $table->dropColumn('foto'); + } + }); + } +}; \ No newline at end of file diff --git a/database/migrations/2026_02_09_144246_add_waktu_to_anekdots_table.php b/database/migrations/2026_02_09_144246_add_waktu_to_anekdots_table.php new file mode 100644 index 0000000..aa35513 --- /dev/null +++ b/database/migrations/2026_02_09_144246_add_waktu_to_anekdots_table.php @@ -0,0 +1,26 @@ +string('waktu')->after('tanggal')->nullable(); + }); + } + + public function down(): void + { + Schema::table('anekdots', function (Blueprint $table) { + $table->dropColumn('waktu'); + }); + } +}; diff --git a/database/migrations/2026_02_09_144712_fix_columns_in_anekdots_table.php b/database/migrations/2026_02_09_144712_fix_columns_in_anekdots_table.php new file mode 100644 index 0000000..f911b3d --- /dev/null +++ b/database/migrations/2026_02_09_144712_fix_columns_in_anekdots_table.php @@ -0,0 +1,29 @@ +date('tanggal')->nullable()->after('siswa_id'); + if (!Schema::hasColumn('anekdots', 'waktu')) $table->string('waktu')->nullable()->after('tanggal'); + if (!Schema::hasColumn('anekdots', 'tempat')) $table->string('tempat')->nullable()->after('waktu'); + if (!Schema::hasColumn('anekdots', 'uraian_kejadian')) $table->text('uraian_kejadian')->nullable()->after('tempat'); + if (!Schema::hasColumn('anekdots', 'analisis_capaian')) $table->text('analisis_capaian')->nullable()->after('uraian_kejadian'); + }); + } + + public function down(): void + { + Schema::table('anekdots', function (Blueprint $table) { + $table->dropColumn(['tanggal', 'waktu', 'tempat', 'uraian_kejadian', 'analisis_capaian']); + }); + } +}; diff --git a/database/migrations/2026_02_09_192524_add_budi_pekerti_to_rapots_table.php b/database/migrations/2026_02_09_192524_add_budi_pekerti_to_rapots_table.php new file mode 100644 index 0000000..6a12974 --- /dev/null +++ b/database/migrations/2026_02_09_192524_add_budi_pekerti_to_rapots_table.php @@ -0,0 +1,43 @@ +text('narasi_agama')->nullable(); + } + + // 2. Cek Kolom B (Budi Pekerti). Kalau belum ada, buat. + if (!Schema::hasColumn('rapots', 'narasi_budi_pekerti')) { + $table->text('narasi_budi_pekerti')->nullable(); + } + + // 3. Cek Kolom E (Kokurikuler) sekalian. + if (!Schema::hasColumn('rapots', 'narasi_kokurikuler')) { + $table->text('narasi_kokurikuler')->nullable(); + } + + // 4. Pastikan kolom C & D juga aman + if (!Schema::hasColumn('rapots', 'narasi_jati_diri')) { + $table->text('narasi_jati_diri')->nullable(); + } + if (!Schema::hasColumn('rapots', 'narasi_literasi')) { + $table->text('narasi_literasi')->nullable(); + } + }); + } + + public function down() + { + // Kosongkan saja agar aman saat rollback + } +}; \ No newline at end of file diff --git a/database/migrations/2026_02_09_193353_add_ttd_columns_to_rapots_table.php b/database/migrations/2026_02_09_193353_add_ttd_columns_to_rapots_table.php new file mode 100644 index 0000000..a21b449 --- /dev/null +++ b/database/migrations/2026_02_09_193353_add_ttd_columns_to_rapots_table.php @@ -0,0 +1,49 @@ +text('refleksi_orang_tua')->nullable(); + } + + // 2. Cek Kolom Nama Guru + if (!Schema::hasColumn('rapots', 'nama_guru')) { + $table->string('nama_guru')->nullable(); + } + + // 3. Cek Kolom NIPY Guru + if (!Schema::hasColumn('rapots', 'nipy_guru')) { + $table->string('nipy_guru')->nullable(); + } + + // 4. Cek Kolom Kepala Sekolah + if (!Schema::hasColumn('rapots', 'nama_kepala_sekolah')) { + $table->string('nama_kepala_sekolah')->nullable(); + } + + // 5. Cek Kolom NIPY Kepala Sekolah + if (!Schema::hasColumn('rapots', 'nipy_kepala_sekolah')) { + $table->string('nipy_kepala_sekolah')->nullable(); + } + + // 6. Pastikan Tanggal Rapot tipe Date (ubah kalau perlu) + if (Schema::hasColumn('rapots', 'tanggal_rapot')) { + $table->date('tanggal_rapot')->nullable()->change(); + } + }); + } + + public function down() + { + // Kosongkan agar aman saat rollback + } +}; \ No newline at end of file diff --git a/database/migrations/2026_02_09_194107_update_rapot_structure_final.php b/database/migrations/2026_02_09_194107_update_rapot_structure_final.php new file mode 100644 index 0000000..2875d45 --- /dev/null +++ b/database/migrations/2026_02_09_194107_update_rapot_structure_final.php @@ -0,0 +1,42 @@ +text('narasi_budi_pekerti')->nullable()->after('narasi_agama'); + } + if (!Schema::hasColumn('rapots', 'narasi_kokurikuler')) { + $table->text('narasi_kokurikuler')->nullable()->after('narasi_literasi'); + } + if (!Schema::hasColumn('rapots', 'refleksi_orang_tua')) { + $table->text('refleksi_orang_tua')->nullable(); + } + // Data Tanda Tangan + if (!Schema::hasColumn('rapots', 'nama_guru')) { + $table->string('nama_guru')->nullable(); + } + if (!Schema::hasColumn('rapots', 'nipy_guru')) { + $table->string('nipy_guru')->nullable(); + } + if (!Schema::hasColumn('rapots', 'nama_kepala_sekolah')) { + $table->string('nama_kepala_sekolah')->nullable(); + } + if (!Schema::hasColumn('rapots', 'nipy_kepala_sekolah')) { + $table->string('nipy_kepala_sekolah')->nullable(); + } + }); + } + + public function down() + { + // Tidak perlu drop column agar data aman + } +}; \ No newline at end of file diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index c668321..1e5db04 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -29,6 +29,14 @@ public function run(): void SiswaSeeder::class, // Data Siswa (Fixed) ]); + // 2. Buat Akun GURU (Contoh: Bu Dwi) + User::create([ + 'name' => 'Dwi Lestari, S.Pd', + 'email' => 'guru@gmail.com', + 'password' => Hash::make('password'), + 'role' => 'guru', + ]); + // CATATAN: Jangan panggil MasterSeeder lagi karena kodenya usang. } } \ No newline at end of file diff --git a/database/seeders/SiswaSeeder.php b/database/seeders/SiswaSeeder.php index 14397b8..3f9f813 100644 --- a/database/seeders/SiswaSeeder.php +++ b/database/seeders/SiswaSeeder.php @@ -12,7 +12,7 @@ public function run() // Data diambil dari CSV yang kamu kirim (Sample 5 Siswa dulu biar cepat) $siswas = [ [ - 'nama' => 'Abdila Kaivan Baihaqi Alzafa', + 'nama_siswa' => 'Abdila Kaivan Baihaqi Alzafa', // SUDAH DIPERBAIKI (nama -> nama_siswa) 'nis' => '2024247', 'jenis_kelamin' => 'L', 'tanggal_lahir' => '2018-03-10', @@ -20,7 +20,7 @@ public function run() 'kelompok_id' => 1 ], [ - 'nama' => 'Hanifah Syafi\'a', // Pakai backslash (\) sebelum tanda petik satu + 'nama_siswa' => 'Hanifah Syafi\'a', 'nis' => '2024268', 'jenis_kelamin' => 'P', 'tanggal_lahir' => '2019-05-12', @@ -28,7 +28,7 @@ public function run() 'kelompok_id' => 1 ], [ - 'nama' => 'Abrizam Rafka Danindra', + 'nama_siswa' => 'Abrizam Rafka Danindra', 'nis' => '2024271', 'jenis_kelamin' => 'L', 'tanggal_lahir' => '2019-07-15', @@ -36,7 +36,7 @@ public function run() 'kelompok_id' => 1 ], [ - 'nama' => 'Achazia Nakhi Shankara', + 'nama_siswa' => 'Achazia Nakhi Shankara', 'nis' => '222285', 'jenis_kelamin' => 'L', 'tanggal_lahir' => '2021-03-30', @@ -44,7 +44,7 @@ public function run() 'kelompok_id' => 1 ], [ - 'nama' => 'Ahmad Farzan Wisanggeni', + 'nama_siswa' => 'Ahmad Farzan Wisanggeni', 'nis' => '2023233', 'jenis_kelamin' => 'L', 'tanggal_lahir' => '2019-01-10', diff --git a/public/images/stampel.png b/public/images/stampel.png new file mode 100644 index 0000000..1c53f35 Binary files /dev/null and b/public/images/stampel.png differ diff --git a/resources/views/admin/anekdot/create.blade.php b/resources/views/admin/anekdot/create.blade.php new file mode 100644 index 0000000..03dc5f0 --- /dev/null +++ b/resources/views/admin/anekdot/create.blade.php @@ -0,0 +1,83 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

πŸ“ Catatan Anekdot Baru

+

Mencatat peristiwa penting perkembangan siswa

+
+ {{-- Ganti yang error tadi dengan ini --}} + + Kembali ke Profil Siswa + +
+ +
+
+
πŸ§’
+
+

Siswa:

+

{{ $siswa->nama_siswa }}

+

NIS: {{ $siswa->nis }} | Kelompok: {{ $siswa->kelompok_id ?? '-' }}

+
+
+
+ +
+ @csrf + +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ +
+ +

*Tuliskan apa yang dilihat dan didengar secara objektif tanpa opini.

+ +
+ +
+ +

*Tuliskan nilai agama, jati diri, atau literasi yang muncul dari kejadian ini.

+ +
+ +
+ +
+ +
+

*Hanya file gambar (JPG, PNG). Ukuran maksimal 2MB.

+
+ +
+ +
+ +
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/admin/ceklis/create.blade.php b/resources/views/admin/ceklis/create.blade.php new file mode 100644 index 0000000..7c1a6e1 --- /dev/null +++ b/resources/views/admin/ceklis/create.blade.php @@ -0,0 +1,70 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

βœ… Input Penilaian Ceklis

+

Siswa: {{ $siswa->nama_siswa }}

+
+ + ← Kembali + +
+ +
+ @csrf + +
+ + +
+ +
+ + +
+ +
+ +
+ + + + +
+
+ +
+ + +
+ +
+ +
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/admin/guru/create.blade.php b/resources/views/admin/guru/create.blade.php index fa7e540..8473a57 100644 --- a/resources/views/admin/guru/create.blade.php +++ b/resources/views/admin/guru/create.blade.php @@ -1,38 +1,81 @@ @extends('layouts.app') @section('content') -
-

βž• Tambah Guru

+
+
+

βž• Tambah Guru Baru

+ ← Kembali +
+ + {{-- Tampilkan Error Validasi --}} + @if ($errors->any()) +
+
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+ @endif
@csrf -
- - {{-- Name harus 'nama_guru', bukan 'nama' --}} - +
+

Biodata Guru

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + +
-
- - {{-- Ganti input text 'bidang' jadi Select 'jenis_guru' sesuai Enum DB --}} - +
+

πŸ” Buat Akun Login

+

Data ini digunakan guru untuk masuk ke dalam aplikasi.

+ +
+
+ + +
+
+ + +
+
-
- - +
+
- -
- - -
- -
@endsection \ No newline at end of file diff --git a/resources/views/admin/guru/edit.blade.php b/resources/views/admin/guru/edit.blade.php index 725955d..66ebf86 100644 --- a/resources/views/admin/guru/edit.blade.php +++ b/resources/views/admin/guru/edit.blade.php @@ -1,16 +1,14 @@ @extends('layouts.app') @section('content') -
+

✏️ Edit Data Guru

← Kembali
- {{-- Cek Error --}} @if ($errors->any()) -