Kasir/resources/js/pages/Tray.vue

241 lines
6.6 KiB
Vue

<template>
<mainLayout>
<!-- Header -->
<div class="p-6">
<!-- Judul -->
<p class="font-serif italic text-[25px] text-D">NAMPAN</p>
<!-- Searchbar -->
<div class="flex justify-end mt-2">
<div class="w-64">
<searchbar v-model:search="searchQuery" />
</div>
</div>
<!-- Tombol -->
<div class="flex gap-2 mt-3 justify-end">
<!-- Tambah Nampan -->
<button
@click="openModal"
class="px-4 py-2 hover:bg-B bg-C rounded-md shadow font-semibold"
>
Tambah Nampan
</button>
<!-- Kosongkan -->
<button
@click="openConfirmModal"
class="px-3 py-2 bg-red-500 hover:bg-red-600 text-white rounded-md"
>
Kosongkan
</button>
</div>
</div>
<!-- Search + List -->
<TrayList :search="searchQuery" @edit="editTray" @delete="deleteTray" />
<!-- Modal Tambah/Edit Nampan -->
<div
v-if="showModal"
class="fixed inset-0 bg-black/75 flex justify-center items-center z-50 backdrop-blur-sm"
>
<div
class="bg-white rounded-lg shadow-lg p-6 w-96 transform transition-all duration-300 scale-95 opacity-0 animate-fadeIn"
>
<h2 class="text-lg font-semibold mb-4 text-[#102c57]">
{{ editingTrayId ? "Edit Nampan" : "Tambah Nampan" }}
</h2>
<label class="block mb-2 text-sm font-medium text-[#102c57]">
Nama Nampan
</label>
<input
v-model="trayName"
type="text"
placeholder="Contoh: A4"
class="w-full border rounded-md p-2 mb-4"
/>
<div class="flex justify-end gap-2">
<button
@click="closeModal"
class="px-4 py-2 bg-gray-400 hover:bg-gray-500 text-white rounded-md"
>
Cancel
</button>
<button
@click="saveTray"
class="px-4 py-2 bg-[#DAC0A3] hover:bg-[#C9A77E] rounded-md text-[#102c57]"
>
Save
</button>
</div>
</div>
</div>
<!-- Modal Konfirmasi Kosongkan -->
<div
v-if="showConfirmModal"
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm"
>
<div
class="bg-white rounded-2xl shadow-xl w-full max-w-md p-6 transform transition-all duration-300 scale-95 opacity-0 animate-fadeIn"
>
<!-- Judul -->
<h2 class="text-xl font-bold text-[#102c57] mb-3 text-center">
Kosongkan semua nampan?
</h2>
<!-- Deskripsi -->
<p class="text-gray-600 text-sm mb-6 text-center leading-relaxed">
Semua item akan dimasukkan ke <span class="font-semibold">Brankas</span>.<br />
Masuk ke menu <b>Brankas</b> untuk mengembalikan item ke nampan.
</p>
<!-- Tombol -->
<div class="flex justify-center gap-3">
<button
@click="closeConfirmModal"
class="px-5 py-2 rounded-lg font-semibold border border-gray-300 text-gray-700 hover:bg-gray-100 transition"
>
Batal
</button>
<button
@click="confirmEmptyTray"
class="px-5 py-2 rounded-lg font-semibold bg-red-500 text-white hover:bg-red-600 transition"
>
Ya, Kosongkan
</button>
</div>
</div>
</div>
</mainLayout>
</template>
<script setup>
import { ref } from "vue";
import axios from "axios";
import mainLayout from "../layouts/mainLayout.vue";
import searchbar from "../components/Searchbar.vue";
import TrayList from "../components/TrayList.vue";
const searchQuery = ref("");
const showModal = ref(false);
const showConfirmModal = ref(false);
const trayName = ref("");
const editingTrayId = ref(null);
// buka modal tambah/edit
const openModal = () => {
showModal.value = true;
};
const closeModal = () => {
trayName.value = "";
editingTrayId.value = null;
showModal.value = false;
};
// simpan nampan
const saveTray = async () => {
if (!trayName.value.trim()) {
alert("Nama Nampan tidak boleh kosong");
return;
}
try {
if (editingTrayId.value) {
await axios.put(
`/api/nampan/${editingTrayId.value}`,
{ nama: trayName.value },
{
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
}
);
alert("Nampan berhasil diupdate");
} else {
await axios.post(
"/api/nampan",
{ nama: trayName.value },
{
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
}
);
alert("Nampan berhasil ditambahkan");
}
closeModal();
location.reload();
} catch (error) {
console.error(error);
alert("Gagal menyimpan nampan");
}
};
// === Konfirmasi kosongkan nampan ===
const openConfirmModal = () => {
showConfirmModal.value = true;
};
const closeConfirmModal = () => {
showConfirmModal.value = false;
};
const confirmEmptyTray = async () => {
try {
await axios.delete("/api/kosongkan-nampan", {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});
alert("Semua item berhasil dipindahkan ke Brankas");
closeConfirmModal();
location.reload();
} catch (error) {
console.error(error);
alert("Gagal mengosongkan nampan");
}
};
const editTray = (tray) => {
trayName.value = tray.nama;
editingTrayId.value = tray.id;
showModal.value = true;
};
const deleteTray = async (id) => {
if (!confirm("Yakin ingin menghapus nampan ini?")) return;
try {
await axios.delete(`/api/nampan/${id}`, {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});
alert("Nampan berhasil dihapus");
location.reload();
} catch (error) {
console.error(error);
alert("Gagal menghapus nampan");
}
};
</script>
<style>
@keyframes fadeIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
.animate-fadeIn {
animation: fadeIn 0.25s ease-out forwards;
}
</style>