243 lines
14 KiB
PHP
243 lines
14 KiB
PHP
@extends('admin.layouts.app')
|
|
@section('title', 'Tambah Kriteria')
|
|
|
|
@section('content')
|
|
<div class="container-fluid">
|
|
<!-- Breadcrumb -->
|
|
<nav aria-label="breadcrumb" class="mb-4">
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{{ route('admin.dashboard') }}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{{ route('admin.kriteria.index') }}">Kriteria & Bobot</a></li>
|
|
<li class="breadcrumb-item active">Tambah</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h2 class="mb-1"><i class="bi bi-sliders me-2"></i>Tambah Kriteria</h2>
|
|
<p class="text-muted mb-0">Buat kriteria seleksi SAW baru</p>
|
|
</div>
|
|
<div>
|
|
<a href="{{ route('admin.kriteria.index') }}" class="btn btn-outline-secondary">
|
|
<i class="bi bi-arrow-left me-1"></i>Kembali
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="mb-0">Formulir Kriteria Baru</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
@if(session('error'))
|
|
<div class="alert alert-danger alert-dismissible fade show mb-4" role="alert">
|
|
<i class="bi bi-exclamation-triangle-fill me-2"></i>{{ session('error') }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
@endif
|
|
|
|
<form action="{{ route('admin.kriteria.store') }}" method="POST">
|
|
@csrf
|
|
|
|
<!-- Section 1: Existing Criteria Weight Adjustments -->
|
|
<div class="mb-4">
|
|
<label class="form-label fw-bold text-success"><i class="bi bi-list-check me-1"></i>Sesuaikan Bobot Kriteria yang Sudah Ada</label>
|
|
<div class="table-responsive bg-light p-3 rounded border border-success-subtle">
|
|
@if($kriteria->isEmpty())
|
|
<p class="text-muted mb-0 text-center py-2">Belum ada kriteria terdaftar.</p>
|
|
@else
|
|
<table class="table table-sm table-borderless align-middle mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th width="100">Kode</th>
|
|
<th>Nama Kriteria</th>
|
|
<th width="150" class="text-end">Bobot Desimal</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($kriteria as $k)
|
|
<tr>
|
|
<td><span class="badge bg-secondary">{{ $k->kode }}</span></td>
|
|
<td>{{ $k->nama }} <small class="text-muted">({{ ucfirst($k->jenis) }})</small></td>
|
|
<td>
|
|
<input type="number" step="0.01" min="0" max="1"
|
|
name="existing_bobot[{{ $k->id }}]"
|
|
class="form-control form-control-sm text-end existing-bobot-input"
|
|
value="{{ old('existing_bobot.'.$k->id, $k->bobot) }}"
|
|
required>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
@endif
|
|
</div>
|
|
<small class="text-muted d-block mt-1">Sesuaikan nilai desimal kriteria di atas agar total penjumlahan dengan kriteria baru bernilai tepat 1.00 (100%).</small>
|
|
</div>
|
|
|
|
<!-- Section 2: Accumulator Indicator -->
|
|
<div class="d-flex justify-content-between align-items-center bg-light p-3 rounded border mb-4">
|
|
<span class="fw-bold"><i class="bi bi-calculator me-1"></i>Total Akumulasi Bobot:</span>
|
|
<span id="total-bobot-indicator" class="badge bg-secondary fs-6">0.00</span>
|
|
</div>
|
|
|
|
<!-- Section 3: New Criteria Details -->
|
|
<div class="card border-success-subtle mb-4" style="background: rgba(45, 122, 79, 0.03);">
|
|
<div class="card-body">
|
|
<h6 class="card-title fw-bold text-success mb-3"><i class="bi bi-plus-circle-fill me-1"></i>Kriteria Baru ({{ $nextCode }})</h6>
|
|
<input type="hidden" name="kode" value="{{ $nextCode }}">
|
|
|
|
<div class="mb-3">
|
|
<label for="nama" class="form-label fw-bold">Nama Kriteria</label>
|
|
<input type="text" name="nama" id="nama" class="form-control @error('nama') is-invalid @enderror" value="{{ old('nama') }}" placeholder="Contoh: Kondisi Atap Rumah" required>
|
|
@error('nama')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="jenis" class="form-label fw-bold">Jenis Atribut</label>
|
|
<select name="jenis" id="jenis" class="form-select @error('jenis') is-invalid @enderror" required>
|
|
<option value="" disabled selected>-- Pilih Jenis --</option>
|
|
<option value="benefit" {{ old('jenis') === 'benefit' ? 'selected' : '' }}>Benefit</option>
|
|
<option value="cost" {{ old('jenis') === 'cost' ? 'selected' : '' }}>Cost</option>
|
|
</select>
|
|
@error('jenis')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="col-md-6 mb-3">
|
|
<label for="bobot" class="form-label fw-bold">Bobot Kriteria Baru</label>
|
|
<input type="number" step="0.01" min="0" max="1" name="bobot" id="bobot" class="form-control @error('bobot') is-invalid @enderror" value="{{ old('bobot') }}" placeholder="Contoh: 0.15" required>
|
|
@error('bobot')
|
|
<div class="invalid-feedback">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 4: Sub-Kriteria (Nilai 1-5) -->
|
|
<div class="card border-primary-subtle mb-4" style="background: rgba(13, 110, 253, 0.02);">
|
|
<div class="card-body">
|
|
<h6 class="card-title fw-bold text-primary mb-3"><i class="bi bi-list-stars me-1"></i>Definisikan Sub-Kriteria (Skala Nilai 1 s.d. 5)</h6>
|
|
|
|
<!-- Panduan Pengisian Berdasarkan Jenis Kriteria -->
|
|
<div class="alert alert-info mb-3 py-3" id="panduan-subkriteria">
|
|
<span id="panduan-text">Pilih <strong>Jenis Atribut</strong> di atas terlebih dahulu untuk melihat panduan skala prioritas.</span>
|
|
</div>
|
|
|
|
<p class="text-muted small">Tuliskan keterangan detail untuk masing-masing opsi pilihan nilai 1 sampai 5 agar mempermudah pengisian nilai kelak.</p>
|
|
|
|
<div class="row g-3">
|
|
<div class="col-md-12">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-danger text-white fw-bold" style="width: 45px;">1</span>
|
|
<input type="text" name="sub_keterangan[1]" class="form-control" placeholder="Keterangan untuk nilai 1 (Sangat Kurang/Rendah/Tidak Layak)" value="{{ old('sub_keterangan.1') }}" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-warning text-dark fw-bold" style="width: 45px;">2</span>
|
|
<input type="text" name="sub_keterangan[2]" class="form-control" placeholder="Keterangan untuk nilai 2 (Kurang/Rendah/Kurang Layak)" value="{{ old('sub_keterangan.2') }}" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-info text-white fw-bold" style="width: 45px;">3</span>
|
|
<input type="text" name="sub_keterangan[3]" class="form-control" placeholder="Keterangan untuk nilai 3 (Cukup/Sedang/Cukup Layak)" value="{{ old('sub_keterangan.3') }}" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-primary text-white fw-bold" style="width: 45px;">4</span>
|
|
<input type="text" name="sub_keterangan[4]" class="form-control" placeholder="Keterangan untuk nilai 4 (Baik/Tinggi/Layak)" value="{{ old('sub_keterangan.4') }}" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-success text-white fw-bold" style="width: 45px;">5</span>
|
|
<input type="text" name="sub_keterangan[5]" class="form-control" placeholder="Keterangan untuk nilai 5 (Sangat Baik/Tinggi/Sangat Layak)" value="{{ old('sub_keterangan.5') }}" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<div class="d-flex gap-2">
|
|
<button type="submit" class="btn btn-success px-4">
|
|
<i class="bi bi-save me-1"></i>Simpan Kriteria
|
|
</button>
|
|
<a href="{{ route('admin.kriteria.index') }}" class="btn btn-light px-4">Batal</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
@push('scripts')
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const existingInputs = document.querySelectorAll('.existing-bobot-input');
|
|
const newBobotInput = document.getElementById('bobot');
|
|
const indicator = document.getElementById('total-bobot-indicator');
|
|
|
|
function calculateTotal() {
|
|
let total = 0;
|
|
existingInputs.forEach(input => {
|
|
total += parseFloat(input.value) || 0;
|
|
});
|
|
total += parseFloat(newBobotInput.value) || 0;
|
|
|
|
indicator.textContent = total.toFixed(2);
|
|
|
|
if (Math.abs(total - 1.00) < 0.001) {
|
|
indicator.className = 'badge bg-success fs-6';
|
|
} else {
|
|
indicator.className = 'badge bg-danger fs-6';
|
|
}
|
|
}
|
|
|
|
existingInputs.forEach(input => input.addEventListener('input', calculateTotal));
|
|
newBobotInput.addEventListener('input', calculateTotal);
|
|
|
|
// Panduan Benefit/Cost untuk Sub-Kriteria
|
|
const jenisSelect = document.getElementById('jenis');
|
|
const panduanEl = document.getElementById('panduan-subkriteria');
|
|
const panduanText = document.getElementById('panduan-text');
|
|
|
|
function updatePanduan() {
|
|
const val = jenisSelect.value;
|
|
if (val === 'benefit') {
|
|
panduanEl.className = 'alert alert-primary mb-3 py-3';
|
|
panduanText.innerHTML = '<i class="bi bi-info-circle-fill me-2"></i>Kriteria <strong>Benefit (Semakin Besar Nilai = Semakin Prioritas/Baik)</strong>:<br>' +
|
|
'• <strong>Nilai 5</strong> = Kondisi terbaik / prioritas tertinggi (contoh: Tanggungan > 4 orang).<br>' +
|
|
'• <strong>Nilai 1</strong> = Kondisi terkecil / prioritas terendah (contoh: Tanggungan 1 orang).';
|
|
} else if (val === 'cost') {
|
|
panduanEl.className = 'alert alert-warning mb-3 py-3 text-dark';
|
|
panduanText.innerHTML = '<i class="bi bi-info-circle-fill me-2"></i>Kriteria <strong>Cost (Semakin Kecil Nilai = Semakin Prioritas/Baik)</strong>:<br>' +
|
|
'• <strong>Nilai 5</strong> = Kondisi terkecil / prioritas tertinggi (contoh: Belum pernah menerima bantuan / Pendapatan terendah).<br>' +
|
|
'• <strong>Nilai 1</strong> = Kondisi terbesar / prioritas terendah (contoh: Aktif menerima banyak jenis bantuan / Pendapatan tertinggi).';
|
|
} else {
|
|
panduanEl.className = 'alert alert-info mb-3 py-3';
|
|
panduanText.innerHTML = 'Pilih <strong>Jenis Atribut</strong> di atas terlebih dahulu untuk melihat panduan skala prioritas.';
|
|
}
|
|
}
|
|
|
|
if (jenisSelect) {
|
|
jenisSelect.addEventListener('change', updatePanduan);
|
|
updatePanduan();
|
|
}
|
|
|
|
calculateTotal();
|
|
});
|
|
</script>
|
|
@endpush
|
|
@endsection
|