MIF_E31232406/resources/views/rt/calon-penerima/edit.blade.php

604 lines
38 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<x-app-layout>
<x-slot name="header">
<div class="flex items-center justify-between flex-wrap gap-3">
<div>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">Edit Pendataan Warga</h2>
<p class="text-sm text-gray-500 mt-0.5">Perbarui data dengan benar sebelum menyimpan.</p>
</div>
<a href="{{ route('rt.calon-penerima.index') }}"
class="inline-flex items-center gap-1.5 px-4 py-2 bg-white border border-gray-200 text-gray-600 text-sm font-medium rounded-xl hover:bg-gray-50 transition">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
</svg>
Kembali
</a>
</div>
</x-slot>
<style>
.input-field { font-size: 16px !important; }
@media (min-width: 640px) { .input-field { font-size: 14px !important; } }
.section-grid {
display: grid;
grid-template-columns: 1fr;
gap: 14px;
padding: 16px;
}
@media (min-width: 640px) {
.section-grid { grid-template-columns: 1fr 1fr; padding: 18px; gap: 16px; }
}
@media (min-width: 1024px) {
.section-grid { grid-template-columns: repeat(4, 1fr); padding: 20px; }
}
.col-span-2-up { grid-column: span 1; }
@media (min-width: 640px) { .col-span-2-up { grid-column: span 2; } }
.section-head { padding: 10px 16px; }
@media (min-width: 640px) { .section-head { padding: 10px 20px; } }
.action-row {
display: flex;
justify-content: flex-end;
gap: 10px;
flex-wrap: wrap;
}
@media (max-width: 480px) {
.action-row { flex-direction: column-reverse; }
.action-row a,
.action-row button { width: 100%; justify-content: center; text-align: center; }
}
@keyframes spin { to { transform: rotate(360deg); } }
.aset-checkbox-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; }
.aset-checkbox-item { display: flex; align-items: center; gap: 8px; padding: 8px 12px;
border: 1px solid #e5e7eb; border-radius: 10px; cursor: pointer; transition: background .15s, border-color .15s; }
.aset-checkbox-item:has(input:checked) { background: #eff6ff; border-color: #93c5fd; }
.aset-checkbox-item input[type=checkbox] { accent-color: #2563eb; width: 15px; height: 15px; flex-shrink: 0; }
.aset-checkbox-item span { font-size: 13px; color: #374151; }
</style>
@if ($errors->any())
<div class="mb-4 flex items-start gap-3 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">
<svg class="w-4 h-4 shrink-0 mt-0.5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01M12 3a9 9 0 100 18A9 9 0 0012 3z"/>
</svg>
<div>
<div class="font-semibold mb-1">Gagal menyimpan, mohon perbaiki:</div>
<ul class="list-disc pl-4 space-y-0.5">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
@endif
<form action="{{ route('rt.calon-penerima.update', $calonPenerima->id) }}" method="POST" id="formEditPendataan" novalidate enctype="multipart/form-data">
@csrf
@method('PUT')
<input type="hidden" name="rt_id" value="{{ $calonPenerima->rt_id }}">
{{-- SECTION 1: Data Identitas --}}
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 mb-4 overflow-hidden">
<div class="section-head border-b border-gray-100 flex items-center gap-2 bg-gray-50">
<div class="w-1 h-4 bg-blue-600 rounded-full"></div>
<h3 class="text-sm font-semibold text-gray-700">Data Identitas</h3>
</div>
<div class="section-grid">
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">RT</label>
<input type="text"
value="RT {{ str_pad($calonPenerima->rt->nomor_rt ?? 0, 3, '0', STR_PAD_LEFT) }}"
class="w-full border border-gray-200 rounded-xl px-3 py-2 bg-gray-100 text-gray-700 cursor-not-allowed"
style="font-size:16px;" readonly>
<p class="text-[11px] text-gray-400 mt-1">RT mengikuti akun RT yang sedang login.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">No. KK <span class="text-red-500">*</span></label>
<input type="text" name="no_kk" id="no_kk" maxlength="16"
value="{{ old('no_kk', $calonPenerima->no_kk) }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="16 digit No. KK" required inputmode="numeric">
<p class="error-msg text-xs text-red-500 mt-1 hidden">No. KK harus 16 digit angka.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">NIK <span class="text-red-500">*</span></label>
<input type="text" name="nik" id="nik" maxlength="16"
value="{{ old('nik', $calonPenerima->nik) }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="16 digit NIK" required inputmode="numeric">
<p class="error-msg text-xs text-red-500 mt-1 hidden">NIK harus tepat 16 digit angka.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Nama Lengkap <span class="text-red-500">*</span></label>
<input type="text" name="nama_lengkap" id="nama_lengkap"
value="{{ old('nama_lengkap', $calonPenerima->nama_lengkap) }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="Nama sesuai KTP" required>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Nama minimal 3 karakter.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Jenis Kelamin <span class="text-red-500">*</span></label>
<select name="jenis_kelamin"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="Laki-laki" {{ old('jenis_kelamin', $calonPenerima->jenis_kelamin) === 'Laki-laki' ? 'selected' : '' }}>Laki-laki</option>
<option value="Perempuan" {{ old('jenis_kelamin', $calonPenerima->jenis_kelamin) === 'Perempuan' ? 'selected' : '' }}>Perempuan</option>
</select>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Tempat Lahir <span class="text-red-500">*</span></label>
<input type="text" name="tempat_lahir" id="tempat_lahir"
value="{{ old('tempat_lahir', $calonPenerima->tempat_lahir) }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="Kota/Kabupaten" required>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Tempat lahir wajib diisi.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Tanggal Lahir <span class="text-red-500">*</span></label>
<input type="date" name="tanggal_lahir" id="tanggal_lahir"
value="{{ old('tanggal_lahir', $calonPenerima->tanggal_lahir ? \Carbon\Carbon::parse($calonPenerima->tanggal_lahir)->format('Y-m-d') : '') }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
required>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Tanggal lahir wajib diisi.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Usia <span class="text-red-500">*</span></label>
<input type="number" name="usia" id="usia" min="17" max="100"
value="{{ old('usia', $calonPenerima->usia) }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="Tahun" required inputmode="numeric">
<p class="error-msg text-xs text-red-500 mt-1 hidden">Usia harus antara 17100 tahun.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Status Perkawinan <span class="text-red-500">*</span></label>
<select name="status_perkawinan" id="status_perkawinan"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="">-- Pilih --</option>
@foreach(['Belum Kawin','Kawin','Cerai Hidup','Cerai Mati'] as $sp)
<option value="{{ $sp }}" {{ old('status_perkawinan', $calonPenerima->status_perkawinan) === $sp ? 'selected' : '' }}>{{ $sp }}</option>
@endforeach
</select>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Status perkawinan wajib dipilih.</p>
</div>
</div>
</div>
{{-- SECTION 2: Data Tempat Tinggal --}}
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 mb-4 overflow-hidden">
<div class="section-head border-b border-gray-100 flex items-center gap-2 bg-gray-50">
<div class="w-1 h-4 bg-emerald-500 rounded-full"></div>
<h3 class="text-sm font-semibold text-gray-700">Data Tempat Tinggal</h3>
</div>
<div class="section-grid">
<div class="field-group col-span-2-up">
<label class="block text-xs font-semibold text-gray-600 mb-1">Alamat <span class="text-red-500">*</span></label>
<input type="text" name="alamat" id="alamat"
value="{{ old('alamat', $calonPenerima->alamat) }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="Jalan, nomor rumah, RT/RW" required>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Alamat minimal 5 karakter.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Dusun</label>
<input type="text" name="desa" id="desa"
value="{{ old('desa', $calonPenerima->desa) }}"
class="w-full border border-gray-200 rounded-xl px-3 py-2 bg-gray-100 text-gray-700 cursor-not-allowed"
style="font-size:16px;" readonly>
<p class="text-[11px] text-gray-400 mt-1">Dusun mengikuti RT dan tidak dapat diubah.</p>
</div>
</div>
</div>
{{-- SECTION 3: Data Ekonomi --}}
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 mb-4 overflow-hidden">
<div class="section-head border-b border-gray-100 flex items-center gap-2 bg-gray-50">
<div class="w-1 h-4 bg-amber-500 rounded-full"></div>
<h3 class="text-sm font-semibold text-gray-700">Data Ekonomi</h3>
</div>
<div class="section-grid">
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Pekerjaan <span class="text-red-500">*</span></label>
<select name="pekerjaan" id="pekerjaan"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="">-- Pilih --</option>
@foreach(['Tidak Bekerja','Buruh Harian Lepas','Petani Kecil','Mengurus Rumah Tangga','Pedagang','Wiraswasta','Karyawan Swasta','Guru Honorer','PNS','TNI/Polri'] as $pkj)
<option value="{{ $pkj }}" {{ old('pekerjaan', $calonPenerima->pekerjaan) === $pkj ? 'selected' : '' }}>{{ $pkj }}</option>
@endforeach
</select>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Pekerjaan wajib dipilih.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Penghasilan (Rp) <span class="text-red-500">*</span></label>
<input type="text" id="penghasilan_display"
value="{{ old('penghasilan', $calonPenerima->penghasilan) ? number_format((float) old('penghasilan', $calonPenerima->penghasilan), 0, ',', '.') : '' }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="0" inputmode="numeric" autocomplete="off">
<input type="hidden" name="penghasilan" id="penghasilan"
value="{{ old('penghasilan', $calonPenerima->penghasilan) }}">
<p class="error-msg text-xs text-red-500 mt-1 hidden">Penghasilan tidak boleh negatif.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Jumlah Tanggungan <span class="text-red-500">*</span></label>
<input type="number" name="jumlah_tanggungan" id="jumlah_tanggungan" min="0"
value="{{ old('jumlah_tanggungan', $calonPenerima->jumlah_tanggungan) }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="Jumlah orang" required inputmode="numeric">
<p class="error-msg text-xs text-red-500 mt-1 hidden">Jumlah tanggungan tidak boleh negatif.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Menerima Bantuan Lain? <span class="text-red-500">*</span></label>
<select name="bantuan_lain"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="tidak" {{ old('bantuan_lain', $calonPenerima->bantuan_lain) === 'tidak' ? 'selected' : '' }}>Tidak</option>
<option value="ya" {{ old('bantuan_lain', $calonPenerima->bantuan_lain) === 'ya' ? 'selected' : '' }}>Ya</option>
</select>
</div>
</div>
{{-- Aset Kepemilikan --}}
<div style="padding: 0 16px 16px;">
@php
$asetOptions = ['motor'=>'Motor','motor tua'=>'Motor Tua','tanah'=>'Tanah','emas'=>'Emas','mobil'=>'Mobil','rumah'=>'Rumah','sepeda'=>'Sepeda','ternak'=>'Ternak'];
$asetLama = strtolower(old('aset_kepemilikan', $calonPenerima->aset_kepemilikan ?? ''));
$asetLamaArr = array_map('trim', explode(',', $asetLama));
$asetManualVal = '';
$asetChecked = [];
foreach ($asetLamaArr as $item) {
if (array_key_exists($item, $asetOptions)) {
$asetChecked[] = $item;
} else if ($item !== '' && $item !== 'tidak punya') {
$asetManualVal .= ($asetManualVal ? ', ' : '') . $item;
}
}
@endphp
<label class="block text-xs font-semibold text-gray-600 mb-2">
Aset Kepemilikan <span class="text-red-500">*</span>
<span class="text-gray-400 font-normal ml-1">(centang semua yang dimiliki)</span>
</label>
<div class="aset-checkbox-grid mb-3" id="aset-checkbox-grid">
@foreach($asetOptions as $val => $label)
<label class="aset-checkbox-item">
<input type="checkbox" name="aset_pilihan[]" value="{{ $val }}"
{{ in_array($val, $asetChecked) ? 'checked' : '' }}>
<span>{{ $label }}</span>
</label>
@endforeach
</div>
<div class="flex flex-col gap-1">
<label class="text-xs text-gray-500">Aset lain (tulis manual, pisahkan dengan koma):</label>
<input type="text" name="aset_manual" id="aset_manual"
value="{{ $asetManualVal }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="Contoh: sawah, kebun, mesin jahit">
</div>
<p class="error-msg-aset text-xs text-red-500 mt-1 hidden">Aset kepemilikan wajib diisi.</p>
</div>
</div>
{{-- SECTION 4: Kondisi Tempat Tinggal --}}
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 mb-4 overflow-hidden">
<div class="section-head border-b border-gray-100 flex items-center gap-2 bg-gray-50">
<div class="w-1 h-4 bg-purple-500 rounded-full"></div>
<h3 class="text-sm font-semibold text-gray-700">Kondisi Tempat Tinggal</h3>
</div>
<div class="section-grid" style="grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));">
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Lantai Rumah <span class="text-red-500">*</span></label>
<select name="lantai_rumah" id="lantai_rumah"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="">-- Pilih --</option>
@foreach(['Tanah','Papan/Kayu','Semen Kasar','Keramik Murah','Keramik'] as $opt)
<option value="{{ $opt }}" {{ old('lantai_rumah', $calonPenerima->lantai_rumah) === $opt ? 'selected' : '' }}>{{ $opt }}</option>
@endforeach
</select>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Lantai rumah wajib dipilih.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Dinding Rumah <span class="text-red-500">*</span></label>
<select name="dinding_rumah" id="dinding_rumah"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="">-- Pilih --</option>
@foreach(['Bambu','Anyaman Bambu/Gedek','Kayu/Papan','Tembok Tidak Plester','Tembok Plester'] as $opt)
<option value="{{ $opt }}" {{ old('dinding_rumah', $calonPenerima->dinding_rumah) === $opt ? 'selected' : '' }}>{{ $opt }}</option>
@endforeach
</select>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Dinding rumah wajib dipilih.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Atap Rumah <span class="text-red-500">*</span></label>
<select name="atap_rumah" id="atap_rumah"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="">-- Pilih --</option>
@foreach(['Bambu/Jerami','Seng','Campuran Seng+Genteng','Genteng','Genteng Beton'] as $opt)
<option value="{{ $opt }}" {{ old('atap_rumah', $calonPenerima->atap_rumah) === $opt ? 'selected' : '' }}>{{ $opt }}</option>
@endforeach
</select>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Atap rumah wajib dipilih.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Luas Rumah () <span class="text-red-500">*</span></label>
<input type="number" name="luas_rumah_m2" id="luas_rumah_m2" min="1"
value="{{ old('luas_rumah_m2', $calonPenerima->luas_rumah_m2) }}"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50"
placeholder="Contoh: 36" required inputmode="numeric">
<p class="error-msg text-xs text-red-500 mt-1 hidden">Luas rumah wajib diisi.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Status Kepemilikan Rumah <span class="text-red-500">*</span></label>
<select name="status_kepemilikan_rumah" id="status_kepemilikan_rumah"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="">-- Pilih --</option>
@foreach(['Menumpang','Sewa/Kontrak','Milik Sendiri'] as $opt)
<option value="{{ $opt }}" {{ old('status_kepemilikan_rumah', $calonPenerima->status_kepemilikan_rumah) === $opt ? 'selected' : '' }}>{{ $opt }}</option>
@endforeach
</select>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Status kepemilikan rumah wajib dipilih.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Meteran Listrik <span class="text-red-500">*</span></label>
<select name="meteran_listrik" id="meteran_listrik"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="">-- Pilih --</option>
@foreach(['450VA'=>'450 VA','900VA'=>'900 VA','1300VA+'=>'1300 VA ke atas'] as $val => $lbl)
<option value="{{ $val }}" {{ old('meteran_listrik', $calonPenerima->meteran_listrik) === $val ? 'selected' : '' }}>{{ $lbl }}</option>
@endforeach
</select>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Meteran listrik wajib dipilih.</p>
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Sumber Air <span class="text-red-500">*</span></label>
<select name="sumber_air" id="sumber_air"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-gray-50">
<option value="">-- Pilih --</option>
@foreach(['Sungai','Sumur','PDAM'] as $opt)
<option value="{{ $opt }}" {{ old('sumber_air', $calonPenerima->sumber_air) === $opt ? 'selected' : '' }}>{{ $opt }}</option>
@endforeach
</select>
<p class="error-msg text-xs text-red-500 mt-1 hidden">Sumber air wajib dipilih.</p>
</div>
</div>
</div>
{{-- SECTION 5: Upload Foto --}}
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 mb-5 overflow-hidden">
<div class="section-head border-b border-gray-100 flex items-center gap-2 bg-gray-50">
<div class="w-1 h-4 bg-rose-500 rounded-full"></div>
<h3 class="text-sm font-semibold text-gray-700">Upload Dokumen & Foto</h3>
<span class="text-xs text-gray-400 font-normal">(kosongkan jika tidak ingin mengganti)</span>
</div>
<div class="section-grid" style="grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));">
@php
$fotoFields = [
'foto_rumah_depan' => 'Foto Rumah Depan',
'foto_rumah_belakang' => 'Foto Rumah Belakang',
'foto_rumah_kanan' => 'Foto Rumah Kanan',
'foto_rumah_kiri' => 'Foto Rumah Kiri',
'foto_kk' => 'Foto KK',
'foto_ktp' => 'Foto KTP',
'foto_meteran_air' => 'Foto Meteran Air',
];
@endphp
@foreach($fotoFields as $field => $label)
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">{{ $label }}</label>
@if($calonPenerima->$field)
<div class="mb-1">
<img src="{{ asset('storage/' . $calonPenerima->$field) }}"
class="w-full h-24 object-cover rounded-lg border border-gray-200">
</div>
@endif
<input type="file" name="{{ $field }}" accept="image/*"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 text-sm bg-gray-50">
</div>
@endforeach
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Foto Rekening Listrik</label>
@if($calonPenerima->foto_rekening_listrik)
<div class="mb-1 text-xs text-blue-600">
<a href="{{ asset('storage/' . $calonPenerima->foto_rekening_listrik) }}" target="_blank">Lihat file saat ini</a>
</div>
@endif
<input type="file" name="foto_rekening_listrik" accept="image/*,.pdf"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 text-sm bg-gray-50">
</div>
<div class="field-group">
<label class="block text-xs font-semibold text-gray-600 mb-1">Dokumen Pendukung Lainnya</label>
@if($calonPenerima->dokumen_pendukung)
<div class="mb-1 text-xs text-blue-600">
<a href="{{ asset('storage/' . $calonPenerima->dokumen_pendukung) }}" target="_blank">Lihat file saat ini</a>
</div>
@endif
<input type="file" name="dokumen_pendukung" accept="image/*,.pdf,.doc,.docx"
class="input-field w-full border border-gray-200 rounded-xl px-3 py-2 text-sm bg-gray-50">
</div>
</div>
</div>
{{-- ACTIONS --}}
<div class="action-row">
<a href="{{ route('rt.calon-penerima.index') }}"
class="inline-flex items-center gap-1.5 px-5 py-2 text-sm font-medium bg-white border border-gray-200 text-gray-600 rounded-xl hover:bg-gray-50 transition">
Batal
</a>
<button type="submit" id="btnSimpan"
style="display:inline-flex;align-items:center;gap:8px;"
class="px-6 py-2 text-sm font-semibold bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition shadow-md shadow-blue-200">
<svg id="btnSpinner"
style="display:none;width:16px;height:16px;animation:spin .7s linear infinite;flex-shrink:0;"
fill="none" viewBox="0 0 24 24">
<circle style="opacity:.25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
<path style="opacity:.75" fill="currentColor" d="M4 12a8 8 0 018-8v8z"/>
</svg>
<span id="btnText">Simpan Perubahan</span>
</button>
</div>
</form>
{{-- TOAST --}}
<div id="toast" class="fixed bottom-5 right-5 z-50 hidden" style="max-width:calc(100vw - 40px);">
<div class="flex items-center gap-3 bg-red-500 text-white text-sm font-medium px-4 py-3 rounded-xl shadow-lg">
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01M12 3a9 9 0 100 18A9 9 0 0012 3z"/>
</svg>
<span id="toast-msg">Ada field yang tidak valid.</span>
</div>
</div>
<script>
function showError(id, msg) {
const input = document.getElementById(id);
const err = input?.parentElement?.querySelector('.error-msg');
if (input) input.classList.add('border-red-400', 'bg-red-50');
if (err) { err.textContent = msg; err.classList.remove('hidden'); }
}
function clearError(id) {
const input = document.getElementById(id);
const err = input?.parentElement?.querySelector('.error-msg');
if (input) input.classList.remove('border-red-400', 'bg-red-50');
if (err) err.classList.add('hidden');
}
function showToast(msg) {
const t = document.getElementById('toast');
document.getElementById('toast-msg').textContent = msg;
t.classList.remove('hidden');
setTimeout(() => t.classList.add('hidden'), 3500);
}
function validateAset() {
const checked = document.querySelectorAll('input[name="aset_pilihan[]"]:checked').length > 0;
const manual = (document.getElementById('aset_manual')?.value ?? '').trim() !== '';
const errEl = document.querySelector('.error-msg-aset');
if (!checked && !manual) {
if (errEl) errEl.classList.remove('hidden');
document.getElementById('aset-checkbox-grid')?.classList.add('ring-1', 'ring-red-400', 'rounded-xl');
return false;
}
if (errEl) errEl.classList.add('hidden');
document.getElementById('aset-checkbox-grid')?.classList.remove('ring-1', 'ring-red-400', 'rounded-xl');
return true;
}
document.querySelectorAll('input[name="aset_pilihan[]"]').forEach(cb => cb.addEventListener('change', validateAset));
document.getElementById('aset_manual')?.addEventListener('input', validateAset);
const rules = {
nik: v => /^\d{16}$/.test(v) ? null : 'NIK harus tepat 16 digit angka.',
no_kk: v => /^\d{16}$/.test(v) ? null : 'No. KK harus tepat 16 digit angka.',
nama_lengkap: v => v.trim().length >= 3 ? null : 'Nama minimal 3 karakter.',
tempat_lahir: v => v.trim().length >= 2 ? null : 'Tempat lahir wajib diisi.',
tanggal_lahir: v => v !== '' ? null : 'Tanggal lahir wajib diisi.',
usia: v => (parseInt(v) >= 17 && parseInt(v) <= 100) ? null : 'Usia harus antara 17100.',
status_perkawinan: v => v !== '' ? null : 'Status perkawinan wajib dipilih.',
alamat: v => v.trim().length >= 5 ? null : 'Alamat minimal 5 karakter.',
desa: v => v.trim().length >= 2 ? null : 'Dusun wajib diisi.',
pekerjaan: v => v !== '' ? null : 'Pekerjaan wajib dipilih.',
penghasilan: v => (v !== '' && parseFloat(v) >= 0) ? null : 'Penghasilan tidak boleh negatif.',
jumlah_tanggungan: v => parseInt(v) >= 0 ? null : 'Jumlah tanggungan tidak boleh negatif.',
lantai_rumah: v => v !== '' ? null : 'Lantai rumah wajib dipilih.',
dinding_rumah: v => v !== '' ? null : 'Dinding rumah wajib dipilih.',
atap_rumah: v => v !== '' ? null : 'Atap rumah wajib dipilih.',
luas_rumah_m2: v => parseInt(v) >= 1 ? null : 'Luas rumah wajib diisi.',
status_kepemilikan_rumah: v => v !== '' ? null : 'Status kepemilikan rumah wajib dipilih.',
meteran_listrik: v => v !== '' ? null : 'Meteran listrik wajib dipilih.',
sumber_air: v => v !== '' ? null : 'Sumber air wajib dipilih.',
};
Object.keys(rules).forEach(id => {
const el = document.getElementById(id);
if (!el) return;
['blur','input','change'].forEach(ev => {
el.addEventListener(ev, () => {
const err = rules[id](el.value);
err ? showError(id, err) : clearError(id);
});
});
});
document.getElementById('tanggal_lahir')?.addEventListener('change', function () {
const dob = new Date(this.value);
const today = new Date();
let age = today.getFullYear() - dob.getFullYear();
const m = today.getMonth() - dob.getMonth();
if (m < 0 || (m === 0 && today.getDate() < dob.getDate())) age--;
if (age >= 0 && age <= 150) { document.getElementById('usia').value = age; clearError('usia'); }
});
const displayInput = document.getElementById('penghasilan_display');
const hiddenInput = document.getElementById('penghasilan');
if (displayInput && hiddenInput) {
displayInput.addEventListener('input', function () {
let raw = this.value.replace(/\D/g, '');
this.value = raw ? parseInt(raw).toLocaleString('id-ID') : '';
hiddenInput.value = raw;
const err = rules['penghasilan'](hiddenInput.value);
err ? showError('penghasilan', err) : clearError('penghasilan');
});
displayInput.addEventListener('blur', function () {
const err = rules['penghasilan'](hiddenInput.value);
err ? showError('penghasilan', err) : clearError('penghasilan');
});
}
document.getElementById('formEditPendataan').addEventListener('submit', function (e) {
if (displayInput && hiddenInput && hiddenInput.value === '') {
hiddenInput.value = displayInput.value.replace(/\D/g, '');
}
let valid = true;
Object.keys(rules).forEach(id => {
const el = document.getElementById(id);
if (!el) return;
const err = rules[id](el.value);
if (err) { showError(id, err); valid = false; }
else clearError(id);
});
if (!validateAset()) valid = false;
if (!valid) {
e.preventDefault();
showToast('Mohon perbaiki field yang tidak valid sebelum menyimpan.');
document.querySelector('.border-red-400, .ring-red-400')?.scrollIntoView({ behavior: 'smooth', block: 'center' });
return;
}
const btn = document.getElementById('btnSimpan');
btn.disabled = true;
btn.style.opacity = '0.75';
btn.style.cursor = 'not-allowed';
document.getElementById('btnSpinner').style.display = 'block';
document.getElementById('btnText').textContent = 'Menyimpan...';
});
</script>
</x-app-layout>