Compare commits
3 Commits
8e59b1f1f1
...
ae4b8a3449
Author | SHA1 | Date | |
---|---|---|---|
|
ae4b8a3449 | ||
|
600c87d9ca | ||
|
b1babd6c26 |
@ -20,9 +20,9 @@ class DatabaseSeeder extends Seeder
|
|||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
User::factory()->create([
|
User::factory()->create([
|
||||||
'nama' => 'Test User',
|
'nama' => 'Test',
|
||||||
'role' => 'owner',
|
'role' => 'owner',
|
||||||
'password' => bcrypt('123123123'),
|
'password' => bcrypt('123123'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
User::factory(2)->create();
|
User::factory(2)->create();
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="my-6">
|
<div class="my-6">
|
||||||
<hr class="border-B mb-5" />
|
<hr class="border-B mb-5" />
|
||||||
<div class="flez flex-row mb-3">
|
<div class="flex flex-row mb-3 overflow-x-auto">
|
||||||
<input type="date" v-model="tanggalDipilih"
|
<input type="date" v-model="tanggalDipilih"
|
||||||
class="mt-1 block rounded-md shadow-sm sm:text-sm bg-A text-D border-B focus:border-C focus:ring focus:outline-none focus:ring-D focus:ring-opacity-50 p-2" />
|
class="mt-1 block rounded-md shadow-sm sm:text-sm bg-A text-D border-B focus:border-C focus:ring focus:outline-none focus:ring-D focus:ring-opacity-50 p-2" />
|
||||||
|
<InputSelect class="ml-3" :options="opsiSales" v-model="salesDipilih" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-5 overflow-x-auto">
|
||||||
<table class="w-full border-collapse border border-C rounded-md">
|
<table class="w-full border-collapse border border-C rounded-md">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-C text-D rounded-t-md">
|
<tr class="bg-C text-D rounded-t-md">
|
||||||
@ -39,10 +39,12 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch, computed } from 'vue';
|
import { ref, onMounted, watch, computed } from 'vue';
|
||||||
|
import InputSelect from './InputSelect.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
const tanggalDipilih = ref('');
|
const tanggalDipilih = ref('');
|
||||||
@ -51,6 +53,24 @@ const loading = ref(false);
|
|||||||
|
|
||||||
const produk = computed(() => data.value?.produk || []);
|
const produk = computed(() => data.value?.produk || []);
|
||||||
|
|
||||||
|
const salesDipilih = ref(null);
|
||||||
|
const opsiSales = ref([
|
||||||
|
{ label: 'Semua Sales', value: null, selected: true },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const fetchSales = async () => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get('/api/sales');
|
||||||
|
const salesData = response.data;
|
||||||
|
opsiSales.value = [{ label: 'Semua Sales', value: null }, ...salesData.map(sales => ({
|
||||||
|
label: sales.nama,
|
||||||
|
value: sales.id,
|
||||||
|
}))];
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Gagal mengambil data sales:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const fetchData = async (date) => {
|
const fetchData = async (date) => {
|
||||||
if (!date) return;
|
if (!date) return;
|
||||||
|
|
||||||
@ -58,8 +78,7 @@ const fetchData = async (date) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`/api/detail-laporan?tanggal=${date}`);
|
const response = await axios.get(`/api/detail-laporan?tanggal=${date}`);
|
||||||
data.value = response.data;
|
data.value = response.data;;
|
||||||
// console.log("Data berhasil diambil:", data.value);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Gagal mengambil data laporan:', error);
|
console.error('Gagal mengambil data laporan:', error);
|
||||||
data.value = null;
|
data.value = null;
|
||||||
@ -71,6 +90,8 @@ const fetchData = async (date) => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const today = new Date().toISOString().split('T')[0];
|
const today = new Date().toISOString().split('T')[0];
|
||||||
tanggalDipilih.value = today;
|
tanggalDipilih.value = today;
|
||||||
|
|
||||||
|
fetchSales();
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(tanggalDipilih, (newDate) => {
|
watch(tanggalDipilih, (newDate) => {
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-5">
|
<div class="mt-5 overflow-x-auto">
|
||||||
<table class="w-full border-collapse border border-C rounded-md">
|
<table class="w-full border-collapse border border-C rounded-md">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-C text-D rounded-t-md">
|
<tr class="bg-C text-D rounded-t-md">
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-5">
|
<div class="mt-5 overflow-x-auto">
|
||||||
<table class="w-full border-collapse border border-C rounded-md">
|
<table class="w-full border-collapse border border-C rounded-md">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-C text-D rounded-t-md">
|
<tr class="bg-C text-D rounded-t-md">
|
||||||
|
@ -144,7 +144,7 @@ const saveMove = async () => {
|
|||||||
},
|
},
|
||||||
body:{
|
body:{
|
||||||
id_nampan: selectedTrayId.value,
|
id_nampan: selectedTrayId.value,
|
||||||
id_produk: selectedItem.value.id_produk, // ikutkan id_produk karena API minta
|
id_produk: selectedItem.value.id_produk,
|
||||||
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -151,7 +151,11 @@ const akunToDelete = ref(null);
|
|||||||
const fetchAkun = async () => {
|
const fetchAkun = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
const response = await axios.get("/api/user");
|
const response = await axios.get("/api/user", {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem("token")}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
akun.value = response.data;
|
akun.value = response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching akun:", error);
|
console.error("Error fetching akun:", error);
|
||||||
@ -180,7 +184,11 @@ const hapusAkun = (item) => {
|
|||||||
|
|
||||||
const confirmDelete = async () => {
|
const confirmDelete = async () => {
|
||||||
try {
|
try {
|
||||||
await axios.delete(`/api/user/${akunToDelete.value.id}`);
|
await axios.delete(`/api/user/${akunToDelete.value.id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem("token")}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
fetchAkun();
|
fetchAkun();
|
||||||
confirmDeleteOpen.value = false;
|
confirmDeleteOpen.value = false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<mainLayout>
|
<mainLayout>
|
||||||
<!-- Modal Buat Item -->
|
<!-- Modal Buat Item -->
|
||||||
<CreateItemModal
|
<CreateItemModal :isOpen="openItemModal" :product="editedProduct" @close="closeItemModal" />
|
||||||
:isOpen="openItemModal"
|
|
||||||
:product="editedProduct"
|
|
||||||
@close="closeItemModal"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="p-6">
|
<div class="p-6">
|
||||||
<p class="font-serif italic text-[25px] text-D">Edit Produk</p>
|
<p class="font-serif italic text-[25px] text-D">Edit Produk</p>
|
||||||
@ -26,7 +22,8 @@
|
|||||||
<div class="mb-3 flex flex-row w-full gap-3">
|
<div class="mb-3 flex flex-row w-full gap-3">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<label class="block text-D mb-1">Berat (g)</label>
|
<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" />
|
<InputField v-model="form.berat" type="number" step="0.01" placeholder="Masukkan berat"
|
||||||
|
@input="calculateHargaJual" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<label class="block text-D mb-1">Kadar (K)</label>
|
<label class="block text-D mb-1">Kadar (K)</label>
|
||||||
@ -37,7 +34,8 @@
|
|||||||
<div class="mb-3 flex flex-row w-full gap-3">
|
<div class="mb-3 flex flex-row w-full gap-3">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<label class="block text-D mb-1">Harga per Gram</label>
|
<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" />
|
<InputField v-model="form.harga_per_gram" type="number" step="0.01" placeholder="Masukkan harga per gram"
|
||||||
|
@input="calculateHargaJual" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<label class="block text-D mb-1">Harga Jual</label>
|
<label class="block text-D mb-1">Harga Jual</label>
|
||||||
@ -83,12 +81,14 @@
|
|||||||
</path>
|
</path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-gray-600 font-medium" v-html="uploadLoading ? 'Uploading...' : 'Unggah<br/>Foto'"></p>
|
<p class="text-xs text-gray-600 font-medium"
|
||||||
|
v-html="uploadLoading ? 'Uploading...' : 'Unggah<br/>Foto'"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input ref="fileInput" type="file" multiple accept="image/jpeg,image/jpg,image/png" @change="handleFileSelect" class="hidden" />
|
<input ref="fileInput" type="file" multiple accept="image/jpeg,image/jpg,image/png" @change="handleFileSelect"
|
||||||
|
class="hidden" />
|
||||||
|
|
||||||
<p class="text-xs text-gray-500 mt-2">Format: JPG, JPEG, PNG (Max: 2MB per file, Max: 6 foto)</p>
|
<p class="text-xs text-gray-500 mt-2">Format: JPG, JPEG, PNG (Max: 2MB per file, Max: 6 foto)</p>
|
||||||
|
|
||||||
@ -164,12 +164,20 @@ const calculateHargaJual = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const loadKategori = async () => {
|
const loadKategori = async () => {
|
||||||
const response = await axios.get("/api/kategori");
|
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 }));
|
category.value = response.data.map((c) => ({ value: c.id, label: c.nama }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadProduk = async () => {
|
const loadProduk = async () => {
|
||||||
const response = await axios.get(`/api/produk/${productId}`);
|
const response = await axios.get(`/api/produk/${productId}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem("token")}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
const produk = response.data;
|
const produk = response.data;
|
||||||
form.value = {
|
form.value = {
|
||||||
nama: produk.nama,
|
nama: produk.nama,
|
||||||
@ -216,7 +224,10 @@ const uploadFiles = async (files) => {
|
|||||||
formData.append("foto", file);
|
formData.append("foto", file);
|
||||||
formData.append("id_user", userId.value);
|
formData.append("id_user", userId.value);
|
||||||
const res = await axios.post("/api/foto/upload", formData, {
|
const res = await axios.post("/api/foto/upload", formData, {
|
||||||
headers: { "Content-Type": "multipart/form-data" },
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem("token")}`,
|
||||||
|
"Content-Type": "multipart/form-data"
|
||||||
|
},
|
||||||
});
|
});
|
||||||
uploadedImages.value.push(res.data);
|
uploadedImages.value.push(res.data);
|
||||||
}
|
}
|
||||||
@ -227,7 +238,11 @@ const uploadFiles = async (files) => {
|
|||||||
|
|
||||||
const removeImage = async (id) => {
|
const removeImage = async (id) => {
|
||||||
try {
|
try {
|
||||||
await axios.delete(`/api/foto/hapus/${id}`);
|
await axios.delete(`/api/foto/hapus/${id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem("token")}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
uploadedImages.value = uploadedImages.value.filter((i) => i.id !== id);
|
uploadedImages.value = uploadedImages.value.filter((i) => i.id !== id);
|
||||||
} catch {
|
} catch {
|
||||||
uploadError.value = "Gagal menghapus foto";
|
uploadError.value = "Gagal menghapus foto";
|
||||||
|
Loading…
Reference in New Issue
Block a user