fix(memo): perbaikkan upload foto di memo, foto existing hilang ketika upload ulang

This commit is contained in:
majid
2025-03-21 09:55:43 +07:00
parent 850074ee7e
commit b6e71ac865
4 changed files with 268 additions and 162 deletions

View File

@@ -186,7 +186,8 @@
<div class="flex flex-wrap items-baseline w-full">
<input type="date-time" id="tanggal_survey" name="tanggal_survey"
class="input w-full" placeholder="Masukkan Tanggal Survey"
value="{{ $permohonan->penilaian->updated_at ?? old('tanggal_survey') }}" @readonly(true)>
value="{{ $permohonan->penilaian->updated_at ?? old('tanggal_survey') }}"
@readonly(true)>
</div>
</div>
@@ -315,10 +316,11 @@
<div class="flex card-footer justify-end gap-5">
@if (Auth::user()->hasAnyRole(['senior-officer', 'surveyor', 'administrator']))
<a class="btn btn-primary" onclick="saveMemo()" {{ $permohonan->status == 'proses-paparan' || $permohonan->status == 'proses-laporan' && Auth::user()->hasAnyRole(['surveyor']) ? 'disabled' : '' }}>
<i class="ki-filled ki-save-2"></i>
Simpan
</a>
<a class="btn btn-primary" onclick="saveMemo()"
{{ $permohonan->status == 'proses-paparan' || ($permohonan->status == 'proses-laporan' && Auth::user()->hasAnyRole(['surveyor'])) ? 'disabled' : '' }}>
<i class="ki-filled ki-save-2"></i>
Simpan
</a>
@endif
@if (Auth::user()->hasAnyRole(['administrator', 'senior-officer', 'EO Appraisal', 'DD Appraisal']))
<a class="btn btn-info"
@@ -347,11 +349,13 @@
document.addEventListener('DOMContentLoaded', function() {
myDropzone = new Dropzone("#dropzone-upload", {
url: "{{ route('penilai.uploadTempPhoto') }}", // Temporary upload route
url: "{{ route('penilai.uploadTempPhoto') }}?permohonan_id={{ $permohonan->id }}&dokument_id={{ request('documentId') }}", // Temporary upload route
paramName: "file",
maxFilesize: 5, // MB
acceptedFiles: "image/*",
addRemoveLinks: true,
uploadMultiple: false,
parallelUploads: 1,
autoProcessQueue: true,
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
@@ -370,132 +374,175 @@
const existingPhotosContainer = document.getElementById('existing-photos');
if (!existingPhotosContainer) return;
@if(isset($memo) && isset($memo->foto))
let existingPhotos;
try {
existingPhotos = @json($memo->foto);
} catch (e) {
console.error('Error parsing existing photos:', e);
return;
}
@if (isset($memo) && isset($memo->foto))
let existingPhotos;
try {
existingPhotos = @json($memo->foto);
} catch (e) {
console.error('Error parsing existing photos:', e);
return;
}
if (Array.isArray(existingPhotos)) {
existingPhotos.forEach(function(photoPath) {
if (typeof photoPath === 'string') {
const photoDiv = document.createElement('div');
photoDiv.className = 'col-md-3 mb-3';
if (Array.isArray(existingPhotos)) {
const BASE_URL = "{{ asset('storage/') }}";
existingPhotos.forEach(function(photoPath) {
if (typeof photoPath === 'string') {
const photoDiv = document.createElement('div');
photoDiv.className = 'col-md-3 mb-3';
const img = document.createElement('img');
img.src = photoPath;
img.className = 'img-fluid';
img.style.maxHeight = '150px';
const img = document.createElement('img');
img.src = BASE_URL + '/' + photoPath;
img.className = 'img-fluid';
img.style.maxHeight = '150px';
const deleteButton = document.createElement('button');
photoDiv.appendChild(img);
existingPhotosContainer.appendChild(photoDiv);
deleteButton.className = 'btn btn-danger btn-sm mt-2';
deleteButton.textContent = 'Hapus';
deleteButton.type = 'button';
deleteButton.onclick = function() {
handleDeletePhoto(photoPath, photoDiv);
};
if (myDropzone) {
let mockFile = { name: photoPath.split('/').pop(), size: 12345 };
myDropzone.emit("addedfile", mockFile);
myDropzone.emit("thumbnail", mockFile, photoPath);
myDropzone.emit("complete", mockFile);
mockFile.previewElement.classList.add("dz-success");
mockFile.previewElement.classList.add("dz-complete");
}
}
});
} else {
console.error('Existing photos is not an array:', existingPhotos);
}
@endif
}
photoDiv.appendChild(img);
photoDiv.appendChild(deleteButton);
existingPhotosContainer.appendChild(photoDiv);
function saveMemo() {
const form = document.getElementById('form-memo');
const formData = new FormData(form);
const jsonData = {
kepada: formData.get('kepada'),
dari: formData.get('dari'),
nomor_memo: formData.get('nomor_memo'),
tanggal: formData.get('tanggal'),
perihal: formData.get('perihal'),
jenis_asset_tidak_sesuai: formData.get('jenis_asset_tidak_sesuai'),
lokasi: {
lokasi: formData.get('lokasi') || '',
address: formData.get('address') || '',
province_code: formData.get('province_code') || '',
city_code: formData.get('city_code') || '',
district_code: formData.get('district_code') || '',
village_code: formData.get('village_code') || '',
tanggal_survey: formData.get('tanggal_survey') || '',
penilai: formData.get('penilai') || '',
},
terlampir: (formData.getAll('terlampir[]') || []),
hasil_survey: (formData.getAll('hasil_survey[]') || []),
kesimpulan_saran: (formData.getAll('kesimpulan_saran[]') || []),
};
showLoadingSwal('Mengirim data ke server...');
const urlParams = new URLSearchParams(window.location.search);
const permohonanId = urlParams.get('permohonanId');
const documentId = urlParams.get('documentId');
// Create a new FormData object to send both JSON and files
const sendFormData = new FormData();
sendFormData.append('permohonan_id', permohonanId);
sendFormData.append('document_id', documentId);
sendFormData.append('memo', JSON.stringify(jsonData));
// Append all files from Dropzone
myDropzone.getAcceptedFiles().forEach((file, index) => {
sendFormData.append(`foto_${index}`, file);
});
const requestUrl = `{{ route('penilai.storeMemoWithPhotos') }}`;
$.ajax({
url: requestUrl,
type: 'POST',
data: sendFormData,
processData: false,
contentType: false,
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function(response) {
hideLoadingSwal();
if (response.success) {
Swal.fire({
title: 'Berhasil!',
text: response.message,
icon: 'success',
confirmButtonText: 'OK'
}).then((response) => {
if (response.isConfirmed) {
// window.location.reload();
if (myDropzone) {
let mockFile = {
name: photoPath.split('/').pop(),
size: 12345
};
myDropzone.emit("addedfile", mockFile);
myDropzone.emit("thumbnail", mockFile, photoPath);
myDropzone.emit("complete", mockFile);
mockFile.previewElement.classList.add("dz-success");
mockFile.previewElement.classList.add("dz-complete");
}
}
});
} else {
console.error('Existing photos is not an array:', existingPhotos);
}
@endif
}
function handleDeletePhoto(photoPath, photoDiv) {
const BASE_URL = "{{ asset('storage/') }}";
Swal.fire({
title: 'Hapus Foto?',
text: "Foto ini akan dihapus secara permanen!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Ya, hapus!'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: "{{ route('penilai.deleteTempPhoto') }}",
method: 'DELETE',
data: {
path: photoPath,
permohonan_id: {{ $permohonan->id ?? 0 }},
dokument_id: '{{ request('documentId') ?? '' }}',
},
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function() {
Swal.fire('Dihapus!', 'Foto berhasil dihapus.', 'success');
photoDiv.remove();
},
error: function() {
Swal.fire('Gagal!', 'Foto gagal dihapus.', 'error');
}
})
}
});
}
function saveMemo() {
const form = document.getElementById('form-memo');
const formData = new FormData(form);
const jsonData = {
kepada: formData.get('kepada'),
dari: formData.get('dari'),
nomor_memo: formData.get('nomor_memo'),
tanggal: formData.get('tanggal'),
perihal: formData.get('perihal'),
jenis_asset_tidak_sesuai: formData.get('jenis_asset_tidak_sesuai'),
lokasi: {
lokasi: formData.get('lokasi') || '',
address: formData.get('address') || '',
province_code: formData.get('province_code') || '',
city_code: formData.get('city_code') || '',
district_code: formData.get('district_code') || '',
village_code: formData.get('village_code') || '',
tanggal_survey: formData.get('tanggal_survey') || '',
penilai: formData.get('penilai') || '',
},
terlampir: (formData.getAll('terlampir[]') || []),
hasil_survey: (formData.getAll('hasil_survey[]') || []),
kesimpulan_saran: (formData.getAll('kesimpulan_saran[]') || []),
};
showLoadingSwal('Mengirim data ke server...');
const urlParams = new URLSearchParams(window.location.search);
const permohonanId = urlParams.get('permohonanId');
const documentId = urlParams.get('documentId');
// Create a new FormData object to send both JSON and files
const sendFormData = new FormData();
sendFormData.append('permohonan_id', permohonanId);
sendFormData.append('document_id', documentId);
sendFormData.append('memo', JSON.stringify(jsonData));
const requestUrl = `{{ route('penilai.storeMemoWithPhotos') }}`;
$.ajax({
url: requestUrl,
type: 'POST',
data: sendFormData,
processData: false,
contentType: false,
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function(response) {
hideLoadingSwal();
if (response.success) {
Swal.fire({
title: 'Berhasil!',
text: response.message,
icon: 'success',
confirmButtonText: 'OK'
}).then((response) => {
if (response.isConfirmed) {
window.location.reload();
}
});
} else {
Swal.fire({
title: 'Error!',
text: response.message || 'Terjadi kesalahan',
icon: 'error',
confirmButtonText: 'OK'
});
}
console.log(response);
},
error: function(xhr, status, error) {
hideLoadingSwal();
Swal.fire({
title: 'Error!',
text: response.message || 'Terjadi kesalahan',
text: 'Terjadi kesalahan saat mengirim data',
icon: 'error',
confirmButtonText: 'OK'
});
}
console.log(response);
},
error: function(xhr, status, error) {
hideLoadingSwal();
Swal.fire({
title: 'Error!',
text: 'Terjadi kesalahan saat mengirim data',
icon: 'error',
confirmButtonText: 'OK'
});
}
});
}
</script>
@endpush
});
}
</script>
@endpush

View File

@@ -0,0 +1,25 @@
{
"kepada": " rustam",
"dari": "dasd",
"nomor_memo": "C04\/250121588\/MAK\/REG0000014\/I\/25",
"tanggal": "2025-03-21",
"perihal": "te",
"jenis_asset_tidak_sesuai": "Alat Berat",
"lokasi": {
"lokasi": "dsad",
"address": "Jl. Kali Pasir Kecil No.1, RT.2\/RW.1, Cikini, Kec. Menteng, Kota Jakarta Pusat, Daerah Khusus Ibukota Jakarta 10330",
"province_code": "12",
"city_code": "",
"district_code": "",
"village_code": "",
"tanggal_survey": "2025-01-21 04:13:33",
"penilai": "rrer"
},
"terlampir": ["llorem"],
"hasil_survey": ["lorm"],
"kesimpulan_saran": ["loren"],
"foto": [
"temp_photos\/1742524956_1. Tampak Akses Jalan Menuju Objek Penilaian.png",
"temp_photos\/1742524957_2. Tampak Akses Jalan Menuju Objek penilaian.png"
]
}