kas, spp, penialaian
This commit is contained in:
parent
03fa985785
commit
f7db432276
|
|
@ -110,47 +110,54 @@ public function edit($id)
|
|||
|
||||
// 5. Update Data Anggota
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$anggota = Anggota::findOrFail($id);
|
||||
$user = User::findOrFail($anggota->user_id);
|
||||
{
|
||||
$anggota = Anggota::findOrFail($id);
|
||||
$user = User::findOrFail($anggota->user_id);
|
||||
|
||||
$request->validate([
|
||||
'email' => 'required|email|unique:users,email,' . $user->id,
|
||||
'nama_lengkap' => 'required',
|
||||
'no_hp' => 'required',
|
||||
'role_id' => 'required|exists:role,id',
|
||||
'kolat_id' => 'required|exists:kolat,id',
|
||||
'status' => 'required|in:aktif,Non-Aktif',
|
||||
$request->validate([
|
||||
'email' => 'required|email|unique:users,email,' . $user->id,
|
||||
'nama_lengkap' => 'required|string|max:255',
|
||||
'no_hp' => 'required',
|
||||
'role_id' => 'required|exists:role,id',
|
||||
'kolat_id' => 'required|exists:kolat,id',
|
||||
'status' => 'required|in:Aktif,Non-Aktif',
|
||||
]);
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
// 1. Update tabel Users (Email & Role)
|
||||
$user->update([
|
||||
'email' => $request->email,
|
||||
'role_id' => $request->role_id,
|
||||
]);
|
||||
|
||||
DB::beginTransaction();
|
||||
// 2. Ambil nama jabatan baru dari role_id
|
||||
$role = Role::find($request->role_id);
|
||||
$nama_jabatan = strtolower($role->nama_role);
|
||||
|
||||
try {
|
||||
// A. Update tabel User (email & role)
|
||||
$user->update([
|
||||
'email' => $request->email,
|
||||
'role_id' => $request->role_id
|
||||
]);
|
||||
// 3. Kelola Upload Foto SK (jika ada)
|
||||
$data = $request->all();
|
||||
$data['jabatan'] = $nama_jabatan;
|
||||
|
||||
// B. Update jabatan berdasarkan role baru
|
||||
$role = Role::find($request->role_id);
|
||||
$nama_jabatan = strtolower($role->nama_role);
|
||||
|
||||
// C. Update tabel Anggota
|
||||
$data_anggota = $request->all();
|
||||
$data_anggota['jabatan'] = $nama_jabatan;
|
||||
|
||||
$anggota->update($data_anggota);
|
||||
|
||||
DB::commit();
|
||||
return redirect()->route('anggota.anggota')
|
||||
->with('success', 'Data ' . $anggota->nama_lengkap . ' berhasil diperbarui!');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error("Gagal update anggota: " . $e->getMessage());
|
||||
return back()->with('error', 'Terjadi kesalahan saat memperbarui data.');
|
||||
if ($request->hasFile('foto_sk')) {
|
||||
$file = $request->file('foto_sk');
|
||||
$nama_file = time() . "_" . $file->getClientOriginalName();
|
||||
$file->move(public_path('uploads/sk'), $nama_file);
|
||||
$data['foto_sk'] = $nama_file;
|
||||
}
|
||||
|
||||
// 4. Update tabel Anggota
|
||||
$anggota->update($data);
|
||||
|
||||
DB::commit();
|
||||
return redirect()->route('anggota.anggota')
|
||||
->with('success', 'Data ' . $anggota->nama_lengkap . ' berhasil diperbarui!');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return back()->with('error', 'Gagal update: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Kas;
|
||||
use Illuminate\Http\Request;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class KasController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
// Menggunakan scope query untuk filter
|
||||
$query = Kas::query();
|
||||
|
||||
if ($request->filled('jenis')) {
|
||||
$query->where('jenis', $request->jenis);
|
||||
}
|
||||
|
||||
if ($request->filled('dari') && $request->filled('sampai')) {
|
||||
$query->whereBetween('tanggal', [$request->dari, $request->sampai]);
|
||||
}
|
||||
|
||||
$data_kas = $query->orderBy('tanggal', 'asc')->orderBy('id', 'asc')->get();
|
||||
|
||||
// Statistik tetap menggunakan data keseluruhan
|
||||
$saldo_sekarang = Kas::saldoTerakhir();
|
||||
|
||||
$pemasukan_bulan_ini = Kas::where('jenis', 'masuk')
|
||||
->whereMonth('tanggal', now()->month)
|
||||
->whereYear('tanggal', now()->year)
|
||||
->sum('nominal');
|
||||
|
||||
$pengeluaran_bulan_ini = Kas::where('jenis', 'keluar')
|
||||
->whereMonth('tanggal', now()->month)
|
||||
->whereYear('tanggal', now()->year)
|
||||
->sum('nominal');
|
||||
|
||||
return view('kas.index', compact('data_kas', 'saldo_sekarang', 'pemasukan_bulan_ini', 'pengeluaran_bulan_ini'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fungsi untuk menyimpan data transaksi baru
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
// 1. Validasi input
|
||||
$request->validate([
|
||||
'tanggal' => 'required|date',
|
||||
'jenis' => 'required|in:masuk,keluar',
|
||||
'kategori' => 'required|string',
|
||||
'nominal' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
// 2. Ambil saldo terakhir untuk kalkulasi saldo_akhir
|
||||
$saldo_terakhir = Kas::saldoTerakhir();
|
||||
|
||||
// 3. Hitung saldo baru
|
||||
if ($request->jenis == 'masuk') {
|
||||
$saldo_baru = $saldo_terakhir + $request->nominal;
|
||||
} else {
|
||||
$saldo_baru = $saldo_terakhir - $request->nominal;
|
||||
}
|
||||
|
||||
// 4. Simpan ke database
|
||||
Kas::create([
|
||||
'tanggal' => $request->tanggal,
|
||||
'jenis' => $request->jenis,
|
||||
'kategori' => $request->kategori,
|
||||
'nominal' => $request->nominal,
|
||||
'keterangan' => $request->keterangan,
|
||||
'saldo_akhir' => $saldo_baru,
|
||||
]);
|
||||
|
||||
return redirect()->route('kas.index')->with('success', 'Transaksi berhasil ditambahkan!');
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$kas = Kas::findOrFail($id);
|
||||
$kas->delete();
|
||||
|
||||
return redirect()->back()->with('success', 'Transaksi berhasil dihapus!');
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
'tanggal' => 'required|date',
|
||||
'jenis' => 'required|in:masuk,keluar',
|
||||
'kategori' => 'required|string',
|
||||
'nominal' => 'required|numeric',
|
||||
]);
|
||||
|
||||
$kas = Kas::findOrFail($id);
|
||||
|
||||
// Logika perhitungan ulang saldo:
|
||||
// Kita ambil saldo sebelum transaksi ini terjadi
|
||||
$saldo_sebelumnya = Kas::where('id', '<', $kas->id)->orderBy('id', 'desc')->first()->saldo_akhir ?? 0;
|
||||
|
||||
// Hitung saldo akhir baru untuk baris ini
|
||||
$saldo_akhir_baru = ($request->jenis == 'masuk')
|
||||
? $saldo_sebelumnya + $request->nominal
|
||||
: $saldo_sebelumnya - $request->nominal;
|
||||
|
||||
$kas->update([
|
||||
'tanggal' => $request->tanggal,
|
||||
'jenis' => $request->jenis,
|
||||
'kategori' => $request->kategori,
|
||||
'nominal' => $request->nominal,
|
||||
'keterangan' => $request->keterangan,
|
||||
'saldo_akhir' => $saldo_akhir_baru
|
||||
]);
|
||||
|
||||
// Catatan: Idealnya setelah edit, semua baris setelahnya juga diupdate saldonya.
|
||||
// Tapi untuk tahap awal, ini sudah cukup fungsional.
|
||||
|
||||
return redirect()->back()->with('success', 'Transaksi berhasil diperbarui!');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,112 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Anggota;
|
||||
use App\Models\Penilaian;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
||||
class PenilaianController extends Controller
|
||||
{
|
||||
//
|
||||
public function index()
|
||||
{
|
||||
$data_pelatih = Anggota::where('jabatan', 'Pelatih')
|
||||
->with('kolat')
|
||||
->get();
|
||||
|
||||
return view('penilaian.index', compact('data_pelatih'));
|
||||
}
|
||||
|
||||
public function create($id)
|
||||
{
|
||||
// BYPASS: Hapus pengecekan auth() agar tidak mental ke login
|
||||
$pelatih = Anggota::with('kolat')->findOrFail($id);
|
||||
return view('penilaian.create', compact('pelatih'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'pelatih_id' => 'required',
|
||||
'metode_pelatihan' => 'required|integer|min:1|max:5',
|
||||
'komunikasi' => 'required|integer|min:1|max:5',
|
||||
'sikap_kepribadian' => 'required|integer|min:1|max:5',
|
||||
'kepemimpinan' => 'required|integer|min:1|max:5',
|
||||
'konsistensi_komitmen' => 'required|integer|min:1|max:5',
|
||||
'kedekatan_interpersonal' => 'required|integer|min:1|max:5',
|
||||
'kritik_saran' => 'nullable|string'
|
||||
]);
|
||||
|
||||
Penilaian::create([
|
||||
'pelatih_id' => $request->pelatih_id,
|
||||
'anggota_id' => 1, // TESTING: Isi manual ID Anggota penilai (misal ID 1)
|
||||
'bulan_evaluasi' => Carbon::now()->startOfMonth(),
|
||||
'metode_pelatihan' => $request->metode_pelatihan,
|
||||
'komunikasi' => $request->komunikasi,
|
||||
'sikap_kepribadian' => $request->sikap_kepribadian,
|
||||
'kepemimpinan' => $request->kepemimpinan,
|
||||
'konsistensi_komitmen' => $request->konsistensi_komitmen,
|
||||
'kedekatan_interpersonal' => $request->kedekatan_interpersonal,
|
||||
'kritik_saran' => $request->kritik_saran,
|
||||
]);
|
||||
|
||||
return redirect()->route('penilaian.index')->with('success', 'Penilaian berhasil disimpan!');
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$pelatih = Anggota::with('kolat')->findOrFail($id);
|
||||
|
||||
// Hitung rata-rata tiap kriteria bulan ini
|
||||
$rekap = Penilaian::where('pelatih_id', $id)
|
||||
->whereMonth('bulan_evaluasi', now()->month)
|
||||
->selectRaw('
|
||||
AVG(metode_pelatihan) as avg_metode,
|
||||
AVG(komunikasi) as avg_komunikasi,
|
||||
AVG(sikap_kepribadian) as avg_sikap,
|
||||
AVG(kepemimpinan) as avg_kepemimpinan,
|
||||
AVG(konsistensi_komitmen) as avg_komitmen,
|
||||
AVG(kedekatan_interpersonal) as avg_interpersonal
|
||||
')->first();
|
||||
|
||||
// Ambil ulasan/kritik saran (Pluck agar anonim)
|
||||
$ulasan = Penilaian::where('pelatih_id', $id)
|
||||
->whereMonth('bulan_evaluasi', now()->month)
|
||||
->whereNotNull('kritik_saran')
|
||||
->pluck('kritik_saran');
|
||||
|
||||
return view('penilaian.rekap', compact('pelatih', 'rekap', 'ulasan'));
|
||||
}
|
||||
|
||||
public function exportPdf($id)
|
||||
{
|
||||
// 1. Ambil data pelatih
|
||||
$pelatih = Anggota::with('kolat')->findOrFail($id);
|
||||
|
||||
// 2. Hitung rata-rata nilai (Rekap)
|
||||
$rekap = Penilaian::where('pelatih_id', $id)
|
||||
->whereMonth('bulan_evaluasi', now()->month)
|
||||
->selectRaw('
|
||||
AVG(metode_pelatihan) as avg_metode,
|
||||
AVG(komunikasi) as avg_komunikasi,
|
||||
AVG(sikap_kepribadian) as avg_sikap,
|
||||
AVG(kepemimpinan) as avg_kepemimpinan,
|
||||
AVG(konsistensi_komitmen) as avg_komitmen,
|
||||
AVG(kedekatan_interpersonal) as avg_interpersonal
|
||||
')->first();
|
||||
|
||||
// 3. Ambil ulasan ulasan anggota
|
||||
$ulasan = Penilaian::where('pelatih_id', $id)
|
||||
->whereMonth('bulan_evaluasi', now()->month)
|
||||
->whereNotNull('kritik_saran')
|
||||
->pluck('kritik_saran');
|
||||
|
||||
// 4. Panggil file view "laporan_pdf" sesuai nama filemu
|
||||
$pdf = Pdf::loadView('penilaian.laporan_pdf', compact('pelatih', 'rekap', 'ulasan'));
|
||||
|
||||
// 5. Download file PDF
|
||||
return $pdf->download('Laporan-Performa-' . $pelatih->nama_lengkap . '.pdf');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Anggota;
|
||||
use App\Models\Kas;
|
||||
use App\Models\Spp;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class SppController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Spp::with(['anggota', 'kolat']);
|
||||
|
||||
// Filter
|
||||
if ($request->filled('status')) {
|
||||
$query->where('status', $request->status);
|
||||
}
|
||||
if ($request->filled('bulan')) {
|
||||
$query->where('bulan', $request->bulan);
|
||||
}
|
||||
if ($request->filled('tahun')) {
|
||||
$query->where('tahun', $request->tahun);
|
||||
}
|
||||
if ($request->filled('cari')) {
|
||||
$query->whereHas('anggota', function($q) use ($request) {
|
||||
$q->where('nama', 'like', '%' . $request->cari . '%');
|
||||
});
|
||||
}
|
||||
|
||||
$data_spp = $query->orderBy('tahun', 'desc')
|
||||
->orderBy('bulan', 'desc')
|
||||
->get();
|
||||
|
||||
$stats = [
|
||||
'lunas' => Spp::where('status', 'lunas')->count(),
|
||||
'pending' => Spp::where('status', 'pending')->count(),
|
||||
'belum_bayar' => Spp::where('status', 'belum_bayar')->count(),
|
||||
'total_pemasukan' => Spp::where('status', 'lunas')->sum('nominal')
|
||||
];
|
||||
|
||||
return view('spp.pengurus.index', compact('data_spp', 'stats'));
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
// Pastikan nama kolom di database adalah 'nama', bukan 'nama_lengkap' (sesuai diskusi sebelumnya)
|
||||
$data_anggota = Anggota::orderBy('nama_lengkap', 'asc')->get();
|
||||
return view('spp.pengurus.create', compact('data_anggota'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'anggota_id' => 'required|exists:anggotas,id',
|
||||
'bulan' => 'required',
|
||||
'tahun' => 'required',
|
||||
'nominal' => 'required|numeric',
|
||||
'jatuh_tempo' => 'required|date',
|
||||
]);
|
||||
|
||||
try {
|
||||
$anggota = Anggota::findOrFail($request->anggota_id);
|
||||
|
||||
Spp::create([
|
||||
'anggota_id' => $request->anggota_id,
|
||||
'kolat_id' => $anggota->kolat_id,
|
||||
'bulan' => $request->bulan,
|
||||
'tahun' => $request->tahun,
|
||||
'nominal' => $request->nominal,
|
||||
'jatuh_tempo' => $request->jatuh_tempo,
|
||||
'status' => 'belum_bayar',
|
||||
]);
|
||||
|
||||
return redirect()->route('spp.index')->with('success', 'Tagihan berhasil dibuat!');
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()->withInput()->with('error', 'Gagal menyimpan: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function bayar(Request $request, $id)
|
||||
{
|
||||
// Perbaikan: Pakai 'anggota' (singular) sesuai relasi model biasanya
|
||||
$spp = Spp::with('anggota')->findOrFail($id);
|
||||
|
||||
if ($spp->status == 'lunas') {
|
||||
return redirect()->back()->with('error', 'Tagihan ini sudah lunas.');
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$saldo_terakhir = Kas::saldoTerakhir() ?? 0;
|
||||
$saldo_baru = $saldo_terakhir + $spp->nominal;
|
||||
|
||||
$kas = Kas::create([
|
||||
'tanggal' => now(),
|
||||
'jenis' => 'masuk',
|
||||
'kategori' => 'SPP',
|
||||
'nominal' => $spp->nominal,
|
||||
'keterangan' => "Bayar SPP " . $spp->anggota->nama . " - " . $spp->bulan . " " . $spp->tahun,
|
||||
'saldo_akhir' => $saldo_baru
|
||||
]);
|
||||
|
||||
$spp->update([
|
||||
'status' => 'lunas',
|
||||
'tanggal_bayar' => now(),
|
||||
'kas_id' => $kas->id
|
||||
]);
|
||||
|
||||
DB::commit();
|
||||
return redirect()->back()->with('success', 'Pembayaran SPP berhasil dicatat!');
|
||||
} catch (\Exception $e) {
|
||||
DB::rollback();
|
||||
return redirect()->back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function generateTagihan(Request $request)
|
||||
{
|
||||
$bulanIni = Carbon::now()->translatedFormat('F');
|
||||
$tahunIni = Carbon::now()->year;
|
||||
$jatuhTempo = Carbon::now()->day(10);
|
||||
|
||||
$anggota = Anggota::all();
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
foreach ($anggota as $agt) {
|
||||
$exists = Spp::where('anggota_id', $agt->id)
|
||||
->where('bulan', $bulanIni)
|
||||
->where('tahun', $tahunIni)
|
||||
->exists();
|
||||
|
||||
if (!$exists) {
|
||||
Spp::create([
|
||||
'anggota_id' => $agt->id,
|
||||
'kolat_id' => $agt->kolat_id,
|
||||
'bulan' => $bulanIni,
|
||||
'tahun' => $tahunIni,
|
||||
'nominal' => 50000,
|
||||
'jatuh_tempo' => $jatuhTempo,
|
||||
'status' => 'belum_bayar',
|
||||
]);
|
||||
}
|
||||
}
|
||||
DB::commit();
|
||||
return redirect()->route('spp.index')->with('success', "Tagihan berhasil dibuat!");
|
||||
} catch (\Exception $e) {
|
||||
DB::rollback();
|
||||
return redirect()->back()->with('error', 'Gagal: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -54,4 +54,5 @@ public function user()
|
|||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Kas extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'kas';
|
||||
|
||||
protected $fillable = [
|
||||
'tanggal',
|
||||
'jenis',
|
||||
'kategori',
|
||||
'nominal',
|
||||
'keterangan',
|
||||
'saldo_akhir'
|
||||
];
|
||||
|
||||
/**
|
||||
* Scope untuk mendapatkan saldo terakhir.
|
||||
* Ini akan memudahkan kamu saat ingin menghitung saldo baru.
|
||||
*/
|
||||
public static function saldoTerakhir()
|
||||
{
|
||||
$last = self::orderBy('id', 'desc')->first();
|
||||
return $last ? $last->saldo_akhir : 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,16 +8,18 @@
|
|||
class Penilaian extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $fillable = [
|
||||
'pelatih_id',
|
||||
'anggota_id',
|
||||
'bulan_evaluasi',
|
||||
'kedisiplinan',
|
||||
'kejelasan_materi',
|
||||
'penguasaan_teknik',
|
||||
'sikap_perilaku',
|
||||
'kritik_saran'
|
||||
];
|
||||
protected $fillable = [
|
||||
'pelatih_id',
|
||||
'anggota_id',
|
||||
'bulan_evaluasi',
|
||||
'metode_pelatihan',
|
||||
'komunikasi',
|
||||
'sikap_kepribadian',
|
||||
'kepemimpinan',
|
||||
'konsistensi_komitmen',
|
||||
'kedekatan_interpersonal',
|
||||
'kritik_saran'
|
||||
];
|
||||
|
||||
// Relasi: Siapa pelatih yang sedang dinilai?
|
||||
public function pelatih()
|
||||
|
|
@ -30,4 +32,29 @@ public function penilai()
|
|||
{
|
||||
return $this->belongsTo(Anggota::class, 'anggota_id');
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$pelatih = Anggota::with('kolat')->findOrFail($id);
|
||||
|
||||
// Hitung rata-rata tiap kriteria bulan ini
|
||||
$rekap = Penilaian::where('pelatih_id', $id)
|
||||
->whereMonth('bulan_evaluasi', now()->month)
|
||||
->selectRaw('
|
||||
AVG(metode_pelatihan) as avg_metode,
|
||||
AVG(komunikasi) as avg_komunikasi,
|
||||
AVG(sikap_kepribadian) as avg_sikap,
|
||||
AVG(kepemimpinan) as avg_kepemimpinan,
|
||||
AVG(konsistensi_komitmen) as avg_komitmen,
|
||||
AVG(kedekatan_interpersonal) as avg_interpersonal
|
||||
')->first();
|
||||
|
||||
// Ambil ulasan/kritik saran (Pluck agar anonim)
|
||||
$ulasan = Penilaian::where('pelatih_id', $id)
|
||||
->whereMonth('bulan_evaluasi', now()->month)
|
||||
->whereNotNull('kritik_saran')
|
||||
->pluck('kritik_saran');
|
||||
|
||||
return view('penilaian.rekap', compact('pelatih', 'rekap', 'ulasan'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Spp extends Model
|
||||
{
|
||||
protected $table = 'spp';
|
||||
protected $fillable = [
|
||||
'anggota_id',
|
||||
'kolat_id',
|
||||
'kas_id',
|
||||
'bulan',
|
||||
'tahun',
|
||||
'nominal',
|
||||
'status',
|
||||
'jatuh_tempo',
|
||||
'keterangan'
|
||||
];
|
||||
|
||||
// Relasi ke Anggota
|
||||
public function anggota()
|
||||
{
|
||||
return $this->belongsTo(Anggota::class);
|
||||
}
|
||||
|
||||
// Relasi ke Kolat
|
||||
public function kolat()
|
||||
{
|
||||
return $this->belongsTo(Kolat::class);
|
||||
}
|
||||
|
||||
// Relasi ke Kas
|
||||
public function kas()
|
||||
{
|
||||
return $this->belongsTo(Kas::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,6 @@ public function up(): void
|
|||
{
|
||||
Schema::create('anggotas', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
// --- RELASI (Penghubung ke Dropdown) ---
|
||||
$table->foreignId('role_id')->constrained('role')->onDelete('cascade');
|
||||
$table->foreignId('kolat_id')->constrained('kolat')->onDelete('cascade');
|
||||
|
|
|
|||
|
|
@ -13,16 +13,19 @@ public function up(): void
|
|||
{
|
||||
Schema::create('penilaians', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('pelatih_id')->constrained('anggotas')->onDelete('cascade'); // Pelatih yang dinilai
|
||||
$table->foreignId('anggota_id')->constrained('anggotas')->onDelete('cascade'); // Anggota yang menilai
|
||||
$table->date('bulan_evaluasi'); // Untuk menandai evaluasi bulan apa
|
||||
$table->foreignId('pelatih_id')->constrained('anggotas')->onDelete('cascade');
|
||||
$table->foreignId('anggota_id')->constrained('anggotas')->onDelete('cascade');
|
||||
$table->date('bulan_evaluasi');
|
||||
|
||||
// Kriteria Evaluasi Pelatih (Skala 1-5 atau 1-10)
|
||||
$table->integer('kedisiplinan')->default(0);
|
||||
$table->integer('kejelasan_materi')->default(0);
|
||||
$table->integer('penguasaan_teknik')->default(0);
|
||||
$table->integer('sikap_perilaku')->default(0); // Etika pelatih
|
||||
$table->text('kritik_saran')->nullable(); // Masukan dari anggota
|
||||
// 6 Kriteria Evaluasi Hasil Wawancara (Skala 1-5)
|
||||
$table->integer('metode_pelatihan')->default(0);
|
||||
$table->integer('komunikasi')->default(0);
|
||||
$table->integer('sikap_kepribadian')->default(0);
|
||||
$table->integer('kepemimpinan')->default(0);
|
||||
$table->integer('konsistensi_komitmen')->default(0);
|
||||
$table->integer('kedekatan_interpersonal')->default(0);
|
||||
|
||||
$table->text('kritik_saran')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
<?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('kas', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->date('tanggal');
|
||||
$table->enum('jenis', ['masuk', 'keluar']);
|
||||
// Kategori untuk membedakan asal uang (SPP, Seragam, Operasional, dll)
|
||||
$table->string('kategori');
|
||||
$table->decimal('nominal', 15, 2);
|
||||
$table->text('keterangan')->nullable();
|
||||
|
||||
// Saldo akhir disimpan per baris transaksi agar history saldo terlihat jelas
|
||||
$table->decimal('saldo_akhir', 15, 2)->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('kas');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?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('spp', function (Blueprint $table) {
|
||||
$table->id();
|
||||
// Gunakan nama tabel sesuai yang ada di Schema::create tabel tujuan
|
||||
$table->foreignId('anggota_id')->constrained('anggotas')->onDelete('cascade');
|
||||
$table->foreignId('kolat_id')->constrained('kolat')->onDelete('cascade');
|
||||
$table->foreignId('kas_id')->nullable()->constrained('kas')->onDelete('set null');
|
||||
|
||||
$table->string('bulan');
|
||||
$table->year('tahun');
|
||||
$table->date('jatuh_tempo');
|
||||
$table->integer('nominal');
|
||||
$table->enum('status', ['lunas', 'pending', 'belum_bayar']);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('spp');
|
||||
}
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
|
|
@ -62,7 +62,7 @@
|
|||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">No. WhatsApp</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0">+62</span>
|
||||
|
||||
<input type="number" name="no_hp" class="form-control" value="{{ old('no_hp', $anggota->no_hp ?? '') }}" placeholder="81234567xxx" required>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
@section('content')
|
||||
<div class="container-fluid py-4">
|
||||
<<<<<<< Updated upstream
|
||||
<!-- Header & Breadcrumb -->
|
||||
=======
|
||||
>>>>>>> Stashed changes
|
||||
<div class="page-header mb-4 text-start">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb bg-transparent p-0 mb-2">
|
||||
|
|
@ -20,183 +16,43 @@ class="text-muted text-decoration-none small">Daftar Anggota</a></li>
|
|||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<<<<<<< Updated upstream
|
||||
<!-- Form Start - Pastikan enctype ada untuk upload foto SK -->
|
||||
=======
|
||||
>>>>>>> Stashed changes
|
||||
<form action="{{ route('anggota.update', $anggota->id) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
<!-- CARD 1: INFORMASI PRIBADI -->
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
||||
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Informasi Pribadi</h5>
|
||||
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Informasi Akun & Pribadi</h5>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">No Induk</label>
|
||||
<input type="text" name="no_induk" class="form-control bg-light fw-bold text-primary"
|
||||
value="{{ $anggota->no_induk }}" readonly>
|
||||
<small class="text-muted" style="font-size: 11px;">* No. induk permanen dan tidak dapat
|
||||
diubah</small>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">Nama Lengkap</label>
|
||||
<input type="text" name="nama_lengkap" class="form-control bg-light"
|
||||
value="{{ $anggota->nama_lengkap }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">No. WhatsApp (HP)</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0">+62</span>
|
||||
<input type="number" name="no_hp" class="form-control"
|
||||
value="{{ $anggota->no_hp }}" placeholder="81234567xxx" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">Alamat Lengkap</label>
|
||||
<input type="text" name="alamat" class="form-control" value="{{ $anggota->alamat }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CARD 2: INFORMASI ORGANISASI -->
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
||||
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||
<h5 class="fw-bold text-success mb-0"><i class="icon-badge me-2"></i>Informasi Organisasi</h5>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Jabatan Organisasi</label>
|
||||
<select name="jabatan" id="jabatanSelect" class="form-select border-primary"
|
||||
onchange="toggleSKFields()" required>
|
||||
<option value="anggota" {{ $anggota->jabatan == 'anggota' ? 'selected' : '' }}>
|
||||
Anggota</option>
|
||||
<option value="pelatih" {{ $anggota->jabatan == 'pelatih' ? 'selected' : '' }}>
|
||||
Pelatih</option>
|
||||
<option value="pengurus" {{ $anggota->jabatan == 'pengurus' ? 'selected' : '' }}>
|
||||
Pengurus</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Tingkatan</label>
|
||||
<input type="text" name="tingkatan" class="form-control"
|
||||
value="{{ $anggota->tingkatan }}" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Status Anggota</label>
|
||||
<select name="status" class="form-select" required>
|
||||
<option value="Aktif" {{ $anggota->status == 'Aktif' ? 'selected' : '' }}>Aktif
|
||||
</option>
|
||||
<option value="Non-Aktif" {{ $anggota->status == 'Non-Aktif' ? 'selected' : '' }}>
|
||||
Non-Aktif</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- BOX DATA SK (Otomatis muncul jika pilih Pelatih/Pengurus) -->
|
||||
<div id="boxSK"
|
||||
class="col-12 mt-3 p-4 bg-light rounded-4 border border-dashed border-danger"
|
||||
style="display: none;">
|
||||
<h6 class="text-danger fw-bold mb-3"><i class="icon-certificate me-2"></i>Data Legalitas
|
||||
SK (Wajib diisi untuk Pelatih/Pengurus)</h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold">Nomor SK</label>
|
||||
<input type="text" name="no_sk" class="form-control"
|
||||
value="{{ $anggota->no_sk ?? '' }}" placeholder="Contoh: SK/001/2026">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold">Tanggal SK</label>
|
||||
<input type="date" name="tgl_sk" class="form-control"
|
||||
value="{{ $anggota->tgl_sk ?? '' }}">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold">Masa Berlaku</label>
|
||||
<input type="date" name="masa_berlaku" class="form-control"
|
||||
value="{{ $anggota->masa_berlaku ?? '' }}">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold">Upload Scan SK</label>
|
||||
<input type="file" name="foto_sk" class="form-control">
|
||||
@if ($anggota->foto_sk)
|
||||
<small class="text-muted mt-1 d-block">File:
|
||||
{{ $anggota->foto_sk }}</small>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- <div class="col-md-12 mt-3">
|
||||
<label class="form-label fw-bold">Asal Kolat</label>
|
||||
<input type="text" name="asal_kolat" class="form-control" value="{{ $anggota->asal_kolat }}" required>
|
||||
</div> --}}
|
||||
<div class="col-md-12 mt-3">
|
||||
<label class="form-label fw-bold">Asal Kolat</label>
|
||||
<select name="kolat_id" class="form-select" required>
|
||||
<option value="" disabled>-- Pilih Kolat --</option>
|
||||
@foreach ($data_kolat as $kolat)
|
||||
<option value="{{ $kolat->id }}"
|
||||
{{ $anggota->kolat_id == $kolat->id ? 'selected' : '' }}>
|
||||
{{ $kolat->nama_kolat }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FOOTER CARD UNTUK BUTTON -->
|
||||
<div class="card-footer bg-light border-0 p-4" style="border-radius: 0 0 20px 20px;">
|
||||
<div class="d-flex justify-content-end align-items-center gap-3">
|
||||
<a href="{{ route('anggota.anggota') }}"
|
||||
class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
||||
<i class="icon-x me-1"></i> Batal
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">
|
||||
<i class="icon-check me-1"></i> Simpan Perubahan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
=======
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
||||
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Informasi Pribadi & Akun</h5>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">No Induk</label>
|
||||
<input type="text" class="form-control bg-light fw-bold text-primary"
|
||||
value="{{ $anggota->no_induk }}" readonly>
|
||||
<small class="text-muted" style="font-size: 11px;">* No. induk permanen</small>
|
||||
<label class="form-label fw-bold">Alamat Email (Login)</label>
|
||||
<input type="email" name="email" class="form-control"
|
||||
value="{{ old('email', $anggota->user->email ?? '') }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">Nama Lengkap</label>
|
||||
<input type="text" name="nama_lengkap" class="form-control"
|
||||
value="{{ old('nama_lengkap', $anggota->nama_lengkap) }}" required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">Alamat Email (Login)</label>
|
||||
<input type="email" name="email" class="form-control"
|
||||
value="{{ old('email', $anggota->user->email ?? '') }}" required>
|
||||
<small class="text-muted" style="font-size: 11px;">* Email digunakan untuk masuk ke sistem</small>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">No Induk</label>
|
||||
<input type="text" class="form-control bg-light fw-bold text-primary"
|
||||
value="{{ $anggota->no_induk }}" readonly>
|
||||
<small class="text-muted" style="font-size: 11px;">* No. induk permanen</small>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">No. WhatsApp (HP)</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0">+62</span>
|
||||
<input type="number" name="no_hp" class="form-control"
|
||||
value="{{ old('no_hp', $anggota->no_hp) }}" placeholder="81234567xxx" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">No. WhatsApp</label>
|
||||
<input type="number" name="no_hp" class="form-control"
|
||||
value="{{ old('no_hp', $anggota->no_hp) }}" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Jenis Kelamin</label>
|
||||
<select name="jenis_kelamin" class="form-select" required>
|
||||
<option value="L" {{ $anggota->jenis_kelamin == 'L' ? 'selected' : '' }}>Laki-laki</option>
|
||||
<option value="P" {{ $anggota->jenis_kelamin == 'P' ? 'selected' : '' }}>Perempuan</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-bold">Alamat Lengkap</label>
|
||||
|
|
@ -214,51 +70,40 @@ class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
|||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Jabatan / Role</label>
|
||||
<select name="role_id" id="roleSelect" class="form-select border-primary"
|
||||
onchange="toggleSKFields()" required>
|
||||
<option value="" disabled>-- Pilih Jabatan --</option>
|
||||
@foreach ($data_role as $role)
|
||||
<option value="{{ $role->id }}"
|
||||
{{ old('role_id', $anggota->role_id) == $role->id ? 'selected' : '' }}>
|
||||
<select name="role_id" id="roleSelect" class="form-select border-primary" onchange="toggleSKFields()" required>
|
||||
@foreach($data_role as $role)
|
||||
<option value="{{ $role->id }}" {{ $anggota->role_id == $role->id ? 'selected' : '' }}>
|
||||
{{ $role->nama_role }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Tingkatan Sabuk</label>
|
||||
<input type="text" name="tingkatan" class="form-control"
|
||||
value="{{ old('tingkatan', $anggota->tingkatan) }}" required>
|
||||
<label class="form-label fw-bold">Tingkatan</label>
|
||||
<input type="text" name="tingkatan" class="form-control" value="{{ $anggota->tingkatan }}" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Status Anggota</label>
|
||||
<select name="status" class="form-select" required>
|
||||
<option value="aktif" {{ old('status', $anggota->status) == 'aktif' ? 'selected' : '' }}>Aktif</option>
|
||||
<option value="Non-Aktif" {{ old('status', $anggota->status) == 'Non-Aktif' ? 'selected' : '' }}>Non-Aktif</option>
|
||||
<option value="Aktif" {{ $anggota->status == 'Aktif' ? 'selected' : '' }}>Aktif</option>
|
||||
<option value="Non-Aktif" {{ $anggota->status == 'Non-Aktif' ? 'selected' : '' }}>Non-Aktif</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="boxSK"
|
||||
class="col-12 mt-3 p-4 bg-light rounded-4 border border-dashed border-danger"
|
||||
style="display: none;">
|
||||
<h6 class="text-danger fw-bold mb-3"><i class="icon-certificate me-2"></i>Data Legalitas SK</h6>
|
||||
<div id="boxSK" class="col-12 mt-3 p-4 bg-light rounded-4 border border-dashed border-danger" style="display: none;">
|
||||
<h6 class="text-danger fw-bold mb-3"><i class="icon-certificate me-2"></i>Legalitas SK</h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-bold">Nomor SK</label>
|
||||
<input type="text" name="no_sk" class="form-control"
|
||||
value="{{ old('no_sk', $anggota->no_sk) }}" placeholder="Contoh: SK/001/2026">
|
||||
<input type="text" name="no_sk" class="form-control" value="{{ $anggota->no_sk }}">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-bold">Masa Berlaku SK</label>
|
||||
<input type="date" name="masa_berlaku" class="form-control"
|
||||
value="{{ old('masa_berlaku', $anggota->masa_berlaku) }}">
|
||||
<label class="form-label small fw-bold">Masa Berlaku</label>
|
||||
<input type="date" name="masa_berlaku" class="form-control" value="{{ $anggota->masa_berlaku }}">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-bold">Update File SK (Opsional)</label>
|
||||
<label class="form-label small fw-bold">Update Foto SK</label>
|
||||
<input type="file" name="foto_sk" class="form-control">
|
||||
@if ($anggota->foto_sk)
|
||||
<small class="text-primary mt-1 d-block"><i class="icon-eye"></i> File saat ini: {{ $anggota->foto_sk }}</small>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -266,10 +111,8 @@ class="col-12 mt-3 p-4 bg-light rounded-4 border border-dashed border-danger"
|
|||
<div class="col-md-12 mt-3">
|
||||
<label class="form-label fw-bold">Asal Kolat</label>
|
||||
<select name="kolat_id" class="form-select" required>
|
||||
<option value="" disabled>-- Pilih Kolat --</option>
|
||||
@foreach ($data_kolat as $kolat)
|
||||
<option value="{{ $kolat->id }}"
|
||||
{{ old('kolat_id', $anggota->kolat_id) == $kolat->id ? 'selected' : '' }}>
|
||||
<option value="{{ $kolat->id }}" {{ $anggota->kolat_id == $kolat->id ? 'selected' : '' }}>
|
||||
{{ $kolat->nama_kolat }}
|
||||
</option>
|
||||
@endforeach
|
||||
|
|
@ -279,117 +122,29 @@ class="col-12 mt-3 p-4 bg-light rounded-4 border border-dashed border-danger"
|
|||
</div>
|
||||
|
||||
<div class="card-footer bg-light border-0 p-4" style="border-radius: 0 0 20px 20px;">
|
||||
<div class="d-flex justify-content-end align-items-center gap-3">
|
||||
<a href="{{ route('anggota.anggota') }}"
|
||||
class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
||||
<i class="icon-x me-1"></i> Batal
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">
|
||||
<i class="icon-check me-1"></i> Simpan Perubahan
|
||||
</button>
|
||||
<div class="d-flex justify-content-end gap-3">
|
||||
<a href="{{ route('anggota.anggota') }}" class="btn btn-outline-secondary px-4 fw-bold btn-cancel">Batal</a>
|
||||
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">Simpan Perubahan</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
>>>>>>> Stashed changes
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
<!-- JAVASCRIPT TOGGLE -->
|
||||
<script>
|
||||
function toggleSKFields() {
|
||||
const jabatan = document.getElementById('jabatanSelect').value;
|
||||
const roleSelect = document.getElementById('roleSelect');
|
||||
const selectedText = roleSelect.options[roleSelect.selectedIndex].text.toLowerCase();
|
||||
const boxSK = document.getElementById('boxSK');
|
||||
|
||||
if (jabatan === 'pelatih' || jabatan === 'pengurus') {
|
||||
if (selectedText.includes('pelatih') || selectedText.includes('pengurus')) {
|
||||
boxSK.style.display = 'block';
|
||||
} else {
|
||||
boxSK.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Jalankan saat pertama kali halaman dimuat
|
||||
=======
|
||||
<script>
|
||||
function toggleSKFields() {
|
||||
const roleSelect = document.getElementById('roleSelect');
|
||||
const boxSK = document.getElementById('boxSK');
|
||||
|
||||
if (roleSelect.selectedIndex >= 0) {
|
||||
const selectedText = roleSelect.options[roleSelect.selectedIndex].text.toLowerCase();
|
||||
|
||||
if (selectedText.includes('pelatih') || selectedText.includes('pengurus')) {
|
||||
boxSK.style.display = 'block';
|
||||
} else {
|
||||
boxSK.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
toggleSKFields();
|
||||
});
|
||||
document.addEventListener("DOMContentLoaded", toggleSKFields);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<<<<<<< Updated upstream
|
||||
.form-control,
|
||||
.form-select {
|
||||
border-radius: 10px;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.form-control:focus,
|
||||
.form-select:focus {
|
||||
=======
|
||||
.form-control, .form-select {
|
||||
border-radius: 10px;
|
||||
padding: 10px 15px;
|
||||
border: 1px solid #dce1e7;
|
||||
}
|
||||
|
||||
.form-control:focus, .form-select:focus {
|
||||
>>>>>>> Stashed changes
|
||||
border-color: #0d6efd;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.1);
|
||||
}
|
||||
|
||||
.btn-cancel {
|
||||
border-radius: 12px;
|
||||
<<<<<<< Updated upstream
|
||||
transition: all 0.3s ease;
|
||||
border: 2px solid #6c757d;
|
||||
}
|
||||
|
||||
.btn-cancel:hover {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-save {
|
||||
border-radius: 12px;
|
||||
background: (45deg, #0d6efd);
|
||||
border: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-save:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(13, 110, 253, 0.4) !important;
|
||||
=======
|
||||
border: 2px solid #6c757d;
|
||||
}
|
||||
|
||||
.btn-save {
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(45deg, #0d6efd, #004dc0);
|
||||
border: none;
|
||||
color: white;
|
||||
>>>>>>> Stashed changes
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -0,0 +1,339 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid py-4">
|
||||
<!-- Header Section -->
|
||||
<div class="page-header mb-4 text-start">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb bg-transparent p-0 mb-2">
|
||||
<li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Home</a></li>
|
||||
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Kas Cabang</li>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class="text-start">
|
||||
<h3 class="fw-bold text-dark mb-1">Buku Kas Digital</h3>
|
||||
<p class="text-muted small">Pantau arus kas masuk dan keluar secara real-time.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success alert-dismissible fade show border-0 shadow-sm mb-4" role="alert" style="border-radius: 15px;">
|
||||
<i class="bi bi-check-circle-fill me-2"></i> <strong>Berhasil!</strong> {{ session('success') }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Row Statistik Utama -->
|
||||
<div class="row mb-4 g-3 text-start">
|
||||
<div class="col-md-4">
|
||||
<div class="card border-0 shadow-sm text-white h-100 overflow-hidden"
|
||||
style="border-radius: 20px; background: linear-gradient(45deg, #0d6efd, #00c6ff);">
|
||||
<div class="card-body p-4 position-relative">
|
||||
<p class="mb-1 small opacity-75">Saldo Kas Saat Ini</p>
|
||||
<h2 class="fw-bold mb-0 text-nowrap">Rp {{ number_format((float)$saldo_sekarang, 0, ',', '.') }}</h2>
|
||||
<i class="icon-wallet position-absolute opacity-25" style="font-size: 80px; right: -10px; bottom: -10px;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card border-0 shadow-sm h-100 border-start border-success border-4" style="border-radius: 15px;">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-success-soft rounded-3 p-3 me-3">
|
||||
<i class="icon-login text-success fs-4"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-0 text-muted small fw-bold uppercase">Pemasukan (Bulan Ini)</p>
|
||||
<h4 class="fw-bold text-success mb-0">Rp {{ number_format((float)$pemasukan_bulan_ini, 0, ',', '.') }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card border-0 shadow-sm h-100 border-start border-danger border-4" style="border-radius: 15px;">
|
||||
<div class="card-body p-4 text-start">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-danger-soft rounded-3 p-3 me-3 text-start">
|
||||
<i class="icon-logout text-danger fs-4"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-0 text-muted small fw-bold uppercase text-start">Pengeluaran (Bulan Ini)</p>
|
||||
<h4 class="fw-bold text-danger mb-0 text-start">Rp {{ number_format((float)$pengeluaran_bulan_ini, 0, ',', '.') }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section Tabel -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm p-2" style="border-radius: 20px;">
|
||||
<div class="card-body p-4">
|
||||
|
||||
<!-- Header Tabel -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 text-start">
|
||||
<div class="text-start">
|
||||
<h5 class="card-title mb-0 fw-bold text-dark">Buku Kas Utama</h5>
|
||||
<p class="text-muted small mb-0">Cabang Jember - Histori seluruh arus kas.</p>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<!-- DROPDOWN FILTER -->
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-light border px-4 py-2 dropdown-toggle shadow-sm"
|
||||
type="button" id="filterDropdown" data-bs-toggle="dropdown"
|
||||
aria-expanded="false" style="border-radius: 12px;">
|
||||
<i class="icon-filter me-1"></i> Filter Data
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end p-4 shadow-lg border-0"
|
||||
aria-labelledby="filterDropdown" style="width: 300px; border-radius: 20px;">
|
||||
|
||||
<form action="{{ route('kas.index') }}" method="GET">
|
||||
<h6 class="fw-bold mb-3">Saring Transaksi</h6>
|
||||
<div class="mb-3 text-start">
|
||||
<label class="form-label small fw-bold">Jenis Kas</label>
|
||||
<select name="jenis" class="form-select border-0 bg-light" style="border-radius: 10px;">
|
||||
<option value="">Semua Jenis</option>
|
||||
<option value="masuk" {{ request('jenis') == 'masuk' ? 'selected' : '' }}>Pemasukan</option>
|
||||
<option value="keluar" {{ request('jenis') == 'keluar' ? 'selected' : '' }}>Pengeluaran</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3 text-start">
|
||||
<label class="form-label small fw-bold">Dari Tanggal</label>
|
||||
<input type="date" name="dari" value="{{ request('dari') }}" class="form-control border-0 bg-light" style="border-radius: 10px;">
|
||||
</div>
|
||||
<div class="mb-3 text-start">
|
||||
<label class="form-label small fw-bold">Sampai Tanggal</label>
|
||||
<input type="date" name="sampai" value="{{ request('sampai') }}" class="form-control border-0 bg-light" style="border-radius: 10px;">
|
||||
</div>
|
||||
<div class="d-grid gap-2 mt-4">
|
||||
<button type="submit" class="btn btn-primary shadow-sm" style="border-radius: 10px;">Terapkan</button>
|
||||
<a href="{{ route('kas.index') }}" class="btn btn-link btn-sm text-decoration-none text-muted">Hapus Filter</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TOMBOL CATAT TRANSAKSI -->
|
||||
<button type="button" class="btn btn-primary px-4 py-2 shadow-sm pulse-button"
|
||||
style="border-radius: 12px;" data-bs-toggle="modal" data-bs-target="#modalTambahKas">
|
||||
<i class="icon-plus me-1"></i> Catat Transaksi
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Label Filter Aktif -->
|
||||
@if(request('dari') || request('sampai') || request('jenis'))
|
||||
<div class="mb-3 text-start">
|
||||
<span class="small text-muted">Filter Aktif: </span>
|
||||
@if(request('jenis')) <span class="badge bg-primary rounded-pill px-3">{{ strtoupper(request('jenis')) }}</span> @endif
|
||||
@if(request('dari')) <span class="badge bg-light text-dark border rounded-pill px-3">Sejak: {{ request('dari') }}</span> @endif
|
||||
<a href="{{ route('kas.index') }}" class="text-danger small ms-2 text-decoration-none"><i class="icon-close"></i> Bersihkan</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle main-table border-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="60" class="text-center">#</th>
|
||||
<th class="text-start">Keterangan Transaksi</th>
|
||||
<th class="text-center">Kategori</th>
|
||||
<th class="text-end">Nominal</th>
|
||||
<th class="text-end">Sisa Saldo</th>
|
||||
<th class="text-center">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($data_kas as $no => $item)
|
||||
<tr>
|
||||
<td class="text-center text-muted small">{{ $no + 1 }}</td>
|
||||
<td class="text-start">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="me-3 bg-{{ $item->jenis == 'masuk' ? 'success' : 'danger' }} rounded-circle p-2" style="width: 10px; height: 10px;"></div>
|
||||
<div>
|
||||
<div class="fw-bold text-dark text-start">{{ \Carbon\Carbon::parse($item->tanggal)->format('d/m/Y') }}</div>
|
||||
<div class="text-muted small text-start">{{ $item->keterangan ?? 'Tanpa keterangan' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="badge {{ $item->jenis == 'masuk' ? 'bg-success-soft text-success' : 'bg-danger-soft text-danger' }} border border-{{ $item->jenis == 'masuk' ? 'success' : 'danger' }} px-3 py-2" style="border-radius: 10px; font-size: 10px;">
|
||||
{{ strtoupper($item->kategori) }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-end fw-bold {{ $item->jenis == 'masuk' ? 'text-success' : 'text-danger' }} text-nowrap">
|
||||
{{ $item->jenis == 'masuk' ? '+' : '-' }} {{ number_format((float)$item->nominal, 0, ',', '.') }}
|
||||
</td>
|
||||
<td class="text-end fw-bold text-dark text-nowrap">
|
||||
Rp {{ number_format((float)$item->saldo_akhir, 0, ',', '.') }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="d-flex justify-content-center gap-2">
|
||||
<!-- Button Edit -->
|
||||
<button type="button" class="btn-action-custom btn-edit" data-bs-toggle="modal" data-bs-target="#modalEditKas{{ $item->id }}">
|
||||
<i class="icon-note"></i>
|
||||
</button>
|
||||
<!-- Form Hapus -->
|
||||
<form action="{{ route('kas.destroy', $item->id) }}" method="POST" id="form-hapus-{{ $item->id }}">
|
||||
@csrf @method('DELETE')
|
||||
<button type="button" class="btn-action-custom btn-delete" onclick="hapusKas('{{ $item->id }}')">
|
||||
<i class="icon-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- MODAL EDIT DI DALAM LOOP -->
|
||||
<div class="modal fade" id="modalEditKas{{ $item->id }}" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 shadow-lg" style="border-radius: 25px;">
|
||||
<div class="modal-header bg-dark text-white border-0 py-3 px-4" style="border-radius: 25px 25px 0 0;">
|
||||
<h5 class="modal-title fw-bold"><i class="icon-pencil me-2"></i>Edit Transaksi</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form action="{{ route('kas.update', $item->id) }}" method="POST">
|
||||
@csrf @method('PUT')
|
||||
<div class="modal-body p-4 text-start">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6 text-start">
|
||||
<label class="form-label small fw-bold">Tanggal</label>
|
||||
<input type="date" name="tanggal" value="{{ $item->tanggal }}" class="form-control custom-input" required>
|
||||
</div>
|
||||
<div class="col-md-6 text-start">
|
||||
<label class="form-label small fw-bold">Jenis Arus</label>
|
||||
<select name="jenis" class="form-select custom-input" required>
|
||||
<option value="masuk" {{ $item->jenis == 'masuk' ? 'selected' : '' }}>Pemasukan (+)</option>
|
||||
<option value="keluar" {{ $item->jenis == 'keluar' ? 'selected' : '' }}>Pengeluaran (-)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 text-start">
|
||||
<label class="form-label small fw-bold">Kategori</label>
|
||||
<input type="text" name="kategori" value="{{ $item->kategori }}" class="form-control custom-input" required>
|
||||
</div>
|
||||
<div class="col-12 text-start">
|
||||
<label class="form-label small fw-bold">Nominal (Rp)</label>
|
||||
<input type="number" name="nominal" value="{{ (float)$item->nominal }}" class="form-control custom-input" required>
|
||||
</div>
|
||||
<div class="col-12 text-start">
|
||||
<label class="form-label small fw-bold">Keterangan (Opsional)</label>
|
||||
<textarea name="keterangan" class="form-control custom-input" rows="2">{{ $item->keterangan }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer border-0 p-4 pt-0">
|
||||
<button type="button" class="btn btn-light px-4" data-bs-dismiss="modal" style="border-radius: 12px;">Batal</button>
|
||||
<button type="submit" class="btn btn-primary px-4 shadow-sm" style="border-radius: 12px;">Update Data</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5">
|
||||
<img src="https://illustrations.popsy.co/blue/no-data-found.svg" width="120" alt="no-data">
|
||||
<p class="text-muted small mt-3">Belum ada transaksi terekam.</p>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Tambah Kas -->
|
||||
<div class="modal fade" id="modalTambahKas" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 shadow-lg" style="border-radius: 25px;">
|
||||
<div class="modal-header bg-primary text-white border-0 py-3 px-4" style="border-radius: 25px 25px 0 0;">
|
||||
<h5 class="modal-title fw-bold"><i class="icon-plus me-2"></i>Catat Transaksi</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form action="{{ route('kas.store') }}" method="POST">
|
||||
@csrf
|
||||
<div class="modal-body p-4 text-start">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6 text-start">
|
||||
<label class="form-label small fw-bold">Tanggal</label>
|
||||
<input type="date" name="tanggal" value="{{ date('Y-m-d') }}" class="form-control custom-input" required>
|
||||
</div>
|
||||
<div class="col-md-6 text-start">
|
||||
<label class="form-label small fw-bold">Jenis Arus</label>
|
||||
<select name="jenis" class="form-select custom-input" required>
|
||||
<option value="masuk">Pemasukan (+)</option>
|
||||
<option value="keluar">Pengeluaran (-)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 text-start">
|
||||
<label class="form-label small fw-bold">Kategori</label>
|
||||
<input type="text" name="kategori" list="list-kategori-add" class="form-control custom-input" placeholder="Misal: SPP, Listrik" required>
|
||||
<datalist id="list-kategori-add">
|
||||
<option value="SPP"><option value="Operasional"><option value="Sumbangan">
|
||||
</datalist>
|
||||
</div>
|
||||
<div class="col-12 text-start">
|
||||
<label class="form-label small fw-bold">Nominal (Rp)</label>
|
||||
<input type="number" name="nominal" class="form-control custom-input" placeholder="0" required>
|
||||
</div>
|
||||
<div class="col-12 text-start">
|
||||
<label class="form-label small fw-bold">Keterangan (Opsional)</label>
|
||||
<textarea name="keterangan" class="form-control custom-input" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer border-0 p-4 pt-0">
|
||||
<button type="button" class="btn btn-light px-4" data-bs-dismiss="modal" style="border-radius: 12px;">Batal</button>
|
||||
<button type="submit" class="btn btn-primary px-4 shadow-sm" style="border-radius: 12px;">Simpan Data</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.bg-success-soft { background-color: #dcfce7; }
|
||||
.bg-danger-soft { background-color: #fee2e2; }
|
||||
.main-table thead th { background-color: #f8fafc; color: #64748b; font-size: 11px; text-transform: uppercase; padding: 15px; border-bottom: 2px solid #f1f5f9; }
|
||||
.main-table tbody td { padding: 15px; border-bottom: 1px solid #f1f5f9; }
|
||||
.custom-input { border-radius: 12px; border: 1px solid #e2e8f0; padding: 10px 15px; }
|
||||
|
||||
/* Button Action Styling */
|
||||
.btn-action-custom { width: 32px; height: 32px; border-radius: 8px; border: none; display: flex; align-items: center; justify-content: center; transition: 0.2s; }
|
||||
.btn-edit { background-color: #e6f7ff; color: #1890ff; }
|
||||
.btn-edit:hover { background-color: #1890ff; color: white; }
|
||||
.btn-delete { background-color: #fff1f0; color: #ff4d4f; }
|
||||
.btn-delete:hover { background-color: #ff4d4f; color: white; }
|
||||
|
||||
.pulse-button:hover { animation: pulse 1.5s infinite; }
|
||||
@keyframes pulse {
|
||||
0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(13, 110, 253, 0.4); }
|
||||
70% { transform: scale(1.05); box-shadow: 0 0 0 10px rgba(13, 110, 253, 0); }
|
||||
100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(13, 110, 253, 0); }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function hapusKas(id) {
|
||||
Swal.fire({
|
||||
title: 'Hapus Transaksi?',
|
||||
text: "Data akan dihapus permanen dan riwayat saldo akan terpengaruh.",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#dc3545',
|
||||
confirmButtonText: 'Ya, Hapus!',
|
||||
borderRadius: '20px'
|
||||
}).then((result) => { if (result.isConfirmed) { document.getElementById('form-hapus-' + id).submit(); } })
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -7,11 +7,11 @@
|
|||
<ol class="breadcrumb bg-transparent p-0 mb-2">
|
||||
<li class="breadcrumb-item"><a href="{{ route('pelatih.index') }}"
|
||||
class="text-muted text-decoration-none small">Daftar Pelatih</a></li>
|
||||
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Edit Data Pelatih</li>
|
||||
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Edit Pelatih</li>
|
||||
</ol>
|
||||
</nav>
|
||||
<h3 class="fw-bold text-dark">Form Edit Data Pelatih</h3>
|
||||
<p class="text-muted small">Perbarui informasi legalitas SK atau status kepelatihan untuk <strong>{{ $pelatih->nama_lengkap }}</strong>.</p>
|
||||
<p class="text-muted small">Perbarui profil pribadi dan legalitas SK pelatih <strong>{{ $pelatih->nama_lengkap }}</strong>.</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
|
@ -22,69 +22,91 @@ class="text-muted text-decoration-none small">Daftar Pelatih</a></li>
|
|||
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
||||
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Identitas Pelatih</h5>
|
||||
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Informasi Akun & Pribadi</h5>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">Alamat Email (Login)</label>
|
||||
<input type="email" name="email" class="form-control"
|
||||
value="{{ old('email', $pelatih->user->email ?? '') }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">Nama Lengkap</label>
|
||||
<input type="text" name="nama_lengkap" class="form-control"
|
||||
value="{{ old('nama_lengkap', $pelatih->nama_lengkap) }}" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">No Induk</label>
|
||||
<input type="text" class="form-control bg-light fw-bold"
|
||||
<input type="text" class="form-control bg-light fw-bold text-primary"
|
||||
value="{{ $pelatih->no_induk }}" readonly>
|
||||
<small class="text-muted" style="font-size: 11px;">* No. induk permanen</small>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Nama Lengkap</label>
|
||||
<input type="text" class="form-control bg-light"
|
||||
value="{{ $pelatih->nama_lengkap }}" readonly>
|
||||
<label class="form-label fw-bold">No. WhatsApp</label>
|
||||
<input type="number" name="no_hp" class="form-control"
|
||||
value="{{ old('no_hp', $pelatih->no_hp) }}" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Asal Kolat</label>
|
||||
<input type="text" class="form-control bg-light"
|
||||
value="{{ $pelatih->kolat->nama_kolat ?? '-' }}" readonly>
|
||||
<label class="form-label fw-bold">Jenis Kelamin</label>
|
||||
<select name="jenis_kelamin" class="form-select" required>
|
||||
<option value="L" {{ $pelatih->jenis_kelamin == 'L' ? 'selected' : '' }}>Laki-laki</option>
|
||||
<option value="P" {{ $pelatih->jenis_kelamin == 'P' ? 'selected' : '' }}>Perempuan</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-bold">Alamat Lengkap</label>
|
||||
<textarea name="alamat" class="form-control" rows="2" required>{{ old('alamat', $pelatih->alamat) }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted mt-2 d-block">* Data identitas di atas bersifat tetap. Ubah di menu Anggota jika terdapat kesalahan input nama/induk.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
||||
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||
<h5 class="fw-bold text-danger mb-0"><i class="icon-certificate me-2"></i>Legalitas & Masa Aktif SK</h5>
|
||||
<h5 class="fw-bold text-danger mb-0"><i class="icon-badge me-2"></i>Informasi Kepelatihan & SK</h5>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold">Nomor SK Kepelatihan</label>
|
||||
<input type="text" name="no_sk" class="form-control border-danger"
|
||||
value="{{ old('no_sk', $pelatih->no_sk) }}" placeholder="Contoh: SK/001/2026" required>
|
||||
@error('no_sk') <small class="text-danger">{{ $message }}</small> @enderror
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold">Tingkatan Sabuk</label>
|
||||
<input type="text" name="tingkatan" class="form-control"
|
||||
value="{{ old('tingkatan', $pelatih->tingkatan) }}" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-bold">Tanggal Terbit SK</label>
|
||||
<input type="date" name="tgl_sk" class="form-control"
|
||||
value="{{ old('tgl_sk', $pelatih->tgl_sk) }}" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-bold">Masa Berlaku</label>
|
||||
<input type="date" name="masa_berlaku" class="form-control"
|
||||
value="{{ old('masa_berlaku', $pelatih->masa_berlaku) }}" required>
|
||||
<div class="col-md-8">
|
||||
<label class="form-label fw-bold">Asal Kolat (Tempat Melatih)</label>
|
||||
<select name="kolat_id" class="form-select" required>
|
||||
@foreach ($data_kolat as $kolat)
|
||||
<option value="{{ $kolat->id }}" {{ $pelatih->kolat_id == $kolat->id ? 'selected' : '' }}>
|
||||
{{ $kolat->nama_kolat }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 mt-4">
|
||||
<div class="p-3 bg-light rounded-4 border">
|
||||
<label class="form-label fw-bold d-block">Update Scan SK (Format: JPG, PNG, PDF | Max: 2MB)</label>
|
||||
<input type="file" name="foto_sk" class="form-control mb-2">
|
||||
|
||||
@if ($pelatih->foto_sk)
|
||||
<div class="d-flex align-items-center mt-2">
|
||||
<i class="icon-file-text text-primary me-2"></i>
|
||||
<small class="text-muted">File saat ini:
|
||||
<a href="{{ asset('storage/' . $pelatih->foto_sk) }}" target="_blank" class="text-decoration-none">
|
||||
Lihat Dokumen SK <i class="icon-external-link"></i>
|
||||
</a>
|
||||
</small>
|
||||
</div>
|
||||
@else
|
||||
<small class="text-warning">Belum ada file SK yang diunggah.</small>
|
||||
<div class="col-12 mt-3 p-4 bg-light rounded-4 border border-dashed border-danger">
|
||||
<h6 class="text-danger fw-bold mb-3"><i class="icon-certificate me-2"></i>Legalitas SK Pelatih</h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-bold">Nomor SK</label>
|
||||
<input type="text" name="no_sk" class="form-control" value="{{ old('no_sk', $pelatih->no_sk) }}">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-bold">Masa Berlaku</label>
|
||||
<input type="date" name="masa_berlaku" class="form-control" value="{{ $pelatih->masa_berlaku }}">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-bold">Update File SK (PDF/JPG)</label>
|
||||
<input type="file" name="foto_sk" class="form-control">
|
||||
</div>
|
||||
@if($pelatih->foto_sk)
|
||||
<div class="col-12">
|
||||
<small class="text-muted">File SK saat ini:
|
||||
<a href="{{ asset('storage/' . $pelatih->foto_sk) }}" target="_blank" class="text-primary fw-bold text-decoration-none">
|
||||
Lihat Dokumen <i class="icon-external-link"></i>
|
||||
</a>
|
||||
</small>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -92,14 +114,9 @@ class="text-muted text-decoration-none small">Daftar Pelatih</a></li>
|
|||
</div>
|
||||
|
||||
<div class="card-footer bg-light border-0 p-4" style="border-radius: 0 0 20px 20px;">
|
||||
<div class="d-flex justify-content-end align-items-center gap-3">
|
||||
<a href="{{ route('pelatih.index') }}"
|
||||
class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
||||
<i class="icon-x me-1"></i> Batal
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">
|
||||
<i class="icon-check me-1"></i> Simpan Perubahan SK
|
||||
</button>
|
||||
<div class="d-flex justify-content-end gap-3">
|
||||
<a href="{{ route('pelatih.index') }}" class="btn btn-outline-secondary px-4 fw-bold btn-cancel">Batal</a>
|
||||
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">Simpan Perubahan Pelatih</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -109,39 +126,12 @@ class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
|||
</div>
|
||||
|
||||
<style>
|
||||
.form-control,
|
||||
.form-select {
|
||||
border-radius: 10px;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: #0d6efd;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.1);
|
||||
}
|
||||
|
||||
.btn-cancel {
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
border: 2px solid #6c757d;
|
||||
}
|
||||
|
||||
.btn-cancel:hover {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-save {
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(45deg, #0d6efd, #004fb1);
|
||||
border: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-save:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(13, 110, 253, 0.4) !important;
|
||||
}
|
||||
.form-control, .form-select { border-radius: 10px; padding: 10px 15px; }
|
||||
.form-control:focus { border-color: #4f46e5; box-shadow: 0 0 0 0.25rem rgba(79, 70, 229, 0.1); }
|
||||
.rounded-4 { border-radius: 15px !important; }
|
||||
.btn-cancel { border-radius: 12px; transition: all 0.3s ease; border: 2px solid #6c757d; }
|
||||
.btn-cancel:hover { background-color: #6c757d; color: white; transform: translateY(-2px); }
|
||||
.btn-save { border-radius: 12px; background: linear-gradient(45deg, #4f46e5, #3730a3); border: none; transition: all 0.3s ease; }
|
||||
.btn-save:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(79, 70, 229, 0.4) !important; }
|
||||
</style>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid py-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card border-0 shadow-sm" style="border-radius: 20px;">
|
||||
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||
<h5 class="fw-bold">Penilaian: <span class="text-primary">{{ $pelatih->nama_lengkap }}</span></h5>
|
||||
<p class="text-muted small">Kolat: {{ $pelatih->kolat->nama_kolat }} | Periode: {{ now()->format('F Y') }}</p>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<form action="{{ route('penilaian.store') }}" method="POST">
|
||||
@csrf
|
||||
<input type="hidden" name="pelatih_id" value="{{ $pelatih->id }}">
|
||||
|
||||
@php
|
||||
$kriterias = [
|
||||
'metode_pelatihan' => 'Metode Pelatihan',
|
||||
'komunikasi' => 'Komunikasi Pelatih & Anggota',
|
||||
'sikap_kepribadian' => 'Sikap & Kepribadian',
|
||||
'kepemimpinan' => 'Kepemimpinan',
|
||||
'konsistensi_komitmen' => 'Konsistensi & Komitmen',
|
||||
'kedekatan_interpersonal' => 'Kedekatan Interpersonal'
|
||||
];
|
||||
@endphp
|
||||
|
||||
@foreach($kriterias as $key => $label)
|
||||
<div class="mb-4 border-bottom pb-3">
|
||||
<label class="fw-bold d-block mb-2">{{ $label }}</label>
|
||||
<div class="d-flex gap-3">
|
||||
@foreach(range(1, 5) as $score)
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="{{ $key }}" id="{{ $key.$score }}" value="{{ $score }}" required>
|
||||
<label class="form-check-label" for="{{ $key.$score }}">{{ $score }} ★</label>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="fw-bold mb-2">Kritik & Saran (Opsional)</label>
|
||||
<textarea name="kritik_saran" class="form-control" rows="3" placeholder="Tulis masukan Anda di sini..." style="border-radius: 12px;"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary py-3 fw-bold" style="border-radius: 12px;">Kirim Penilaian Anonim</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid py-4">
|
||||
<div class="page-header mb-4 text-start">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb bg-transparent p-0 mb-2">
|
||||
<li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Home</a></li>
|
||||
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Penilaian Pelatih</li>
|
||||
</ol>
|
||||
</nav>
|
||||
<h3 class="fw-bold text-dark">SDM Merpati Putih</h3>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm" style="border-radius: 20px;">
|
||||
<div class="card-body p-4">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div class="text-start">
|
||||
<h5 class="card-title mb-0 fw-bold text-dark">Evaluasi Kinerja Pelatih</h5>
|
||||
<p class="text-muted small mb-0">Kelola penilaian bulanan berdasarkan kompetensi pelatih cabang.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success border-0 shadow-sm mb-4" style="border-radius: 12px;">
|
||||
<i class="bi bi-check-circle me-2"></i> {{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle main-table text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="60">No</th>
|
||||
<th>Identitas Pelatih</th>
|
||||
<th>No. SK & Masa Berlaku</th>
|
||||
<th>Kolat</th>
|
||||
<th>Status SK</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($data_pelatih as $no => $item)
|
||||
<tr>
|
||||
<td class="text-muted small text-center">{{ $no + 1 }}</td>
|
||||
<td>
|
||||
<div class="fw-bold text-dark text-center">{{ $item->nama_lengkap }}</div>
|
||||
<small class="text-muted d-block text-center">ID: {{ $item->no_induk }}</small>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="small fw-bold">{{ $item->no_sk ?? '-' }}</div>
|
||||
<div class="text-muted" style="font-size: 11px;">
|
||||
Hingga: {{ $item->masa_berlaku ? \Carbon\Carbon::parse($item->masa_berlaku)->format('d M Y') : '-' }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="badge bg-info-soft text-info px-3">{{ $item->kolat->nama_kolat ?? '-' }}</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
@php
|
||||
$isExpired = $item->masa_berlaku ? \Carbon\Carbon::now()->gt($item->masa_berlaku) : true;
|
||||
@endphp
|
||||
<span class="badge rounded-pill {{ !$isExpired ? 'bg-success-soft text-success' : 'bg-danger-soft text-danger' }} px-3 border">
|
||||
{{ !$isExpired ? 'Berlaku' : 'Expired' }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="d-flex justify-content-center gap-2">
|
||||
<a href="{{ route('penilaian.create', $item->id) }}"
|
||||
class="btn btn-sm btn-action-evaluate fw-bold px-3 shadow-xs">
|
||||
<i class="bi bi-star-fill me-1"></i> Beri Nilai
|
||||
</a>
|
||||
<a href="{{ route('penilaian.show', $item->id) }}" class="btn btn-sm btn-outline-primary fw-bold px-3 shadow-xs" style="border-radius:10px;">
|
||||
<i class="bi bi-bar-chart-fill"></i> Rekap
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5 text-muted">Data pelatih tidak ditemukan.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.main-table thead th {
|
||||
background-color: #f8faff;
|
||||
padding: 18px 10px;
|
||||
font-size: 0.75rem;
|
||||
color: #8c98a5;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
border-bottom: 2px solid #edf2f9;
|
||||
}
|
||||
.main-table tbody td {
|
||||
padding: 20px 10px;
|
||||
border-bottom: 1px solid #f1f4f8;
|
||||
color: #495057;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.bg-success-soft { background-color: #e6fffa; color: #38b2ac; }
|
||||
.bg-danger-soft { background-color: #fff5f5; color: #e53e3e; }
|
||||
.bg-info-soft { background-color: #e0f2fe; color: #0ea5e9; }
|
||||
|
||||
/* Style Tombol Beri Nilai (Warna Biru Indigo agar elegan) */
|
||||
.btn-action-evaluate {
|
||||
background-color: #eef2ff;
|
||||
color: #4f46e5;
|
||||
border: 1px solid #e0e7ff;
|
||||
border-radius: 10px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
.btn-action-evaluate:hover {
|
||||
background-color: #4f46e5 !important;
|
||||
color: white !important;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.shadow-xs { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); }
|
||||
</style>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Laporan Performa - {{ $pelatih->nama_lengkap }}</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; color: #333; line-height: 1.5; }
|
||||
.header { text-align: center; border-bottom: 2px solid #4f46e5; padding-bottom: 10px; margin-bottom: 20px; }
|
||||
.header h2 { margin: 0; color: #4f46e5; text-transform: uppercase; }
|
||||
.header p { margin: 5px 0 0; font-size: 12px; color: #666; }
|
||||
|
||||
.info-table { width: 100%; margin-bottom: 20px; font-size: 13px; }
|
||||
.info-table td { padding: 3px 0; }
|
||||
.label { font-weight: bold; width: 120px; }
|
||||
|
||||
.section-title { background: #f0f2f5; padding: 8px; font-weight: bold; font-size: 14px; margin: 20px 0 10px; border-left: 4px solid #4f46e5; }
|
||||
|
||||
table.data-table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }
|
||||
table.data-table th { background: #4f46e5; color: white; text-align: left; padding: 10px; font-size: 12px; }
|
||||
table.data-table td { padding: 10px; border-bottom: 1px solid #eee; font-size: 12px; }
|
||||
|
||||
.bar-container { background: #eee; width: 100%; height: 10px; border-radius: 5px; }
|
||||
.bar-fill { background: #4f46e5; height: 10px; border-radius: 5px; }
|
||||
|
||||
.ulasan-item { padding: 10px; border-bottom: 1px solid #f0f0f0; font-size: 11px; font-style: italic; }
|
||||
.footer { position: fixed; bottom: 0; width: 100%; text-align: center; font-size: 10px; color: #999; border-top: 1px solid #eee; padding-top: 5px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h2>LAPORAN EVALUASI PELATIH</h2>
|
||||
<p>PPS BETAKO MERPATI PUTIH - CABANG JEMBER</p>
|
||||
</div>
|
||||
|
||||
<table class="info-table">
|
||||
<tr>
|
||||
<td class="label">Nama Pelatih</td>
|
||||
<td>: {{ $pelatih->nama_lengkap }}</td>
|
||||
<td class="label">Periode</td>
|
||||
<td>: {{ now()->format('F Y') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Unit Latihan</td>
|
||||
<td>: Kolat {{ $pelatih->kolat->nama_kolat ?? '-' }}</td>
|
||||
<td class="label">Tanggal Cetak</td>
|
||||
<td>: {{ now()->format('d/m/Y') }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="section-title">A. STATISTIK PENILAIAN</div>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Aspek Penilaian</th>
|
||||
<th width="50">Skor</th>
|
||||
<th width="150">Visual</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@php
|
||||
$scores = [
|
||||
'Metode Pelatihan' => $rekap->avg_metode,
|
||||
'Komunikasi' => $rekap->avg_komunikasi,
|
||||
'Sikap & Etika' => $rekap->avg_sikap,
|
||||
'Kepemimpinan' => $rekap->avg_kepemimpinan,
|
||||
'Komitmen' => $rekap->avg_komitmen,
|
||||
'Interpersonal' => $rekap->avg_interpersonal,
|
||||
];
|
||||
@endphp
|
||||
@foreach($scores as $label => $val)
|
||||
<tr>
|
||||
<td>{{ $label }}</td>
|
||||
<td><strong>{{ number_format($val, 1) }}</strong></td>
|
||||
<td>
|
||||
<div class="bar-container">
|
||||
<div class="bar-fill" style="width: {{ ($val / 5) * 100 }}%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="section-title">B. ULASAN & MASUKAN ANGGOTA</div>
|
||||
@forelse($ulasan as $text)
|
||||
<div class="ulasan-item">"{{ $text }}"</div>
|
||||
@empty
|
||||
<p style="font-size: 11px; color: #666;">Belum ada ulasan tertulis.</p>
|
||||
@endforelse
|
||||
|
||||
<div class="footer">
|
||||
Laporan ini dihasilkan secara otomatis oleh Sistem TapakMP - Merpati Putih Jember
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid py-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h3 class="fw-bold text-dark mb-0">Laporan Performa Pelatih</h3>
|
||||
<p class="text-muted small">Periode: {{ now()->format('F Y') }}</p>
|
||||
</div>
|
||||
<a href="{{ route('penilaian.index') }}" class="btn btn-outline-secondary px-4 shadow-sm" style="border-radius: 12px;">
|
||||
<i class="bi bi-arrow-left me-2"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-10">
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 24px; background: linear-gradient(to right, #4f46e5, #6366f1);">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<img src="https://ui-avatars.com/api/?name={{ urlencode($pelatih->nama_lengkap) }}&background=fff&color=4f46e5&size=128"
|
||||
class="rounded-circle border border-4 border-white shadow-sm" width="80">
|
||||
<div class="ms-4 text-white">
|
||||
<h4 class="fw-bold mb-1">{{ $pelatih->nama_lengkap }}</h4>
|
||||
<span class="badge bg-white text-primary rounded-pill px-3">Kolat {{ $pelatih->kolat->nama_kolat ?? '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-4">
|
||||
@php
|
||||
$kriteria = [
|
||||
'metode_pelatihan' => ['label' => 'Metode Pelatihan', 'icon' => 'bi-book', 'color' => '#4f46e5'],
|
||||
'komunikasi' => ['label' => 'Komunikasi', 'icon' => 'bi-chat-dots', 'color' => '#10b981'],
|
||||
'sikap_kepribadian' => ['label' => 'Sikap & Etika', 'icon' => 'bi-person-badge', 'color' => '#06b6d4'],
|
||||
'kepemimpinan' => ['label' => 'Kepemimpinan', 'icon' => 'bi-award', 'color' => '#f59e0b'],
|
||||
'konsistensi_komitmen' => ['label' => 'Komitmen', 'icon' => 'bi-shield-check', 'color' => '#ef4444'],
|
||||
'kedekatan_interpersonal' => ['label' => 'Interpersonal', 'icon' => 'bi-people', 'color' => '#6366f1'],
|
||||
];
|
||||
|
||||
$scores = [
|
||||
'metode_pelatihan' => $rekap->avg_metode,
|
||||
'komunikasi' => $rekap->avg_komunikasi,
|
||||
'sikap_kepribadian' => $rekap->avg_sikap,
|
||||
'kepemimpinan' => $rekap->avg_kepemimpinan,
|
||||
'konsistensi_komitmen' => $rekap->avg_komitmen,
|
||||
'kedekatan_interpersonal' => $rekap->avg_interpersonal
|
||||
];
|
||||
@endphp
|
||||
|
||||
@foreach($kriteria as $key => $attr)
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<div class="card border-0 shadow-sm h-100" style="border-radius: 20px;">
|
||||
<div class="card-body p-3">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="rounded-circle d-flex align-items-center justify-content-center"
|
||||
style="width: 40px; height: 40px; background-color: {{ $attr['color'] }}15; color: {{ $attr['color'] }};">
|
||||
<i class="bi {{ $attr['icon'] }}"></i>
|
||||
</div>
|
||||
<span class="ms-2 small fw-bold text-muted uppercase">{{ $attr['label'] }}</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-end justify-content-between">
|
||||
<h3 class="fw-bold mb-0 text-dark">{{ number_format($scores[$key], 1) }}</h3>
|
||||
<small class="text-muted">/ 5.0</small>
|
||||
</div>
|
||||
<div class="progress mt-2" style="height: 6px; border-radius: 10px;">
|
||||
<div class="progress-bar" style="width: {{ ($scores[$key] / 5) * 100 }}%; background-color: {{ $attr['color'] }}; border-radius: 10px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm" style="border-radius: 24px;">
|
||||
<div class="card-header bg-transparent border-0 p-4 pb-0">
|
||||
<h5 class="fw-bold text-dark mb-0"><i class="bi bi-chat-square-quote me-2 text-primary"></i>Kritik & Saran Anggota</h5>
|
||||
<hr class="mt-3 mb-0">
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<div class="row">
|
||||
@forelse($ulasan as $teks)
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="p-3 bg-light border-0 h-100 shadow-xs" style="border-radius: 15px;">
|
||||
<p class="text-dark mb-2 small" style="line-height: 1.5;">"{{ $teks }}"</p>
|
||||
<small class="text-muted italic" style="font-size: 10px;">— Masukan Anonim</small>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-center py-5 w-100">
|
||||
<p class="text-muted small">Belum ada ulasan tertulis untuk periode ini.</p>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.shadow-xs { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02); }
|
||||
.uppercase { text-transform: uppercase; letter-spacing: 0.5px; }
|
||||
.italic { font-style: italic; }
|
||||
.progress { background-color: #f0f2f5; }
|
||||
</style>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid py-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<!-- Header Halaman -->
|
||||
<div class="d-flex align-items-center mb-4">
|
||||
<a href="{{ route('spp.index') }}" class="btn btn-light shadow-sm me-3" style="border-radius: 10px;">
|
||||
<i class="fas fa-arrow-left"></i>
|
||||
</a>
|
||||
<h3 class="fw-bold text-dark mb-0">Tambah Tagihan SPP Manual</h3>
|
||||
</div>
|
||||
|
||||
<!-- Alert Notifikasi -->
|
||||
@if(session('error'))
|
||||
<div class="alert alert-danger border-0 shadow-sm mb-4" style="border-radius: 12px;">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card border-0 shadow-sm" style="border-radius: 20px;">
|
||||
<div class="card-body p-4">
|
||||
|
||||
<form action="{{ route('spp.store') }}" method="POST">
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
<!-- Pilih Anggota -->
|
||||
<div class="col-12">
|
||||
<label class="form-label small fw-bold">Pilih Anggota</label>
|
||||
<select name="anggota_id" class="form-select border-0 bg-light py-3 @error('anggota_id') is-invalid @enderror" style="border-radius: 12px;" required>
|
||||
<option value="" selected disabled>Cari nama anggota...</option>
|
||||
@foreach($data_anggota as $agt)
|
||||
<option value="{{ $agt->id }}" {{ old('anggota_id') == $agt->id ? 'selected' : '' }}>
|
||||
{{ $agt->nama }} (ID: {{ $agt->id }})
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('anggota_id')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Periode Bulan -->
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small fw-bold">Untuk Bulan</label>
|
||||
<select name="bulan" class="form-select border-0 bg-light py-3" style="border-radius: 12px;" required>
|
||||
@php
|
||||
$bulanArr = ['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember'];
|
||||
$currentMonth = date('F'); // Default bulan sekarang
|
||||
@endphp
|
||||
@foreach($bulanArr as $bln)
|
||||
<option value="{{ $bln }}" {{ (old('bulan') ?? $bln) == $bln ? 'selected' : '' }}>{{ $bln }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Periode Tahun -->
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small fw-bold">Tahun</label>
|
||||
<select name="tahun" class="form-select border-0 bg-light py-3" style="border-radius: 12px;" required>
|
||||
<option value="2025" {{ old('tahun') == '2025' ? 'selected' : '' }}>2025</option>
|
||||
<option value="2026" {{ (old('tahun') ?? '2026') == '2026' ? 'selected' : '' }}>2026</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Nominal -->
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small fw-bold">Nominal SPP (Rp)</label>
|
||||
<input type="number" name="nominal" class="form-control border-0 bg-light py-3"
|
||||
placeholder="Contoh: 50000" value="{{ old('nominal', 50000) }}" style="border-radius: 12px;" required>
|
||||
</div>
|
||||
|
||||
<!-- Jatuh Tempo -->
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small fw-bold">Tanggal Jatuh Tempo</label>
|
||||
<input type="date" name="jatuh_tempo" class="form-control border-0 bg-light py-3"
|
||||
value="{{ old('jatuh_tempo', date('Y-m-10')) }}" style="border-radius: 12px;" required>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="col-12 mt-4">
|
||||
<hr class="text-muted opacity-25">
|
||||
<div class="d-flex justify-content-end gap-2">
|
||||
<button type="reset" class="btn btn-light px-4 py-2 fw-bold" style="border-radius: 10px;">Reset</button>
|
||||
<button type="submit" class="btn btn-primary px-4 py-2 fw-bold shadow-sm" style="border-radius: 10px; background-color: #0d6efd;">
|
||||
<i class="fas fa-save me-1"></i> Simpan Tagihan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.bg-light { background-color: #f8f9fa !important; }
|
||||
.form-label { color: #555; }
|
||||
input:focus, select:focus, textarea:focus {
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.1) !important;
|
||||
background-color: #fff !important;
|
||||
border: 1px solid #0d6efd !important;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
@extends('layout.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid py-4">
|
||||
<!-- Header Section -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h3 class="fw-bold text-dark mb-1">Manajemen SPP</h3>
|
||||
<p class="text-muted small mb-0">Kelola tagihan dan pembayaran SPP anggota Merpati Putih.</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<form action="{{ route('spp.generate') }}" method="POST">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-warning text-white px-3 py-2 shadow-sm" style="border-radius: 10px;" onclick="return confirm('Generate tagihan otomatis untuk bulan ini?')">
|
||||
<i class="fas fa-cog me-1"></i> Generate Tagihan
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<a href="{{ route('spp.create') }}" class="btn btn-danger px-3 py-2 shadow-sm" style="border-radius: 10px; display: flex; align-items: center; text-decoration: none;">
|
||||
<i class="fas fa-plus me-1"></i> Tambah Manual
|
||||
</a>
|
||||
|
||||
<button class="btn btn-info text-white px-3 py-2 shadow-sm" style="border-radius: 10px; background-color: #0099bc;">
|
||||
<i class="fas fa-download me-1"></i> Export
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistik Cards -->
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-md-3">
|
||||
<div class="card border-0 shadow-sm border-start border-success border-4 h-100" style="border-radius: 15px;">
|
||||
<div class="card-body p-4 d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<p class="text-success small fw-bold mb-1 uppercase">SPP LUNAS</p>
|
||||
<h3 class="fw-bold mb-0">{{ $stats['lunas'] }}</h3>
|
||||
</div>
|
||||
<i class="fas fa-check-circle text-success fs-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card border-0 shadow-sm border-start border-warning border-4 h-100" style="border-radius: 15px;">
|
||||
<div class="card-body p-4 d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<p class="text-warning small fw-bold mb-1 uppercase">PENDING</p>
|
||||
<h3 class="fw-bold mb-0">{{ $stats['pending'] }}</h3>
|
||||
</div>
|
||||
<i class="fas fa-clock text-warning fs-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card border-0 shadow-sm border-start border-danger border-4 h-100" style="border-radius: 15px;">
|
||||
<div class="card-body p-4 d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<p class="text-danger small fw-bold mb-1 uppercase">BELUM BAYAR</p>
|
||||
<h3 class="fw-bold mb-0">{{ $stats['belum_bayar'] }}</h3>
|
||||
</div>
|
||||
<i class="fas fa-exclamation-triangle text-danger fs-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card border-0 shadow-sm border-start border-primary border-4 h-100" style="border-radius: 15px;">
|
||||
<div class="card-body p-4 d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<p class="text-primary small fw-bold mb-1 uppercase">TOTAL MASUK</p>
|
||||
<h3 class="fw-bold mb-0">Rp {{ number_format($stats['total_pemasukan'], 0, ',', '.') }}</h3>
|
||||
</div>
|
||||
<i class="fas fa-money-bill-wave text-primary fs-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filter Data SPP -->
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px; overflow: hidden;">
|
||||
<div class="card-header border-0 py-3 text-white" style="background-color: #0d6efd;">
|
||||
<h6 class="mb-0 fw-bold"><i class="fas fa-filter me-2"></i>Filter Data SPP</h6>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<form action="{{ route('spp.index') }}" method="GET" class="row g-3 align-items-end">
|
||||
<div class="col-md-2">
|
||||
<label class="form-label small fw-bold">Tahun</label>
|
||||
<select name="tahun" class="form-select border-0 bg-light">
|
||||
<option value="2026" {{ request('tahun') == '2026' ? 'selected' : '' }}>2026</option>
|
||||
<option value="2025" {{ request('tahun') == '2025' ? 'selected' : '' }}>2025</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold">Bulan</label>
|
||||
<select name="bulan" class="form-select border-0 bg-light">
|
||||
<option value="">Semua Bulan</option>
|
||||
@foreach(['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember'] as $m)
|
||||
<option value="{{ $m }}" {{ request('bulan') == $m ? 'selected' : '' }}>{{ $m }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small fw-bold">Status</label>
|
||||
<select name="status" class="form-select border-0 bg-light">
|
||||
<option value="">Semua Status</option>
|
||||
<option value="lunas" {{ request('status') == 'lunas' ? 'selected' : '' }}>Lunas</option>
|
||||
<option value="belum_bayar" {{ request('status') == 'belum_bayar' ? 'selected' : '' }}>Belum Bayar</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-bold">Cari Anggota</label>
|
||||
<input type="text" name="cari" class="form-control border-0 bg-light" placeholder="Nama anggota..." value="{{ request('cari') }}">
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
<button type="submit" class="btn btn-primary px-4 shadow-sm" style="background-color: #0d6efd; border-radius: 10px;">
|
||||
<i class="fas fa-search me-1"></i> Filter
|
||||
</button>
|
||||
<a href="{{ route('spp.index') }}" class="btn btn-light px-4 shadow-sm" style="border-radius: 10px;">
|
||||
<i class="fas fa-sync-alt me-1"></i> Reset
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Daftar Tagihan Section -->
|
||||
<div class="card border-0 shadow-sm" style="border-radius: 20px; overflow: hidden;">
|
||||
<div class="card-header border-0 py-3 text-white d-flex justify-content-between align-items-center" style="background-color: #0d6efd;">
|
||||
<h6 class="mb-0 fw-bold"><i class="fas fa-money-check me-2"></i>Daftar Tagihan SPP</h6>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
@if($data_spp->isEmpty())
|
||||
<div class="py-5 text-center">
|
||||
<i class="fas fa-file-invoice-dollar text-muted mb-4" style="font-size: 80px; opacity: 0.2;"></i>
|
||||
<h5 class="fw-bold text-muted">Belum ada data tagihan SPP</h5>
|
||||
<p class="text-muted small">Silakan tambah manual atau generate otomatis.</p>
|
||||
<a href="{{ route('spp.create') }}" class="btn btn-danger text-white px-4 py-2 mt-2" style="border-radius: 10px;">Tambah Manual</a>
|
||||
</div>
|
||||
@else
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="bg-light text-muted uppercase">
|
||||
<tr>
|
||||
<th class="ps-4" style="width: 30%;">Anggota</th>
|
||||
<th>Periode</th>
|
||||
<th>Nominal</th>
|
||||
<th>Status</th>
|
||||
<th class="text-center">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data_spp as $spp)
|
||||
<tr>
|
||||
<td class="ps-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<!-- Avatar Inisial -->
|
||||
<div class="rounded-circle bg-primary text-white d-flex align-items-center justify-content-center me-3 shadow-sm"
|
||||
style="width: 40px; height: 40px; font-size: 14px; font-weight: bold; background: linear-gradient(45deg, #0d6efd, #0099bc);">
|
||||
{{ strtoupper(substr($spp->anggota->nama, 0, 1)) }}
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold text-dark" style="font-size: 0.95rem;">{{ $spp->anggota->nama }}</div>
|
||||
<span class="badge bg-light text-muted border fw-normal" style="font-size: 0.75rem;">
|
||||
ID: {{ $spp->anggota_id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-dark fw-medium">{{ $spp->bulan }}</div>
|
||||
<div class="small text-muted">{{ $spp->tahun }}</div>
|
||||
</td>
|
||||
<td class="fw-bold text-dark">
|
||||
Rp {{ number_format($spp->nominal, 0, ',', '.') }}
|
||||
</td>
|
||||
<td>
|
||||
@if($spp->status == 'lunas')
|
||||
<span class="badge bg-success-soft text-success rounded-pill px-3">
|
||||
<i class="fas fa-check-circle me-1"></i> Lunas
|
||||
</span>
|
||||
@elseif($spp->status == 'belum_bayar' && \Carbon\Carbon::parse($spp->jatuh_tempo)->isPast())
|
||||
<span class="badge bg-danger-soft text-danger rounded-pill px-3">
|
||||
<i class="fas fa-exclamation-circle me-1"></i> Terlambat
|
||||
</span>
|
||||
@else
|
||||
<span class="badge bg-warning-soft text-warning rounded-pill px-3">
|
||||
<i class="fas fa-clock me-1"></i> Belum Bayar
|
||||
</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-center">
|
||||
@if($spp->status != 'lunas')
|
||||
<form action="{{ route('spp.bayar', $spp->id) }}" method="POST" class="d-inline">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-sm btn-primary px-3 shadow-sm"
|
||||
style="border-radius: 8px;"
|
||||
onclick="return confirm('Konfirmasi pembayaran untuk {{ $spp->anggota->nama }}?')">
|
||||
Bayar
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<span class="text-success small fw-bold">
|
||||
<i class="fas fa-check-double me-1"></i> Terbayar
|
||||
</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.bg-light { background-color: #f8f9fa !important; }
|
||||
.uppercase { text-transform: uppercase; letter-spacing: 0.8px; font-size: 10px; font-weight: 700; }
|
||||
.fs-1 { font-size: 2.2rem !important; opacity: 0.2; }
|
||||
|
||||
/* Soft Badge Styles */
|
||||
.bg-success-soft { background-color: rgba(25, 135, 84, 0.12); }
|
||||
.bg-danger-soft { background-color: rgba(220, 53, 69, 0.12); }
|
||||
.bg-warning-soft { background-color: rgba(255, 193, 7, 0.15); }
|
||||
|
||||
.table-hover tbody tr:hover {
|
||||
background-color: rgba(13, 110, 253, 0.03);
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.form-select, .form-control {
|
||||
border-radius: 10px;
|
||||
padding: 0.6rem 1rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
|
@ -4,9 +4,12 @@
|
|||
use App\Http\Controllers\AuthController;
|
||||
use App\Http\Controllers\DashboardController;
|
||||
use App\Http\Controllers\JadwalController;
|
||||
use App\Http\Controllers\KasController;
|
||||
use App\Http\Controllers\KolatController;
|
||||
use App\Http\Controllers\PelatihController;
|
||||
use App\Http\Controllers\PenilaianController;
|
||||
use App\Http\Controllers\PresensiController;
|
||||
use App\Http\Controllers\SppController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
||||
|
|
@ -103,3 +106,30 @@
|
|||
Route::post('/tambah-manual', [PresensiController::class, 'storeManual'])->name('storeManual');
|
||||
});
|
||||
|
||||
//Penialaian
|
||||
|
||||
Route::prefix('penilaian')->name('penilaian.')->group(function () {
|
||||
Route::get('/', [PenilaianController::class, 'index'])->name('index');
|
||||
// Hilangkan kata 'penilaian' di dalam sini karena sudah ada di prefix
|
||||
Route::get('/create/{id}', [PenilaianController::class, 'create'])->name('create');
|
||||
Route::post('/store', [PenilaianController::class, 'store'])->name('store');
|
||||
Route::get('/penilaian/rekap/{id}', [PenilaianController::class, 'show'])->name('show');
|
||||
});
|
||||
|
||||
//Kas
|
||||
Route::prefix('kas')->name('kas.')->group(function () {
|
||||
Route::get('/', [KasController::class, 'index'])->name('index');
|
||||
Route::post('/store', [KasController::class, 'store'])->name('store');
|
||||
Route::put('/update/{id}', [KasController::class, 'update'])->name('update');
|
||||
Route::delete('/{id}', [KasController::class, 'destroy'])->name('destroy');
|
||||
});
|
||||
|
||||
// Group SPP
|
||||
Route::prefix('spp')->name('spp.')->group(function () {
|
||||
Route::get('/', [SppController::class, 'index'])->name('index');
|
||||
Route::get('/create', [SppController::class, 'create'])->name('create');
|
||||
Route::post('/store', [SppController::class, 'store'])->name('store');
|
||||
Route::post('/bayar/{id}', [SppController::class, 'bayar'])->name('bayar');
|
||||
Route::post('/generate', [SppController::class, 'generateTagihan'])->name('generate');
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue