manajemen latihan belum
This commit is contained in:
parent
2092a810ce
commit
65bc2458ac
|
|
@ -13,12 +13,26 @@ class JadwalController extends Controller
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
// Mengambil data jadwal beserta relasi kolat dan pelatih
|
$data_jadwal = Jadwal::with(['kolat', 'pelatih'])
|
||||||
$data_jadwal = Jadwal::with(['kolat', 'pelatih'])->orderBy('tanggal', 'desc')->get();
|
->orderBy('tanggal', 'desc')
|
||||||
|
->orderBy('jam_mulai', 'desc')
|
||||||
|
->get();
|
||||||
|
|
||||||
return view('jadwal.jadwal', compact('data_jadwal'));
|
return view('jadwal.jadwal', compact('data_jadwal'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function konfirmasiSelesai($id)
|
||||||
|
{
|
||||||
|
$jadwal = Jadwal::findOrFail($id);
|
||||||
|
|
||||||
|
// Kita paksa ubah status ke 'selesai'
|
||||||
|
$jadwal->status = 'selesai';
|
||||||
|
$jadwal->save();
|
||||||
|
|
||||||
|
return redirect()->route('jadwal.index')
|
||||||
|
->with('success', 'Latihan ' . $jadwal->judul_kegiatan . ' telah dikonfirmasi selesai!');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
|
|
@ -70,19 +84,21 @@ public function edit($id)
|
||||||
$query->where('nama_role', 'Pelatih');
|
$query->where('nama_role', 'Pelatih');
|
||||||
})->get();
|
})->get();
|
||||||
|
|
||||||
return view('jadwal.edit', compact('jadwal', 'data_kolat', 'data_pelatih'));
|
return view('jadwal.editjadwal', compact('jadwal', 'data_kolat', 'data_pelatih'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id)
|
||||||
{
|
{
|
||||||
$jadwal = Jadwal::findOrFail($id);
|
$jadwal = Jadwal::findOrFail($id);
|
||||||
|
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'judul_kegiatan' => 'required|string',
|
'judul_kegiatan' => 'required|string|max:255',
|
||||||
'kolat_id' => 'required',
|
'kolat_id' => 'required|exists:kolat,id',
|
||||||
'pelatih_id' => 'required',
|
'pelatih_id' => 'required|exists:anggotas,id',
|
||||||
'tanggal' => 'required|date',
|
'jenis' => 'required|in:Rutin,Tambahan,Pengumuman',
|
||||||
|
'tanggal' => 'required|date',
|
||||||
|
'jam_mulai' => 'required',
|
||||||
|
'lokasi' => 'required|string',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$jadwal->update($request->all());
|
$jadwal->update($request->all());
|
||||||
|
|
@ -100,4 +116,5 @@ public function destroy($id)
|
||||||
return redirect()->route('jadwal.index')
|
return redirect()->route('jadwal.index')
|
||||||
->with('success', 'Jadwal telah dihapus dari sistem.');
|
->with('success', 'Jadwal telah dihapus dari sistem.');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ public function store(Request $request)
|
||||||
public function edit($id)
|
public function edit($id)
|
||||||
{
|
{
|
||||||
$pelatih = Anggota::findOrFail($id);
|
$pelatih = Anggota::findOrFail($id);
|
||||||
return view('pelatih.edit', compact('pelatih'));
|
return view('pelatih.editpelatih', compact('pelatih'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,152 @@
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
// TAMBAHAN WAJIB: Memanggil Facades dan Model yang digunakan
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use App\Models\Jadwal;
|
||||||
|
use App\Models\Presensi;
|
||||||
|
use App\Models\Anggota;
|
||||||
|
|
||||||
class PresensiController extends Controller
|
class PresensiController extends Controller
|
||||||
{
|
{
|
||||||
//
|
public function index()
|
||||||
|
{
|
||||||
|
// Mengambil semua jadwal secara manual menggunakan Query Builder (JOIN)
|
||||||
|
$data_jadwal = DB::table('jadwals')
|
||||||
|
->leftJoin('anggotas', 'jadwals.pelatih_id', '=', 'anggotas.id')
|
||||||
|
->leftJoin('kolat', 'jadwals.kolat_id', '=', 'kolat.id') // Sesuaikan jika nama tabel di database kamu adalah 'kolat'
|
||||||
|
->select(
|
||||||
|
'jadwals.*',
|
||||||
|
'anggotas.nama_lengkap as nama_pelatih',
|
||||||
|
'kolat.nama_kolat as nama_kolat'
|
||||||
|
)
|
||||||
|
->orderBy('jadwals.tanggal', 'desc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Pastikan nama foldernya konsisten (admin atau pengurus)
|
||||||
|
return view('presensi.pengurus.index', compact('data_jadwal'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function kehadiran($jadwal_id)
|
||||||
|
{
|
||||||
|
// Variabel dibuat dengan nama $jadwal (tunggal)
|
||||||
|
$jadwal = Jadwal::with(['kolat', 'pelatih'])->findOrFail($jadwal_id);
|
||||||
|
|
||||||
|
$data_presensi = Presensi::with('anggota', 'pelatihVerifikator')
|
||||||
|
->where('jadwal_id', $jadwal_id)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$daftar_anggota = Anggota::where('kolat_id', $jadwal->kolat_id)
|
||||||
|
->where('status', 'Aktif')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Pastikan di sini tulisannya 'jadwal' (sesuai nama variabel di atas)
|
||||||
|
return view('presensi.pengurus.kehadiran', compact('jadwal', 'data_presensi', 'daftar_anggota'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2. Proses Pelatih klik "Konfirmasi Hadir"
|
||||||
|
*/
|
||||||
|
public function konfirmasi($presensi_id)
|
||||||
|
{
|
||||||
|
$presensi = Presensi::findOrFail($presensi_id);
|
||||||
|
|
||||||
|
// Ubah status menjadi terverifikasi dan catat ID Pelatih yang klik
|
||||||
|
$presensi->update([
|
||||||
|
'is_verified' => true,
|
||||||
|
'verified_by' => Auth::user()->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', 'Kehadiran ' . $presensi->anggota->nama_lengkap . ' berhasil dikonfirmasi!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 3. Proses Pelatih input manual dari Modal (Kasus Lupa HP)
|
||||||
|
*/
|
||||||
|
public function storeManual(Request $request)
|
||||||
|
{
|
||||||
|
// Validasi input dari form modal
|
||||||
|
$request->validate([
|
||||||
|
'jadwal_id' => 'required|exists:jadwals,id',
|
||||||
|
'anggota_id' => 'required|exists:anggotas,id',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Cek apakah anggota tersebut sudah absen sebelumnya agar tidak ada data ganda (double input)
|
||||||
|
$sudah_absen = Presensi::where('jadwal_id', $request->jadwal_id)
|
||||||
|
->where('anggota_id', $request->anggota_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($sudah_absen) {
|
||||||
|
return redirect()->back()->with('error', 'Anggota tersebut sudah tercatat di daftar kehadiran!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simpan data presensi baru
|
||||||
|
// Karena diinput langsung oleh pelatih, is_verified otomatis bernilai true
|
||||||
|
Presensi::create([
|
||||||
|
'jadwal_id' => $request->jadwal_id,
|
||||||
|
'anggota_id' => $request->anggota_id,
|
||||||
|
'status' => 'Hadir',
|
||||||
|
'waktu_presensi' => now(), // Waktu dicatat saat form disubmit
|
||||||
|
'is_verified' => true, // Langsung Sah
|
||||||
|
'verified_by' => Auth::user()->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', 'Presensi manual berhasil ditambahkan!');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function indexAnggota()
|
||||||
|
{
|
||||||
|
$now = \Carbon\Carbon::now('Asia/Jakarta');
|
||||||
|
$hari_ini = $now->format('Y-m-d');
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
// 1. Ambil jadwal latihan yang terjadi HARI INI sesuai dengan Kolat si Anggota
|
||||||
|
// Asumsinya di tabel anggotas (users) ada kolom kolat_id
|
||||||
|
$jadwal_hari_ini = Jadwal::with('pelatih')
|
||||||
|
->where('tanggal', $hari_ini)
|
||||||
|
->where('kolat_id', $user->kolat_id)
|
||||||
|
->orderBy('jam_mulai', 'asc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// 2. Cek apakah anggota ini sudah absen di jadwal tersebut
|
||||||
|
// Menggunakan pluck() untuk mengambil ID jadwal hari ini saja
|
||||||
|
$presensi_saya = Presensi::where('anggota_id', $user->id)
|
||||||
|
->whereIn('jadwal_id', $jadwal_hari_ini->pluck('id'))
|
||||||
|
->get()
|
||||||
|
->keyBy('jadwal_id'); // Jadikan ID jadwal sebagai key array agar mudah dicek di View
|
||||||
|
|
||||||
|
return view('presensi.anggota.index', compact('jadwal_hari_ini', 'presensi_saya', 'now'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeMandiri(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'jadwal_id' => 'required|exists:jadwals,id',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
// Cek agar tidak bisa klik absen 2 kali (Double submit)
|
||||||
|
$sudah_absen = Presensi::where('jadwal_id', $request->jadwal_id)
|
||||||
|
->where('anggota_id', $user->id)
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($sudah_absen) {
|
||||||
|
return redirect()->back()->with('error', 'Kamu sudah melakukan absensi untuk jadwal ini!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simpan data presensi dengan status is_verified = false (Menunggu ACC)
|
||||||
|
Presensi::create([
|
||||||
|
'jadwal_id' => $request->jadwal_id,
|
||||||
|
'anggota_id' => $user->id,
|
||||||
|
'status' => 'Hadir',
|
||||||
|
'waktu_presensi' => now(),
|
||||||
|
'is_verified' => false, // Belum Sah, butuh ACC Pelatih
|
||||||
|
'verified_by' => null
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', 'Berhasil! Kehadiranmu sedang menunggu konfirmasi Pelatih.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,14 @@ class Presensi extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'jadwal_id',
|
'jadwal_id',
|
||||||
'anggota_id',
|
'anggota_id',
|
||||||
'status',
|
'status',
|
||||||
'keterangan',
|
'keterangan',
|
||||||
'waktu_presensi'
|
'waktu_presensi',
|
||||||
];
|
'is_verified',
|
||||||
|
'verified_by'
|
||||||
|
];
|
||||||
|
|
||||||
// Relasi: Presensi ini untuk jadwal yang mana?
|
// Relasi: Presensi ini untuk jadwal yang mana?
|
||||||
public function jadwal()
|
public function jadwal()
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'timezone' => 'UTC',
|
'timezone' => 'Asia/Jakarta',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,22 @@
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('presensis', function (Blueprint $table) {
|
Schema::create('presensis', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('jadwal_id')->constrained('jadwals')->onDelete('cascade');
|
$table->foreignId('jadwal_id')->constrained('jadwals')->onDelete('cascade');
|
||||||
$table->foreignId('anggota_id')->constrained('anggotas')->onDelete('cascade');
|
$table->foreignId('anggota_id')->constrained('anggotas')->onDelete('cascade');
|
||||||
$table->enum('status', ['Hadir', 'Izin', 'Sakit', 'Alfa'])->default('Alfa');
|
$table->enum('status', ['Hadir', 'Izin', 'Sakit', 'Alfa'])->default('Alfa');
|
||||||
$table->text('keterangan')->nullable(); // Alasan izin/sakit
|
$table->text('keterangan')->nullable();
|
||||||
$table->timestamp('waktu_presensi')->nullable(); // Catat jam tepatnya dia absen
|
$table->timestamp('waktu_presensi')->nullable();
|
||||||
$table->timestamps();
|
|
||||||
});
|
// TAMBAHKAN 2 BARIS INI:
|
||||||
|
$table->boolean('is_verified')->default(false); // Untuk tahu sudah di-ACC pelatih atau belum
|
||||||
|
$table->unsignedBigInteger('verified_by')->nullable(); // Untuk catat ID pelatih yang meng-ACC
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
// Tambahkan foreign key untuk verified_by
|
||||||
|
$table->foreign('verified_by')->references('id')->on('anggotas');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?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('jadwals', function (Blueprint $table) {
|
||||||
|
// Tambahkan kolom status dengan default 'pending'
|
||||||
|
$table->string('status')->default('pending')->after('jenis');
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('jadwals', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('status');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?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('jadwals', function (Blueprint $table) {
|
||||||
|
// Menambah kolom untuk simpan foto kegiatan (pengganti WA)
|
||||||
|
$table->string('foto_bukti')->nullable()->after('lokasi');
|
||||||
|
// Menambah kolom untuk materi/catatan latihan
|
||||||
|
$table->text('catatan_latihan')->nullable()->after('foto_bukti');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('jadwals', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['foto_bukti', 'catatan_latihan']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -12,6 +12,9 @@ class DatabaseSeeder extends Seeder
|
||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
|
$this->call([
|
||||||
|
RoleSeeder::class,
|
||||||
|
]);
|
||||||
// \App\Models\User::factory(10)->create();
|
// \App\Models\User::factory(10)->create();
|
||||||
|
|
||||||
// \App\Models\User::factory()->create([
|
// \App\Models\User::factory()->create([
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class RoleSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$roles = ['Anggota', 'Pelatih', 'Pengurus'];
|
||||||
|
|
||||||
|
foreach ($roles as $role) {
|
||||||
|
DB::table('role')->insert([
|
||||||
|
'nama_role' => $role,
|
||||||
|
'slug' => Str::slug($role),
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,181 +1,221 @@
|
||||||
@extends('layout.app')
|
@extends('layout.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container-fluid py-4">
|
<div class="container-fluid py-4">
|
||||||
<!-- Header & Breadcrumb -->
|
<!-- Header & Breadcrumb -->
|
||||||
<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="{{ route('anggota.anggota') }}" class="text-muted text-decoration-none small">Daftar Anggota</a></li>
|
<li class="breadcrumb-item"><a href="{{ route('anggota.anggota') }}"
|
||||||
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Edit Anggota</li>
|
class="text-muted text-decoration-none small">Daftar Anggota</a></li>
|
||||||
</ol>
|
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Edit Anggota</li>
|
||||||
</nav>
|
</ol>
|
||||||
<h3 class="fw-bold text-dark">Form Edit Anggota Merpati Putih</h3>
|
</nav>
|
||||||
<p class="text-muted small">Perbarui informasi identitas atau legalitas SK anggota di bawah ini.</p>
|
<h3 class="fw-bold text-dark">Form Edit Anggota Merpati Putih</h3>
|
||||||
</div>
|
<p class="text-muted small">Perbarui informasi identitas atau legalitas SK anggota di bawah ini.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<!-- Form Start - Pastikan enctype ada untuk upload foto SK -->
|
<!-- Form Start - Pastikan enctype ada untuk upload foto SK -->
|
||||||
<form action="{{ route('anggota.update', $anggota->id) }}" method="POST" enctype="multipart/form-data">
|
<form action="{{ route('anggota.update', $anggota->id) }}" method="POST" enctype="multipart/form-data">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
|
|
||||||
<!-- CARD 1: INFORMASI PRIBADI -->
|
<!-- CARD 1: INFORMASI PRIBADI -->
|
||||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
<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">
|
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||||
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Informasi Pribadi</h5>
|
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Informasi Pribadi</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-4">
|
<div class="card-body p-4">
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label fw-bold">No Induk</label>
|
<label class="form-label fw-bold">No Induk</label>
|
||||||
<input type="text" name="no_induk" class="form-control bg-light fw-bold text-primary" value="{{ $anggota->no_induk }}" readonly>
|
<input type="text" name="no_induk" class="form-control bg-light fw-bold text-primary"
|
||||||
<small class="text-muted" style="font-size: 11px;">* No. induk permanen dan tidak dapat diubah</small>
|
value="{{ $anggota->no_induk }}" readonly>
|
||||||
</div>
|
<small class="text-muted" style="font-size: 11px;">* No. induk permanen dan tidak dapat
|
||||||
<div class="col-md-6">
|
diubah</small>
|
||||||
<label class="form-label fw-bold">Nama Lengkap</label>
|
</div>
|
||||||
<input type="text" name="nama_lengkap" class="form-control bg-light" value="{{ $anggota->nama_lengkap }}" required>
|
<div class="col-md-6">
|
||||||
</div>
|
<label class="form-label fw-bold">Nama Lengkap</label>
|
||||||
<div class="col-md-6">
|
<input type="text" name="nama_lengkap" class="form-control bg-light"
|
||||||
<label class="form-label fw-bold">No. WhatsApp (HP)</label>
|
value="{{ $anggota->nama_lengkap }}" required>
|
||||||
<div class="input-group">
|
</div>
|
||||||
<span class="input-group-text bg-light border-end-0">+62</span>
|
<div class="col-md-6">
|
||||||
<input type="number" name="no_hp" class="form-control" value="{{ $anggota->no_hp }}" placeholder="81234567xxx" required>
|
<label class="form-label fw-bold">No. WhatsApp (HP)</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-text bg-light border-end-0">+62</span>
|
||||||
|
<input type="number" name="no_hp" class="form-control"
|
||||||
|
value="{{ $anggota->no_hp }}" placeholder="81234567xxx" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-bold">Alamat Lengkap</label>
|
||||||
|
<input type="text" name="alamat" class="form-control" value="{{ $anggota->alamat }}"
|
||||||
|
required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<label class="form-label fw-bold">Alamat Lengkap</label>
|
|
||||||
<input type="text" name="alamat" class="form-control" value="{{ $anggota->alamat }}" required>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- CARD 2: INFORMASI ORGANISASI -->
|
<!-- CARD 2: INFORMASI ORGANISASI -->
|
||||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
<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">
|
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||||
<h5 class="fw-bold text-success mb-0"><i class="icon-badge me-2"></i>Informasi Organisasi</h5>
|
<h5 class="fw-bold text-success mb-0"><i class="icon-badge me-2"></i>Informasi Organisasi</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-4">
|
<div class="card-body p-4">
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label fw-bold">Jabatan Organisasi</label>
|
<label class="form-label fw-bold">Jabatan Organisasi</label>
|
||||||
<select name="jabatan" id="jabatanSelect" class="form-select border-primary" onchange="toggleSKFields()" required>
|
<select name="jabatan" id="jabatanSelect" class="form-select border-primary"
|
||||||
<option value="anggota" {{ $anggota->jabatan == 'anggota' ? 'selected' : '' }}>Anggota</option>
|
onchange="toggleSKFields()" required>
|
||||||
<option value="pelatih" {{ $anggota->jabatan == 'pelatih' ? 'selected' : '' }}>Pelatih</option>
|
<option value="anggota" {{ $anggota->jabatan == 'anggota' ? 'selected' : '' }}>
|
||||||
<option value="pengurus" {{ $anggota->jabatan == 'pengurus' ? 'selected' : '' }}>Pengurus</option>
|
Anggota</option>
|
||||||
</select>
|
<option value="pelatih" {{ $anggota->jabatan == 'pelatih' ? 'selected' : '' }}>
|
||||||
</div>
|
Pelatih</option>
|
||||||
<div class="col-md-4">
|
<option value="pengurus" {{ $anggota->jabatan == 'pengurus' ? 'selected' : '' }}>
|
||||||
<label class="form-label fw-bold">Tingkatan</label>
|
Pengurus</option>
|
||||||
<input type="text" name="tingkatan" class="form-control" value="{{ $anggota->tingkatan }}" required>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label fw-bold">Status Anggota</label>
|
<label class="form-label fw-bold">Tingkatan</label>
|
||||||
<select name="status" class="form-select" required>
|
<input type="text" name="tingkatan" class="form-control"
|
||||||
<option value="Aktif" {{ $anggota->status == 'Aktif' ? 'selected' : '' }}>Aktif</option>
|
value="{{ $anggota->tingkatan }}" required>
|
||||||
<option value="Non-Aktif" {{ $anggota->status == 'Non-Aktif' ? 'selected' : '' }}>Non-Aktif</option>
|
</div>
|
||||||
</select>
|
<div class="col-md-4">
|
||||||
</div>
|
<label class="form-label fw-bold">Status Anggota</label>
|
||||||
|
<select name="status" class="form-select" required>
|
||||||
|
<option value="Aktif" {{ $anggota->status == 'Aktif' ? 'selected' : '' }}>Aktif
|
||||||
|
</option>
|
||||||
|
<option value="Non-Aktif" {{ $anggota->status == 'Non-Aktif' ? 'selected' : '' }}>
|
||||||
|
Non-Aktif</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- BOX DATA SK (Otomatis muncul jika pilih Pelatih/Pengurus) -->
|
<!-- BOX DATA SK (Otomatis muncul jika pilih Pelatih/Pengurus) -->
|
||||||
<div id="boxSK" class="col-12 mt-3 p-4 bg-light rounded-4 border border-dashed border-danger" style="display: none;">
|
<div id="boxSK"
|
||||||
<h6 class="text-danger fw-bold mb-3"><i class="icon-certificate me-2"></i>Data Legalitas SK (Wajib diisi untuk Pelatih/Pengurus)</h6>
|
class="col-12 mt-3 p-4 bg-light rounded-4 border border-dashed border-danger"
|
||||||
<div class="row g-3">
|
style="display: none;">
|
||||||
<div class="col-md-3">
|
<h6 class="text-danger fw-bold mb-3"><i class="icon-certificate me-2"></i>Data Legalitas
|
||||||
<label class="form-label small fw-bold">Nomor SK</label>
|
SK (Wajib diisi untuk Pelatih/Pengurus)</h6>
|
||||||
<input type="text" name="no_sk" class="form-control" value="{{ $anggota->no_sk ?? '' }}" placeholder="Contoh: SK/001/2026">
|
<div class="row g-3">
|
||||||
</div>
|
<div class="col-md-3">
|
||||||
<div class="col-md-3">
|
<label class="form-label small fw-bold">Nomor SK</label>
|
||||||
<label class="form-label small fw-bold">Tanggal SK</label>
|
<input type="text" name="no_sk" class="form-control"
|
||||||
<input type="date" name="tgl_sk" class="form-control" value="{{ $anggota->tgl_sk ?? '' }}">
|
value="{{ $anggota->no_sk ?? '' }}" placeholder="Contoh: SK/001/2026">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<label class="form-label small fw-bold">Masa Berlaku</label>
|
<label class="form-label small fw-bold">Tanggal SK</label>
|
||||||
<input type="date" name="masa_berlaku" class="form-control" value="{{ $anggota->masa_berlaku ?? '' }}">
|
<input type="date" name="tgl_sk" class="form-control"
|
||||||
</div>
|
value="{{ $anggota->tgl_sk ?? '' }}">
|
||||||
<div class="col-md-3">
|
</div>
|
||||||
<label class="form-label small fw-bold">Upload Scan SK</label>
|
<div class="col-md-3">
|
||||||
<input type="file" name="foto_sk" class="form-control">
|
<label class="form-label small fw-bold">Masa Berlaku</label>
|
||||||
@if($anggota->foto_sk)
|
<input type="date" name="masa_berlaku" class="form-control"
|
||||||
<small class="text-muted mt-1 d-block">File: {{ $anggota->foto_sk }}</small>
|
value="{{ $anggota->masa_berlaku ?? '' }}">
|
||||||
@endif
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label small fw-bold">Upload Scan SK</label>
|
||||||
|
<input type="file" name="foto_sk" class="form-control">
|
||||||
|
@if ($anggota->foto_sk)
|
||||||
|
<small class="text-muted mt-1 d-block">File:
|
||||||
|
{{ $anggota->foto_sk }}</small>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-12 mt-3">
|
{{-- <div class="col-md-12 mt-3">
|
||||||
<label class="form-label fw-bold">Asal Kolat</label>
|
<label class="form-label fw-bold">Asal Kolat</label>
|
||||||
<input type="text" name="asal_kolat" class="form-control" value="{{ $anggota->asal_kolat }}" required>
|
<input type="text" name="asal_kolat" class="form-control" value="{{ $anggota->asal_kolat }}" required>
|
||||||
|
</div> --}}
|
||||||
|
<div class="col-md-12 mt-3">
|
||||||
|
<label class="form-label fw-bold">Asal Kolat</label>
|
||||||
|
<select name="kolat_id" class="form-select" required>
|
||||||
|
<option value="" disabled>-- Pilih Kolat --</option>
|
||||||
|
@foreach ($data_kolat as $kolat)
|
||||||
|
<option value="{{ $kolat->id }}"
|
||||||
|
{{ $anggota->kolat_id == $kolat->id ? 'selected' : '' }}>
|
||||||
|
{{ $kolat->nama_kolat }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- FOOTER CARD UNTUK BUTTON -->
|
||||||
|
<div class="card-footer bg-light border-0 p-4" style="border-radius: 0 0 20px 20px;">
|
||||||
|
<div class="d-flex justify-content-end align-items-center gap-3">
|
||||||
|
<a href="{{ route('anggota.anggota') }}"
|
||||||
|
class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
||||||
|
<i class="icon-x me-1"></i> Batal
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">
|
||||||
|
<i class="icon-check me-1"></i> Simpan Perubahan
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
<!-- FOOTER CARD UNTUK BUTTON -->
|
</div>
|
||||||
<div class="card-footer bg-light border-0 p-4" style="border-radius: 0 0 20px 20px;">
|
|
||||||
<div class="d-flex justify-content-end align-items-center gap-3">
|
|
||||||
<a href="{{ route('anggota.anggota') }}" class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
|
||||||
<i class="icon-x me-1"></i> Batal
|
|
||||||
</a>
|
|
||||||
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">
|
|
||||||
<i class="icon-check me-1"></i> Simpan Perubahan
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- JAVASCRIPT TOGGLE -->
|
<!-- JAVASCRIPT TOGGLE -->
|
||||||
<script>
|
<script>
|
||||||
function toggleSKFields() {
|
function toggleSKFields() {
|
||||||
const jabatan = document.getElementById('jabatanSelect').value;
|
const jabatan = document.getElementById('jabatanSelect').value;
|
||||||
const boxSK = document.getElementById('boxSK');
|
const boxSK = document.getElementById('boxSK');
|
||||||
|
|
||||||
if (jabatan === 'pelatih' || jabatan === 'pengurus') {
|
if (jabatan === 'pelatih' || jabatan === 'pengurus') {
|
||||||
boxSK.style.display = 'block';
|
boxSK.style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
boxSK.style.display = 'none';
|
boxSK.style.display = 'none';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Jalankan saat pertama kali halaman dimuat
|
// Jalankan saat pertama kali halaman dimuat
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
toggleSKFields();
|
toggleSKFields();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.form-control, .form-select {
|
.form-control,
|
||||||
border-radius: 10px;
|
.form-select {
|
||||||
padding: 10px 15px;
|
border-radius: 10px;
|
||||||
}
|
padding: 10px 15px;
|
||||||
.form-control:focus, .form-select:focus {
|
}
|
||||||
border-color: #0d6efd;
|
|
||||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.1);
|
.form-control:focus,
|
||||||
}
|
.form-select:focus {
|
||||||
.btn-cancel {
|
border-color: #0d6efd;
|
||||||
border-radius: 12px;
|
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.1);
|
||||||
transition: all 0.3s ease;
|
}
|
||||||
border: 2px solid #6c757d;
|
|
||||||
}
|
.btn-cancel {
|
||||||
.btn-cancel:hover {
|
border-radius: 12px;
|
||||||
background-color: #6c757d;
|
transition: all 0.3s ease;
|
||||||
color: white;
|
border: 2px solid #6c757d;
|
||||||
transform: translateY(-2px);
|
}
|
||||||
}
|
|
||||||
.btn-save {
|
.btn-cancel:hover {
|
||||||
border-radius: 12px;
|
background-color: #6c757d;
|
||||||
background: (45deg, #0d6efd);
|
color: white;
|
||||||
border: none;
|
transform: translateY(-2px);
|
||||||
transition: all 0.3s ease;
|
}
|
||||||
}
|
|
||||||
.btn-save:hover {
|
.btn-save {
|
||||||
transform: translateY(-2px);
|
border-radius: 12px;
|
||||||
box-shadow: 0 5px 15px rgba(13, 110, 253, 0.4) !important;
|
background: (45deg, #0d6efd);
|
||||||
}
|
border: none;
|
||||||
</style>
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-save:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 5px 15px rgba(13, 110, 253, 0.4) !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
@extends('layout.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-fluid py-4">
|
||||||
|
<div class="page-header mb-4 text-start">
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb bg-transparent p-0 mb-2">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('jadwal.index') }}"
|
||||||
|
class="text-muted text-decoration-none small">Daftar Jadwal</a></li>
|
||||||
|
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Edit Jadwal</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
<h3 class="fw-bold text-dark">Edit Agenda Latihan</h3>
|
||||||
|
<p class="text-muted small">Perbarui detail waktu, lokasi, atau pelatih yang bertugas untuk agenda ini.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form action="{{ route('jadwal.update', $jadwal->id) }}" 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-primary mb-0"><i class="icon-calendar me-2"></i>Informasi Agenda</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-4">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label fw-bold">Judul Kegiatan / Materi Latihan</label>
|
||||||
|
<input type="text" name="judul_kegiatan" class="form-control"
|
||||||
|
value="{{ old('judul_kegiatan', $jadwal->judul_kegiatan) }}" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-bold">Kelompok Latihan (Kolat)</label>
|
||||||
|
<select name="kolat_id" class="form-select" required>
|
||||||
|
@foreach($data_kolat as $kolat)
|
||||||
|
<option value="{{ $kolat->id }}" {{ $jadwal->kolat_id == $kolat->id ? 'selected' : '' }}>
|
||||||
|
{{ $kolat->nama_kolat }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-bold">Pelatih Bertugas</label>
|
||||||
|
<select name="pelatih_id" class="form-select" required>
|
||||||
|
@foreach($data_pelatih as $pelatih)
|
||||||
|
<option value="{{ $pelatih->id }}" {{ $jadwal->pelatih_id == $pelatih->id ? 'selected' : '' }}>
|
||||||
|
{{ $pelatih->nama_lengkap }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-bold">Tanggal</label>
|
||||||
|
<input type="date" name="tanggal" class="form-control"
|
||||||
|
value="{{ old('tanggal', $jadwal->tanggal) }}" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-bold">Jam Mulai</label>
|
||||||
|
<input type="time" name="jam_mulai" class="form-control"
|
||||||
|
value="{{ old('jam_mulai', substr($jadwal->jam_mulai, 0, 5)) }}" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-bold">Jam Selesai (Opsional)</label>
|
||||||
|
<input type="time" name="jam_selesai" class="form-control"
|
||||||
|
value="{{ old('jam_selesai', $jadwal->jam_selesai ? substr($jadwal->jam_selesai, 0, 5) : '') }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-bold">Lokasi / Tempat Latihan</label>
|
||||||
|
<input type="text" name="lokasi" class="form-control"
|
||||||
|
value="{{ old('lokasi', $jadwal->lokasi) }}" placeholder="Contoh: GOR Perjuangan" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-bold">Tipe Agenda</label>
|
||||||
|
<select name="jenis" class="form-select" required>
|
||||||
|
<option value="Rutin" {{ $jadwal->jenis == 'Rutin' ? 'selected' : '' }}>Rutin</option>
|
||||||
|
<option value="Tambahan" {{ $jadwal->jenis == 'Tambahan' ? 'selected' : '' }}>Tambahan</option>
|
||||||
|
<option value="Pengumuman" {{ $jadwal->jenis == 'Pengumuman' ? 'selected' : '' }}>Pengumuman</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label fw-bold">Deskripsi / Catatan Tambahan</label>
|
||||||
|
<textarea name="deskripsi" class="form-control" rows="3">{{ old('deskripsi', $jadwal->deskripsi) }}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer bg-light border-0 p-4" style="border-radius: 0 0 20px 20px;">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<div class="small text-muted">
|
||||||
|
Status saat ini: <span class="badge bg-{{ $jadwal->status == 'selesai' ? 'success' : 'secondary' }}">{{ strtoupper($jadwal->status) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex gap-3">
|
||||||
|
<a href="{{ route('jadwal.index') }}" class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
||||||
|
Batal
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">
|
||||||
|
Simpan Perubahan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="text-center mt-2">
|
||||||
|
<form action="{{ route('jadwal.destroy', $jadwal->id) }}" method="POST" onsubmit="return confirm('Hapus jadwal ini secara permanen?')">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="submit" class="btn btn-link text-danger text-decoration-none small">
|
||||||
|
<i class="icon-trash"></i> Hapus Agenda Ini
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.form-control, .form-select { border-radius: 10px; padding: 10px 15px; }
|
||||||
|
.btn-cancel { border-radius: 12px; transition: 0.3s; border: 2px solid #6c757d; }
|
||||||
|
.btn-save { border-radius: 12px; background: linear-gradient(45deg, #0d6efd, #004fb1); border: none; transition: 0.3s; }
|
||||||
|
.btn-save:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(13, 110, 253, 0.4) !important; }
|
||||||
|
</style>
|
||||||
|
@endsection
|
||||||
|
|
@ -12,6 +12,13 @@
|
||||||
<h3 class="fw-bold text-dark">Manajemen Latihan TapakMP</h3>
|
<h3 class="fw-bold text-dark">Manajemen Latihan TapakMP</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if(session('success'))
|
||||||
|
<div class="alert alert-success alert-dismissible fade show border-0 shadow-sm mb-4" role="alert" style="border-radius: 15px;">
|
||||||
|
<strong>Berhasil!</strong> {{ session('success') }}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card border-0 shadow-sm" style="border-radius: 20px;">
|
<div class="card border-0 shadow-sm" style="border-radius: 20px;">
|
||||||
|
|
@ -32,32 +39,59 @@
|
||||||
<table class="table table-hover align-middle main-table">
|
<table class="table table-hover align-middle main-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="60">No</th>
|
<th width="50" class="text-center">No</th>
|
||||||
<th>Kegiatan & Deskripsi</th>
|
<th>Kegiatan & Pelatih</th>
|
||||||
<th>Kolat</th>
|
<th class="text-center">Status</th>
|
||||||
<th>Pelatih Bertugas</th>
|
|
||||||
<th>Waktu & Lokasi</th>
|
<th>Waktu & Lokasi</th>
|
||||||
<th>Tipe</th>
|
<th class="text-center">Tipe</th>
|
||||||
<th>Aksi</th>
|
<th class="text-center" width="220">Aksi</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@forelse ($data_jadwal as $no => $item)
|
@forelse ($data_jadwal as $no => $item)
|
||||||
|
@php
|
||||||
|
// Set timezone ke Jakarta agar sinkron dengan waktu Indonesia
|
||||||
|
$now = \Carbon\Carbon::now('Asia/Jakarta');
|
||||||
|
$start = \Carbon\Carbon::parse($item->tanggal . ' ' . $item->jam_mulai, 'Asia/Jakarta');
|
||||||
|
$end = $item->jam_selesai
|
||||||
|
? \Carbon\Carbon::parse($item->tanggal . ' ' . $item->jam_selesai, 'Asia/Jakarta')
|
||||||
|
: $start->copy()->addHours(2);
|
||||||
|
|
||||||
|
$dbStatus = trim(strtolower($item->status));
|
||||||
|
|
||||||
|
// Logika Penentuan Label Status
|
||||||
|
if ($dbStatus == 'selesai') {
|
||||||
|
$status_label = 'Selesai';
|
||||||
|
$status_color = 'success';
|
||||||
|
} elseif ($now->greaterThanOrEqualTo($start) && $now->lessThanOrEqualTo($end)) {
|
||||||
|
$status_label = 'Berlangsung';
|
||||||
|
$status_color = 'primary';
|
||||||
|
} elseif ($now->lt($start)) {
|
||||||
|
$status_label = 'Mendatang';
|
||||||
|
$status_color = 'secondary';
|
||||||
|
} else {
|
||||||
|
$status_label = 'Menunggu Konfirmasi';
|
||||||
|
$status_color = 'warning';
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
<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->judul_kegiatan }}</div>
|
<div class="fw-bold text-dark text-start ps-2">
|
||||||
<small class="text-muted text-start ps-3 d-block">{{ Str::limit($item->deskripsi, 40) }}</small>
|
{{ $item->judul_kegiatan }}
|
||||||
|
@if($dbStatus == 'selesai')
|
||||||
|
<i class="bi bi-check-circle-fill text-success ms-1"></i>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<small class="text-muted text-start ps-2 d-block">
|
||||||
|
<i class="icon-user small"></i> {{ $item->pelatih->nama_lengkap ?? 'Belum Ditentukan' }}
|
||||||
|
</small>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<span class="badge bg-light text-dark border px-3" style="border-radius: 8px;">
|
<span class="badge bg-{{ $status_color }} px-3 py-2" style="border-radius: 8px; font-size: 11px;">
|
||||||
{{ $item->kolat->nama_kolat ?? '-' }}
|
{{ $status_label }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
<div class="fw-bold text-dark small">{{ $item->pelatih->nama_lengkap ?? 'Belum Ditentukan' }}</div>
|
|
||||||
<small class="text-muted" style="font-size: 10px;">ID: {{ $item->pelatih->no_induk ?? '-' }}</small>
|
|
||||||
</td>
|
|
||||||
<td class="text-start ps-4">
|
<td class="text-start ps-4">
|
||||||
<div class="small fw-bold text-dark">
|
<div class="small fw-bold text-dark">
|
||||||
<i class="icon-calendar me-1"></i> {{ \Carbon\Carbon::parse($item->tanggal)->format('d M Y') }}
|
<i class="icon-calendar me-1"></i> {{ \Carbon\Carbon::parse($item->tanggal)->format('d M Y') }}
|
||||||
|
|
@ -66,45 +100,52 @@
|
||||||
<i class="icon-clock me-1"></i> {{ substr($item->jam_mulai, 0, 5) }} - {{ $item->jam_selesai ? substr($item->jam_selesai, 0, 5) : 'Selesai' }}
|
<i class="icon-clock me-1"></i> {{ substr($item->jam_mulai, 0, 5) }} - {{ $item->jam_selesai ? substr($item->jam_selesai, 0, 5) : 'Selesai' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="small text-muted text-truncate" style="max-width: 150px;">
|
<div class="small text-muted text-truncate" style="max-width: 150px;">
|
||||||
<i class="icon-map-pin me-1"></i> {{ $item->lokasi }}
|
<i class="icon-map-pin me-1 text-danger"></i> {{ $item->lokasi }}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
@php
|
@php
|
||||||
$bg_color = 'bg-secondary-soft text-secondary';
|
$bg_type = 'bg-secondary-soft text-secondary';
|
||||||
if($item->jenis == 'Rutin') $bg_color = 'bg-success-soft text-success border-success';
|
if($item->jenis == 'Rutin') $bg_type = 'bg-success-soft text-success border-success';
|
||||||
elseif($item->jenis == 'Tambahan') $bg_color = 'bg-info-soft text-info border-info';
|
elseif($item->jenis == 'Tambahan') $bg_type = 'bg-info-soft text-info border-info';
|
||||||
elseif($item->jenis == 'Pengumuman') $bg_color = 'bg-danger-soft text-danger border-danger';
|
elseif($item->jenis == 'Pengumuman') $bg_type = 'bg-danger-soft text-danger border-danger';
|
||||||
@endphp
|
@endphp
|
||||||
<span class="badge rounded-pill {{ $bg_color }} px-3 border">
|
<span class="badge rounded-pill {{ $bg_type }} px-3 border" style="font-size: 10px;">
|
||||||
{{ $item->jenis }}
|
{{ $item->jenis }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<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">
|
||||||
<button class="btn btn-sm btn-action-detail fw-bold px-3 shadow-xs"
|
|
||||||
data-bs-toggle="modal"
|
|
||||||
data-bs-target="#modalDetailJadwal{{ $item->id }}">
|
|
||||||
<i class="icon-eye"></i> Detail
|
|
||||||
</button>
|
|
||||||
|
|
||||||
@if($item->jenis != 'Pengumuman')
|
{{-- TOMBOL KONFIRMASI: Muncul jika sudah masuk jamnya, bukan pengumuman, dan belum selesai --}}
|
||||||
<a href="#" class="btn btn-sm btn-outline-primary fw-bold px-3" style="border-radius: 10px;">
|
@if($dbStatus != 'selesai' && $item->jenis != 'Pengumuman' && $now->greaterThanOrEqualTo($start))
|
||||||
<i class="icon-check-square"></i> Absen
|
<form action="{{ route('jadwal.konfirmasi', $item->id) }}" method="POST" id="form-selesai-{{ $item->id }}" class="d-inline">
|
||||||
</a>
|
@csrf
|
||||||
|
<button type="button" class="btn btn-sm btn-success fw-bold px-2 shadow-xs"
|
||||||
|
style="border-radius: 10px;"
|
||||||
|
onclick="konfirmasiLatihan('{{ $item->id }}', '{{ $item->judul_kegiatan }}')">
|
||||||
|
<i class="bi bi-check2-square"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
<button class="btn btn-sm btn-action-detail fw-bold px-2 shadow-xs"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#modalDetailJadwal{{ $item->id }}">
|
||||||
|
<i class="icon-eye"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
<a href="{{ route('jadwal.edit', $item->id) }}"
|
<a href="{{ route('jadwal.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>
|
<i class="icon-pencil"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{{-- MODAL DETAIL JADWAL (Identik dengan Modal Anggota) --}}
|
{{-- MODAL DETAIL JADWAL --}}
|
||||||
<div class="modal fade" id="modalDetailJadwal{{ $item->id }}" tabindex="-1" aria-hidden="true">
|
<div class="modal fade" id="modalDetailJadwal{{ $item->id }}" tabindex="-1" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-lg">
|
||||||
<div class="modal-content" style="border-radius: 20px; border: none; overflow: hidden;">
|
<div class="modal-content" style="border-radius: 20px; border: none; overflow: hidden;">
|
||||||
<div class="modal-header bg-primary text-white border-0 py-3 px-4">
|
<div class="modal-header bg-primary text-white border-0 py-3 px-4">
|
||||||
<h5 class="modal-title fw-bold">
|
<h5 class="modal-title fw-bold">
|
||||||
|
|
@ -117,48 +158,27 @@ class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs">
|
||||||
<div class="col-md-4 text-center border-end">
|
<div class="col-md-4 text-center border-end">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="bg-light rounded-circle d-inline-flex align-items-center justify-content-center shadow-sm"
|
<div class="bg-light rounded-circle d-inline-flex align-items-center justify-content-center shadow-sm"
|
||||||
style="width: 120px; height: 120px; border: 4px solid #f8f9fa;">
|
style="width: 100px; height: 100px; border: 4px solid #f8f9fa;">
|
||||||
<i class="icon-clipboard text-primary" style="font-size: 60px;"></i>
|
<i class="icon-clipboard text-primary" style="font-size: 50px;"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h5 class="fw-bold mb-1">{{ $item->judul_kegiatan }}</h5>
|
<h5 class="fw-bold mb-1 text-dark">{{ $item->judul_kegiatan }}</h5>
|
||||||
<p class="text-muted small mb-3">ID Jadwal: #JDL-{{ $item->id }}</p>
|
<p class="text-muted small mb-3">Status: <span class="text-{{ $status_color }} fw-bold">{{ strtoupper($status_label) }}</span></p>
|
||||||
<span class="badge rounded-pill {{ $bg_color }} px-4 py-2 border shadow-xs">
|
|
||||||
{{ $item->jenis }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-8 ps-md-4 text-start">
|
<div class="col-md-8 ps-md-4 text-start">
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-12">
|
|
||||||
<h6 class="fw-bold text-primary mb-3 border-bottom pb-2">Informasi Pelaksanaan</h6>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<small class="text-muted d-block">Pelatih Bertugas</small>
|
<small class="text-muted d-block small">Pelatih</small>
|
||||||
<span class="fw-bold text-dark">{{ $item->pelatih->nama_lengkap ?? '-' }}</span>
|
<span class="fw-bold text-dark">{{ $item->pelatih->nama_lengkap ?? '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<small class="text-muted d-block">Kelompok Latihan (Kolat)</small>
|
<small class="text-muted d-block small">Kolat</small>
|
||||||
<span class="fw-bold text-dark">{{ $item->kolat->nama_kolat ?? '-' }}</span>
|
<span class="fw-bold text-dark">{{ $item->kolat->nama_kolat ?? '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-12 mt-3">
|
||||||
<small class="text-muted d-block">Hari & Tanggal</small>
|
<h6 class="fw-bold text-primary border-bottom pb-1 small">Deskripsi Kegiatan</h6>
|
||||||
<span class="fw-bold text-dark">{{ \Carbon\Carbon::parse($item->tanggal)->translatedFormat('l, d F Y') }}</span>
|
<p class="small text-muted mb-0" style="white-space: pre-line;">{{ $item->deskripsi ?? 'Tidak ada deskripsi.' }}</p>
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<small class="text-muted d-block">Waktu</small>
|
|
||||||
<span class="fw-bold text-dark">{{ substr($item->jam_mulai, 0, 5) }} - {{ $item->jam_selesai ? substr($item->jam_selesai, 0, 5) : 'Selesai' }} WIB</span>
|
|
||||||
</div>
|
|
||||||
<div class="col-12">
|
|
||||||
<small class="text-muted d-block">Lokasi Tempat</small>
|
|
||||||
<span class="fw-bold text-dark"><i class="icon-map-pin me-1 text-danger"></i>{{ $item->lokasi }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-12 mt-4">
|
|
||||||
<h6 class="fw-bold text-primary mb-3 border-bottom pb-2">Deskripsi & Catatan</h6>
|
|
||||||
<div class="p-3 rounded-3" style="background-color: #f8faff; border: 1px solid #edf2f9;">
|
|
||||||
<p class="mb-0 text-dark small" style="white-space: pre-line;">{{ $item->deskripsi ?? 'Tidak ada deskripsi tambahan untuk agenda ini.' }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -166,14 +186,13 @@ class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs">
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer border-0 px-4 pb-4">
|
<div class="modal-footer border-0 px-4 pb-4">
|
||||||
<button type="button" class="btn btn-light px-4" data-bs-dismiss="modal" style="border-radius: 10px;">Tutup</button>
|
<button type="button" class="btn btn-light px-4" data-bs-dismiss="modal" style="border-radius: 10px;">Tutup</button>
|
||||||
<a href="{{ route('jadwal.edit', $item->id) }}" class="btn btn-warning text-white px-4" style="border-radius: 10px;">Edit Jadwal</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7" class="text-center py-5 text-muted small">Belum ada jadwal latihan atau pengumuman.</td>
|
<td colspan="6" class="text-center py-5 text-muted small">Belum ada jadwal latihan atau pengumuman.</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
@ -187,22 +206,38 @@ class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.main-table thead th { background-color: #f8faff; padding: 18px 10px; font-size: 0.75rem; color: #8c98a5; letter-spacing: 1px; text-transform: uppercase; border-bottom: 2px solid #edf2f9; }
|
.main-table thead th { background-color: #f8faff; padding: 15px 10px; font-size: 0.7rem; color: #8c98a5; letter-spacing: 1px; text-transform: uppercase; border-bottom: 2px solid #edf2f9; }
|
||||||
.main-table tbody td { padding: 20px 10px; border-bottom: 1px solid #f1f4f8; color: #495057; font-size: 0.9rem; }
|
.main-table tbody td { padding: 15px 10px; border-bottom: 1px solid #f1f4f8; color: #495057; font-size: 0.85rem; }
|
||||||
|
|
||||||
/* Soft Badges */
|
|
||||||
.bg-success-soft { background-color: #e6fffa; color: #38b2ac; }
|
.bg-success-soft { background-color: #e6fffa; color: #38b2ac; }
|
||||||
.bg-info-soft { background-color: #e0f2fe; color: #0ea5e9; }
|
.bg-info-soft { background-color: #e0f2fe; color: #0ea5e9; }
|
||||||
.bg-danger-soft { background-color: #fff5f5; color: #e53e3e; }
|
.bg-danger-soft { background-color: #fff5f5; color: #e53e3e; }
|
||||||
.bg-secondary-soft { background-color: #f3f4f6; color: #6b7280; }
|
.bg-secondary-soft { background-color: #f3f4f6; color: #6b7280; }
|
||||||
|
|
||||||
/* Buttons Action */
|
|
||||||
.btn-action-detail { background-color: #f0f7ff; color: #0d6efd; border: 1px solid #d0e4ff; border-radius: 10px; transition: 0.3s; }
|
.btn-action-detail { background-color: #f0f7ff; color: #0d6efd; border: 1px solid #d0e4ff; border-radius: 10px; transition: 0.3s; }
|
||||||
.btn-action-edit { background-color: #fff8e6; color: #f59e0b; border: 1px solid #ffecb3; border-radius: 10px; transition: 0.3s; }
|
.btn-action-edit { background-color: #fff8e6; color: #f59e0b; border: 1px solid #ffecb3; border-radius: 10px; transition: 0.3s; }
|
||||||
|
|
||||||
.btn-action-edit:hover { background-color: #f59e0b !important; color: white !important; transform: translateY(-2px); }
|
.btn-action-edit:hover { background-color: #f59e0b !important; color: white !important; transform: translateY(-2px); }
|
||||||
.btn-action-detail:hover { background-color: #0d6efd !important; color: white !important; transform: translateY(-2px); }
|
.btn-action-detail:hover { background-color: #0d6efd !important; color: white !important; transform: translateY(-2px); }
|
||||||
|
|
||||||
.shadow-xs { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); }
|
.shadow-xs { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function konfirmasiLatihan(id, judul) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Konfirmasi Selesai',
|
||||||
|
text: "Apakah benar latihan '" + judul + "' telah dilaksanakan?",
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#198754', // Warna hijau sukses
|
||||||
|
cancelButtonColor: '#6c757d',
|
||||||
|
confirmButtonText: 'Ya, Sudah Selesai!',
|
||||||
|
cancelButtonText: 'Batal',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '20px'
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
// Submit form jika user klik OK
|
||||||
|
document.getElementById('form-selesai-' + id).submit();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -100,5 +100,7 @@
|
||||||
</script>
|
</script>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
@extends('layout.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-fluid py-4">
|
||||||
|
<div class="page-header mb-4 text-start">
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb bg-transparent p-0 mb-2">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('pelatih.index') }}"
|
||||||
|
class="text-muted text-decoration-none small">Daftar Pelatih</a></li>
|
||||||
|
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Edit Data Pelatih</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
<h3 class="fw-bold text-dark">Form Edit Data Pelatih</h3>
|
||||||
|
<p class="text-muted small">Perbarui informasi legalitas SK atau status kepelatihan untuk <strong>{{ $pelatih->nama_lengkap }}</strong>.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form action="{{ route('pelatih.update', $pelatih->id) }}" method="POST" 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">
|
||||||
|
<h5 class="fw-bold text-primary mb-0"><i class="icon-user me-2"></i>Identitas Pelatih</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-4">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-bold">No Induk</label>
|
||||||
|
<input type="text" class="form-control bg-light fw-bold"
|
||||||
|
value="{{ $pelatih->no_induk }}" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-bold">Nama Lengkap</label>
|
||||||
|
<input type="text" class="form-control bg-light"
|
||||||
|
value="{{ $pelatih->nama_lengkap }}" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-bold">Asal Kolat</label>
|
||||||
|
<input type="text" class="form-control bg-light"
|
||||||
|
value="{{ $pelatih->kolat->nama_kolat ?? '-' }}" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted mt-2 d-block">* Data identitas di atas bersifat tetap. Ubah di menu Anggota jika terdapat kesalahan input nama/induk.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
||||||
|
<div class="card-header bg-white border-0 pt-4 px-4">
|
||||||
|
<h5 class="fw-bold text-danger mb-0"><i class="icon-certificate me-2"></i>Legalitas & Masa Aktif SK</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-4">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-bold">Nomor SK Kepelatihan</label>
|
||||||
|
<input type="text" name="no_sk" class="form-control border-danger"
|
||||||
|
value="{{ old('no_sk', $pelatih->no_sk) }}" placeholder="Contoh: SK/001/2026" required>
|
||||||
|
@error('no_sk') <small class="text-danger">{{ $message }}</small> @enderror
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label fw-bold">Tanggal Terbit SK</label>
|
||||||
|
<input type="date" name="tgl_sk" class="form-control"
|
||||||
|
value="{{ old('tgl_sk', $pelatih->tgl_sk) }}" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label fw-bold">Masa Berlaku</label>
|
||||||
|
<input type="date" name="masa_berlaku" class="form-control"
|
||||||
|
value="{{ old('masa_berlaku', $pelatih->masa_berlaku) }}" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-12 mt-4">
|
||||||
|
<div class="p-3 bg-light rounded-4 border">
|
||||||
|
<label class="form-label fw-bold d-block">Update Scan SK (Format: JPG, PNG, PDF | Max: 2MB)</label>
|
||||||
|
<input type="file" name="foto_sk" class="form-control mb-2">
|
||||||
|
|
||||||
|
@if ($pelatih->foto_sk)
|
||||||
|
<div class="d-flex align-items-center mt-2">
|
||||||
|
<i class="icon-file-text text-primary me-2"></i>
|
||||||
|
<small class="text-muted">File saat ini:
|
||||||
|
<a href="{{ asset('storage/' . $pelatih->foto_sk) }}" target="_blank" class="text-decoration-none">
|
||||||
|
Lihat Dokumen SK <i class="icon-external-link"></i>
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<small class="text-warning">Belum ada file SK yang diunggah.</small>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer bg-light border-0 p-4" style="border-radius: 0 0 20px 20px;">
|
||||||
|
<div class="d-flex justify-content-end align-items-center gap-3">
|
||||||
|
<a href="{{ route('pelatih.index') }}"
|
||||||
|
class="btn btn-outline-secondary px-4 fw-bold btn-cancel">
|
||||||
|
<i class="icon-x me-1"></i> Batal
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-primary px-5 fw-bold btn-save shadow">
|
||||||
|
<i class="icon-check me-1"></i> Simpan Perubahan SK
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.form-control,
|
||||||
|
.form-select {
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus {
|
||||||
|
border-color: #0d6efd;
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-cancel {
|
||||||
|
border-radius: 12px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: 2px solid #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-cancel:hover {
|
||||||
|
background-color: #6c757d;
|
||||||
|
color: white;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-save {
|
||||||
|
border-radius: 12px;
|
||||||
|
background: linear-gradient(45deg, #0d6efd, #004fb1);
|
||||||
|
border: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-save:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 5px 15px rgba(13, 110, 253, 0.4) !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endsection
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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 text-center">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="60">No</th>
|
<th width="60">No</th>
|
||||||
|
|
@ -46,10 +46,10 @@
|
||||||
<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">{{ $item->nama_lengkap }}</div>
|
<div class="fw-bold text-dark text-start text-center">{{ $item->nama_lengkap }}</div>
|
||||||
<small class="text-muted text-start d-block">ID: {{ $item->no_induk }}</small>
|
<small class="text-muted text-start d-block text-center">ID: {{ $item->no_induk }}</small>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-start">
|
<td class="text-start text-center">
|
||||||
<div class="small fw-bold">{{ $item->no_sk }}</div>
|
<div class="small fw-bold">{{ $item->no_sk }}</div>
|
||||||
<div class="text-muted" style="font-size: 11px;">Hingga: {{ \Carbon\Carbon::parse($item->masa_berlaku)->format('d M Y') }}</div>
|
<div class="text-muted" style="font-size: 11px;">Hingga: {{ \Carbon\Carbon::parse($item->masa_berlaku)->format('d M Y') }}</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
@extends('layout.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-fluid py-4">
|
||||||
|
<div class="page-header mb-4 text-start">
|
||||||
|
<h3 class="fw-bold text-dark">Kehadiran Latihan</h3>
|
||||||
|
<p class="text-muted small">Silakan lakukan absensi mandiri untuk jadwal hari ini.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if(session('success'))
|
||||||
|
<div class="alert alert-success alert-dismissible fade show border-0 shadow-sm rounded-3 mb-4">
|
||||||
|
<i class="bi bi-check-circle-fill me-2"></i> {{ session('success') }}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if(session('error'))
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show border-0 shadow-sm rounded-3 mb-4">
|
||||||
|
<i class="bi bi-exclamation-circle-fill me-2"></i> {{ session('error') }}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
@forelse($jadwal_hari_ini as $jadwal)
|
||||||
|
<div class="col-md-6 col-lg-4 mb-4">
|
||||||
|
<div class="card border-0 shadow-sm" style="border-radius: 20px;">
|
||||||
|
<div class="card-body p-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-start mb-3">
|
||||||
|
<span class="badge bg-primary-soft text-primary px-3 py-2 rounded-pill shadow-xs">
|
||||||
|
{{ $jadwal->jenis }}
|
||||||
|
</span>
|
||||||
|
<span class="small fw-bold text-muted">{{ \Carbon\Carbon::parse($jadwal->tanggal)->format('d M Y') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5 class="fw-bold text-dark mb-1">{{ $jadwal->judul_kegiatan }}</h5>
|
||||||
|
<p class="small text-muted mb-3"><i class="bi bi-person-fill me-1"></i> Pelatih: {{ $jadwal->pelatih->nama_lengkap ?? '-' }}</p>
|
||||||
|
|
||||||
|
<div class="bg-light p-3 rounded-3 mb-4">
|
||||||
|
<div class="small fw-bold text-dark mb-1"><i class="bi bi-clock me-2 text-primary"></i>{{ substr($jadwal->jam_mulai, 0, 5) }} - Selesai</div>
|
||||||
|
<div class="small text-muted"><i class="bi bi-geo-alt-fill me-2 text-danger"></i>{{ $jadwal->lokasi }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- LOGIKA TOMBOL ABSEN --}}
|
||||||
|
@if(isset($presensi_saya[$jadwal->id]))
|
||||||
|
{{-- Jika sudah absen --}}
|
||||||
|
@if($presensi_saya[$jadwal->id]->is_verified)
|
||||||
|
<button class="btn btn-success w-100 fw-bold disabled py-2" style="border-radius: 12px;">
|
||||||
|
<i class="bi bi-check2-all me-1"></i> Kehadiran Disahkan
|
||||||
|
</button>
|
||||||
|
@else
|
||||||
|
<button class="btn btn-warning w-100 fw-bold disabled py-2" style="border-radius: 12px; color: #854d0e; background-color: #fef08a; border:none;">
|
||||||
|
<i class="bi bi-hourglass-split me-1"></i> Menunggu Konfirmasi
|
||||||
|
</button>
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
|
{{-- Jika belum absen, tampilkan tombol submit --}}
|
||||||
|
<form action="{{ route('anggota.presensi.store') }}" method="POST">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="jadwal_id" value="{{ $jadwal->id }}">
|
||||||
|
<button type="submit" class="btn btn-primary w-100 fw-bold py-2 shadow-sm" style="border-radius: 12px;" onclick="return confirm('Apakah kamu yakin ingin absen untuk jadwal ini?')">
|
||||||
|
<i class="bi bi-hand-index-thumb me-1"></i> Absen Sekarang
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@empty
|
||||||
|
<div class="col-12 text-center py-5">
|
||||||
|
<img src="https://cdn-icons-png.flaticon.com/512/7486/7486747.png" width="120" class="mb-3 opacity-50" alt="No Schedule">
|
||||||
|
<h5 class="text-muted fw-bold">Tidak ada jadwal latihan hari ini.</h5>
|
||||||
|
<p class="text-muted small">Selamat istirahat atau berlatih mandiri di rumah!</p>
|
||||||
|
</div>
|
||||||
|
@endforelse
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.bg-primary-soft { background-color: #e0f2fe; color: #0ea5e9; }
|
||||||
|
</style>
|
||||||
|
@endsection
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
@extends('layout.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-fluid py-4">
|
||||||
|
<div class="page-header mb-4 text-start">
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb bg-transparent p-0 mb-2">
|
||||||
|
<li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Home</a></li>
|
||||||
|
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Presensi Latihan</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
<h3 class="fw-bold text-dark">Rekap Presensi Latihan</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if(session('success'))
|
||||||
|
<div class="alert alert-success alert-dismissible fade show border-0 shadow-sm mb-4" role="alert" style="border-radius: 15px;">
|
||||||
|
<strong>Berhasil!</strong> {{ session('success') }}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm" style="border-radius: 20px;">
|
||||||
|
<div class="card-body p-4">
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<div class="text-start">
|
||||||
|
<h5 class="card-title mb-0 fw-bold text-dark">Pilih Jadwal Latihan</h5>
|
||||||
|
<p class="text-muted small mb-0">Klik tombol cek kehadiran untuk memverifikasi absen anggota dan upload bukti latihan.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover align-middle main-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="50" class="text-center">No</th>
|
||||||
|
<th>Kegiatan & Pelatih</th>
|
||||||
|
<th class="text-center">Status Jadwal</th>
|
||||||
|
<th>Waktu & Lokasi</th>
|
||||||
|
<th class="text-center">Tipe</th>
|
||||||
|
<th class="text-center" width="150">Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@forelse ($data_jadwal as $no => $item)
|
||||||
|
@php
|
||||||
|
// Set timezone ke Jakarta agar sinkron dengan waktu Indonesia
|
||||||
|
$now = \Carbon\Carbon::now('Asia/Jakarta');
|
||||||
|
$start = \Carbon\Carbon::parse($item->tanggal . ' ' . $item->jam_mulai, 'Asia/Jakarta');
|
||||||
|
$end = $item->jam_selesai
|
||||||
|
? \Carbon\Carbon::parse($item->tanggal . ' ' . $item->jam_selesai, 'Asia/Jakarta')
|
||||||
|
: $start->copy()->addHours(2);
|
||||||
|
|
||||||
|
$dbStatus = trim(strtolower($item->status));
|
||||||
|
|
||||||
|
// Logika Penentuan Label Status
|
||||||
|
if ($dbStatus == 'selesai') {
|
||||||
|
$status_label = 'Selesai';
|
||||||
|
$status_color = 'success';
|
||||||
|
} elseif ($now->greaterThanOrEqualTo($start) && $now->lessThanOrEqualTo($end)) {
|
||||||
|
$status_label = 'Berlangsung';
|
||||||
|
$status_color = 'primary';
|
||||||
|
} elseif ($now->lt($start)) {
|
||||||
|
$status_label = 'Mendatang';
|
||||||
|
$status_color = 'secondary';
|
||||||
|
} else {
|
||||||
|
$status_label = 'Menunggu Konfirmasi';
|
||||||
|
$status_color = 'warning';
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted small text-center">{{ $no + 1 }}</td>
|
||||||
|
<td>
|
||||||
|
<div class="fw-bold text-dark text-start ps-2">
|
||||||
|
{{ $item->judul_kegiatan }}
|
||||||
|
@if($dbStatus == 'selesai')
|
||||||
|
<i class="bi bi-check-circle-fill text-success ms-1"></i>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<small class="text-muted text-start ps-2 d-block">
|
||||||
|
{{-- Pemanggilan dari Query Builder Manual --}}
|
||||||
|
<i class="icon-user small"></i> {{ $item->nama_pelatih ?? 'Belum Ditentukan' }}
|
||||||
|
</small>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<span class="badge bg-{{ $status_color }} px-3 py-2" style="border-radius: 8px; font-size: 11px;">
|
||||||
|
{{ $status_label }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-start ps-4">
|
||||||
|
<div class="small fw-bold text-dark">
|
||||||
|
<i class="icon-calendar me-1"></i> {{ \Carbon\Carbon::parse($item->tanggal)->format('d M Y') }}
|
||||||
|
</div>
|
||||||
|
<div class="small text-muted">
|
||||||
|
<i class="icon-clock me-1"></i> {{ substr($item->jam_mulai, 0, 5) }} - {{ $item->jam_selesai ? substr($item->jam_selesai, 0, 5) : 'Selesai' }}
|
||||||
|
</div>
|
||||||
|
<div class="small text-muted text-truncate" style="max-width: 150px;">
|
||||||
|
<i class="icon-map-pin me-1 text-danger"></i> {{ $item->lokasi }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
@php
|
||||||
|
$bg_type = 'bg-secondary-soft text-secondary';
|
||||||
|
if($item->jenis == 'Rutin') $bg_type = 'bg-success-soft text-success border-success';
|
||||||
|
elseif($item->jenis == 'Tambahan') $bg_type = 'bg-info-soft text-info border-info';
|
||||||
|
elseif($item->jenis == 'Pengumuman') $bg_type = 'bg-danger-soft text-danger border-danger';
|
||||||
|
@endphp
|
||||||
|
<span class="badge rounded-pill {{ $bg_type }} px-3 border" style="font-size: 10px;">
|
||||||
|
{{ $item->jenis }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
{{-- Tombol Cek Kehadiran --}}
|
||||||
|
<a href="{{ route('presensi.kehadiran', $item->id) }}"
|
||||||
|
class="btn btn-sm btn-info fw-bold px-3 shadow-xs text-white"
|
||||||
|
style="border-radius: 10px;">
|
||||||
|
<i class="bi bi-person-check-fill me-1"></i> Cek Kehadiran
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-center py-5 text-muted small">Belum ada jadwal latihan tersedia.</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.main-table thead th { background-color: #f8faff; padding: 15px 10px; font-size: 0.7rem; color: #8c98a5; letter-spacing: 1px; text-transform: uppercase; border-bottom: 2px solid #edf2f9; }
|
||||||
|
.main-table tbody td { padding: 15px 10px; border-bottom: 1px solid #f1f4f8; color: #495057; font-size: 0.85rem; }
|
||||||
|
.bg-success-soft { background-color: #e6fffa; color: #38b2ac; }
|
||||||
|
.bg-info-soft { background-color: #e0f2fe; color: #0ea5e9; }
|
||||||
|
.bg-danger-soft { background-color: #fff5f5; color: #e53e3e; }
|
||||||
|
.bg-secondary-soft { background-color: #f3f4f6; color: #6b7280; }
|
||||||
|
.shadow-xs { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); }
|
||||||
|
.btn-info { background-color: #0ea5e9; border: none; transition: 0.3s; }
|
||||||
|
.btn-info:hover { background-color: #0284c7; transform: translateY(-2px); }
|
||||||
|
</style>
|
||||||
|
@endsection
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
@extends('layout.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-fluid py-4">
|
||||||
|
<div class="page-header mb-4 text-start">
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb bg-transparent p-0 mb-2">
|
||||||
|
<li class="breadcrumb-item"><a href="#" class="text-muted text-decoration-none small">Home</a></li>
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('presensi.index') }}" class="text-muted text-decoration-none small">Presensi Latihan</a></li>
|
||||||
|
<li class="breadcrumb-item active text-primary fw-bold small" aria-current="page">Verifikasi Kehadiran</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
<h3 class="fw-bold text-dark">Verifikasi Kehadiran Anggota</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Menampilkan Pesan Sukses --}}
|
||||||
|
@if(session('success'))
|
||||||
|
<div class="alert alert-success alert-dismissible fade show border-0 shadow-sm mb-4" role="alert" style="border-radius: 15px;">
|
||||||
|
<strong>Berhasil!</strong> {{ session('success') }}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- Menampilkan Pesan Error (Misal: Input manual ganda) --}}
|
||||||
|
@if(session('error'))
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show border-0 shadow-sm mb-4" role="alert" style="border-radius: 15px;">
|
||||||
|
<strong>Gagal!</strong> {{ session('error') }}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- KARTU INFORMASI JADWAL --}}
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm" style="border-radius: 20px; background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);">
|
||||||
|
<div class="card-body p-4 text-white">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h5 class="fw-bold mb-1">{{ $jadwal->judul_kegiatan }}</h5>
|
||||||
|
<p class="mb-0 small" style="opacity: 0.9;">
|
||||||
|
<i class="icon-map-pin me-1"></i> {{ $jadwal->lokasi }} |
|
||||||
|
<i class="icon-calendar me-1"></i> {{ \Carbon\Carbon::parse($jadwal->tanggal)->format('d M Y') }} |
|
||||||
|
<i class="icon-clock me-1"></i> {{ substr($jadwal->jam_mulai, 0, 5) }} - {{ $jadwal->jam_selesai ? substr($jadwal->jam_selesai, 0, 5) : 'Selesai' }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-md-end mt-3 mt-md-0">
|
||||||
|
<span class="badge bg-white text-primary px-3 py-2 rounded-pill shadow-sm">
|
||||||
|
Kolat: {{ $jadwal->kolat->nama_kolat ?? '-' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- TABEL PRESENSI --}}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm" style="border-radius: 20px;">
|
||||||
|
<div class="card-body p-4">
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<div class="text-start">
|
||||||
|
<h5 class="card-title mb-0 fw-bold text-dark">Daftar Absensi Masuk</h5>
|
||||||
|
<p class="text-muted small mb-0">Klik konfirmasi untuk mensahkan kehadiran anggota.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Tombol Buka Modal Tambah Manual --}}
|
||||||
|
<button class="btn btn-primary px-4 py-2 shadow-sm" style="border-radius: 12px;" data-bs-toggle="modal" data-bs-target="#modalTambahManual">
|
||||||
|
<i class="bi bi-plus-lg me-1"></i> Tambah Manual
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover align-middle main-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="60" class="text-center">No</th>
|
||||||
|
<th>Identitas Anggota</th>
|
||||||
|
<th class="text-center">Waktu Absen</th>
|
||||||
|
<th class="text-center">Status Verifikasi</th>
|
||||||
|
<th class="text-center" width="180">Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@forelse ($data_presensi as $no => $item)
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted small text-center">{{ $no + 1 }}</td>
|
||||||
|
<td>
|
||||||
|
<div class="fw-bold text-dark text-start ps-2">{{ $item->anggota->nama_lengkap }}</div>
|
||||||
|
<small class="text-muted text-start ps-2 d-block">ID: {{ $item->anggota->no_induk }}</small>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<span class="badge bg-light text-dark border px-3" style="border-radius: 8px;">
|
||||||
|
<i class="icon-clock me-1 text-primary"></i> {{ \Carbon\Carbon::parse($item->waktu_presensi)->format('H:i') }} WIB
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
@if($item->is_verified)
|
||||||
|
<span class="badge bg-success-soft text-success border-success px-3 border rounded-pill">
|
||||||
|
<i class="bi bi-check-circle-fill me-1"></i> Sah
|
||||||
|
</span>
|
||||||
|
<div class="small text-muted mt-1" style="font-size: 10px;">
|
||||||
|
Oleh: {{ $item->pelatihVerifikator->nama_lengkap ?? 'Pelatih' }}
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<span class="badge bg-warning text-dark px-3 rounded-pill shadow-xs">
|
||||||
|
<i class="bi bi-hourglass-split me-1"></i> Menunggu
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
@if(!$item->is_verified)
|
||||||
|
{{-- Tombol Konfirmasi Hadir --}}
|
||||||
|
<form action="{{ route('presensi.konfirmasi', $item->id) }}" method="POST" class="d-inline">
|
||||||
|
@csrf
|
||||||
|
<button type="submit" class="btn btn-sm btn-action-edit fw-bold px-3 shadow-xs" onclick="return confirm('Konfirmasi kehadiran anggota ini?')">
|
||||||
|
<i class="bi bi-check2-square me-1"></i> Konfirmasi
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
@else
|
||||||
|
<button class="btn btn-sm btn-light fw-bold px-3 text-muted border disabled" style="border-radius: 10px;">
|
||||||
|
Selesai
|
||||||
|
</button>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" class="text-center py-5 text-muted small">Belum ada anggota yang melakukan absensi masuk.</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- MODAL TAMBAH MANUAL (KASUS LUPA HP) --}}
|
||||||
|
<div class="modal fade" id="modalTambahManual" tabindex="-1" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content" style="border-radius: 20px; border: none; overflow: hidden;">
|
||||||
|
<div class="modal-header bg-primary text-white border-0 py-3 px-4">
|
||||||
|
<h5 class="modal-title fw-bold">
|
||||||
|
<i class="bi bi-person-plus-fill me-2"></i>Input Presensi Manual
|
||||||
|
</h5>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<form action="{{ route('presensi.storeManual') }}" method="POST">
|
||||||
|
@csrf
|
||||||
|
{{-- Hidden input untuk ID Jadwal --}}
|
||||||
|
<input type="hidden" name="jadwal_id" value="{{ $jadwal->id }}">
|
||||||
|
|
||||||
|
<div class="modal-body p-4">
|
||||||
|
<div class="alert alert-info border-0 shadow-sm small" style="border-radius: 10px;">
|
||||||
|
<i class="bi bi-info-circle-fill me-2"></i> Gunakan form ini untuk anggota yang lupa membawa perangkat atau tidak bisa absen mandiri.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 text-start">
|
||||||
|
<label class="form-label fw-bold text-dark small">Pilih Nama Anggota</label>
|
||||||
|
<select name="anggota_id" class="form-select shadow-none" style="border-radius: 10px; border-color: #d0e4ff;" required>
|
||||||
|
<option value="">-- Silakan Pilih Anggota --</option>
|
||||||
|
@foreach($daftar_anggota as $anggota)
|
||||||
|
<option value="{{ $anggota->id }}">{{ $anggota->no_induk }} - {{ $anggota->nama_lengkap }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer border-0 px-4 pb-4 d-flex justify-content-between">
|
||||||
|
<button type="button" class="btn btn-light px-4 shadow-sm" data-bs-dismiss="modal" style="border-radius: 10px;">Batal</button>
|
||||||
|
<button type="submit" class="btn btn-success px-4 shadow-sm" style="border-radius: 10px;">
|
||||||
|
<i class="bi bi-check-lg me-1"></i> Simpan & Sahkan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.main-table thead th { background-color: #f8faff; padding: 18px 10px; font-size: 0.75rem; color: #8c98a5; letter-spacing: 1px; text-transform: uppercase; border-bottom: 2px solid #edf2f9; }
|
||||||
|
.main-table tbody td { padding: 20px 10px; border-bottom: 1px solid #f1f4f8; color: #495057; font-size: 0.9rem; }
|
||||||
|
.bg-success-soft { background-color: #e6fffa; color: #38b2ac; }
|
||||||
|
.btn-action-edit { background-color: #f0f7ff; color: #0d6efd; border: 1px solid #d0e4ff; border-radius: 10px; transition: 0.3s; }
|
||||||
|
.btn-action-edit:hover { background-color: #0d6efd !important; color: white !important; transform: translateY(-2px); }
|
||||||
|
.shadow-xs { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); }
|
||||||
|
</style>
|
||||||
|
@endsection
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
use App\Http\Controllers\JadwalController;
|
use App\Http\Controllers\JadwalController;
|
||||||
use App\Http\Controllers\KolatController;
|
use App\Http\Controllers\KolatController;
|
||||||
use App\Http\Controllers\PelatihController;
|
use App\Http\Controllers\PelatihController;
|
||||||
|
use App\Http\Controllers\PresensiController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -64,6 +65,7 @@
|
||||||
//prefix diguakan untuk mengelompokkan route yang berhubungan dengan jadwal
|
//prefix diguakan untuk mengelompokkan route yang berhubungan dengan jadwal
|
||||||
Route::prefix('jadwal')->group(function () {
|
Route::prefix('jadwal')->group(function () {
|
||||||
Route::get('/', [JadwalController::class, 'index'])->name('jadwal.index');
|
Route::get('/', [JadwalController::class, 'index'])->name('jadwal.index');
|
||||||
|
Route::post('/jadwal/{id}/konfirmasi', [JadwalController::class, 'konfirmasiSelesai'])->name('jadwal.konfirmasi');
|
||||||
Route::get('/create', [JadwalController::class, 'create'])->name('jadwal.create');
|
Route::get('/create', [JadwalController::class, 'create'])->name('jadwal.create');
|
||||||
Route::get('/{id}/detail', [JadwalController::class, 'show'])->name('jadwal.show');
|
Route::get('/{id}/detail', [JadwalController::class, 'show'])->name('jadwal.show');
|
||||||
Route::post('/store', [JadwalController::class, 'store'])->name('jadwal.store');
|
Route::post('/store', [JadwalController::class, 'store'])->name('jadwal.store');
|
||||||
|
|
@ -72,3 +74,14 @@
|
||||||
Route::delete('/{id}/delete', [JadwalController::class, 'destroy'])->name('jadwal.destroy');
|
Route::delete('/{id}/delete', [JadwalController::class, 'destroy'])->name('jadwal.destroy');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- ROUTE PRESENSI (ABSENSI) ---
|
||||||
|
Route::prefix('presensi')->name('presensi.')->group(function () {
|
||||||
|
Route::get('/', [PresensiController::class, 'index'])->name('index');
|
||||||
|
// Halaman daftar kehadiran (View Admin/Pelatih)
|
||||||
|
Route::get('/kehadiran/{jadwal_id}', [PresensiController::class, 'kehadiran'])->name('kehadiran');
|
||||||
|
// konfirmasi pelatih
|
||||||
|
Route::post('/konfirmasi/{presensi_id}', [PresensiController::class, 'konfirmasi'])->name('konfirmasi');
|
||||||
|
// Proses tambah presensi manual (Kasus Lupa HP)
|
||||||
|
Route::post('/tambah-manual', [PresensiController::class, 'storeManual'])->name('storeManual');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue