Kasir/resources/js/pages/EditProduk.vue
2025-10-27 20:02:02 +07:00

250 lines
7.9 KiB
Vue

<template>
<mainLayout>
<!-- Modal Buat Item -->
<CreateItemModal
:isOpen="openItemModal"
:product="editedProduct"
@close="closeItemModal"
/>
<div class="p-6">
<p class="font-serif italic text-[25px] text-D">Edit Produk</p>
<div class="flex flex-col md:flex-row mt-5 gap-6">
<!-- Form Section -->
<div class="flex-1">
<div class="mb-3">
<label class="block text-D mb-1">Nama Produk</label>
<InputField
v-model="form.nama"
type="text"
placeholder="Masukkan nama produk"
/>
</div>
<div class="mb-3">
<label class="block text-D mb-1">Kategori</label>
<InputSelect
v-model="form.id_kategori"
:options="category"
placeholder="Pilih kategori"
/>
</div>
<div class="mb-3 flex flex-row w-full gap-3">
<div class="flex-1">
<label class="block text-D mb-1">Berat (g)</label>
<InputField
v-model="form.berat"
type="number"
step="0.01"
placeholder="Masukkan berat"
@input="calculateHargaJual"
/>
</div>
<div class="flex-1">
<label class="block text-D mb-1">Kadar (K)</label>
<InputField
v-model="form.kadar"
type="number"
placeholder="Masukkan kadar"
/>
</div>
</div>
<div class="mb-3 flex flex-row w-full gap-3">
<div class="flex-1">
<label class="block text-D mb-1">Harga per Gram</label>
<InputField
v-model="form.harga_per_gram"
type="number"
step="0.01"
placeholder="Masukkan harga per gram"
@input="calculateHargaJual"
/>
</div>
<div class="flex-1">
<label class="block text-D mb-1">Harga Jual</label>
<InputField
v-model="form.harga_jual"
type="number"
step="0.01"
placeholder="Masukkan harga jual"
/>
</div>
</div>
</div>
<!-- Image Upload Section -->
<div class="flex-1">
<PhotoUploader v-model="uploadedImages" :maxPhotos="6" @error="handleUploadError" />
</div>
</div>
<div class="mt-6 flex justify-end flex-row gap-3">
<button
@click="back"
class="px-6 py-2 rounded-md bg-gray-400 hover:bg-gray-500 text-white"
>
Batal
</button>
<button
@click="submitForm"
:disabled="loading || !isFormValid"
class="bg-C text-D px-6 py-2 rounded-md hover:bg-B disabled:bg-B disabled:text-white disabled:cursor-not-allowed"
>
{{ loading ? "Menyimpan..." : "Simpan Perubahan" }}
</button>
</div>
</div>
</mainLayout>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import axios from "axios";
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 PhotoUploader from "../components/PhotoUploader.vue";
const route = useRoute();
const router = useRouter();
const productId = route.params.id;
const form = ref({
nama: "",
id_kategori: null,
berat: 0,
kadar: 0,
harga_per_gram: 0,
harga_jual: 0,
});
const category = ref([]);
const uploadedImages = ref([]);
const loading = ref(false);
const openItemModal = ref(false);
const editedProduct = ref(null);
const isFormValid = computed(() => {
return (
form.value.nama &&
form.value.id_kategori &&
form.value.berat > 0 &&
form.value.kadar > 0 &&
form.value.harga_per_gram > 0 &&
form.value.harga_jual > 0
);
});
const calculateHargaJual = () => {
const berat = parseFloat(form.value.berat) || 0;
const hargaPerGram = parseFloat(form.value.harga_per_gram) || 0;
if (berat > 0 && hargaPerGram > 0) {
form.value.harga_jual = berat * hargaPerGram;
}
};
const loadKategori = async () => {
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 () => {
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 () => {
try {
const response = await axios.get(`/api/foto`, {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});
uploadedImages.value = response.data;
} catch (error) {
console.error("Error loading photos:", error);
}
};
const handleUploadError = (error) => {
console.error('Upload error:', error);
};
const submitForm = async () => {
loading.value = true;
try {
await axios.put(`/api/produk/${productId}`, form.value, {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});
router.push("/produk?message=Produk berhasil diperbarui");
} catch (err) {
console.error("Submit error:", err);
alert(err.response?.data?.message || "Gagal menyimpan produk");
} finally {
loading.value = false;
}
};
const closeItemModal = () => {
openItemModal.value = false;
editedProduct.value = null;
};
const back = async () => {
loading.value = true;
try{
console.log(localStorage.getItem("token"));
await axios.delete('/api/all/foto', {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});
router.push('/produk');
} catch (e){
console.error("Error image ", e);
} finally {
loading.value = false;
}
};
onMounted(async () => {
await loadKategori();
await loadProduk();
await loadFoto();
});
</script>