diff --git a/resources/js/pages/EditProduk.vue b/resources/js/pages/EditProduk.vue index 9e57d13..36b41f4 100644 --- a/resources/js/pages/EditProduk.vue +++ b/resources/js/pages/EditProduk.vue @@ -54,9 +54,7 @@
- + -
+
-
-
+
+
+ + + +
+
+ + + + +
+

+
+
+ + +
+
-
+
+ Upload dari File +
+
+ Pilih foto dari galeri +
+
+ +
-

+
+
+ Ambil dari Kamera +
+
+ Foto langsung dengan kamera +
+
+
@@ -214,6 +281,43 @@
+ + +
+ + +
+
+ + +
+ + +
+
+
@@ -225,7 +329,6 @@ import mainLayout from "../layouts/mainLayout.vue"; import InputField from "../components/InputField.vue"; import InputSelect from "../components/InputSelect.vue"; import CreateItemModal from "../components/CreateItemModal.vue"; -import { errorMessages } from "@vue/compiler-core"; const route = useRoute(); const router = useRouter(); @@ -248,6 +351,11 @@ const uploadLoading = ref(false); const uploadError = ref(""); const isDragging = ref(false); const fileInput = ref(null); +const showUploadMenu = ref(false); +const showCamera = ref(false); +const video = ref(null); +const canvas = ref(null); +let stream = null; const openItemModal = ref(false); const editedProduct = ref(null); @@ -272,31 +380,37 @@ const calculateHargaJual = () => { }; const loadKategori = async () => { - const response = await axios.get("/api/kategori", { - headers: { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }, - }); - category.value = response.data.map((c) => ({ value: c.id, label: c.nama })); + try { + const response = await axios.get("/api/kategori", { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }); + category.value = response.data.map((c) => ({ value: c.id, label: c.nama })); + } catch (error) { + console.error("Error loading categories:", error); + } }; const loadProduk = async () => { - const response = await axios.get(`/api/produk/edit/${productId}`, { - headers: { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }, - }); - const produk = response.data; - // console.log(produk); - - form.value = { - nama: produk.nama, - id_kategori: produk.id_kategori, - berat: produk.berat, - kadar: produk.kadar, - harga_per_gram: produk.harga_per_gram, - harga_jual: produk.harga_jual, - }; + try { + const response = await axios.get(`/api/produk/edit/${productId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }); + const produk = response.data; + form.value = { + nama: produk.nama, + id_kategori: produk.id_kategori, + berat: produk.berat, + kadar: produk.kadar, + harga_per_gram: produk.harga_per_gram, + harga_jual: produk.harga_jual, + }; + } catch (error) { + console.error("Error loading product:", error); + } }; const loadFoto = async () => { @@ -307,20 +421,23 @@ const loadFoto = async () => { }, }); uploadedImages.value = response.data; - // console.log(uploadedImages.value); - } catch (e) { - console.error(e); - + } catch (error) { + console.error("Error loading photos:", error); uploadError.value = "Gagal memuat foto"; } }; -const triggerFileInput = () => { +const toggleUploadMenu = () => { if (!uploadLoading.value && uploadedImages.value.length < 6) { - fileInput.value?.click(); + showUploadMenu.value = !showUploadMenu.value; } }; +const triggerFileUpload = () => { + showUploadMenu.value = false; + fileInput.value?.click(); +}; + const handleFileSelect = (e) => { const files = Array.from(e.target.files); uploadFiles(files); @@ -335,60 +452,47 @@ const handleDrop = (e) => { }; const uploadFiles = async (files) => { - uploadError.value = ''; - - if (uploadedImages.value.length + files.length > 6) { - uploadError.value = 'Maksimal 6 foto yang dapat diupload'; - return; - } - - const validFiles = files.filter(file => { - const isValidType = ['image/jpeg', 'image/jpg', 'image/png'].includes(file.type); - const isValidSize = file.size <= 2 * 1024 * 1024; - - if (!isValidType) { - uploadError.value = 'Format file harus JPG, JPEG, atau PNG'; - return false; + uploadError.value = ''; + if (uploadedImages.value.length + files.length > 6) { + uploadError.value = 'Maksimal 6 foto yang dapat diupload'; + return; } - - if (!isValidSize) { - uploadError.value = 'Ukuran file maksimal 2MB'; - return false; + const validFiles = files.filter(file => { + const isValidType = ['image/jpeg', 'image/jpg', 'image/png'].includes(file.type); + const isValidSize = file.size <= 2 * 1024 * 1024; + if (!isValidType) { + uploadError.value = 'Format file harus JPG, JPEG, atau PNG'; + return false; + } + if (!isValidSize) { + uploadError.value = 'Ukuran file maksimal 2MB'; + return false; + } + return true; + }); + if (validFiles.length === 0) return; + uploadLoading.value = true; + try { + for (const file of validFiles) { + const formData = new FormData(); + formData.append('foto', file); + const response = await axios.post('/api/foto', formData, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + 'Content-Type': 'multipart/form-data', + }, + }); + uploadedImages.value.push(response.data); + } + if (fileInput.value) { + fileInput.value.value = ''; + } + } catch (error) { + console.error('Upload error:', error); + uploadError.value = error.response?.data?.message || 'Gagal mengupload foto'; + } finally { + uploadLoading.value = false; } - - return true; - }); - - if (validFiles.length === 0) return; - - uploadLoading.value = true; - - try { - for (const file of validFiles) { - const formData = new FormData(); - formData.append('foto', file); - - const response = await axios.post('/api/foto', formData, { - headers: { - Authorization: `Bearer ${localStorage.getItem("token")}`, - 'Content-Type': 'multipart/form-data', - - }, - }); - - uploadedImages.value.push(response.data); - } - - if (fileInput.value) { - fileInput.value.value = ''; - } - - } catch (error) { - console.error('Upload error:', error); - uploadError.value = error.response?.data?.message || 'Gagal mengupload foto'; - } finally { - uploadLoading.value = false; - } }; const removeImage = async (id) => { @@ -404,21 +508,51 @@ const removeImage = async (id) => { } }; +const openCameraModal = async () => { + showUploadMenu.value = false; + showCamera.value = true; + try { + stream = await navigator.mediaDevices.getUserMedia({ video: true }); + video.value.srcObject = stream; + } catch (err) { + console.error("Gagal akses kamera:", err); + alert("Tidak bisa mengakses kamera, cek izin browser!"); + closeCamera(); + } +}; + +const closeCamera = () => { + showCamera.value = false; + if (stream) { + stream.getTracks().forEach(track => track.stop()); + stream = null; + } +}; + +const capturePhoto = () => { + const ctx = canvas.value.getContext("2d"); + canvas.value.width = video.value.videoWidth; + canvas.value.height = video.value.videoHeight; + ctx.drawImage(video.value, 0, 0); + canvas.value.toBlob(async (blob) => { + if (!blob) return; + await uploadFiles([new File([blob], "camera_photo.png", { type: "image/png" })]); + closeCamera(); + }, "image/png"); +}; + const submitForm = async () => { loading.value = true; try { - await axios.put( - `/api/produk/${productId}`,form.value, - { - headers: { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }, - } - ); + await axios.put(`/api/produk/${productId}`, form.value, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }); router.push("/produk?message=Produk berhasil diperbarui"); } catch (err) { - errorMessages.value = err.response?.data?.message || "Gagal menyimpan produk"; - console.error(err); + console.error("Submit error:", err); + uploadError.value = err.response?.data?.message || "Gagal menyimpan produk"; } finally { loading.value = false; } @@ -426,6 +560,7 @@ const submitForm = async () => { const closeItemModal = () => { openItemModal.value = false; + editedProduct.value = null; }; const back = () => { @@ -435,7 +570,6 @@ const back = () => { onMounted(async () => { await loadKategori(); await loadProduk(); - loadFoto(); + await loadFoto(); }); - - + \ No newline at end of file