Kasir/resources/js/components/EditAkun.vue
2025-09-12 16:59:38 +07:00

210 lines
6.5 KiB
Vue

<template>
<div class="fixed inset-0 flex items-center justify-center bg-black/65 z-50">
<div class="bg-white rounded-lg p-6 w-96 shadow-lg">
<h2 class="text-lg font-bold mb-4">Edit Akun</h2>
<form @submit.prevent="updateAkun" class="space-y-3">
<!-- Nama -->
<div>
<label for="nama" class="block text-sm font-medium">Nama</label>
<InputField
v-model="form.nama"
id="nama"
type="text"
:required="true"
@input="clearError('nama')"
/>
<p v-if="errors.nama" class="text-red-500 text-sm">{{ errors.nama }}</p>
</div>
<!-- Password -->
<div>
<label for="password" class="block text-sm font-medium">Password</label>
<InputPassword
v-model="form.password"
id="password"
type="password"
:required="false"
@input="clearError('password')"
/>
<p class="text-sm">Kosongkan jika tidak ingin ubah password</p>
<p v-if="errors.password" class="text-red-500 text-sm">{{ errors.password }}</p>
</div>
<!-- Confirm Password -->
<div v-if="form.password">
<label for="confirmPassword" class="block text-sm font-medium">Konfirmasi Password</label>
<InputPassword
v-model="form.confirmPassword"
id="confirmPassword"
type="password"
:required="false"
@input="clearError('confirmPassword')"
/>
<p v-if="errors.confirmPassword" class="text-red-500 text-sm">
{{ errors.confirmPassword }}
</p>
</div>
<!-- Role -->
<div>
<label for="role" class="block text-sm font-medium">Peran</label>
<!-- 🔒 Kalau akun sendiri tampil readonly -->
<template v-if="isEditingSelf">
<p class="mt-1 px-3 py-2 border rounded bg-gray-100 text-gray-700">
{{ form.role === 'owner' ? 'Owner' : 'Kasir' }}
</p>
</template>
<!-- 🔓 Kalau akun lain bisa diubah -->
<template v-else>
<InputSelect
v-model="form.role"
:options="[
{ value: 'owner', label: 'Owner' },
{ value: 'kasir', label: 'Kasir' }
]"
placeholder="-- Pilih Peran --"
@change="clearError('role')"
/>
<p v-if="errors.role" class="text-red-500 text-sm">{{ errors.role }}</p>
</template>
</div>
<!-- Tombol -->
<div class="flex justify-end gap-2 mt-4">
<button
type="button"
@click="$emit('close')"
class="bg-gray-300 hover:bg-gray-400 px-4 py-2 rounded"
>
Batal
</button>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded disabled:opacity-50 disabled:cursor-not-allowed"
:disabled="!isFormValid"
>
Ubah
</button>
</div>
</form>
<!-- Error global -->
<p v-if="errorMessage" class="text-red-500 text-sm mt-3">
{{ errorMessage }}
</p>
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
import axios from "axios";
import InputField from "@/components/InputField.vue";
import InputSelect from "@/components/InputSelect.vue";
import InputPassword from "./InputPassword.vue";
const props = defineProps({
akun: {
type: Object,
required: true,
},
});
const emit = defineEmits(["refresh", "close"]);
const form = ref({
nama: props.akun?.nama || "",
password: "",
confirmPassword: "",
role: props.akun?.role || "",
});
const errors = ref({ nama: "", password: "", confirmPassword: "", role: "" });
const errorMessage = ref("");
const loggedInId = ref(localStorage.getItem("userId")); // 🔥 ambil dari localStorage
const isFormValid = computed(() => {
if (form.value.password && form.value.password !== form.value.confirmPassword) {
return false;
}
return (
form.value.nama.trim() &&
form.value.role &&
!errors.value.nama &&
!errors.value.password &&
!errors.value.confirmPassword &&
!errors.value.role
);
});
// 🔥 ini cek apakah akun yang diedit adalah akun sendiri
const isEditingSelf = computed(() => {
return String(props.akun.id) === String(loggedInId.value);
});
const clearError = (field) => {
errors.value[field] = "";
errorMessage.value = "";
};
const validateForm = () => {
let valid = true;
errors.value = { nama: "", password: "", confirmPassword: "", role: "" };
if (!form.value.nama) {
errors.value.nama = "Nama wajib diisi";
valid = false;
}
if (form.value.password && form.value.password.length < 6) {
errors.value.password = "Password minimal 6 karakter";
valid = false;
}
if (form.value.password && form.value.password !== form.value.confirmPassword) {
errors.value.confirmPassword = "Konfirmasi password tidak cocok";
valid = false;
}
if (!form.value.role) {
errors.value.role = "Role wajib dipilih";
valid = false;
}
return valid;
};
const updateAkun = async () => {
if (!validateForm()) return;
try {
const payload = { ...form.value };
if (!payload.password) delete payload.password;
delete payload.confirmPassword;
await axios.put(`/api/user/${props.akun.id}`, payload, {
headers: { Authorization: `Bearer ${localStorage.getItem("token")}` },
});
emit("refresh");
emit("close");
} catch (err) {
if (err.response?.status === 422 && err.response.data.errors) {
const backendErrors = err.response.data.errors;
Object.keys(backendErrors).forEach((key) => {
errors.value[key] = backendErrors[key][0];
});
} else {
errorMessage.value = err.response?.data?.message || "Gagal update akun.";
}
console.error("Gagal update akun:", err);
}
};
onMounted(() => {
console.log("Akun.id:", props.akun.id);
console.log("LoggedInId:", loggedInId.value);
console.log("isEditingSelf:", isEditingSelf.value);
});
</script>