Update Role fasilitator, kordinator

This commit is contained in:
2026-11-04 14:24:51 +07:00
parent b5b046ed86
commit 41da3a71ee
48 changed files with 586 additions and 164 deletions
+20 -1
View File
@@ -47,7 +47,7 @@
<option value="">Pilih Role</option>
@foreach($roles as $roleEnum)
<option value="{{ $roleEnum->value }}" {{ old('role', \App\Enums\Role::PETANI->value) === $roleEnum->value ? 'selected' : '' }}>
{{ ucfirst(str_replace('_', ' ', $roleEnum->value)) }}
{{ $roleEnum->label() }}
</option>
@endforeach
</select>
@@ -55,6 +55,19 @@
</div>
</div>
{{-- Hanya untuk role Koordinator --}}
<div class="row {{ old('role') === \App\Enums\Role::KOORDINATOR->value ? '' : 'd-none' }}" id="koordinator-komoditas-wrapper">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-koordinator-komoditas">Komoditas yang Dikoordinasikan<span class="text-danger">*</span></label>
<select id="add-koordinator-komoditas" name="komoditas_ids[]" class="select2 form-select @error('komoditas_ids') is-invalid @enderror" multiple data-placeholder="Pilih Komoditas" style="width: 100%">
@foreach($komoditasOptions as $komoditas)
<option value="{{ $komoditas->id }}" @selected(in_array($komoditas->id, old('komoditas_ids', [])))>{{ $komoditas->nama }}</option>
@endforeach
</select>
@error('komoditas_ids')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-telepon">No. Telepon<span class="text-danger">*</span></label>
@@ -183,6 +196,12 @@
$(document).ready(function () {
$('.select2').select2();
// Pilihan komoditas hanya tampil untuk role Koordinator
$('#add-profile-role').on('change', function () {
const isKoordinator = $(this).val() === @json(\App\Enums\Role::KOORDINATOR->value);
$('#koordinator-komoditas-wrapper').toggleClass('d-none', !isKoordinator);
});
$(document).on('click', '.password-toggle', function () {
const input = this.closest('.input-group').querySelector('input');
const icon = this.querySelector('i');
@@ -111,7 +111,7 @@
<option value="">-- All Roles --</option>
@foreach($roles as $roleEnum)
<option value="{{ $roleEnum->value }}" {{ request('role') == $roleEnum->value ? 'selected' : '' }}>
{{ ucfirst(str_replace('_', ' ', $roleEnum->value)) }}
{{ $roleEnum->label() }}
</option>
@endforeach
</select>
@@ -164,14 +164,24 @@
$roleColors = [
'super_admin' => 'bg-label-danger',
'admin' => 'bg-label-warning',
'fasilitator' => 'bg-label-info',
'koordinator' => 'bg-label-primary',
'enumerator' => 'bg-label-info',
'fasilitator' => 'bg-label-dark',
'petani' => 'bg-label-success',
];
$color = $roleColors[$roleKey] ?? 'bg-label-secondary';
$roleLabel = ($user->role instanceof \App\Enums\Role)
? $user->role->label()
: ucfirst(str_replace('_', ' ', (string) $roleKey));
@endphp
<span class="badge {{ $color }}">
{{ ucfirst(str_replace('_', ' ', $roleKey)) }}
{{ $roleLabel }}
</span>
@if($roleKey === 'koordinator')
<small class="d-block text-muted mt-1">
{{ $user->koordinatorKomoditas->pluck('komoditas.nama')->filter()->join(', ') ?: 'Belum ada komoditas' }}
</small>
@endif
</td>
<td>
@if($user->email_verified_at)
@@ -191,6 +201,16 @@
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $user->id }}" data-name="{{ $user->name }}" title="Delete">
<i class="ti tabler-trash ti-md"></i>
</a>
@if($roleKey === 'koordinator')
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill btn-komoditas-koordinator"
title="Atur Komoditas"
data-url="{{ route('users.komoditas.update', $user->id) }}"
data-name="{{ $user->name }}"
data-selected='@json($user->koordinatorKomoditas->pluck('komoditas_id')->values())'>
<i class="ti tabler-plant ti-md"></i>
</a>
@endif
@if(!$user->email_verified_at)
<button type="button"
@@ -241,7 +261,9 @@
<option value="" selected disabled>-- Pilih Role Akses --</option>
<option value="super_admin">🟣 Super Admin</option>
<option value="admin">🟣 Admin</option>
<option value="fasilitator">🟣 Fasilitator</option>
<option value="koordinator">🟣 Koordinator</option>
<option value="enumerator">🟣 Enumerator</option>
<option value="fasilitator">🟣 Fasilitator (Pemateri Workshop)</option>
<option value="offtaker">🟣 Offtaker</option>
</select>
</div>
@@ -395,4 +417,67 @@
});
});
</script>
<script>
// Atur komoditas yang ditangani koordinator
$(function () {
const komoditasOptions = @json($komoditasOptions);
$(document).on('click', '.btn-komoditas-koordinator', function () {
const url = $(this).data('url');
const nama = $(this).data('name');
const selected = ($(this).data('selected') || []).map(Number);
const checkboxes = komoditasOptions.map(function (k) {
const checked = selected.includes(k.id) ? 'checked' : '';
return `<div class="form-check text-start mb-2">
<input class="form-check-input komoditas-koordinator-check" type="checkbox" value="${k.id}" id="kk-${k.id}" ${checked}>
<label class="form-check-label" for="kk-${k.id}">${$('<div>').text(k.nama).html()}</label>
</div>`;
}).join('');
Swal.fire({
title: 'Komoditas Koordinator',
html: `<p class="text-muted mb-4">Pilih komoditas yang dikoordinasikan oleh <strong>${$('<div>').text(nama).html()}</strong>.</p>
<div class="px-4">${checkboxes || '<p class="text-muted">Belum ada komoditas utama.</p>'}</div>`,
showCancelButton: true,
confirmButtonText: '<i class="ti tabler-check me-1"></i> Simpan',
cancelButtonText: 'Batal',
customClass: {
popup: 'rounded-4',
confirmButton: 'btn btn-primary me-3',
cancelButton: 'btn btn-label-secondary'
},
buttonsStyling: false,
preConfirm: function () {
const ids = Array.from(Swal.getPopup().querySelectorAll('.komoditas-koordinator-check:checked')).map(el => el.value);
if (ids.length === 0) {
Swal.showValidationMessage('Pilih minimal satu komoditas.');
return false;
}
return ids;
}
}).then(function (result) {
if (!result.isConfirmed) {
return;
}
$.ajax({
url: url,
type: 'PUT',
headers: { 'X-CSRF-TOKEN': csrfToken, 'Accept': 'application/json' },
data: { komoditas_ids: result.value },
success: function (res) {
Swal.fire({ icon: 'success', title: 'Berhasil!', text: res.message, showConfirmButton: false, timer: 1500 })
.then(() => location.reload());
},
error: function (xhr) {
const res = xhr.responseJSON || {};
const errors = res.errors ? Object.values(res.errors).flat().join('<br>') : null;
Swal.fire({ icon: 'error', title: 'Gagal!', html: errors || res.message || 'Gagal menyimpan komoditas.' });
}
});
});
});
});
</script>
@endpush