ubah layout

This commit is contained in:
SitiAfiah 2026-05-19 19:12:08 +07:00
parent 2ccaa0b4c5
commit 06f672b441
37 changed files with 2006 additions and 721 deletions

View File

@ -26,7 +26,7 @@ public function showLogin()
* Proses Login * Proses Login
*/ */
public function login(Request $request) public function login(Request $request)
{ {
$credentials = $request->validate([ $credentials = $request->validate([
'email' => 'required|email', 'email' => 'required|email',
'password' => 'required', 'password' => 'required',
@ -35,7 +35,7 @@ public function login(Request $request)
if (Auth::attempt($credentials)) { if (Auth::attempt($credentials)) {
$user = Auth::user(); $user = Auth::user();
// Proteksi Status: Jika belum diaktifkan admin, tidak boleh masuk // 1. Proteksi Status: Jika belum diaktifkan admin, tidak boleh masuk
if ($user->anggota && $user->anggota->status !== 'Aktif') { if ($user->anggota && $user->anggota->status !== 'Aktif') {
Auth::logout(); Auth::logout();
return back()->with('error', 'Akun Anda sedang dalam tahap verifikasi admin. Mohon tunggu.'); return back()->with('error', 'Akun Anda sedang dalam tahap verifikasi admin. Mohon tunggu.');
@ -43,14 +43,31 @@ public function login(Request $request)
$request->session()->regenerate(); $request->session()->regenerate();
// Redirect sesuai role jika diperlukan, atau ke dashboard utama // 2. Ambil Nama Role (samakan logikanya dengan Middleware)
return redirect()->intended('/dashboard')->with('success', 'Selamat datang kembali!'); $roleName = null;
if ($user->role) {
$roleName = $user->role->nama_role;
} elseif ($user->anggota && $user->anggota->role) {
$roleName = $user->anggota->role->nama_role;
}
// 3. Logika Pengarahan (Redirect) berdasarkan String Role
if ($roleName === 'Anggota') {
return redirect()->route('anggota.dashboard')->with('success', 'Selamat datang, Anggota!');
}
if ($roleName === 'Pelatih' || $roleName === 'Pengurus') {
return redirect()->route('dashboard')->with('success', 'Selamat datang, Pelatih/Pengurus!');
}
// Default redirect jika entah kenapa role kosong
return redirect()->intended('/dashboard');
} }
return back()->withErrors([ return back()->withErrors([
'email' => 'Email atau password yang Anda masukkan salah.', 'email' => 'Email atau password yang Anda masukkan salah.',
])->onlyInput('email'); ])->onlyInput('email');
} }
/** /**
* Menampilkan Halaman Register * Menampilkan Halaman Register

View File

@ -1,30 +1,44 @@
<?php <?php
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Anggota; use App\Models\Anggota;
use App\Models\Kolat; use App\Models\Kolat;
use App\Models\Presensi; use App\Models\Presensi;
use App\Models\Role; use App\Models\Role;
use App\Models\Spp; use App\Models\Spp;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
// use Illuminate\Http\Request; use Illuminate\Http\Request;
class DashboardController extends Controller class DashboardController extends Controller
{ {
public function index() public function index()
{ {
// --- 1. DATA STATISTIK UTAMA --- // --- 1. DATA STATISTIK UTAMA ---
$total_anggota_aktif = Anggota::where('status', 'Aktif')->count(); // Menghitung anggota dengan status Aktif
// // Menghitung jumlah Kolat yang terdaftar
$total_kolat = Kolat::count(); $total_kolat = Kolat::count();
// Ambil ID Role Pelatih secara dinamis $roleAnggota = Role::where('nama_role', 'Anggota')->first();
$rolePelatih = Role::where('nama_role', 'Pelatih')->first(); $rolePelatih = Role::where('nama_role', 'Pelatih')->first();
$total_pelatih = $rolePelatih ? Anggota::where('role_id', $rolePelatih->id)->count() : 0;
// Hitung SPP yang statusnya masih 'pending' atau 'belum_lunas' // 2. Hitung jumlah "Anggota" (Hanya yang ber-role 'Anggota' DAN berstatus 'Aktif')
$total_anggota_aktif = Anggota::where('status', 'Aktif')
->where('role_id', $roleAnggota->id)
->count();
// 3. Hitung jumlah "Pelatih" (Hanya yang ber-role 'Pelatih' DAN berstatus 'Aktif')
$total_pelatih = Anggota::where('status', 'Aktif')
->where('role_id', $rolePelatih->id)
->count();
// Menghitung SPP yang belum lunas (Pending atau Belum Lunas)
// Pastikan 'pending' dan 'belum_lunas' sesuai dengan isi kolom status di database Anda
$spp_pending = Spp::whereIn('status', ['pending', 'belum_lunas'])->count(); $spp_pending = Spp::whereIn('status', ['pending', 'belum_lunas'])->count();
// --- 2. DATA GRAFIK LINE (TREN PRESENSI 7 HARI) --- // --- 2. DATA GRAFIK LINE (TREN PRESENSI 7 HARI) ---
// Mengambil data kehadiran 7 hari terakhir untuk grafik
$grafikPresensi = Presensi::select( $grafikPresensi = Presensi::select(
DB::raw('DATE(created_at) as date'), DB::raw('DATE(created_at) as date'),
DB::raw('count(*) as total') DB::raw('count(*) as total')
@ -35,35 +49,47 @@ public function index()
->orderBy('date', 'ASC') ->orderBy('date', 'ASC')
->get(); ->get();
// --- 3. DATA GRAFIK DOUGHNUT (KOMPOSISI SABUK) --- // --- 3. DATA GRAFIK DOUGHNUT (KOMPOSISI TINGKATAN) ---
// Menghitung persebaran anggota berdasarkan kolom 'tingkatan'
$persebaran_sabuk = Anggota::select('tingkatan', DB::raw('count(*) as total')) $persebaran_sabuk = Anggota::select('tingkatan', DB::raw('count(*) as total'))
->groupBy('tingkatan') ->groupBy('tingkatan')
->get(); ->get();
// --- 4. DATA AKTIVITAS TERBARU (REAL DARI SPP) --- // --- 4. DATA AKTIVITAS TERBARU (DARI TRANSAKSI SPP) ---
// Mengambil 5 transaksi SPP terbaru beserta data anggotanya
$aktivitas = Spp::with('anggota') $aktivitas = Spp::with('anggota')
->latest() ->latest()
->take(5) ->take(5)
->get() ->get()
->map(function ($item) { ->map(function ($item) {
// Menentukan warna badge berdasarkan status
$statusLower = strtolower($item->status);
$badge = 'danger'; // Default
if ($statusLower == 'lunas') $badge = 'success';
if ($statusLower == 'pending') $badge = 'warning';
return [ return [
'waktu' => $item->created_at->format('d/m/Y H:i'), 'waktu' => $item->created_at->format('d/m/Y H:i'),
'kegiatan' => 'Pembayaran SPP: ' . ($item->keterangan ?? 'Iuran Bulanan'), 'kegiatan' => 'Pembayaran SPP: ' . ($item->keterangan ?? 'Iuran Bulanan'),
'user' => $item->anggota->nama_lengkap ?? 'System', 'user' => $item->anggota->nama_lengkap ?? 'Anggota', // Pastikan kolom 'nama_lengkap' ada
'status' => strtoupper($item->status), 'status' => strtoupper($item->status),
'badge' => $item->status == 'lunas' ? 'success' : ($item->status == 'pending' ? 'warning' : 'danger') 'badge' => $badge
]; ];
}); });
// --- 5. LOGIKA KELAYAKAN UNTUK RINGKASAN --- // --- 5. LOGIKA KELAYAKAN (RINGKASAN REKAP) ---
// Menarik data anggota yang memenuhi syarat kehadiran 75%
// Eager Loading 'presensi' agar query lebih cepat
$anggota = Anggota::with('presensi')->get(); $anggota = Anggota::with('presensi')->get();
$jumlah_layak_ujian = $anggota->filter(function($item) { $jumlah_layak_ujian = $anggota->filter(function ($item) {
$total = $item->presensi->count(); $total = $item->presensi->count();
$hadir = $item->presensi->where('status', 'hadir')->count(); $hadir = $item->presensi->where('status', 'hadir')->count();
$persen = $total > 0 ? ($hadir / $total) * 100 : 0; $persen = $total > 0 ? ($hadir / $total) * 100 : 0;
return $persen >= 75; return $persen >= 75;
})->count(); })->count();
// --- 6. RETURN KE VIEW ---
// Pastikan path view sesuai (folder dashboard, file dashboard.blade.php)
return view('dashboard.dashboard', compact( return view('dashboard.dashboard', compact(
'total_anggota_aktif', 'total_anggota_aktif',
'total_pelatih', 'total_pelatih',

View File

@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LandingPageController extends Controller
{
//
}

View File

@ -0,0 +1,77 @@
<?php
namespace App\Http\Controllers;
use App\Models\Anggota;
use App\Models\Jadwal;
use App\Models\Kas;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class MemberDashboardController extends Controller
{
// public function index()
// {
// // 1. Ambil data profil anggota yang sedang login
// $user = Auth::user();
// $anggota = Anggota::where('user_id', $user->id)->first();
// if (!$anggota) {
// return redirect('/')->with('error', 'Data anggota tidak ditemukan.');
// }
// // 2. Ambil Jadwal Latihan (Hanya yang sesuai dengan Kolat si anggota)
// $jadwal = Jadwal::where('kolat_id', $anggota->kolat_id)
// ->where('tanggal', '>=', now())
// ->orderBy('tanggal', 'asc')
// ->take(5)
// ->get();
// // 3. Ambil Tagihan SPP (Contoh: mencari data di tabel kas yang belum lunas)
// // Asumsi Anda punya kolom 'anggota_id' dan 'status' di tabel Kas/SPP
// $tagihan_spp = Kas::where('no_induk', $anggota->no_induk)
// ->where('status', 'Pending')
// ->get();
// // 4. Hitung Ringkasan (Contoh: Total kehadiran)
// // Ini hanya dummy, silakan sesuaikan dengan tabel absensi Anda
// $persentase_hadir = 85;
// return view('anggota.dashboard', compact('anggota', 'jadwal', 'tagihan_spp', 'persentase_hadir'));
// }
public function index()
{
// 1. Ambil data profil anggota yang sedang login
$user = Auth::user();
$anggota = Anggota::where('user_id', $user->id)->first();
if (!$anggota) {
return redirect('/')->with('error', 'Data anggota tidak ditemukan.');
}
// 2. Ambil Jadwal Latihan (Hanya yang sesuai dengan Kolat si anggota)
$jadwal = Jadwal::where('kolat_id', $anggota->kolat_id)
->where('tanggal', '>=', now())
->orderBy('tanggal', 'asc')
->take(5)
->get();
// 3. Ambil Tagihan SPP
// PERBAIKAN: Menggunakan relasi spp() yang sudah Anda buat di model Anggota.
// Asumsi di tabel SPP Anda terdapat kolom 'status' (misal: 'Pending' atau 'Belum Lunas')
$tagihan_spp = $anggota->spp()->where('status', 'Pending')->get();
// 4. Hitung Ringkasan Kehadiran
// Contoh mengambil total kehadiran dari relasi riwayatPresensi()
// Ini asumsikan Anda memiliki kolom 'status_hadir' (misal: 'Hadir') di tabel Presensi
$total_latihan = $anggota->riwayatPresensi()->count();
$total_hadir = $anggota->riwayatPresensi()->where('status', 'Hadir')->count();
$persentase_hadir = 0;
if ($total_latihan > 0) {
$persentase_hadir = round(($total_hadir / $total_latihan) * 100);
}
return view('anggota.dashboard', compact('anggota', 'jadwal', 'tagihan_spp', 'persentase_hadir'));
}
}

View File

@ -12,7 +12,10 @@ class PenilaianController extends Controller
{ {
public function index() public function index()
{ {
$data_pelatih = Anggota::where('jabatan', 'Pelatih') // Mencari anggota berdasarkan relasi 'role' yang bernama 'Pelatih'
$data_pelatih = Anggota::whereHas('role', function ($query) {
$query->where('nama_role', 'Pelatih');
})
->with('kolat') ->with('kolat')
->get(); ->get();
@ -110,4 +113,16 @@ public function exportPdf($id)
return $pdf->download('Laporan-Performa-' . $pelatih->nama_lengkap . '.pdf'); return $pdf->download('Laporan-Performa-' . $pelatih->nama_lengkap . '.pdf');
} }
public function indexAnggota()
{
// Ubah juga bagian ini menggunakan whereHas
$data_pelatih = Anggota::whereHas('role', function ($query) {
$query->where('nama_role', 'Pelatih');
})
->with('kolat')
->get();
return view('penilaian.anggota_index', compact('data_pelatih'));
}
} }

View File

@ -5,6 +5,7 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
class ProfileController extends Controller class ProfileController extends Controller
{ {
@ -30,22 +31,42 @@ public function update(Request $request)
{ {
$anggota = Auth::user()->anggota; $anggota = Auth::user()->anggota;
// Validasi data yang boleh diubah oleh anggota[cite: 1, 2] // 1. Validasi input, tambahkan validasi untuk foto
$request->validate([ $request->validate([
'nama_lengkap' => 'required|string|max:255', 'nama_lengkap' => 'required|string|max:255',
'no_hp' => 'required|numeric', 'no_hp' => 'required|numeric',
'tempat_lahir' => 'required|string', 'tempat_lahir' => 'required|string',
'tgl_lahir' => 'required|date', 'tgl_lahir' => 'required|date',
'jenis_kelamin'=> 'required|in:L,P', 'jenis_kelamin' => 'required|in:L,P',
'alamat' => 'required|string', 'alamat' => 'required|string',
'foto_profil' => 'nullable|image|mimes:jpeg,png,jpg|max:2048', // Maksimal 2MB
]); ]);
// Mengambil data input // 2. Ambil data teks
$input = $request->only([ $input = $request->only([
'nama_lengkap', 'no_hp', 'tempat_lahir', 'tgl_lahir', 'jenis_kelamin', 'alamat' 'nama_lengkap',
'no_hp',
'tempat_lahir',
'tgl_lahir',
'jenis_kelamin',
'alamat'
]); ]);
// Proses update data ke database // 3. Logika Upload Foto
if ($request->hasFile('foto_profil')) {
// Jika anggota sudah punya foto sebelumnya, hapus file lamanya dari storage
if ($anggota->foto_profil && Storage::disk('public')->exists($anggota->foto_profil)) {
Storage::disk('public')->delete($anggota->foto_profil);
}
// Simpan foto baru ke folder 'profil_images' di dalam storage/app/public
$path = $request->file('foto_profil')->store('profil_images', 'public');
// Masukkan path foto baru ke dalam array input untuk disimpan ke database
$input['foto_profil'] = $path;
}
// 4. Update data ke database
$anggota->update($input); $anggota->update($input);
// Update nama di tabel users agar sinkron // Update nama di tabel users agar sinkron
@ -53,7 +74,7 @@ public function update(Request $request)
'name' => $request->nama_lengkap 'name' => $request->nama_lengkap
]); ]);
return redirect()->route('profil.edit')->with('success', 'Profil Anda berhasil diperbarui!'); return redirect()->route('profile.edit')->with('success', 'Profil Anda berhasil diperbarui!');
} }
/** /**

View File

@ -30,7 +30,7 @@ public function index(Request $request) // Tambahkan Request untuk filter
$dataRekap = $anggota->map(function ($item) { $dataRekap = $anggota->map(function ($item) {
// Logika Presensi // Logika Presensi
$totalPertemuan = $item->presensi->count(); $totalPertemuan = $item->presensi->count();
$hadir = $item->presensi->where('status', 'hadir')->count(); $hadir = $item->presensi->where('status', 'Hadir')->count();
$persentasePresensi = $totalPertemuan > 0 ? ($hadir / $totalPertemuan) * 100 : 0; $persentasePresensi = $totalPertemuan > 0 ? ($hadir / $totalPertemuan) * 100 : 0;
// Logika SPP // Logika SPP

View File

@ -16,19 +16,32 @@ class CheckRole
*/ */
public function handle(Request $request, Closure $next, ...$roles): Response public function handle(Request $request, Closure $next, ...$roles): Response
{ {
// 1. Pastikan user sudah login
if (!Auth::check()) { if (!Auth::check()) {
return redirect('login'); return redirect()->route('login');
} }
// 2. Ambil nama role user yang sedang login (lewat relasi yang kita buat kemarin) $user = Auth::user();
$userRole = Auth::user()->role->nama_role; $namaRole = null;
// 3. Cek apakah role user ada di dalam daftar role yang diperbolehkan? // 2. Ambil nama_role dari relasi.
if (in_array($userRole, $roles)) { if ($user->role) {
$namaRole = $user->role->nama_role;
} elseif ($user->anggota && $user->anggota->role) {
$namaRole = $user->anggota->role->nama_role;
}
// ==========================================
// LETAKKAN KODE DD DI SINI (UNTUK DEBUGGING)
// ==========================================
// dd('Role di DB: ' . $namaRole, 'Role di Rute: ', $roles);
// 3. Cek apakah nama_role user ada di dalam daftar role
if (in_array($namaRole, $roles)) {
return $next($request); return $next($request);
} }
// 4. Kalau nggak cocok, lempar ke halaman 403 (Forbidden) // 4. Jika role tidak cocok, tolak akses
abort(403, 'Akses Ditolak. Anda tidak memiliki wewenang untuk mengakses halaman ini.'); abort(403, 'Akses Ditolak. Anda tidak memiliki wewenang untuk mengakses halaman ini.');
} }
} }

View File

@ -21,6 +21,28 @@ public function handle(Request $request, Closure $next, string ...$guards): Resp
foreach ($guards as $guard) { foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) { if (Auth::guard($guard)->check()) {
// Ambil data user yang sedang login
$user = Auth::guard($guard)->user();
$roleName = null;
// Cek nama role sesuai struktur relasi TapakMP
if ($user->role) {
$roleName = $user->role->nama_role;
} elseif ($user->anggota && $user->anggota->role) {
$roleName = $user->anggota->role->nama_role;
}
// Arahkan ke dashboard yang sesuai
if ($roleName === 'Anggota') {
return redirect()->route('anggota.dashboard');
}
if ($roleName === 'Pelatih' || $roleName === 'Pengurus') {
return redirect()->route('dashboard');
}
// Default bawaan Laravel jika role tidak terdefinisi
return redirect(RouteServiceProvider::HOME); return redirect(RouteServiceProvider::HOME);
} }
} }

View File

@ -13,7 +13,7 @@ class Anggota extends Model
protected $table = 'anggotas'; protected $table = 'anggotas';
protected $fillable = [ protected $fillable = [
'user_id', 'no_induk', 'nama_lengkap', 'role_id', 'jenis_kelamin', 'user_id', 'no_induk', 'nama_lengkap', 'foto_profil', 'role_id', 'jenis_kelamin',
'tempat_lahir', 'tgl_lahir', 'no_hp', 'kolat_id', 'tempat_lahir', 'tgl_lahir', 'no_hp', 'kolat_id',
'tingkatan', 'tgl_gabung', 'status', 'alamat', 'tingkatan', 'tgl_gabung', 'status', 'alamat',
'catatan_medis', 'jabatan', 'no_sk', 'masa_berlaku', 'foto_sk' 'catatan_medis', 'jabatan', 'no_sk', 'masa_berlaku', 'foto_sk'

View File

@ -2,6 +2,13 @@
namespace App\Providers; namespace App\Providers;
use App\Models\Anggota;
use App\Models\Jadwal;
use App\Models\Kas;
use App\Models\Spp;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
@ -19,6 +26,99 @@ public function register(): void
*/ */
public function boot(): void public function boot(): void
{ {
// View::composer('*', function ($view) {
if (Auth::check()) {
$user = Auth::user();
$userRole = $user->role->nama_role; // Sesuaikan dengan cara Anda ambil role
$notifications = [];
$unreadCount = 0;
// --- 1. LOGIKA NOTIFIKASI PENGURUS ---
if ($userRole == 'Pengurus') {
// A. Verifikasi SPP Pending
$sppPending = Spp::where('status', 'pending')->count();
if ($sppPending > 0) {
$notifications[] = [
'icon' => 'bi-cash-stack text-warning',
'title' => 'Verifikasi SPP',
'msg' => "Ada $sppPending bukti bayar menunggu validasi.",
'link' => route('spp.index')
];
}
// B. Verifikasi Anggota Baru (Pendaftar)
$anggotaBaru = Anggota::where('status', 'Pending')->count();
if ($anggotaBaru > 0) {
$notifications[] = [
'icon' => 'bi-person-plus text-primary',
'title' => 'Verifikasi Anggota',
'msg' => "Ada $anggotaBaru calon anggota baru perlu divalidasi.",
'link' => route('anggota.anggota')
];
}
// C. Kandidat Pelatih Baru (Kriteria: Usia >= 18 & Tingkatan Balik 1)
// Kita hitung menggunakan Carbon untuk tanggal lahir
$kandidatPelatih = Anggota::where('tingkatan', 'Balik 1')
->where('status', 'Aktif')
->where('tgl_lahir', '<=', Carbon::now()->subYears(18))
->count();
if ($kandidatPelatih > 0) {
$notifications[] = [
'icon' => 'bi-star-fill text-info',
'title' => 'Kandidat Pelatih',
'msg' => "Ada $kandidatPelatih anggota Balik 1 berusia 18th siap jadi Pelatih.",
'link' => route('anggota.anggota') // Bisa diarahkan ke daftar anggota filter Balik 1
];
}
// D. Peringatan Saldo Kas Kritis (< 500rb)
$saldo = Kas::sum('nominal');
if ($saldo < 500000) {
$notifications[] = [
'icon' => 'bi-exclamation-triangle text-danger',
'title' => 'Peringatan Saldo',
'msg' => "Saldo Kas Cabang kritis: Rp " . number_format($saldo, 0, ',', '.'),
'link' => route('kas.index')
];
}
}
// --- LOGIKA NOTIFIKASI PELATIH ---
if ($userRole == 'Pelatih') {
$jadwalHariIni = Jadwal::whereDate('tanggal', date('Y-m-d'))->count();
if ($jadwalHariIni > 0) {
$notifications[] = [
'icon' => 'bi-calendar-event text-primary',
'title' => 'Jadwal Latihan',
'message' => "Anda memiliki $jadwalHariIni jadwal hari ini.",
'link' => route('jadwal.index')
];
$unreadCount += 1;
}
}
// --- LOGIKA NOTIFIKASI ANGGOTA ---
if ($userRole == 'Anggota') {
$sppSaya = Spp::where('anggota_id', $user->anggota->id)
->where('status', 'belum_lunas')->count();
if ($sppSaya > 0) {
$notifications[] = [
'icon' => 'bi-cash-stack text-danger',
'title' => 'Tagihan SPP',
'message' => "Anda memiliki $sppSaya tagihan belum terbayar.",
'link' => route('spp.anggota.index')
];
$unreadCount += 1;
}
}
// Kirim data ke SEMUA View
$view->with('globalNotifications', $notifications);
$view->with('globalUnreadCount', $unreadCount);
}
});
} }
} }

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('anggotas', function (Blueprint $table) {
$table->string('foto_profil')->nullable()->after('nama_lengkap');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('anggotas', function (Blueprint $table) {
$table->dropColumn('foto_profil');
});
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -57,7 +57,7 @@ class="btn btn-primary px-4 py-2 shadow-sm d-flex align-items-center"
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover align-middle main-table"> <table class="table table-hover align-middle main-table">
<thead> <thead>
<tr> <tr class="text-center">
<th width="60">No</th> <th width="60">No</th>
<th>Identitas Anggota</th> <th>Identitas Anggota</th>
<th>Email</th> <th>Email</th>
@ -109,12 +109,12 @@ class="badge rounded-pill {{ $item->status == 'Aktif' ? 'bg-success-soft text-su
<button class="btn btn-sm btn-action-detail fw-bold px-3 shadow-xs" <button class="btn btn-sm btn-action-detail fw-bold px-3 shadow-xs"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#modalDetail{{ $item->id }}"> data-bs-target="#modalDetail{{ $item->id }}">
<i class="icon-eye"></i> Detail <i class="bi bi-eye"></i>
</button> </button>
<a href="{{ route('anggota.edit', $item->id) }}" <a href="{{ route('anggota.edit', $item->id) }}"
class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs"> class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs">
<i class="icon-pencil"></i> Edit <i class="bi bi-pencil"></i>
</a> </a>
</div> </div>
</td> </td>

View File

@ -0,0 +1,221 @@
@extends('layout.app')
@section('content')
<style>
/* Mengatur ulang font agar lebih modern (Opsional jika template Anda sudah punya) */
body { background-color: #f8fafc; }
/* Profil Header dengan Gradasi Modern */
.bg-gradient-primary {
background: linear-gradient(135deg, #0d6efd 0%, #0043a8 100%);
color: white;
position: relative;
overflow: hidden;
}
/* Dekorasi latar belakang (lingkaran transparan) */
.bg-gradient-primary::after {
content: ''; position: absolute; top: -50%; right: -10%;
width: 300px; height: 300px; background: rgba(255,255,255,0.05);
border-radius: 50%;
}
/* Kartu Global */
.card-custom {
border: none;
border-radius: 16px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
/* Efek Hover untuk Kartu Statistik */
.card-hover:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08);
}
/* Badge & Label */
.badge-soft-primary { background-color: rgba(255,255,255,0.2); color: #fff; backdrop-filter: blur(5px); }
.icon-box {
width: 48px; height: 48px; display: flex; align-items: center; justify-content: center;
border-radius: 12px; font-size: 1.25rem;
}
.icon-box-primary { background-color: #e0f2fe; color: #0284c7; }
.icon-box-warning { background-color: #fef3c7; color: #d97706; }
.icon-box-success { background-color: #dcfce7; color: #16a34a; }
/* Tabel Modern */
.table-modern th {
font-weight: 600; color: #64748b; font-size: 0.85rem;
text-transform: uppercase; letter-spacing: 0.5px;
border-bottom: 2px solid #f1f5f9; background-color: transparent;
}
.table-modern td {
vertical-align: middle; border-bottom: 1px solid #f1f5f9;
color: #334155; padding: 1rem 0.5rem;
}
.table-modern tbody tr:hover { background-color: #f8fafc; }
/* List Tagihan */
.bill-item {
border: 1px solid #e2e8f0; border-radius: 12px; padding: 1rem;
transition: all 0.2s ease; border-left: 4px solid #f59e0b;
}
.bill-item:hover { background-color: #f8fafc; border-color: #cbd5e1; border-left-color: #f59e0b; }
</style>
<div class="container-fluid p-4">
<div class="row mb-4">
<div class="col-12">
<div class="card card-custom bg-gradient-primary p-4 p-md-5">
<div class="d-flex flex-column flex-md-row align-items-center position-relative" style="z-index: 1;">
<div class="flex-shrink-0 mb-3 mb-md-0">
<img src="https://ui-avatars.com/api/?name={{ urlencode($anggota->nama_lengkap) }}&background=ffffff&color=0d6efd&size=120&bold=true"
class="rounded-circle shadow-sm border border-3 border-white" width="100" alt="Foto Profil">
</div>
<div class="flex-grow-1 ms-md-4 text-center text-md-start">
<h3 class="fw-bold mb-1">Selamat datang, {{ $anggota->nama_lengkap }}!</h3>
<p class="mb-0 text-white-50" style="font-size: 1.1rem;">
No. Induk: <strong>{{ $anggota->no_induk }}</strong>
</p>
</div>
<div class="mt-3 mt-md-0 text-center text-md-end">
<span class="badge badge-soft-primary px-4 py-2 rounded-pill fs-6 border border-light shadow-sm">
<i class="fas fa-check-circle me-1"></i> {{ strtoupper($anggota->status ?? 'ANGGOTA AKTIF') }}
</span>
</div>
</div>
</div>
</div>
</div>
<div class="row g-4 mb-4">
<div class="col-md-4">
<div class="card card-custom card-hover h-100 p-4 border-0">
<div class="d-flex align-items-center justify-content-between">
<div>
<p class="text-muted fw-semibold mb-1" style="font-size: 0.85rem;">TINGKATAN SAAT INI</p>
<h3 class="fw-bold text-dark mb-0">{{ $anggota->tingkatan ?? '-' }}</h3>
</div>
<div class="icon-box icon-box-primary shadow-sm">
<i class="bi bi-award"></i>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card card-custom card-hover h-100 p-4 border-0">
<div class="d-flex align-items-center justify-content-between">
<div>
<p class="text-muted fw-semibold mb-1" style="font-size: 0.85rem;">STATUS TAGIHAN</p>
<h3 class="fw-bold text-dark mb-0">{{ $tagihan_spp->count() }} <span class="fs-6 text-muted fw-normal">Bulan Pending</span></h3>
</div>
<div class="icon-box icon-box-warning shadow-sm">
<i class="bi bi-wallet2"></i>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card card-custom card-hover h-100 p-4 border-0">
<div class="d-flex align-items-center justify-content-between">
<div>
<p class="text-muted fw-semibold mb-1" style="font-size: 0.85rem;">KEHADIRAN LATIHAN</p>
<h3 class="fw-bold text-dark mb-0">{{ $persentase_hadir }}%</h3>
</div>
<div class="icon-box icon-box-success shadow-sm">
<i class="bi bi-graph-up-arrow"></i>
</div>
</div>
</div>
</div>
</div>
<div class="row g-4">
<div class="col-lg-7">
<div class="card card-custom h-100 border-0">
<div class="card-header bg-white border-0 pt-4 pb-0 px-4 d-flex align-items-center justify-content-between">
<h5 class="fw-bold text-dark mb-0">Jadwal Latihan Terdekat</h5>
<a href="#" class="btn btn-sm btn-light text-primary fw-semibold rounded-pill px-3">Lihat Semua</a>
</div>
<div class="card-body px-4 pt-3 pb-4 table-responsive">
<table class="table table-modern table-borderless align-middle mb-0">
<thead>
<tr>
<th>Kegiatan</th>
<th>Waktu</th>
<th>Lokasi</th>
</tr>
</thead>
<tbody>
@forelse($jadwal as $j)
<tr>
<td>
<div class="d-flex align-items-center">
<div class="bg-light rounded p-2 me-3 text-primary"><i class="fas fa-dumbbell"></i></div>
<span class="fw-bold text-dark">{{ $j->judul_kegiatan }}</span>
</div>
</td>
<td>
<span class="d-block fw-semibold text-dark">{{ \Carbon\Carbon::parse($j->tanggal)->translatedFormat('d M Y') }}</span>
<small class="text-muted">{{ \Carbon\Carbon::parse($j->jam_mulai)->format('H:i') }} - {{ \Carbon\Carbon::parse($j->jam_selesai)->format('H:i') }} WIB</small>
</td>
<td>
<span class="badge bg-light text-dark border"><i class="fas fa-map-marker-alt text-danger me-1"></i> {{ $j->lokasi }}</span>
</td>
</tr>
@empty
<tr>
<td colspan="3" class="text-center py-5">
<img src="https://cdn-icons-png.flaticon.com/512/7486/7486744.png" alt="No Schedule" width="80" class="mb-3 opacity-50">
<h6 class="fw-bold text-secondary">Belum Ada Jadwal</h6>
<p class="text-muted small mb-0">Istirahat dulu, belum ada jadwal latihan dalam waktu dekat.</p>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
<div class="col-lg-5">
<div class="card card-custom h-100 border-0 bg-white">
<div class="card-header bg-white border-0 pt-4 pb-0 px-4">
<h5 class="fw-bold text-dark mb-0">Tagihan SPP Anda</h5>
</div>
<div class="card-body px-4 pt-4 pb-4">
@if($tagihan_spp->isEmpty())
<div class="text-center py-5">
<div class="bg-success bg-opacity-10 rounded-circle d-inline-flex p-4 mb-3">
<i class="fas fa-check fs-1 text-success"></i>
</div>
<h5 class="fw-bold text-dark">Semua Lunas!</h5>
<p class="text-muted mb-0">Terima kasih telah disiplin membayar iuran bulanan.</p>
</div>
@else
<div class="d-flex flex-column gap-3">
@foreach($tagihan_spp as $spp)
<div class="bill-item bg-white shadow-sm d-flex justify-content-between align-items-center">
<div class="d-flex align-items-center">
<div class="bg-warning bg-opacity-10 text-warning rounded p-3 me-3">
<i class="bi bi-wallet2 fs-5"></i>
</div>
<div>
<h6 class="fw-bold text-dark mb-1">SPP Bulan {{ $spp->bulan ?? 'Ini' }}</h6>
<span class="text-danger fw-bold fs-6">Rp {{ number_format($spp->nominal ?? 0, 0, ',', '.') }}</span>
</div>
</div>
<button class="btn btn-primary rounded-pill px-4 fw-semibold shadow-sm">Bayar</button>
</div>
@endforeach
</div>
@endif
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -3,118 +3,128 @@
@section('content') @section('content')
<div class="container-fluid py-4"> <div class="container-fluid py-4">
<!-- Header Section --> <!-- Header Section -->
<div class="d-flex justify-content-between align-items-center mb-4 text-start"> <div class="row align-items-center mb-4">
<div> <div class="col-md-8 text-start">
<h3 class="fw-bold text-dark mb-1">Dashboard Pengurus</h3> <h3 class="fw-bold text-dark mb-1">Pusat Kendali Operasional</h3>
<p class="text-muted small">Ringkasan data Merpati Putih Cabang Jember {{ date('d M Y') }}</p> <p class="text-muted small">
<i class="bi bi-calendar3 me-1"></i> {{ date('l, d M Y') }}
<span class="mx-2"></span>
<i class="bi bi-clock me-1"></i> <span id="realtime-clock">--:--</span>
</p>
</div>
<div class="col-md-4 text-md-end">
<div class="d-inline-flex align-items-center bg-white p-2 shadow-sm" style="border-radius: 12px;">
<div class="bg-primary-soft text-primary p-2 rounded-3 me-3" style="background-color: #e7f0ff; color: #0d6efd;">
<i class="bi bi-shield-lock-fill"></i>
</div>
<div class="text-start me-3">
<small class="text-muted d-block" style="font-size: 10px;">ROLE AKSES</small>
<span class="fw-bold small text-primary">Administrator</span>
</div>
</div> </div>
<div>
<span class="badge bg-primary-soft text-primary px-3 py-2 rounded-pill">
<i class="fas fa-user-shield me-1"></i> Mode Administrator
</span>
</div> </div>
</div> </div>
<!-- Statistik Cards --> <!-- Statistik Cards: Sekarang Bisa Diklik (Linked) -->
<div class="row g-3 mb-4"> <div class="row g-4 mb-4">
<div class="col-md-3"> @php
<div class="card border-0 shadow-sm p-3" style="border-radius: 15px; border-left: 5px solid #0d6efd;"> $stats = [
<div class="d-flex align-items-center"> ['label' => 'Anggota Aktif', 'value' => $total_anggota_aktif, 'icon' => 'bi-people', 'color' => '#0d6efd', 'desc' => 'Kelola Anggota', 'link' => route('anggota.anggota')],
<div class="p-3 bg-primary bg-opacity-10 rounded-3 text-primary me-3"> ['label' => 'Total Pelatih', 'value' => $total_pelatih, 'icon' => 'bi-person-badge', 'color' => '#198754', 'desc' => 'Manajemen Pelatih', 'link' => route('pelatih.index')],
<i class="fas fa-users fa-lg"></i> ['label' => 'Unit Kolat', 'value' => $total_kolat, 'icon' => 'bi-building', 'color' => '#0dcaf0', 'desc' => 'Daftar Kolat', 'link' => route('kolat.index')],
</div> ['label' => 'SPP Tertunda', 'value' => $spp_pending, 'icon' => 'bi-cash-stack', 'color' => '#f21136', 'desc' => 'Verifikasi SPP', 'link' => route('spp.index')]
<div> ];
<small class="text-muted d-block">Anggota Aktif</small> @endphp
<h4 class="fw-bold mb-0">{{ $total_anggota_aktif }}</h4>
</div> @foreach($stats as $stat)
</div> <div class="col-xl-3 col-md-6">
</div> <a href="{{ $stat['link'] }}" class="text-decoration-none">
</div> <div class="card border-0 shadow-sm h-100 stat-card" style="border-radius: 20px; background: white; transition: 0.3s;">
<div class="col-md-3"> <div class="card-body p-4 text-start">
<div class="card border-0 shadow-sm p-3" style="border-radius: 15px; border-left: 5px solid #198754;"> <div class="d-flex justify-content-between mb-3">
<div class="d-flex align-items-center"> <div class="icon-box rounded-3" style="background-color: {{ $stat['color'] }}15; color: {{ $stat['color'] }}; width: 45px; height: 45px; display: flex; align-items: center; justify-content: center;">
<div class="p-3 bg-success bg-opacity-10 rounded-3 text-success me-3"> <i class="bi {{ $stat['icon'] }}" style="font-size: 1.2rem;"></i>
<i class="fas fa-user-tie fa-lg"></i>
</div>
<div>
<small class="text-muted d-block">Total Pelatih</small>
<h4 class="fw-bold mb-0">{{ $total_pelatih }}</h4>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card border-0 shadow-sm p-3" style="border-radius: 15px; border-left: 5px solid #0dcaf0;">
<div class="d-flex align-items-center">
<div class="p-3 bg-info bg-opacity-10 rounded-3 text-info me-3">
<i class="fas fa-university fa-lg"></i>
</div>
<div>
<small class="text-muted d-block">Total Kolat</small>
<h4 class="fw-bold mb-0">{{ $total_kolat }}</h4>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card border-0 shadow-sm p-3" style="border-radius: 15px; border-left: 5px solid #ffc107;">
<div class="d-flex align-items-center">
<div class="p-3 bg-warning bg-opacity-10 rounded-3 text-warning me-3">
<i class="fas fa-file-invoice-dollar fa-lg"></i>
</div>
<div>
<small class="text-muted d-block">SPP Tertunda</small>
<h4 class="fw-bold mb-0">{{ $spp_pending }}</h4>
</div> </div>
<span class="text-primary small"><i class="bi bi-arrow-right-short" style="font-size: 1.5rem;"></i></span>
</div>
<h3 class="fw-bold mb-1 text-dark">{{ $stat['value'] }}</h3>
<p class="text-dark fw-bold small mb-1">{{ $stat['label'] }}</p>
<p class="text-muted mb-0" style="font-size: 11px;">{{ $stat['desc'] }}</p>
</div> </div>
</div> </div>
</a>
</div> </div>
@endforeach
</div> </div>
<!-- Charts Row --> <!-- Charts Row -->
<div class="row g-4 mb-4 text-start"> <div class="row g-4 mb-4 text-start">
<div class="col-md-8"> <div class="col-lg-8">
<div class="card border-0 shadow-sm p-4" style="border-radius: 20px;"> <div class="card border-0 shadow-sm p-4" style="border-radius: 25px;">
<h6 class="fw-bold text-dark mb-4"><i class="fas fa-chart-line me-2 text-primary"></i>Tren Kehadiran Latihan (7 Hari Terakhir)</h6> <div class="d-flex justify-content-between align-items-center mb-4">
<div style="height: 300px;"> <div>
<h6 class="fw-bold text-dark mb-1">Tren Kehadiran</h6>
<small class="text-muted font-12">Grafik kehadiran 7 hari terakhir</small>
</div>
<a href="{{ route('laporan.presensi') }}" class="btn btn-light btn-sm text-primary fw-bold" style="border-radius: 10px;">Lihat Laporan</a>
</div>
<div style="height: 320px;">
<canvas id="chartPresensi"></canvas> <canvas id="chartPresensi"></canvas>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4">
<div class="card border-0 shadow-sm p-4" style="border-radius: 20px;"> <div class="col-lg-4">
<h6 class="fw-bold text-dark mb-4"><i class="fas fa-chart-pie me-2 text-primary"></i>Komposisi Tingkatan</h6> <div class="card border-0 shadow-sm p-4" style="border-radius: 25px;">
<div style="height: 300px;"> <h6 class="fw-bold text-dark mb-1 text-center">Komposisi Sabuk</h6>
<div style="height: 250px; position: relative;">
<canvas id="chartSabuk"></canvas> <canvas id="chartSabuk"></canvas>
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -15%); text-align: center;">
<h4 class="mb-0 fw-bold">{{ $total_anggota_aktif }}</h4>
<small class="text-muted small">Anggota</small>
</div>
</div>
<div class="mt-4">
<div class="d-grid">
<a href="{{ route('anggota.anggota') }}" class="btn btn-outline-primary btn-sm rounded-pill">Detail Anggota</a>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- Activities & Quick Actions Row --> <!-- Log Transaksi & Kelayakan -->
<div class="row g-4 text-start"> <div class="row g-4 text-start">
<!-- Aktivitas Terbaru --> <div class="col-lg-8">
<div class="col-md-8"> <div class="card border-0 shadow-sm" style="border-radius: 25px; overflow: hidden;">
<div class="card border-0 shadow-sm p-4" style="border-radius: 20px;"> <div class="card-header bg-white border-0 p-4 pb-0 d-flex justify-content-between align-items-center">
<h6 class="fw-bold text-dark mb-4">Aktivitas Transaksi Terbaru</h6> <h6 class="fw-bold text-dark mb-0">Aktivitas Terbaru</h6>
<a href="{{ route('spp.index') }}" class="small text-decoration-none">Lihat Semua</a>
</div>
<div class="card-body p-0">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover align-middle"> <table class="table table-hover align-middle mb-0">
<thead class="bg-light"> <thead class="bg-light text-muted small">
<tr class="small text-muted"> <tr>
<th>WAKTU</th> <th class="ps-4 border-0">USER</th>
<th>KEGIATAN</th> <th class="border-0">KEGIATAN</th>
<th>USER</th> <th class="border-0 text-center">STATUS</th>
<th>STATUS</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach($aktivitas as $act) @foreach($aktivitas as $act)
<tr> <tr>
<td class="small text-muted">{{ $act['waktu'] }}</td> <td class="ps-4">
<td class="small fw-bold">{{ $act['kegiatan'] }}</td> <div class="d-flex align-items-center">
<td class="small">{{ $act['user'] }}</td> <div class="rounded-circle me-3 d-flex align-items-center justify-content-center fw-bold" style="width: 35px; height: 35px; font-size: 12px; background-color: #e7f0ff; color: #0d6efd;">
<td> {{ substr($act['user'], 0, 1) }}
<span class="badge bg-{{ $act['badge'] }}-soft text-{{ $act['badge'] }} px-2 py-1 rounded small"> </div>
<span class="small fw-bold text-dark">{{ $act['user'] }}</span>
</div>
</td>
<td class="small text-muted">{{ $act['kegiatan'] }}</td>
<td class="text-center">
<span class="badge rounded-pill bg-{{ $act['badge'] }} px-3 py-2" style="font-size: 10px; opacity: 0.8;">
{{ $act['status'] }} {{ $act['status'] }}
</span> </span>
</td> </td>
@ -125,29 +135,22 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Quick Actions & Summary -->
<div class="col-md-4">
<div class="card border-0 shadow-sm p-4 h-100" style="border-radius: 20px; background: linear-gradient(135deg, #ffffff 0%, #f8faff 100%);">
<h6 class="fw-bold text-dark mb-4">Ringkasan Operasional</h6>
<div class="mb-4">
<small class="text-muted d-block mb-2">Kelayakan Ujian Saat Ini</small>
<div class="d-flex align-items-center">
<h3 class="fw-bold text-primary mb-0 me-2">{{ $jumlah_layak_ujian }}</h3>
<span class="text-muted small">Anggota Siap Ujian</span>
</div>
<div class="progress mt-2" style="height: 5px;">
<div class="progress-bar bg-primary" style="width: {{ ($total_anggota_aktif > 0) ? ($jumlah_layak_ujian/$total_anggota_aktif)*100 : 0 }}%"></div>
</div>
</div> </div>
<div class="d-grid gap-2"> <div class="col-lg-4">
<a href="{{ route('rekap.index') }}" class="btn btn-primary py-3 rounded-3 shadow-sm"> <div class="card border-0 shadow-sm p-4 h-100 text-center" style="border-radius: 25px; background: linear-gradient(180deg, #ffffff 0%, #f0f7ff 100%);">
<i class="fas fa-clipboard-check me-2"></i> Buka Rekap Kelayakan <h6 class="fw-bold text-dark mb-4">Ringkasan Kelayakan</h6>
</a> <div class="d-inline-block position-relative mb-3 mx-auto" style="width: 130px;">
<a href="{{ route('spp.index') }}" class="btn btn-outline-primary py-3 rounded-3"> <canvas id="progressUjian"></canvas>
<i class="fas fa-wallet me-2"></i> Verifikasi SPP <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; width: 100%;">
<h2 class="fw-bold text-primary mb-0" style="line-height: 1;">{{ $jumlah_layak_ujian }}</h2>
<small class="text-muted d-block" style="font-size: 10px; margin-top: -2px;">Siswa</small>
</div>
</div>
<p class="small text-muted px-2">Siswa dinyatakan layak mengikuti ujian berdasarkan presensi & SPP.</p>
<div class="d-grid gap-3 mt-auto">
<a href="{{ route('rekap.index') }}" class="btn btn-primary py-3 rounded-4 shadow-sm fw-bold">
<i class="bi bi-clipboard-check me-2"></i> Buka Rekap Kelayakan
</a> </a>
</div> </div>
</div> </div>
@ -155,22 +158,38 @@
</div> </div>
</div> </div>
<!-- Chart JS --> <style>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> .stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0,0,0,0.1) !important;
}
.bg-primary-soft { background-color: #e7f0ff; }
</style>
<script> <script>
// Grafik Presensi (Line Chart) function updateClock() {
const now = new Date();
const timeStr = now.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' });
document.getElementById('realtime-clock').textContent = timeStr + ' WIB';
}
setInterval(updateClock, 1000); updateClock();
document.addEventListener("DOMContentLoaded", function() {
// Line Chart
const ctxP = document.getElementById('chartPresensi').getContext('2d'); const ctxP = document.getElementById('chartPresensi').getContext('2d');
new Chart(ctxP, { new Chart(ctxP, {
type: 'line', type: 'line',
data: { data: {
labels: {!! json_encode($grafikPresensi->pluck('date')) !!}, labels: {!! json_encode($grafikPresensi->pluck('date')) !!},
datasets: [{ datasets: [{
label: 'Jumlah Hadir', label: 'Kehadiran',
data: {!! json_encode($grafikPresensi->pluck('total')) !!}, data: {!! json_encode($grafikPresensi->pluck('total')) !!},
borderColor: '#0d6efd', borderColor: '#0d6efd',
backgroundColor: 'rgba(13, 110, 253, 0.05)', backgroundColor: 'rgba(13, 110, 253, 0.05)',
fill: true,
tension: 0.4, tension: 0.4,
fill: true,
pointRadius: 4,
pointBackgroundColor: '#fff',
borderWidth: 3 borderWidth: 3
}] }]
}, },
@ -178,11 +197,14 @@
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
plugins: { legend: { display: false } }, plugins: { legend: { display: false } },
scales: { y: { beginAtZero: true, grid: { display: false } }, x: { grid: { display: false } } } scales: {
x: { grid: { display: false } },
y: { grid: { color: '#f0f0f0' } }
}
} }
}); });
// Grafik Sabuk (Doughnut Chart) // Doughnut Chart
const ctxS = document.getElementById('chartSabuk').getContext('2d'); const ctxS = document.getElementById('chartSabuk').getContext('2d');
new Chart(ctxS, { new Chart(ctxS, {
type: 'doughnut', type: 'doughnut',
@ -190,23 +212,27 @@
labels: {!! json_encode($persebaran_sabuk->pluck('tingkatan')) !!}, labels: {!! json_encode($persebaran_sabuk->pluck('tingkatan')) !!},
datasets: [{ datasets: [{
data: {!! json_encode($persebaran_sabuk->pluck('total')) !!}, data: {!! json_encode($persebaran_sabuk->pluck('total')) !!},
backgroundColor: ['#0d6efd', '#0dcaf0', '#198754', '#ffc107', '#dc3545', '#6610f2'] backgroundColor: ['#0d6efd', '#0dcaf0', '#198754', '#ffc107', '#dc3545', '#6f42c1'],
borderWidth: 0,
hoverOffset: 10
}] }]
}, },
options: { options: { responsive: true, maintainAspectRatio: false, cutout: '80%', plugins: { legend: { display: false } } }
responsive: true, });
maintainAspectRatio: false,
cutout: '75%', // Progress Ujian
plugins: { legend: { position: 'bottom', labels: { usePointStyle: true, boxWidth: 10 } } } const ctxU = document.getElementById('progressUjian').getContext('2d');
} new Chart(ctxU, {
type: 'doughnut',
data: {
datasets: [{
data: [{{ $jumlah_layak_ujian }}, {{ max(1, $total_anggota_aktif - $jumlah_layak_ujian) }}],
backgroundColor: ['#0d6efd', '#f1f5f9'],
borderWidth: 0
}]
},
options: { cutout: '85%', plugins: { tooltip: {enabled: false} } }
});
}); });
</script> </script>
<style>
.bg-primary-soft { background-color: #e7f0ff; }
.bg-success-soft { background-color: #e6fffa; }
.bg-warning-soft { background-color: #fffaf0; }
.bg-info-soft { background-color: #e0f2fe; }
.bg-danger-soft { background-color: #fff5f5; }
</style>
@endsection @endsection

View File

@ -9,7 +9,7 @@
<meta name="keywords" content=""> <meta name="keywords" content="">
<!-- Favicons --> <!-- Favicons -->
<link href="{{ asset('assets/img/favicon.png') }}" rel="icon"> <link href="{{ asset('assets/img/logo1.jpg') }}" rel="icon">
<link href="{{ asset('assets/img/apple-touch-icon.png') }}" rel="apple-touch-icon"> <link href="{{ asset('assets/img/apple-touch-icon.png') }}" rel="apple-touch-icon">
<!-- Fonts --> <!-- Fonts -->
@ -47,9 +47,9 @@
<i class="bi bi-phone d-flex align-items-center ms-4"><span>081776198245</span></i> <i class="bi bi-phone d-flex align-items-center ms-4"><span>081776198245</span></i>
</div> </div>
<div class="social-links d-none d-md-flex align-items-center"> <div class="social-links d-none d-md-flex align-items-center">
<a href="#" class="facebook"><i class="bi bi-facebook"></i></a> <a href="https://www.facebook.com/share/1ATYmi4SUw/" class="facebook"><i class="bi bi-facebook"></i></a>
<a href="#" class="instagram"><i class="bi bi-instagram"></i></a> <a href="https://www.instagram.com/mpcabangjember?igsh=cnA1andsNno4NXUx" class="instagram"><i class="bi bi-instagram"></i></a>
<a href="#" class="linkedin"><i class="bi bi-linkedin"></i></a> {{-- <a href="#" class="linkedin"><i class="bi bi-linkedin"></i></a> --}}
</div> </div>
</div> </div>
</div><!-- End Top Bar --> </div><!-- End Top Bar -->
@ -65,11 +65,11 @@
<nav id="navmenu" class="navmenu"> <nav id="navmenu" class="navmenu">
<ul> <ul>
<li><a href="index.html" class="active">Home</a></li> <li><a href="#hero" class="active">Home</a></li>
<li><a href="about.html">Tentang</a></li> <li><a href="#about">Tentang</a></li>
<li><a href="services.html">Fitur Utama</a></li> <li><a href="#services">Fitur Utama</a></li>
<li><a href="projects.html">Panduan</a></li> <li><a href="#call-to-action">Kontak</a></li>
<li><a href="contact.html">Kontak</a></li>
</ul> </ul>
<i class="mobile-nav-toggle d-xl-none bi bi-list"></i> <i class="mobile-nav-toggle d-xl-none bi bi-list"></i>
</nav> </nav>
@ -95,8 +95,7 @@
<p>Membangun organisasi yang lebih tertib, transparan, dan terintegrasi melalui TapakMP.</p> <p>Membangun organisasi yang lebih tertib, transparan, dan terintegrasi melalui TapakMP.</p>
<div class="hero-buttons"> <div class="hero-buttons">
<a href="#" class="btn-primary">Masuk Sistem</a> <a href="{{ route('login') }}" class="btn-primary">Masuk Sistem</a>
<a href="#" class="btn-secondary">Jadwal Latihan</a>
</div> </div>
<div class="trust-badges"> <div class="trust-badges">
@ -174,23 +173,14 @@
</div> </div>
</div> </div>
</div> </div>
<div class="cta-container mt-5" data-aos="fade-up" data-aos-delay="800">
<a href="about.html" class="btn btn-primary">Akses Ruang Anggota</a>
</div>
</div> </div>
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
<div class="about-image position-relative" data-aos="fade-left" data-aos-delay="200"> <div class="about-image position-relative" data-aos="fade-left" data-aos-delay="200">
<img src="{{ asset('assets/img/construction/project-3.webp') }}" alt="Construction Team" class="img-fluid main-image rounded"> <img src="{{ asset('assets/img/construction/gambar3.jpeg') }}" alt="Construction Team" class="img-fluid main-image rounded">
<div class="image-overlay"> <div class="image-overlay">
<img src="{{ asset('assets/img/construction/project-7.webp') }}" alt="Construction Project" class="img-fluid rounded"> <img src="{{ asset('assets/img/construction/gambar2.jpeg') }}" alt="Construction Project" class="img-fluid rounded">
</div>
<div class="experience-badge" data-aos="zoom-in" data-aos-delay="500">
<span>25+</span>
<p>Years of Experience</p>
</div> </div>
</div> </div>
</div> </div>
@ -285,151 +275,45 @@
<!-- Call To Action Section --> <!-- Call To Action Section -->
<section id="call-to-action" class="call-to-action section light-background"> <section id="call-to-action" class="call-to-action section light-background">
<div class="container" data-aos="fade-up">
<div class="row justify-content-center">
<div class="col-lg-8 text-center">
<div class="container" data-aos="fade-up" data-aos-delay="100"> <!-- Badge Status -->
<div class="badge-wrapper mb-3">
<div class="row g-5 align-items-center"> <span class="cta-badge" style="background: rgba(var(--accent-color-rgb), 0.1); padding: 8px 20px; border-radius: 50px; font-size: 14px; font-weight: 600; color: var(--accent-color);">
<i class="bi bi-shield-check"></i> Terintegrasi & Aman Sejak 2026
<div class="col-lg-6">
<div class="cta-hero-content" data-aos="fade-right" data-aos-delay="200">
<div class="badge-wrapper">
<span class="cta-badge">
<i class="bi bi-shield-check"></i>
Terintegrasi & Aman Sejak 2026
</span> </span>
</div> </div>
<h2>Siap Melangkah Bersama TapakMP?</h2> <!-- Heading & Deskripsi -->
<p>Pastikan data Anda atau Kelompok Latihan (Kolat) <h2 style="font-size: 2.5rem; font-weight: 700; margin-bottom: 20px;">Siap Melangkah Bersama TapakMP?</h2>
Anda terdata secara resmi di Cabang Jember. Hubungi admin <p class="lead mb-4">
kami jika Anda mengalamikendala akses atau ingin mendaftarkan akun baru.</p> Pastikan data Anda atau Kelompok Latihan (Kolat) terdata secara resmi di Cabang Jember.
Hubungi admin kami untuk bantuan pendaftaran akun baru, kendala akses, atau panduan sistem.
</p>
<div class="feature-highlights"> <!-- Feature Highlights (Inline) -->
<div class="highlight-item"> <div class="d-flex flex-wrap justify-content-center gap-3 mb-5">
<i class="bi bi-check-circle-fill"></i> <div class="highlight-item"><i class="bi bi-check-circle-fill text-success"></i> Akun Anggota</div>
<span>Bantuan pendaftaran akun anggota baru</span> <div class="highlight-item"><i class="bi bi-check-circle-fill text-success"></i> Dukungan Teknis</div>
</div> <div class="highlight-item"><i class="bi bi-check-circle-fill text-success"></i> Panduan Admin</div>
<div class="highlight-item">
<i class="bi bi-check-circle-fill"></i>
<span>Dukungan teknis kendala <i>login</i> dan <i>password</i></span>
</div>
<div class="highlight-item">
<i class="bi bi-check-circle-fill"></i>
<span>Layanan panduan input data keuangan & absensi</span>
</div>
</div>
</div>
</div> </div>
<div class="col-lg-6"> <!-- Tombol Kontak Utama -->
<div class="cta-form-section" data-aos="fade-left" data-aos-delay="300"> <div class="cta-actions">
<div class="form-container"> <a href="https://wa.me/6281617376290" class="btn btn-primary btn-lg px-5 py-3 shadow-sm" target="_blank" rel="noopener noreferrer" style="border-radius: 50px; font-weight: 600;">
<div class="form-header"> <i class="bi bi-whatsapp me-2"></i> Hubungi Admin Melalui WhatsApp
<h3>Hubungi Admin Cabang</h3>
<p>Lengkapi data di bawah untuk bantuan administrasi sistem</p>
</div>
<form action="forms/get-a-quote.php" method="post" class="php-email-form">
<div class="row g-3">
<div class="col-md-6">
<div class="form-group">
<input type="text" name="name" class="form-control" placeholder="Nama Lengkap" required="">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="email" name="email" class="form-control" placeholder="Alamat Email Aktif" required="">
</div>
</div>
<div class="col-12">
<div class="form-group">
<input type="tel" name="phone" class="form-control" placeholder="Nomor WhatsApp" required="">
</div>
</div>
<div class="col-12">
<div class="form-group">
<select name="type" class="form-control" required="">
<option value="">Pilih Jenis Bantuan</option>
<option value="residential">Pendaftaran akun baru</option>
<option value="commercial">Masalah Login</option>
<option value="renovation">Laporan Keuangan</option>
<option value="other">Lainnya</option>
</select>
</div>
</div>
<div class="col-12">
<div class="form-group">
<textarea name="message" class="form-control" rows="4" placeholder="Detail Pesan atau Kendala" required=""></textarea>
</div>
</div>
</div>
<div class="loading">Loading</div>
<div class="error-message"></div>
<div class="sent-message">Kirim Pesan Sekarang!</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="bi bi-send"></i>
Kirim Pesan
</button>
<div class="contact-alternative">
<span>Atau hubungi kami secara langsung melalui:</span>
<a href="https://wa.me/6281617376290" class="phone-link" target="_blank" rel="noopener noreferrer">
<i class="bi bi-whatsapp"></i>
+62 816-1737-6290
</a> </a>
</div> <p class="mt-3 text-muted small">
</div> <i class="bi bi-clock me-1"></i> Jam Operasional Admin: <strong>08.00 - 17.00 WIB</strong>
</form> </p>
</div>
<div class="trust-indicators" data-aos="fade-up" data-aos-delay="400">
<div class="row g-3">
<div class="col-4">
<div class="trust-item">
<div class="trust-icon">
<i class="bi bi-clock"></i>
</div>
<div class="trust-content">
<span class="trust-number">08.00 - 17.00</span>
<span class="trust-label">Respon Admin</span>
</div>
</div>
</div>
<div class="col-4">
<div class="trust-item">
<div class="trust-icon">
<i class="bi bi-star-fill"></i>
</div>
<div class="trust-content">
<span class="trust-number">4.9</span>
<span class="trust-label">Customer Rating</span>
</div>
</div>
</div>
<div class="col-4">
<div class="trust-item">
<div class="trust-icon">
<i class="bi bi-hammer"></i>
</div>
<div class="trust-content">
<span class="trust-number">350+</span>
<span class="trust-label">Projects Done</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</section><!-- /Call To Action Section --> </section><!-- /Call To Action Section -->
</main> </main>
@ -437,66 +321,66 @@
<div class="container footer-top"> <div class="container footer-top">
<div class="row gy-4"> <div class="row gy-4">
<!-- Bagian Tentang (About) -->
<div class="col-lg-5 col-md-12 footer-about"> <div class="col-lg-5 col-md-12 footer-about">
<a href="index.html" class="logo d-flex align-items-center"> <a href="index.html" class="logo d-flex align-items-center">
<span class="sitename">MyWebsite</span> <span class="sitename">TapakMP</span>
</a> </a>
<p>Cras fermentum odio eu feugiat lide par naso tierra. Justo eget nada terra videa magna derita valies darta donna mare fermentum iaculis eu non diam phasellus.</p> <p>Sistem informasi manajemen terpadu PPS Betako Merpati Putih Cabang Jember. Mewujudkan transparansi data anggota, administrasi keuangan, dan absensi dalam satu genggaman.</p>
<div class="social-links d-flex mt-4"> <div class="social-links d-flex mt-4">
<a href=""><i class="bi bi-twitter-x"></i></a> <a href="https://www.instagram.com/mpcabangjember?igsh=cnA1andsNno4NXUx"><i class="bi bi-instagram"></i></a>
<a href=""><i class="bi bi-facebook"></i></a> <a href="https://youtube.com/@ppsbetakomerpatiputihcaban8671?si=7332dwKZXmF5_auT"><i class="bi bi-youtube"></i></a>
<a href=""><i class="bi bi-instagram"></i></a> <a href="https://www.facebook.com/share/1ATYmi4SUw/"><i class="bi bi-facebook"></i></a>
<a href=""><i class="bi bi-linkedin"></i></a>
</div> </div>
</div> </div>
<div class="col-lg-2 col-6 footer-links"> <!-- Tautan Penting -->
<h4>Useful Links</h4> {{-- <div class="col-lg-2 col-6 footer-links">
<h4>Navigasi</h4>
<ul> <ul>
<li><a href="#">Home</a></li> <li><a href="#">Beranda</a></li>
<li><a href="#">About us</a></li> <li><a href="#">Tentang Kami</a></li>
<li><a href="#">Services</a></li> <li><a href="#">Data Kolat</a></li>
<li><a href="#">Terms of service</a></li> <li><a href="#">Jadwal Latihan</a></li>
<li><a href="#">Privacy policy</a></li> <li><a href="#">Kebijakan Privasi</a></li>
</ul>
</div> --}}
<!-- Fitur Sistem -->
<div class="col-lg-3 col-3 footer-links">
<h4>Fitur Utama</h4>
<ul>
<li><a href="#">Manajemen Anggota</a></li>
<li><a href="#">Iuran SPP & Keuangan</a></li>
<li><a href="#">Presensi Digital</a></li>
<li><a href="#">Laporan Cabang</a></li>
<li><a href="#">Database Pelatih</a></li>
</ul> </ul>
</div> </div>
<div class="col-lg-2 col-6 footer-links"> <!-- Informasi Kontak Cabang -->
<h4>Our Services</h4> <div class="col-lg-4 col-md-12 footer-contact text-center text-md-start">
<ul> <h4>Kontak Cabang</h4>
<li><a href="#">Web Design</a></li> <p>Sekretariat Merpati Putih Jember</p>
<li><a href="#">Web Development</a></li> <p>Jember, Jawa Timur</p>
<li><a href="#">Product Management</a></li> <p>Indonesia</p>
<li><a href="#">Marketing</a></li> <p class="mt-4"><strong>WhatsApp:</strong> <span>+62 816-1737-6290</span></p>
<li><a href="#">Graphic Design</a></li> <p><strong>Email:</strong> <span>admin@tapakmp.com</span></p>
</ul>
</div>
<div class="col-lg-3 col-md-12 footer-contact text-center text-md-start">
<h4>Contact Us</h4>
<p>A108 Adam Street</p>
<p>New York, NY 535022</p>
<p>United States</p>
<p class="mt-4"><strong>Phone:</strong> <span>+1 5589 55488 55</span></p>
<p><strong>Email:</strong> <span>info@example.com</span></p>
</div> </div>
</div> </div>
</div> </div>
<!-- Copyright -->
<div class="container copyright text-center mt-4"> <div class="container copyright text-center mt-4">
<p>© <span>Copyright</span> <strong class="px-1 sitename">Constructo</strong> <span>All Rights Reserved</span></p> <p>© 2026 <span>Copyright</span> <strong class="px-1 sitename">TapakMP</strong> <span>All Rights Reserved</span></p>
<div class="credits"> <div class="credits">
<!-- All the links in the footer should remain intact. --> Dikembangkan oleh <a href="#">Siti</a> | Cabang Jember
<!-- You can delete the links only if you've purchased the pro version. -->
<!-- Licensing information: https://bootstrapmade.com/license/ -->
<!-- Purchase the pro version with working PHP/AJAX contact form: [buy-url] -->
Designed by <a href="https://bootstrapmade.com/">BootstrapMade</a> | <a href="https://bootstrapmade.com/tools/">DevTools</a>
</div> </div>
</div> </div>
</footer> </footer>
<!-- Scroll Top --> <!-- Scroll Top -->
<a href="#" id="scroll-top" class="scroll-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a> <a href="#" id="scroll-top" class="scroll-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a>

View File

@ -232,13 +232,13 @@
<div class="d-flex justify-content-center gap-2"> <div class="d-flex justify-content-center gap-2">
<!-- Button Edit --> <!-- Button Edit -->
<button type="button" class="btn-action-custom btn-edit" data-bs-toggle="modal" data-bs-target="#modalEditKas{{ $item->id }}"> <button type="button" class="btn-action-custom btn-edit" data-bs-toggle="modal" data-bs-target="#modalEditKas{{ $item->id }}">
<i class="icon-note"></i> <i class="bi bi-pencil"></i>
</button> </button>
<!-- Form Hapus --> <!-- Form Hapus -->
<form action="{{ route('kas.destroy', $item->id) }}" method="POST" id="form-hapus-{{ $item->id }}"> <form action="{{ route('kas.destroy', $item->id) }}" method="POST" id="form-hapus-{{ $item->id }}">
@csrf @method('DELETE') @csrf @method('DELETE')
<button type="button" class="btn-action-custom btn-delete" onclick="hapusKas('{{ $item->id }}')"> <button type="button" class="btn-action-custom btn-delete" onclick="hapusKas('{{ $item->id }}')">
<i class="icon-trash"></i> <i class="bi bi-trash"></i>
</button> </button>
</form> </form>
</div> </div>

View File

@ -55,7 +55,7 @@
<div class="fw-bold text-dark">Kolat {{ $item->nama_kolat }}</div> <div class="fw-bold text-dark">Kolat {{ $item->nama_kolat }}</div>
<small class="text-muted d-block">Pusat Latihan Unit</small> <small class="text-muted d-block">Pusat Latihan Unit</small>
</td> </td>
<td class="text-start"> <td class="text-center">
<span class="text-muted small"> <span class="text-muted small">
<i class="bi bi-geo-alt me-1"></i> {{ $item->alamat_kolat ?? 'Alamat belum diatur' }} <i class="bi bi-geo-alt me-1"></i> {{ $item->alamat_kolat ?? 'Alamat belum diatur' }}
</span> </span>
@ -65,7 +65,7 @@
<!-- Edit Button --> <!-- Edit Button -->
<a href="{{ route('kolat.edit', $item->id) }}" <a href="{{ route('kolat.edit', $item->id) }}"
class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs"> class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs">
<i class="bi bi-pencil-square"></i> Edit <i class="bi bi-pencil-square"></i>
</a> </a>
<!-- Delete Button dengan SweetAlert --> <!-- Delete Button dengan SweetAlert -->
@ -73,7 +73,7 @@ class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs">
@csrf @csrf
@method('DELETE') @method('DELETE')
<button type="button" onclick="confirmDelete({{ $item->id }})" class="btn btn-sm btn-action-delete fw-bold px-3 shadow-xs"> <button type="button" onclick="confirmDelete({{ $item->id }})" class="btn btn-sm btn-action-delete fw-bold px-3 shadow-xs">
<i class="bi bi-trash"></i> Hapus <i class="bi bi-trash"></i>
</button> </button>
</form> </form>
</div> </div>

View File

@ -3,13 +3,13 @@
@section('content') @section('content')
<div class="container-fluid py-4"> <div class="container-fluid py-4">
<div class="page-header mb-4 text-start"> <div class="page-header mb-4 text-start">
<nav aria-label="breadcrumb"> {{-- <nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent p-0 mb-2"> <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"><a href="#" class="text-muted text-decoration-none small">Home</a></li>
<li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Laporan</a></li> <li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Laporan</a></li>
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Laporan Anggota</li> <li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Laporan Anggota</li>
</ol> </ol>
</nav> </nav> --}}
<h3 class="fw-bold text-dark">Laporan Keanggotaan</h3> <h3 class="fw-bold text-dark">Laporan Keanggotaan</h3>
<p class="text-muted small">Rekapitulasi dan filter data anggota Merpati Putih Cabang Jember.</p> <p class="text-muted small">Rekapitulasi dan filter data anggota Merpati Putih Cabang Jember.</p>
</div> </div>
@ -66,7 +66,7 @@
<thead> <thead>
<tr> <tr>
<th width="60" class="text-center">No</th> <th width="60" class="text-center">No</th>
<th>Identitas Anggota</th> <th class="text-center">Identitas Anggota</th>
<th class="text-center">Tingkatan & Kolat</th> <th class="text-center">Tingkatan & Kolat</th>
<th class="text-center">Status</th> <th class="text-center">Status</th>
</tr> </tr>
@ -76,8 +76,8 @@
<tr> <tr>
<td class="text-muted small text-center">{{ $no + 1 }}</td> <td class="text-muted small text-center">{{ $no + 1 }}</td>
<td> <td>
<div class="fw-bold text-dark text-start ps-3">{{ $item->nama_lengkap }}</div> <div class="fw-bold text-dark text-start ps-3 text-center">{{ $item->nama_lengkap }}</div>
<small class="text-muted text-start ps-3 d-block">ID: {{ $item->no_induk }}</small> <small class="text-muted text-start ps-3 d-block text-center">ID: {{ $item->no_induk }}</small>
</td> </td>
<td class="text-center"> <td class="text-center">
<span class="badge bg-info-soft text-info px-3 py-2 rounded-pill">{{ $item->tingkatan }}</span> <span class="badge bg-info-soft text-info px-3 py-2 rounded-pill">{{ $item->tingkatan }}</span>

View File

@ -2,14 +2,14 @@
@section('content') @section('content')
<div class="container-fluid py-4 text-start"> <div class="container-fluid py-4 text-start">
<div class="page-header mb-4"> {{-- <div class="page-header mb-4">
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent p-0 mb-2"> <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"><a href="#" class="text-muted text-decoration-none small">Home</a></li>
<li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Laporan</a></li> <li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Laporan</a></li>
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Laporan Kas</li> <li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Laporan Kas</li>
</ol> </ol>
</nav> </nav> --}}
<h3 class="fw-bold text-dark">Laporan Keuangan (Kas)</h3> <h3 class="fw-bold text-dark">Laporan Keuangan (Kas)</h3>
<p class="text-muted small">Rekapitulasi dan filter arus kas masuk dan keluar organisasi.</p> <p class="text-muted small">Rekapitulasi dan filter arus kas masuk dan keluar organisasi.</p>
</div> </div>
@ -54,13 +54,13 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover align-middle main-table"> <table class="table table-hover align-middle main-table">
<thead> <thead>
<tr> <tr class="text-center">
<th width="50" class="text-center">No</th> <th width="50">No</th>
<th width="130">Tanggal</th> <th width="130">Tanggal</th>
<th>Kategori & Keterangan</th> <th>Kategori & Keterangan</th>
<th class="text-end">Masuk (Rp)</th> <th>Masuk (Rp)</th>
<th class="text-end">Keluar (Rp)</th> <th>Keluar (Rp)</th>
<th class="text-end">Saldo Akhir</th> <th>Saldo Akhir</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -68,21 +68,21 @@
<tr> <tr>
<td class="text-muted small text-center">{{ $no + 1 }}</td> <td class="text-muted small text-center">{{ $no + 1 }}</td>
<td> <td>
<div class="fw-bold text-dark">{{ \Carbon\Carbon::parse($kas->tanggal)->format('d M Y') }}</div> <div class="fw-bold text-dark text-center">{{ \Carbon\Carbon::parse($kas->tanggal)->format('d M Y') }}</div>
</td> </td>
<td> <td class="text-center">
<span class="badge {{ $kas->jenis == 'masuk' ? 'bg-success-soft text-success border-success' : 'bg-danger-soft text-danger border-danger' }} border px-3 py-1 mb-1 rounded-pill" style="font-size: 10px;"> <span class="badge {{ $kas->jenis == 'masuk' ? 'bg-success-soft text-success border-success' : 'bg-danger-soft text-danger border-danger' }} border px-3 py-1 mb-1 rounded-pill" style="font-size: 10px;">
{{ strtoupper($kas->kategori) }} {{ strtoupper($kas->kategori) }}
</span> </span>
<div class="small text-muted mt-1">{{ $kas->keterangan ?? 'Tanpa keterangan' }}</div> <div class="small text-muted mt-1 text-center">{{ $kas->keterangan ?? 'Tanpa keterangan' }}</div>
</td> </td>
<td class="text-end text-success fw-bold"> <td class="text-end text-success fw-bold text-center">
{{ $kas->jenis == 'masuk' ? '+ ' . number_format($kas->nominal, 0, ',', '.') : '-' }} {{ $kas->jenis == 'masuk' ? '+ ' . number_format($kas->nominal, 0, ',', '.') : '-' }}
</td> </td>
<td class="text-end text-danger fw-bold"> <td class="text-end text-danger fw-bold text-center">
{{ $kas->jenis == 'keluar' ? '- ' . number_format($kas->nominal, 0, ',', '.') : '-' }} {{ $kas->jenis == 'keluar' ? '- ' . number_format($kas->nominal, 0, ',', '.') : '-' }}
</td> </td>
<td class="text-end fw-bold text-dark"> <td class="text-end fw-bold text-dark text-center">
{{ number_format($kas->saldo_akhir, 0, ',', '.') }} {{ number_format($kas->saldo_akhir, 0, ',', '.') }}
</td> </td>
</tr> </tr>

View File

@ -3,13 +3,13 @@
@section('content') @section('content')
<div class="container-fluid py-4 text-start"> <div class="container-fluid py-4 text-start">
<div class="page-header mb-4"> <div class="page-header mb-4">
<nav aria-label="breadcrumb"> {{-- <nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent p-0 mb-2"> <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"><a href="#" class="text-muted text-decoration-none small">Home</a></li>
<li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Laporan</a></li> <li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Laporan</a></li>
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Laporan Presensi</li> <li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Laporan Presensi</li>
</ol> </ol>
</nav> </nav> --}}
<h3 class="fw-bold text-dark">Laporan Kehadiran Latihan</h3> <h3 class="fw-bold text-dark">Laporan Kehadiran Latihan</h3>
<p class="text-muted small">Rekapitulasi absensi anggota untuk bahan evaluasi rapat tahunan.</p> <p class="text-muted small">Rekapitulasi absensi anggota untuk bahan evaluasi rapat tahunan.</p>
</div> </div>
@ -73,18 +73,18 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover align-middle main-table"> <table class="table table-hover align-middle main-table">
<thead> <thead>
<tr> <tr class="text-center">
<th width="50">No</th> <th width="50">No</th>
<th>Anggota</th> <th>Anggota</th>
<th>Jadwal & Kolat</th> <th>Jadwal & Kolat</th>
<th class="text-center">Status</th> <th>Status</th>
<th>Verifikator</th> <th>Verifikator</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@forelse($data_presensi as $no => $p) @forelse($data_presensi as $no => $p)
<tr> <tr class="text-center">
<td class="text-center text-muted small">{{ $no + 1 }}</td> <td class=" text-muted small">{{ $no + 1 }}</td>
<td> <td>
<div class="fw-bold text-dark">{{ $p->anggota->nama_lengkap ?? '-' }}</div> <div class="fw-bold text-dark">{{ $p->anggota->nama_lengkap ?? '-' }}</div>
<small class="text-muted">Waktu: {{ $p->waktu_presensi ? \Carbon\Carbon::parse($p->waktu_presensi)->format('H:i') : '-' }} WIB</small> <small class="text-muted">Waktu: {{ $p->waktu_presensi ? \Carbon\Carbon::parse($p->waktu_presensi)->format('H:i') : '-' }} WIB</small>
@ -93,7 +93,7 @@
<div class="fw-medium text-dark">{{ \Carbon\Carbon::parse($p->jadwal->tanggal)->format('d M Y') }}</div> <div class="fw-medium text-dark">{{ \Carbon\Carbon::parse($p->jadwal->tanggal)->format('d M Y') }}</div>
<div class="small text-muted">Kolat: {{ $p->jadwal->kolat->nama_kolat ?? '-' }}</div> <div class="small text-muted">Kolat: {{ $p->jadwal->kolat->nama_kolat ?? '-' }}</div>
</td> </td>
<td class="text-center"> <td>
@php @php
$color = ['Hadir'=>'success', 'Izin'=>'info', 'Sakit'=>'warning', 'Alfa'=>'danger'][$p->status] ?? 'secondary'; $color = ['Hadir'=>'success', 'Izin'=>'info', 'Sakit'=>'warning', 'Alfa'=>'danger'][$p->status] ?? 'secondary';
@endphp @endphp

View File

@ -116,9 +116,9 @@
<thead> <thead>
<tr> <tr>
<th width="50" class="text-center">No</th> <th width="50" class="text-center">No</th>
<th>Identitas Anggota</th> <th class="text-center">Identitas Anggota</th>
<th class="text-center">Periode Tagihan</th> <th class="text-center">Periode Tagihan</th>
<th class="text-end">Nominal (Rp)</th> <th class="text-center">Nominal (Rp)</th>
<th class="text-center">Status</th> <th class="text-center">Status</th>
</tr> </tr>
</thead> </thead>
@ -127,13 +127,13 @@
<tr> <tr>
<td class="text-muted small text-center">{{ $no + 1 }}</td> <td class="text-muted small text-center">{{ $no + 1 }}</td>
<td> <td>
<div class="fw-bold text-dark text-start">{{ $spp->anggota->nama_lengkap ?? '-' }}</div> <div class="fw-bold text-dark text-center">{{ $spp->anggota->nama_lengkap ?? '-' }}</div>
<small class="text-muted text-start d-block mt-1" style="font-size: 11px;">Kolat: {{ $spp->kolat->nama_kolat ?? '-' }}</small> <small class="text-muted text-center d-block mt-1" style="font-size: 11px;">Kolat: {{ $spp->kolat->nama_kolat ?? '-' }}</small>
</td> </td>
<td class="text-center"> <td class="text-center">
<span class="badge bg-light text-dark border px-3 py-2 rounded-pill">{{ $spp->bulan }} {{ $spp->tahun }}</span> <span class="badge bg-light text-dark border px-3 py-2 rounded-pill">{{ $spp->bulan }} {{ $spp->tahun }}</span>
</td> </td>
<td class="text-end fw-bold text-dark"> <td class="text-center fw-bold text-dark">
{{ number_format($spp->nominal, 0, ',', '.') }} {{ number_format($spp->nominal, 0, ',', '.') }}
</td> </td>
<td class="text-center"> <td class="text-center">

View File

@ -3,7 +3,7 @@
<div class="d-flex align-items-center justify-content-between"> <div class="d-flex align-items-center justify-content-between">
<a href="index.html" class="logo d-flex align-items-center"> <a href="index.html" class="logo d-flex align-items-center">
<img src="{{ asset('asset/img/logo.png') }}" alt=""> <img src="{{ asset('asset/img/logo.png') }}" alt="">
<span class="d-none d-lg-block">NiceAdmin</span> <span class="d-none d-lg-block">TapakMP</span>
</a> </a>
<i class="bi bi-list toggle-sidebar-btn"></i> <i class="bi bi-list toggle-sidebar-btn"></i>
</div><!-- End Logo --> </div><!-- End Logo -->
@ -25,164 +25,92 @@
</li><!-- End Search Icon--> </li><!-- End Search Icon-->
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link nav-icon" href="#" data-bs-toggle="dropdown"> <a class="nav-link nav-icon" href="#" data-bs-toggle="dropdown">
<i class="bi bi-bell"></i> <i class="bi bi-bell"></i>
<span class="badge bg-primary badge-number">4</span> {{-- Menampilkan angka total notifikasi --}}
@if (isset($globalUnreadCount) && $globalUnreadCount > 0)
<span class="badge bg-primary badge-number">{{ $globalUnreadCount }}</span>
@elseif(isset($globalNotifications) && count($globalNotifications) > 0)
<span class="badge bg-primary badge-number">{{ count($globalNotifications) }}</span>
@endif
</a><!-- End Notification Icon --> </a><!-- End Notification Icon -->
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow notifications"> <ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow notifications shadow">
<li class="dropdown-header"> <li class="dropdown-header">
You have 4 new notifications @php
<a href="#"><span class="badge rounded-pill bg-primary p-2 ms-2">View all</span></a> $totalNotif =
isset($globalUnreadCount) && $globalUnreadCount > 0
? $globalUnreadCount
: (isset($globalNotifications)
? count($globalNotifications)
: 0);
@endphp
Anda memiliki {{ $totalNotif }} notifikasi baru
<a href="#"><span class="badge rounded-pill bg-primary p-2 ms-2">Lihat Semua</span></a>
</li> </li>
<li> <li>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
</li> </li>
{{-- Loop Notifikasi Dinamis --}}
@if (isset($globalNotifications) && count($globalNotifications) > 0)
@foreach ($globalNotifications as $notif)
<li class="notification-item"> <li class="notification-item">
<i class="bi bi-exclamation-circle text-warning"></i> <a href="{{ $notif['link'] }}" class="d-flex text-decoration-none">
<i class="bi {{ $notif['icon'] }} me-3"></i>
<div> <div>
<h4>Lorem Ipsum</h4> <h4 class="text-dark">{{ $notif['title'] }}</h4>
<p>Quae dolorem earum veritatis oditseno</p> {{-- Mendukung key 'msg' atau 'message' agar tidak error --}}
<p>30 min. ago</p> <p class="text-muted small mb-0">{{ $notif['msg'] ?? ($notif['message'] ?? '') }}
</p>
</div> </div>
</a>
</li> </li>
<li> <li>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
</li> </li>
@endforeach
<li class="notification-item"> @else
<i class="bi bi-x-circle text-danger"></i> <li class="notification-item text-center">
<div> <p class="text-muted small mb-0 p-3">Tidak ada notifikasi baru</p>
<h4>Atque rerum nesciunt</h4>
<p>Quae dolorem earum veritatis oditseno</p>
<p>1 hr. ago</p>
</div>
</li> </li>
@endif
<li>
<hr class="dropdown-divider">
</li>
<li class="notification-item">
<i class="bi bi-check-circle text-success"></i>
<div>
<h4>Sit rerum fuga</h4>
<p>Quae dolorem earum veritatis oditseno</p>
<p>2 hrs. ago</p>
</div>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="notification-item">
<i class="bi bi-info-circle text-primary"></i>
<div>
<h4>Dicta reprehenderit</h4>
<p>Quae dolorem earum veritatis oditseno</p>
<p>4 hrs. ago</p>
</div>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-footer"> <li class="dropdown-footer">
<a href="#">Show all notifications</a> <a href="#">Tampilkan semua notifikasi</a>
</li> </li>
</ul><!-- End Notification Dropdown Items --> </ul><!-- End Notification Dropdown Items -->
</li><!-- End Notification Nav --> </li><!-- End Notification Nav -->
<li class="nav-item dropdown">
<a class="nav-link nav-icon" href="#" data-bs-toggle="dropdown">
<i class="bi bi-chat-left-text"></i>
<span class="badge bg-success badge-number">3</span>
</a><!-- End Messages Icon -->
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow messages">
<li class="dropdown-header">
You have 3 new messages
<a href="#"><span class="badge rounded-pill bg-primary p-2 ms-2">View all</span></a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="message-item">
<a href="#">
<img src="{{ asset('asset/img/messages-1.jpg') }}" alt="" class="rounded-circle">
<div>
<h4>Maria Hudson</h4>
<p>Velit asperiores et ducimus soluta repudiandae labore officia est ut...</p>
<p>4 hrs. ago</p>
</div>
</a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="message-item">
<a href="#">
<img src="{{ asset('asset/img/messages-2.jpg') }}" alt="" class="rounded-circle">
<div>
<h4>Anna Nelson</h4>
<p>Velit asperiores et ducimus soluta repudiandae labore officia est ut...</p>
<p>6 hrs. ago</p>
</div>
</a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="message-item">
<a href="#">
<img src="{{ asset('asset/img/messages-3.jpg') }}" alt="" class="rounded-circle">
<div>
<h4>David Muldon</h4>
<p>Velit asperiores et ducimus soluta repudiandae labore officia est ut...</p>
<p>8 hrs. ago</p>
</div>
</a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-footer">
<a href="#">Show all messages</a>
</li>
</ul><!-- End Messages Dropdown Items -->
</li><!-- End Messages Nav -->
<li class="nav-item dropdown pe-3"> <li class="nav-item dropdown pe-3">
<a class="nav-link nav-profile d-flex align-items-center pe-0" href="#" data-bs-toggle="dropdown"> <a class="nav-link nav-profile d-flex align-items-center pe-0" href="#" data-bs-toggle="dropdown">
<img src="{{ asset('asset/img/profile-img.jpg') }}" alt="Profile" class="rounded-circle">
<span class="d-none d-md-block dropdown-toggle ps-2">K. Anderson</span> @if (Auth::user()->anggota?->foto_profil)
</a><!-- End Profile Iamge Icon --> <img src="{{ asset('storage/' . Auth::user()->anggota->foto_profil) }}" alt="Profile"
class="rounded-circle" style="width: 36px; height: 36px; object-fit: cover;">
@else
<img src="https://ui-avatars.com/api/?name={{ urlencode(Auth::user()->anggota?->nama_lengkap ?? Auth::user()->email) }}&background=e9ecef&color=0d6efd"
alt="Profile" class="rounded-circle" style="width: 36px; height: 36px; object-fit: cover;">
@endif
<span class="d-none d-md-block dropdown-toggle ps-2">
{{ Auth::user()->anggota?->nama_lengkap ?? Auth::user()->email }}
</span>
</a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow profile"> <ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow profile">
<li class="dropdown-header"> <li class="dropdown-header">
<h6>Kevin Anderson</h6> <h6>{{ Auth::user()->anggota?->nama_lengkap ?? Auth::user()->email }}</h6>
<span>Web Designer</span> <span>{{ Auth::user()->role?->nama_role ?? 'Pengguna' }}</span>
</li> </li>
<li> <li>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
</li> </li>
<li> <li>
<a class="dropdown-item d-flex align-items-center" href="users-profile.html"> <a class="dropdown-item d-flex align-items-center" href="{{ route('profile.edit') }}">
<i class="bi bi-person"></i> <i class="bi bi-person"></i>
<span>My Profile</span> <span>My Profile</span>
</a> </a>
@ -190,7 +118,7 @@
<li> <li>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
</li> </li>
{{--
<li> <li>
<a class="dropdown-item d-flex align-items-center" href="users-profile.html"> <a class="dropdown-item d-flex align-items-center" href="users-profile.html">
<i class="bi bi-gear"></i> <i class="bi bi-gear"></i>
@ -199,9 +127,9 @@
</li> </li>
<li> <li>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
</li> </li> --}}
<li> {{-- <li>
<a class="dropdown-item d-flex align-items-center" href="pages-faq.html"> <a class="dropdown-item d-flex align-items-center" href="pages-faq.html">
<i class="bi bi-question-circle"></i> <i class="bi bi-question-circle"></i>
<span>Need Help?</span> <span>Need Help?</span>
@ -209,7 +137,7 @@
</li> </li>
<li> <li>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
</li> </li> --}}
<li> <li>
<a class="dropdown-item d-flex align-items-center" href="{{ route('logout') }}" <a class="dropdown-item d-flex align-items-center" href="{{ route('logout') }}"
@ -229,4 +157,4 @@
</ul> </ul>
</nav><!-- End Icons Navigation --> </nav><!-- End Icons Navigation -->
</header> </header>

View File

@ -1,6 +1,13 @@
@php @php
// Ambil nama role user yang login saat ini // Ambil nama role user dengan logika yang sama persis seperti di Middleware
$userRole = auth()->user()->role->nama_role ?? 'Anggota'; $user = auth()->user();
$userRole = null;
if ($user->role) {
$userRole = $user->role->nama_role;
} elseif ($user->anggota && $user->anggota->role) {
$userRole = $user->anggota->role->nama_role;
}
@endphp @endphp
<aside id="sidebar" class="sidebar"> <aside id="sidebar" class="sidebar">
@ -10,10 +17,19 @@
{{-- MENU DASHBOARD (Semua Role Bisa Akses) --}} {{-- MENU DASHBOARD (Semua Role Bisa Akses) --}}
{{-- ======================================================== --}} {{-- ======================================================== --}}
<li class="nav-item"> <li class="nav-item">
@if($userRole === 'Anggota')
<!-- Link khusus untuk Anggota -->
<a class="nav-link {{ request()->routeIs('anggota.dashboard') ? '' : 'collapsed' }}" href="{{ route('anggota.dashboard') }}">
<i class="bi bi-grid"></i>
<span>Dashboard</span>
</a>
@else
<!-- Link untuk Pelatih dan Pengurus -->
<a class="nav-link {{ request()->routeIs('dashboard') ? '' : 'collapsed' }}" href="{{ route('dashboard') }}"> <a class="nav-link {{ request()->routeIs('dashboard') ? '' : 'collapsed' }}" href="{{ route('dashboard') }}">
<i class="bi bi-grid"></i> <i class="bi bi-grid"></i>
<span>Dashboard</span> <span>Dashboard</span>
</a> </a>
@endif
</li> </li>
{{-- ======================================================== --}} {{-- ======================================================== --}}
@ -66,7 +82,8 @@
</li> </li>
<!-- Link Penilaian masih manual (sesuaikan id pelatihnya nanti) --> <!-- Link Penilaian masih manual (sesuaikan id pelatihnya nanti) -->
<li> <li>
<a href="#" class="{{ request()->routeIs('penilaian.*') ? 'active' : '' }}"> <!-- href saya ganti '#' sementara, karena anggota belum punya rute index penilaian sendiri -->
<a href="{{ route('penilaian.anggota_index') }}" class="{{ request()->routeIs('penilaian.anggota_index') ? 'active' : '' }}">
<i class="bi bi-circle"></i><span>Isi Nilai Pelatih</span> <i class="bi bi-circle"></i><span>Isi Nilai Pelatih</span>
</a> </a>
</li> </li>
@ -84,7 +101,7 @@
</a> </a>
</li> </li>
<li> <li>
<a href="{{ route('penilaian.index') }}" class="{{ request()->routeIs('penilaian.*') ? 'active' : '' }}"> <a href="{{ route('penilaian.index') }}" class="{{ request()->routeIs('penilaian.index', 'penilaian.show') ? 'active' : '' }}">
<i class="bi bi-circle"></i><span>Rekap Penilaian</span> <i class="bi bi-circle"></i><span>Rekap Penilaian</span>
</a> </a>
</li> </li>
@ -134,10 +151,10 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link {{ request()->routeIs('laporan.*') ? '' : 'collapsed' }}" <a class="nav-link {{ request()->routeIs('laporan.*') ? '' : 'collapsed' }}"
data-bs-target="#laporan-nav" data-bs-toggle="collapse" href="#" data-bs-target="#laporan-nav" data-bs-toggle="collapse" href="#"
aria-expanded="{{ request()->routeIs('laporan.*') ? 'true' : 'false' }}"> aria-expanded="{{ request()->routeIs('laporan.*', 'rekap.*') ? 'true' : 'false' }}">
<i class="bi bi-file-earmark-bar-graph"></i><span>Laporan</span><i class="bi bi-chevron-down ms-auto"></i> <i class="bi bi-file-earmark-bar-graph"></i><span>Laporan</span><i class="bi bi-chevron-down ms-auto"></i>
</a> </a>
<ul id="laporan-nav" class="nav-content collapse {{ request()->routeIs('laporan.*') ? 'show' : '' }}" data-bs-parent="#sidebar-nav"> <ul id="laporan-nav" class="nav-content collapse {{ request()->routeIs('laporan.*', 'rekap.*') ? 'show' : '' }}" data-bs-parent="#sidebar-nav">
{{-- Hanya Pengurus --}} {{-- Hanya Pengurus --}}
@if($userRole == 'Pengurus') @if($userRole == 'Pengurus')
@ -178,7 +195,7 @@
{{-- ======================================================== --}} {{-- ======================================================== --}}
{{-- MENU AKUN (Semua Bisa Akses) --}} {{-- MENU AKUN (Semua Bisa Akses) --}}
{{-- ======================================================== --}} {{-- ======================================================== --}}
<li class="nav-heading mt-3">Akun</li> {{-- <li class="nav-heading mt-3">Akun</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link collapsed" href="{{ route('profile.edit') }}"> <a class="nav-link collapsed" href="{{ route('profile.edit') }}">
<i class="bi bi-person"></i><span>Profile Saya</span> <i class="bi bi-person"></i><span>Profile Saya</span>
@ -189,6 +206,6 @@
<a class="nav-link collapsed text-danger" href="#" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"> <a class="nav-link collapsed text-danger" href="#" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
<i class="bi bi-box-arrow-right"></i><span>Logout</span> <i class="bi bi-box-arrow-right"></i><span>Logout</span>
</a> </a>
</li> </li> --}}
</ul> </ul>
</aside> </aside>

View File

@ -6,7 +6,7 @@
<meta content="width=device-width, initial-scale=1.0" name="viewport"> <meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Login - TapakMP</title> <title>Login - TapakMP</title>
<link href="{{ asset('assets/img/favicon.png') }}" rel="icon"> <link href="{{ asset('assets/img/logo1.jpg') }}" rel="icon">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Ubuntu:wght@400;500;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Ubuntu:wght@400;500;700&display=swap" rel="stylesheet">
<link href="{{ asset('assets/vendor/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet"> <link href="{{ asset('assets/vendor/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">
@ -51,6 +51,19 @@
border-color: var(--accent-color); border-color: var(--accent-color);
box-shadow: 0 0 0 0.25rem rgba(254, 185, 0, 0.1); box-shadow: 0 0 0 0.25rem rgba(254, 185, 0, 0.1);
} }
/* Style untuk tombol Show Password agar rapi */
.btn-toggle-password {
border: 1px solid #dee2e6;
border-left: none;
background: #f8f9fa;
color: #6c757d;
}
.btn-toggle-password:hover {
background: #e9ecef;
color: var(--dark-blue);
}
.btn-auth { .btn-auth {
background-color: var(--accent-color); background-color: var(--accent-color);
border: none; border: none;
@ -104,7 +117,12 @@
</div> </div>
<div class="input-group"> <div class="input-group">
<span class="input-group-text bg-light"><i class="bi bi-lock"></i></span> <span class="input-group-text bg-light"><i class="bi bi-lock"></i></span>
<input type="password" name="password" class="form-control" placeholder="••••••••" required> <!-- Tambahkan ID agar bisa dimanipulasi JS -->
<input type="password" name="password" id="passwordInput" class="form-control" placeholder="••••••••" required>
<!-- Tombol Toggle Mata -->
<button class="btn btn-toggle-password" type="button" id="togglePassword">
<i class="bi bi-eye" id="eyeIcon"></i>
</button>
</div> </div>
</div> </div>
@ -123,7 +141,21 @@
</div> </div>
<script> <script>
// Popup jika berhasil register atau pesan sukses lainnya // Fitur Show/Hide Password
const togglePassword = document.querySelector('#togglePassword');
const passwordInput = document.querySelector('#passwordInput');
const eyeIcon = document.querySelector('#eyeIcon');
togglePassword.addEventListener('click', function () {
const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password';
passwordInput.setAttribute('type', type);
// Ganti ikon mata
eyeIcon.classList.toggle('bi-eye');
eyeIcon.classList.toggle('bi-eye-slash');
});
// Popup SweetAlert
@if(session('success')) @if(session('success'))
Swal.fire({ Swal.fire({
icon: 'success', icon: 'success',
@ -133,7 +165,6 @@
}); });
@endif @endif
// Popup jika gagal login manual (dilempar via with('error', '...'))
@if(session('error')) @if(session('error'))
Swal.fire({ Swal.fire({
icon: 'warning', icon: 'warning',
@ -143,7 +174,6 @@
}); });
@endif @endif
// [TAMBAHAN BARU] Popup jika validasi gagal (Email/Password salah)
@if($errors->any()) @if($errors->any())
Swal.fire({ Swal.fire({
icon: 'error', icon: 'error',

View File

@ -82,8 +82,8 @@
<td class="text-center"> <td class="text-center">
<div class="d-flex justify-content-center gap-2"> <div class="d-flex justify-content-center gap-2">
<a href="{{ route('pelatih.edit', $item->id) }}" <a href="{{ route('pelatih.edit', $item->id) }}"
class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs"> class="btn btn-sm btn-action-edit fw-bold px-2 shadow-xs">
<i class="icon-pencil"></i> Edit SK <i class="bi bi-pencil"></i>
</a> </a>
</div> </div>
</td> </td>

View File

@ -0,0 +1,133 @@
@extends('layout.app')
@section('content')
<div class="container-fluid py-4">
<!-- Header Halaman -->
<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> --}}
<div class="d-flex justify-content-between align-items-center flex-wrap">
<div>
<h3 class="fw-bold text-dark mb-1">Daftar Pelatih</h3>
<p class="text-muted small mb-0">Pilih pelatih di bawah ini untuk menambahkan evaluasi performa latihan.</p>
</div>
</div>
</div>
<!-- Grid Card Pelatih -->
<div class="row g-4">
@forelse($data_pelatih as $pelatih)
<div class="col-md-4 col-lg-3">
<div class="card border-0 h-100 pelatih-card">
<div class="card-body p-4 text-center d-flex flex-column align-items-center">
<!-- Foto Pelatih -->
<div class="foto-wrapper mb-3">
@if($pelatih->foto_profil)
<img src="{{ asset('storage/' . $pelatih->foto_profil) }}" alt="Foto {{ $pelatih->nama_lengkap }}" class="rounded-circle object-fit-cover shadow-sm">
@else
<div class="placeholder-foto rounded-circle d-flex align-items-center justify-content-center shadow-sm text-primary">
<i class="bi bi-person-fill"></i>
</div>
@endif
</div>
<!-- Identitas -->
<h6 class="fw-bold text-dark mb-1 w-100 text-truncate" title="{{ $pelatih->nama_lengkap }}">
{{ $pelatih->nama_lengkap }}
</h6>
<div class="text-muted small mb-4 w-100 text-truncate" title="{{ $pelatih->kolat->nama_kolat ?? 'Belum ada kolat' }}">
<i class="bi bi-geo-alt-fill text-danger me-1"></i> {{ $pelatih->kolat->nama_kolat ?? 'Belum ada kolat' }}
</div>
<!-- Tombol Aksi -->
<div class="mt-auto w-100">
<a href="{{ route('penilaian.create', $pelatih->id) }}" class="btn btn-success btn-tambah w-100 shadow-sm fw-bold">
<i class="bi bi-plus-circle me-2"></i> Tambah Penilaian
</a>
</div>
</div>
</div>
</div>
@empty
<!-- Jika Data Pelatih Kosong -->
<div class="col-12">
<div class="card border-0 shadow-sm text-center py-5 empty-state">
<div class="card-body">
<div class="empty-icon-wrapper mb-3 mx-auto">
<i class="bi bi-inbox text-muted"></i>
</div>
<h5 class="fw-bold text-dark">Tidak Ada Data Pelatih</h5>
<p class="text-muted small mb-0">Saat ini belum ada data pelatih yang dapat dinilai.</p>
</div>
</div>
</div>
@endforelse
</div>
</div>
<!-- CSS Tambahan Khusus Halaman Ini -->
<style>
/* Styling Card Utama */
.pelatih-card {
border-radius: 20px;
box-shadow: 0 4px 12px rgba(0,0,0,0.04);
transition: all 0.3s ease;
}
/* Efek Hover (Melayang) pada Card */
.pelatih-card:hover {
transform: translateY(-8px);
box-shadow: 0 12px 24px rgba(0,0,0,0.1);
}
/* Styling Area Foto */
.foto-wrapper img, .placeholder-foto {
width: 100px;
height: 100px;
border: 4px solid #ffffff; /* Bingkai putih agar menonjol */
box-shadow: 0 4px 10px rgba(0,0,0,0.08); /* Bayangan halus di bawah foto */
}
/* Jika foto tidak ada */
.placeholder-foto {
background-color: #f0f4f8;
font-size: 3.5rem;
}
/* Styling Tombol Tambah Penilaian */
.btn-tambah {
border-radius: 12px;
padding: 10px 0;
background-color: #198754; /* Hijau *success* */
border: none;
transition: all 0.3s ease;
}
/* Efek saat tombol disorot kursor */
.btn-tambah:hover {
background-color: #146c43;
transform: scale(1.03); /* Membesar sedikit */
}
/* Styling saat data kosong (Empty State) */
.empty-state {
border-radius: 20px;
background-color: #ffffff;
}
.empty-icon-wrapper {
width: 80px;
height: 80px;
background-color: #f8f9fa;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 2.5rem;
}
</style>
@endsection

View File

@ -1,51 +1,99 @@
@extends('layout.app') {{-- @extends('layout.app')
@section('content') @section('content')
<div class="container-fluid py-4"> <div class="container-fluid py-4">
<div class="row justify-content-center"> <!-- Menggunakan col-12 agar card membentang penuh (Full Width) -->
<div class="col-md-8"> <div class="row">
<div class="card border-0 shadow-sm" style="border-radius: 20px;"> <div class="col-12">
<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> <!-- Tombol Kembali -->
<p class="text-muted small">Kolat: {{ $pelatih->kolat->nama_kolat }} | Periode: {{ now()->format('F Y') }}</p> <a href="{{ route('penilaian.anggota_index') }}" class="text-decoration-none text-muted mb-3 d-inline-block">
<i class="bi bi-arrow-left me-1"></i> Kembali ke Daftar Pelatih
</a>
<div class="card border-0 shadow-sm form-penilaian-card">
<!-- Header Card Friendly -->
<div class="card-header text-center border-0 pt-5 pb-4 bg-white" style="border-radius: 20px 20px 0 0;">
<div class="pelatih-avatar mb-3 mx-auto">
@if($pelatih->foto_profil)
<img src="{{ asset('storage/' . $pelatih->foto_profil) }}" alt="Foto">
@else
<i class="bi bi-person-fill"></i>
@endif
</div> </div>
<div class="card-body p-4"> <h4 class="fw-bold mb-1">Nilai Kak <span style="color: var(--accent-color);">{{ $pelatih->nama_lengkap }}</span></h4>
<span class="badge bg-light text-dark px-3 py-2 rounded-pill mt-2">
<i class="bi bi-geo-alt-fill text-danger me-1"></i> Kolat: {{ $pelatih->kolat->nama_kolat ?? '-' }}
</span>
<p class="text-muted small mt-3 px-3 mx-auto" style="max-width: 600px;">
Yuk, berikan penilaian jujurmu untuk evaluasi bulan {{ now()->translatedFormat('F Y') }}. Tenang saja, namamu akan dirahasiakan! 🤫
</p>
</div>
<div class="card-body p-4 p-lg-5 pt-2">
<form action="{{ route('penilaian.store') }}" method="POST"> <form action="{{ route('penilaian.store') }}" method="POST">
@csrf @csrf
<input type="hidden" name="pelatih_id" value="{{ $pelatih->id }}"> <input type="hidden" name="pelatih_id" value="{{ $pelatih->id }}">
@php @php
$kriterias = [ $kriterias = [
'metode_pelatihan' => 'Metode Pelatihan', 'metode_pelatihan' => 'Cara Menyampaikan Materi',
'komunikasi' => 'Komunikasi Pelatih & Anggota', 'komunikasi' => 'Cara Berkomunikasi dengan Anggota',
'sikap_kepribadian' => 'Sikap & Kepribadian', 'sikap_kepribadian' => 'Sikap & Kedisiplinan Pelatih',
'kepemimpinan' => 'Kepemimpinan', 'kepemimpinan' => 'Jiwa Kepemimpinan di Lapangan',
'konsistensi_komitmen' => 'Konsistensi & Komitmen', 'konsistensi_komitmen' => 'Kehadiran & Semangat Melatih',
'kedekatan_interpersonal' => 'Kedekatan Interpersonal' 'kedekatan_interpersonal' => 'Kedekatan & Kepedulian'
];
// Emoji untuk masing-masing nilai 1-5
$emojis = [
1 => '😞',
2 => '😐',
3 => '🙂',
4 => '😄',
5 => '🤩'
]; ];
@endphp @endphp
<!-- Dibikin 2 Kolom untuk Layar Besar agar tidak terlalu kosong saat Full Width -->
<div class="row g-4">
@foreach($kriterias as $key => $label) @foreach($kriterias as $key => $label)
<div class="mb-4 border-bottom pb-3"> <div class="col-md-6">
<label class="fw-bold d-block mb-2">{{ $label }}</label> <div class="kriteria-box h-100 p-4 rounded-4 bg-light">
<div class="d-flex gap-3"> <label class="fw-bold d-block mb-4 text-dark text-center fs-6">{{ $label }}</label>
<div class="d-flex justify-content-between gap-2 gap-md-3">
@foreach(range(1, 5) as $score) @foreach(range(1, 5) as $score)
<div class="form-check form-check-inline"> <div class="rating-wrapper flex-fill">
<input class="form-check-input" type="radio" name="{{ $key }}" id="{{ $key.$score }}" value="{{ $score }}" required> <!-- Input Radio disembunyikan -->
<label class="form-check-label" for="{{ $key.$score }}">{{ $score }} </label> <input class="rating-input" type="radio" name="{{ $key }}" id="{{ $key.$score }}" value="{{ $score }}" required>
<!-- Label dibuat seperti tombol kotak -->
<label class="rating-label w-100" for="{{ $key.$score }}">
<span class="emoji-rate">{{ $emojis[$score] }}</span>
<span class="score-text">{{ $score }}</span>
</label>
</div> </div>
@endforeach @endforeach
</div> </div>
<!-- Keterangan text di bawah angka (Hanya tampil 1 dan 5) -->
<div class="d-flex justify-content-between mt-3 px-2 text-muted fw-medium" style="font-size: 0.75rem;">
<span>Kurang</span>
<span>Sangat Baik</span>
</div>
</div>
</div> </div>
@endforeach @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>
<div class="d-grid"> <div class="mb-4 mt-5">
<button type="submit" class="btn btn-primary py-3 fw-bold" style="border-radius: 12px;">Kirim Penilaian Anonim</button> <label class="fw-bold mb-3 text-dark fs-5">Pesan, Kritik & Saran 📝</label>
<textarea name="kritik_saran" class="form-control bg-light border-0" rows="5" placeholder="Tulis masukan, pujian, atau saranmu di sini (boleh dikosongi)..." style="border-radius: 15px; padding: 20px; resize: none;"></textarea>
</div>
<div class="d-grid mt-5">
<button type="submit" class="btn btn-submit-nilai py-3 fw-bold fs-5">
<i class="bi bi-send-fill me-2"></i> Kirim Penilaian Rahasia
</button>
</div> </div>
</form> </form>
</div> </div>
@ -53,4 +101,400 @@
</div> </div>
</div> </div>
</div> </div>
<style>
/* Styling Card Utama */
.form-penilaian-card {
border-radius: 20px;
overflow: hidden;
}
/* Foto Profil Kecil di Atas */
.pelatih-avatar {
width: 100px;
height: 100px;
background: #f8f9fa;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 3.5rem;
color: var(--dark-blue, #06163a);
border: 5px solid #fff;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
.pelatih-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
/* Menyembunyikan radio button asli */
.rating-input {
display: none;
}
/* Kotak Pilihan Angka & Emoji */
.rating-label {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 5px;
background: #ffffff;
border: 2px solid #e9ecef;
border-radius: 15px;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
color: #6c757d;
}
.emoji-rate {
font-size: 1.8rem;
margin-bottom: 5px;
filter: grayscale(100%); /* Bikin abu-abu dulu kalau belum dipilih */
opacity: 0.6;
transition: all 0.2s ease;
}
.score-text {
font-weight: 700;
font-size: 1.1rem;
}
/* Efek Saat Di-Hover (Sentuh) */
.rating-label:hover {
background: #f1f5f9;
border-color: #cbd5e1;
}
.rating-label:hover .emoji-rate {
filter: grayscale(0%);
opacity: 1;
transform: scale(1.1);
}
/* Efek Saat Di-Klik (Dipilih) */
.rating-input:checked + .rating-label {
background: var(--accent-color, #feb900);
border-color: var(--accent-color, #feb900);
color: var(--dark-blue, #06163a);
transform: translateY(-4px);
box-shadow: 0 8px 20px rgba(254, 185, 0, 0.3);
}
.rating-input:checked + .rating-label .emoji-rate {
filter: grayscale(0%);
opacity: 1;
transform: scale(1.2);
}
/* Input Textarea Focus */
textarea.form-control:focus {
background: #ffffff !important;
border: 2px solid var(--accent-color, #feb900) !important;
box-shadow: 0 0 0 0.25rem rgba(254, 185, 0, 0.1) !important;
}
/* Tombol Submit */
.btn-submit-nilai {
background: var(--dark-blue, #06163a);
color: #fff;
border-radius: 15px;
border: none;
transition: all 0.3s;
}
.btn-submit-nilai:hover {
background: var(--accent-color, #feb900);
color: var(--dark-blue, #06163a);
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(254, 185, 0, 0.4);
}
</style>
@endsection --}}
@extends('layout.app')
@section('content')
<!-- Wrapper khusus untuk membuat tampilan full-screen dan berpusat di tengah -->
<div class="d-flex align-items-center justify-content-center py-4" style="min-height: 85vh; background: linear-gradient(135deg, #f8faff 0%, #edf2f9 100%); margin: -1.5rem; padding: 2rem;">
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-8 col-xl-6">
<a href="{{ route('penilaian.anggota_index') }}" class="text-decoration-none text-muted mb-3 d-inline-flex align-items-center fw-medium btn-batal">
<i class="bi bi-arrow-left-circle-fill fs-4 me-2 text-primary"></i> Batal & Kembali
</a>
<div class="card border-0 shadow-lg form-kuis-card">
<!-- Progress Bar Interaktif -->
<div class="progress-wrapper px-4 pt-4 pb-2">
<div class="d-flex justify-content-between align-items-center mb-2">
<span class="text-muted fw-bold small text-uppercase tracking-wider" id="progressText">Pertanyaan 1 dari 6</span>
<span class="badge bg-primary-soft text-primary rounded-pill px-3"><i class="bi bi-star-fill me-1 text-warning"></i> Evaluasi Bulanan</span>
</div>
<div class="progress" style="height: 10px; border-radius: 20px; background-color: #e2e8f0;">
<div class="progress-bar progress-bar-striped progress-bar-animated" id="formProgressBar" role="progressbar" style="width: 14%; background-color: var(--accent-color, #feb900); border-radius: 20px;" aria-valuenow="14" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="card-body p-4 p-sm-5 relative text-center">
<!-- Profil Pelatih Mini -->
<div class="d-inline-flex align-items-center bg-light rounded-pill p-2 pe-4 mb-4 border shadow-sm mx-auto">
@if($pelatih->foto_profil)
<img src="{{ asset('storage/' . $pelatih->foto_profil) }}" alt="Foto" class="rounded-circle object-fit-cover me-3" style="width: 40px; height: 40px;">
@else
<div class="rounded-circle bg-primary text-white d-flex align-items-center justify-content-center me-3" style="width: 40px; height: 40px;">
<i class="bi bi-person-fill"></i>
</div>
@endif
<div class="text-start">
<div class="fw-bold text-dark lh-1" style="font-size: 0.9rem;">Kak {{ $pelatih->nama_lengkap }}</div>
<div class="text-muted" style="font-size: 0.75rem;">Kolat {{ $pelatih->kolat->nama_kolat ?? '-' }}</div>
</div>
</div>
<form action="{{ route('penilaian.store') }}" method="POST" id="formPenilaian">
@csrf
<input type="hidden" name="pelatih_id" value="{{ $pelatih->id }}">
@php
$kriterias = [
'metode_pelatihan' => 'Bagaimana cara Kakak Pelatih menyampaikan materi hari ini?',
'komunikasi' => 'Seberapa asik dan jelas komunikasinya dengan anggota?',
'sikap_kepribadian' => 'Bagaimana sikap dan kedisiplinan pelatih di lapangan?',
'kepemimpinan' => 'Seberapa baik jiwa kepemimpinan pelatih saat memandu latihan?',
'konsistensi_komitmen' => 'Seberapa semangat pelatih saat melatih kita?',
'kedekatan_interpersonal' => 'Seberapa dekat dan peduli pelatih dengan para anggota?'
];
$emojis = [
1 => ['icon' => '😞', 'text' => 'Kurang'],
2 => ['icon' => '😐', 'text' => 'Biasa'],
3 => ['icon' => '🙂', 'text' => 'Cukup'],
4 => ['icon' => '😄', 'text' => 'Bagus'],
5 => ['icon' => '🤩', 'text' => 'Keren!']
];
$step = 1;
@endphp
<!-- LOOPING PERTANYAAN KUIS -->
@foreach($kriterias as $key => $pertanyaan)
<div class="form-step" id="step-{{ $step }}" {!! $step > 1 ? 'style="display: none;"' : '' !!}>
<h3 class="fw-bolder text-dark mb-5 lh-base px-2 pertanyaan-teks" style="font-size: clamp(1.2rem, 3vw, 1.8rem);">
{{ $pertanyaan }}
</h3>
<div class="d-flex justify-content-center flex-wrap gap-2 gap-md-3 mb-4">
@foreach(range(1, 5) as $score)
<div class="rating-wrapper">
<input class="rating-input" type="radio" name="{{ $key }}" id="{{ $key.$score }}" value="{{ $score }}" onclick="nextStep({{ $step }})" required>
<label class="rating-label shadow-sm" for="{{ $key.$score }}">
<span class="emoji-rate">{{ $emojis[$score]['icon'] }}</span>
<span class="score-text mt-2">{{ $emojis[$score]['text'] }}</span>
</label>
</div>
@endforeach
</div>
@if($step > 1)
<button type="button" class="btn btn-link text-muted text-decoration-none mt-3 fw-medium btn-mundur" onclick="prevStep({{ $step }})">
<i class="bi bi-arrow-up text-primary me-1"></i> Ganti jawaban sebelumnya
</button>
@endif
</div>
@php $step++; @endphp
@endforeach
<!-- STEP TERAKHIR: KRITIK & SARAN -->
<div class="form-step" id="step-7" style="display: none;">
<div class="mb-4">
<span class="emoji-rate d-inline-block mb-3" style="font-size: 4rem; filter: none; opacity: 1;">📝</span>
<h3 class="fw-bolder text-dark mb-2">Satu langkah lagi!</h3>
<p class="text-muted">Ada pesan, kritik, saran, atau pujian untuk Kak {{ $pelatih->nama_lengkap }}? (Boleh dikosongkan kok)</p>
</div>
<textarea name="kritik_saran" class="form-control bg-light border-0 mb-4 shadow-inner" rows="5" placeholder="Ketik pesan rahasiamu di sini..." style="border-radius: 20px; padding: 25px; resize: none; font-size: 1.1rem;"></textarea>
<div class="d-grid gap-3 mt-5">
<button type="submit" class="btn btn-submit-nilai py-3 fw-bold fs-5 shadow">
<i class="bi bi-send-fill me-2"></i> Kirim Penilaian Sekarang
</button>
<button type="button" class="btn btn-light py-3 fw-bold text-muted btn-kembali-akhir" onclick="prevStep(7)">
Koreksi jawaban sebelumnya
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
/* Styling Card Super Halus */
.form-kuis-card {
border-radius: 30px;
overflow: hidden;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
box-shadow: 0 20px 40px rgba(0,0,0,0.08) !important;
}
.bg-primary-soft { background-color: rgba(6, 22, 58, 0.1); }
.tracking-wider { letter-spacing: 1px; }
/* Tombol Kembali / Batal */
.btn-batal:hover { transform: translateX(-5px); transition: 0.3s; }
.btn-mundur:hover, .btn-kembali-akhir:hover { background-color: #f1f5f9; border-radius: 15px; }
/* Menyembunyikan radio button asli */
.rating-input { display: none; }
/* Kotak Pilihan Angka & Emoji */
.rating-wrapper {
flex: 1;
min-width: 75px;
max-width: 110px;
}
.rating-label {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 25px 10px;
background: #ffffff;
border: 2px solid #e2e8f0;
border-radius: 25px;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); /* Efek memantul (bouncy) */
color: #94a3b8;
height: 100%;
}
.emoji-rate {
font-size: 3rem;
line-height: 1;
filter: grayscale(100%);
opacity: 0.4;
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.score-text {
font-weight: 700;
font-size: 0.9rem;
}
/* Efek Saat Di-Hover (Sentuh) */
.rating-label:hover {
background: #f8fafc;
border-color: #cbd5e1;
transform: translateY(-5px);
}
.rating-label:hover .emoji-rate {
filter: grayscale(0%);
opacity: 1;
transform: scale(1.1);
}
/* Efek Saat Di-Klik (Dipilih) */
.rating-input:checked + .rating-label {
background: var(--accent-color, #feb900);
border-color: var(--accent-color, #feb900);
color: var(--dark-blue, #06163a);
transform: translateY(-10px) scale(1.05);
box-shadow: 0 15px 30px rgba(254, 185, 0, 0.4) !important;
}
.rating-input:checked + .rating-label .emoji-rate {
filter: grayscale(0%);
opacity: 1;
transform: scale(1.2);
}
/* Animasi Transisi Halus antar Pertanyaan */
.form-step {
animation: slideUpFade 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
@keyframes slideUpFade {
0% { opacity: 0; transform: translateY(30px) scale(0.95); }
100% { opacity: 1; transform: translateY(0) scale(1); }
}
/* Styling Textarea */
.shadow-inner { box-shadow: inset 0 2px 4px rgba(0,0,0,0.05); }
textarea.form-control:focus {
background: #ffffff !important;
border: 2px solid var(--accent-color, #feb900) !important;
box-shadow: 0 0 0 0.3rem rgba(254, 185, 0, 0.15) !important;
}
/* Tombol Submit Utama */
.btn-submit-nilai {
background: var(--dark-blue, #06163a);
color: #fff;
border-radius: 20px;
border: none;
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.btn-submit-nilai:hover {
background: var(--accent-color, #feb900);
color: var(--dark-blue, #06163a);
transform: translateY(-5px);
box-shadow: 0 10px 25px rgba(254, 185, 0, 0.5) !important;
}
</style>
<!-- SCRIPT UNTUK PINDAH HALAMAN OTOMATIS & PROGRESS BAR -->
<script>
const totalSteps = 7;
const progressText = document.getElementById('progressText');
const progressBar = document.getElementById('formProgressBar');
function nextStep(currentStep) {
// Beri jeda 400ms agar user bisa melihat animasi emojinya membesar sebelum pindah layar
setTimeout(() => {
document.getElementById('step-' + currentStep).style.display = 'none';
let next = currentStep + 1;
if (next <= totalSteps) {
document.getElementById('step-' + next).style.display = 'block';
updateProgress(next);
}
}, 400);
}
function prevStep(currentStep) {
document.getElementById('step-' + currentStep).style.display = 'none';
let prev = currentStep - 1;
if (prev >= 1) {
document.getElementById('step-' + prev).style.display = 'block';
updateProgress(prev);
}
}
function updateProgress(step) {
// Update teks (jika di step terakhir ubah teksnya)
if (step === totalSteps) {
progressText.innerText = "Langkah Terakhir!";
} else {
progressText.innerText = "Pertanyaan " + step + " dari " + (totalSteps - 1);
}
// Hitung persentase progress (Step 7 = 100%)
let percent = (step / totalSteps) * 100;
progressBar.style.width = percent + '%';
progressBar.setAttribute('aria-valuenow', percent);
}
</script>
@endsection @endsection

View File

@ -3,12 +3,12 @@
@section('content') @section('content')
<div class="container-fluid py-4"> <div class="container-fluid py-4">
<div class="page-header mb-4 text-start"> <div class="page-header mb-4 text-start">
<nav aria-label="breadcrumb"> {{-- <nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent p-0 mb-2"> <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"><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> <li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Penilaian Pelatih</li>
</ol> </ol>
</nav> </nav> --}}
<h3 class="fw-bold text-dark">SDM Merpati Putih</h3> <h3 class="fw-bold text-dark">SDM Merpati Putih</h3>
</div> </div>

View File

@ -31,7 +31,7 @@
</div> </div>
{{-- Form Tersembunyi untuk Submit Data --}} {{-- Form Tersembunyi untuk Submit Data --}}
<form id="form-scan" action="{{ route('presensi.storeMandiri') }}" method="POST" style="display: none;"> <form id="form-scan" action="{{ route('presensi.anggota.storeMandiri') }}" method="POST" style="display: none;">
@csrf @csrf
<input type="hidden" name="jadwal_id" id="jadwal_id_input"> <input type="hidden" name="jadwal_id" id="jadwal_id_input">
</form> </form>

View File

@ -1,4 +1,4 @@
@extends('layout.app') {{-- @extends('layout.app')
@section('content') @section('content')
<div class="container-fluid py-4"> <div class="container-fluid py-4">
@ -235,4 +235,270 @@
} }
.bg-light { background-color: #f8f9fa !important; } .bg-light { background-color: #f8f9fa !important; }
</style> </style>
@endsection --}}
@extends('layout.app')
@section('content')
<div class="container-fluid py-4">
<div class="row mb-4">
<div class="col-12">
<div class="card shadow-sm border-0" style="border-radius: 20px; background: linear-gradient(135deg, #0d6efd 0%, #0a58ca 100%);">
<div class="card-body p-4 d-flex align-items-center position-relative overflow-hidden">
<div class="position-absolute top-0 end-0 opacity-10 mt-n4 me-n4">
<i class="icon-shield" style="font-size: 150px; color: white;"></i>
</div>
<div class="bg-white rounded-circle d-flex justify-content-center align-items-center shadow p-1 me-4" style="width: 80px; height: 80px; z-index: 1;">
@if($anggota->foto_profil)
<img src="{{ asset('storage/' . $anggota->foto_profil) }}" alt="Avatar" class="rounded-circle" style="width: 100%; height: 100%; object-fit: cover;">
@else
<img src="https://ui-avatars.com/api/?name={{ urlencode($anggota->nama_lengkap) }}&background=e9ecef&color=0d6efd&size=80" alt="Avatar" class="rounded-circle" style="width: 100%; height: 100%;">
@endif
</div>
<div style="z-index: 1;">
<h3 class="fw-bold text-white mb-1">{{ $anggota->nama_lengkap }}</h3>
<p class="text-white-50 mb-0"><i class="icon-map-pin me-1"></i> Kolat {{ $anggota->kolat->nama_kolat }}</p>
</div>
</div>
</div>
</div>
</div>
@if(session('success'))
<div class="alert alert-success border-0 shadow-sm mb-4" style="border-radius: 15px;">
<i class="icon-check-circle me-2"></i> {{ session('success') }}
</div>
@endif
@if($errors->any())
<div class="alert alert-danger border-0 shadow-sm mb-4" style="border-radius: 15px;">
<div class="d-flex align-items-center mb-2">
<i class="icon-alert-triangle me-2 fs-5"></i> <strong>Pembaruan Gagal!</strong>
</div>
<ul class="mb-0">
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="row">
<div class="col-md-8">
<form action="{{ route('profile.update') }}" method="POST" id="formProfil" enctype="multipart/form-data">
@csrf
@method('PUT')
<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 d-flex justify-content-between align-items-center">
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Data Pribadi</h5>
<button type="button" id="btnEditMode" class="btn btn-sm btn-outline-primary rounded-pill px-3 fw-bold">
<i class="icon-edit-2 me-1"></i> Edit Data
</button>
</div>
<div class="card-body p-4">
<div class="row g-3">
<div class="col-md-12 mb-2">
<label class="form-label fw-bold">Foto Profil (Opsional)</label>
<input type="file" name="foto_profil" class="form-control profil-input" accept="image/jpeg,image/png,image/jpg" disabled>
<small class="text-muted d-block mt-1">Format: JPG, JPEG, PNG. Maksimal 2MB. Kosongkan jika tidak ingin mengubah foto.</small>
</div>
<div class="col-md-12">
<label class="form-label fw-bold">Nama Lengkap</label>
<input type="text" name="nama_lengkap" class="form-control profil-input"
value="{{ old('nama_lengkap', $anggota->nama_lengkap) }}" disabled required>
</div>
<div class="col-md-6">
<label class="form-label fw-bold">Alamat Email (User ID)</label>
<input type="email" class="form-control bg-light"
value="{{ $anggota->user->email }}" readonly>
</div>
<div class="col-md-6">
<label class="form-label fw-bold">No. WhatsApp</label>
<input type="number" name="no_hp" class="form-control profil-input"
value="{{ old('no_hp', $anggota->no_hp) }}" disabled required>
</div>
<div class="col-md-6">
<label class="form-label fw-bold">Tempat Lahir</label>
<input type="text" name="tempat_lahir" class="form-control profil-input"
value="{{ old('tempat_lahir', $anggota->tempat_lahir) }}" disabled required>
</div>
<div class="col-md-6">
<label class="form-label fw-bold">Tanggal Lahir</label>
<input type="date" name="tgl_lahir" class="form-control profil-input"
value="{{ old('tgl_lahir', $anggota->tgl_lahir) }}" disabled required>
</div>
<div class="col-md-6">
<label class="form-label fw-bold">Jenis Kelamin</label>
<select name="jenis_kelamin" class="form-select form-control profil-input" disabled required>
<option value="L" {{ old('jenis_kelamin', $anggota->jenis_kelamin) == 'L' ? 'selected' : '' }}>Laki-laki</option>
<option value="P" {{ old('jenis_kelamin', $anggota->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 profil-input" rows="3" disabled required>{{ old('alamat', $anggota->alamat) }}</textarea>
</div>
</div>
</div>
<div class="card-footer bg-light border-0 p-4 d-none" id="footerSimpanProfil" style="border-radius: 0 0 20px 20px;">
<div class="d-flex justify-content-end gap-2">
<button type="button" id="btnBatalEdit" class="btn btn-light px-4 fw-bold shadow-sm" style="border-radius: 10px;">Batal</button>
<button type="submit" class="btn btn-primary px-4 fw-bold shadow" style="border-radius: 10px;">Simpan Perubahan</button>
</div>
</div>
</div>
</form>
<form action="{{ route('profile.password') }}" method="POST">
@csrf
@method('PUT')
<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-dark mb-0"><i class="icon-lock me-2 text-warning"></i>Keamanan & Password</h5>
</div>
<div class="card-body p-4">
<div class="row g-3">
<div class="col-md-12">
<label class="form-label fw-bold">Password Saat Ini</label>
<input type="password" name="current_password" class="form-control" placeholder="Masukkan password lama" required>
</div>
<div class="col-md-6">
<label class="form-label fw-bold">Password Baru</label>
<input type="password" name="password" class="form-control" placeholder="Minimal 8 karakter" required>
</div>
<div class="col-md-6">
<label class="form-label fw-bold">Konfirmasi Password Baru</label>
<input type="password" name="password_confirmation" class="form-control" placeholder="Ulangi password baru" required>
</div>
</div>
</div>
<div class="card-footer bg-white border-0 px-4 pb-4 pt-0">
<button type="submit" class="btn btn-warning text-dark fw-bold shadow-sm w-100" style="border-radius: 10px;">
Perbarui Password
</button>
</div>
</div>
</form>
</div>
<div class="col-md-4">
<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>Status Organisasi</h5>
</div>
<div class="card-body p-4">
<div class="mb-3">
<label class="text-muted small d-block">Nomor Induk Anggota</label>
<span class="fw-bold text-primary fs-5">{{ $anggota->no_induk }}</span>
</div>
<hr class="opacity-10">
<div class="mb-3">
<label class="form-label fw-bold">Jabatan</label>
<div class="p-2 bg-light rounded text-dark fw-semibold border border-light">
{{ $anggota->role->nama_role }}
</div>
</div>
<div class="mb-3">
<label class="form-label fw-bold">Asal Kolat</label>
<div class="p-2 bg-light rounded text-dark fw-semibold border border-light">
Kolat {{ $anggota->kolat->nama_kolat }}
</div>
</div>
<div class="mb-3">
<label class="form-label fw-bold">Tingkatan Sabuk</label>
<div class="p-2 bg-light rounded text-dark fw-semibold border border-light">
{{ $anggota->tingkatan ?? 'Belum ada data' }}
</div>
</div>
</div>
</div>
<div class="card border-0 shadow-sm" style="border-radius: 20px; background-color: #fff4f4;">
<div class="card-body p-4 text-center">
<div class="rounded-circle bg-white d-inline-flex p-3 mb-3 shadow-sm">
<i class="icon-help-circle text-danger fs-4"></i>
</div>
<h6 class="fw-bold text-danger">Butuh Bantuan?</h6>
<p class="small text-muted mb-0">Jika data organisasi (Kolat/Jabatan/Tingkat) tidak sesuai, silakan hubungi Pengurus Cabang melalui pelatih Anda.</p>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const btnEditMode = document.getElementById('btnEditMode');
const btnBatalEdit = document.getElementById('btnBatalEdit');
const inputs = document.querySelectorAll('.profil-input');
const footerSimpan = document.getElementById('footerSimpanProfil');
// Fungsi untuk mengaktifkan mode edit
btnEditMode.addEventListener('click', function() {
inputs.forEach(input => {
input.removeAttribute('disabled');
input.classList.add('border-primary'); // Highlight input yang bisa diedit
});
btnEditMode.classList.add('d-none'); // Sembunyikan tombol Edit
footerSimpan.classList.remove('d-none'); // Munculkan tombol Simpan
inputs[0].focus(); // Fokus ke input pertama
});
// Fungsi untuk membatalkan mode edit
btnBatalEdit.addEventListener('click', function() {
inputs.forEach(input => {
input.setAttribute('disabled', 'disabled');
input.classList.remove('border-primary');
});
btnEditMode.classList.remove('d-none');
footerSimpan.classList.add('d-none');
// Opsi: reset form ke nilai awal jika dibatalkan
document.getElementById('formProfil').reset();
});
});
</script>
<style>
.form-control {
border-radius: 10px;
padding: 10px 15px;
border: 1px solid #dce1e7;
transition: all 0.3s;
}
.form-select {
border-radius: 10px;
padding: 10px 15px;
border: 1px solid #dce1e7;
transition: all 0.3s;
}
.form-control:disabled, .form-select:disabled {
background-color: #f8f9fa;
cursor: not-allowed;
opacity: 0.8;
}
.form-control:focus, .form-select:focus {
border-color: #0d6efd;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.1);
}
.border-primary {
border-color: #0d6efd !important;
background-color: #fff !important;
}
.bg-light { background-color: #f8f9fa !important; }
</style>
@endsection @endsection

View File

@ -3,12 +3,12 @@
@section('content') @section('content')
<div class="container-fluid py-4"> <div class="container-fluid py-4">
<div class="page-header mb-4 text-start"> <div class="page-header mb-4 text-start">
<nav aria-label="breadcrumb"> {{-- <nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent p-0 mb-2"> <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"><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">Rekap Kelayakan</li> <li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Rekap Kelayakan</li>
</ol> </ol>
</nav> </nav> --}}
<h3 class="fw-bold text-dark">Rekap Kelayakan Anggota</h3> <h3 class="fw-bold text-dark">Rekap Kelayakan Anggota</h3>
<p class="text-muted small">Penentuan kelayakan ujian berdasarkan presensi dan administrasi SPP.</p> <p class="text-muted small">Penentuan kelayakan ujian berdasarkan presensi dan administrasi SPP.</p>
</div> </div>
@ -55,12 +55,12 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover align-middle main-table"> <table class="table table-hover align-middle main-table">
<thead> <thead>
<tr> <tr class="text-center">
<th width="60" class="text-center">No</th> <th width="60">No</th>
<th>Identitas</th> <th>Identitas</th>
<th class="text-center">Presensi</th> <th>Presensi</th>
<th class="text-center">Status SPP</th> <th>Status SPP</th>
<th class="text-center">Kelayakan Ujian</th> <th>Kelayakan Ujian</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -68,8 +68,8 @@
<tr> <tr>
<td class="text-muted small text-center">{{ $no + 1 }}</td> <td class="text-muted small text-center">{{ $no + 1 }}</td>
<td> <td>
<div class="fw-bold text-dark text-start ps-3">{{ $item['nama'] }}</div> <div class="fw-bold text-dark ps-3 text-center">{{ $item['nama'] }}</div>
<small class="text-muted text-start ps-3 d-block">Tingkat: {{ $item['tingkatan'] }}</small> <small class="text-muted text-center ps-3 d-block">Tingkat: {{ $item['tingkatan'] }}</small>
</td> </td>
<td class="text-center"> <td class="text-center">
<span class="fw-bold {{ $item['persentase_presensi'] >= 75 ? 'text-primary' : 'text-warning' }}"> <span class="fw-bold {{ $item['persentase_presensi'] >= 75 ? 'text-primary' : 'text-warning' }}">

View File

@ -7,6 +7,7 @@
use App\Http\Controllers\KasController; use App\Http\Controllers\KasController;
use App\Http\Controllers\KolatController; use App\Http\Controllers\KolatController;
use App\Http\Controllers\LaporanController; use App\Http\Controllers\LaporanController;
use App\Http\Controllers\MemberDashboardController;
use App\Http\Controllers\PelatihController; use App\Http\Controllers\PelatihController;
use App\Http\Controllers\PenilaianController; use App\Http\Controllers\PenilaianController;
use App\Http\Controllers\PresensiController; use App\Http\Controllers\PresensiController;
@ -44,12 +45,18 @@
// ======================================================= // =======================================================
Route::middleware('auth')->group(function () { Route::middleware('auth')->group(function () {
Route::post('/logout', [AuthController::class, 'logout'])->name('logout'); Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
Route::get('/profile/edit', [ProfileController::class, 'edit'])->name('profile.edit');
Route::put('/profile/update', [ProfileController::class, 'update'])->name('profile.update');
Route::put('/profile/password', [ProfileController::class, 'updatePassword'])->name('profile.password');
// ======================================================= // =======================================================
// 1. BLOK KHUSUS ANGGOTA // 1. BLOK KHUSUS ANGGOTA
// ======================================================= // =======================================================
Route::middleware('checkrole:Anggota')->group(function () { Route::middleware('checkrole:Anggota')->group(function () {
Route::get('/dashboard/anggota', [MemberDashboardController::class, 'index'])->name('anggota.dashboard');
// SPP Anggota (Upload Bukti) // SPP Anggota (Upload Bukti)
Route::prefix('anggota/spp')->name('spp.anggota.')->group(function () { Route::prefix('anggota/spp')->name('spp.anggota.')->group(function () {
Route::get('/', [SppController::class, 'indexAnggota'])->name('index'); Route::get('/', [SppController::class, 'indexAnggota'])->name('index');
@ -66,6 +73,7 @@
}); });
// Penilaian (Anggota mengisi nilai) // Penilaian (Anggota mengisi nilai)
Route::get('/penilaian/anggota', [PenilaianController::class, 'indexAnggota'])->name('penilaian.anggota_index');
Route::get('/penilaian/create/{id}', [PenilaianController::class, 'create'])->name('penilaian.create'); Route::get('/penilaian/create/{id}', [PenilaianController::class, 'create'])->name('penilaian.create');
Route::post('/penilaian/store', [PenilaianController::class, 'store'])->name('penilaian.store'); Route::post('/penilaian/store', [PenilaianController::class, 'store'])->name('penilaian.store');
}); });
@ -74,6 +82,8 @@
// 2. BLOK KHUSUS PENGURUS & PELATIH (Bisa Akses Bersama) // 2. BLOK KHUSUS PENGURUS & PELATIH (Bisa Akses Bersama)
// ======================================================= // =======================================================
Route::middleware('checkrole:Pengurus,Pelatih')->group(function () { Route::middleware('checkrole:Pengurus,Pelatih')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
// Lihat Master Data Dasar // Lihat Master Data Dasar
Route::get('/anggota', [AnggotaController::class, 'anggota'])->name('anggota.anggota'); Route::get('/anggota', [AnggotaController::class, 'anggota'])->name('anggota.anggota');
Route::get('/anggota/tambah', [AnggotaController::class, 'create'])->name('anggota.create'); Route::get('/anggota/tambah', [AnggotaController::class, 'create'])->name('anggota.create');
@ -171,9 +181,6 @@
}); });
Route::get('/profile/edit', [ProfileController::class, 'edit'])->name('profile.edit');
Route::put('/profile/update', [ProfileController::class, 'update'])->name('profile.update');
Route::put('/profile/password', [ProfileController::class, 'updatePassword'])->name('profile.password');
}); });