250 lines
7.9 KiB
Vue
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>
|