first commit antrean operasi
This commit is contained in:
No files matched your search
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<v-dialog v-model="dialog" max-width="500">
|
||||
<v-card>
|
||||
<v-card-title class="d-flex justify-space-between align-center">
|
||||
<span class="text-h5">Tambah Penjamin Asuransi</span>
|
||||
<v-btn icon="mdi-close" variant="text" @click="closeDialog"></v-btn>
|
||||
</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-card-text class="pa-4">
|
||||
<v-form ref="form" v-model="isValid" @submit.prevent="submitForm">
|
||||
|
||||
<v-select
|
||||
v-model="selectedType"
|
||||
:items="optionInsuranceType"
|
||||
label="Tipe Penjamin *"
|
||||
:rules = "requiredRules"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
class="mb-3"
|
||||
></v-select>
|
||||
|
||||
<v-text-field
|
||||
v-model="formData.nama"
|
||||
label="Nama Penjamin *"
|
||||
:rules="textRules"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
|
||||
<v-text-field
|
||||
v-model="formData.contact"
|
||||
label="No Telp *"
|
||||
:rules="phoneRules"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
class="mb-3"
|
||||
hint="Masukkan hanya angka, min 9 - max 15 digit."
|
||||
></v-text-field>
|
||||
|
||||
<v-textarea
|
||||
v-model="formData.alamat"
|
||||
label="Alamat Kantor"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
rows="3"
|
||||
class="mb-3"
|
||||
></v-textarea>
|
||||
|
||||
<v-switch
|
||||
v-model="formData.isActive"
|
||||
label="Aktifkan Sekarang"
|
||||
color="success"
|
||||
density="compact"
|
||||
hide-details
|
||||
class="mb-4"
|
||||
></v-switch>
|
||||
|
||||
<small class="text-caption text-error">* Bidang yang wajib diisi</small>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions class="pa-4 pt-0">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="error" variant="flat" @click="closeDialog">Batal</v-btn>
|
||||
|
||||
<v-btn
|
||||
color="primary"
|
||||
variant="flat"
|
||||
:disabled="!isValid"
|
||||
@click="submitForm"
|
||||
>
|
||||
Simpan Data
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, watch} from 'vue';
|
||||
|
||||
const form = ref(null);
|
||||
const isValid = ref(false);
|
||||
|
||||
const {phoneRules, textRules, requiredRules} = useValidation();
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
guarantorType: {
|
||||
type: String,
|
||||
default: '--Silahkan Pilih--'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const selectedType = ref(props.guarantorType);
|
||||
|
||||
// Pantau perubahan agar tidak terkunci di nilai pertama (null/default)
|
||||
watch(() => props.guarantorType, (newVal) => {
|
||||
if (newVal) {
|
||||
selectedType.value = newVal;
|
||||
}
|
||||
}, { immediate: true }); // immediate agar langsung sinkron saat awal
|
||||
|
||||
|
||||
// Definisikan emit untuk mengirim event kembali ke parent
|
||||
const emit = defineEmits(['update:modelValue', 'data-saved']);
|
||||
|
||||
// State lokal untuk dialog (sinkronisasi dengan modelValue)
|
||||
const dialog = ref(props.modelValue);
|
||||
|
||||
const optionInsuranceType = [
|
||||
{title: 'Asuransi', value: 'insurance'},
|
||||
{title: 'Perusahaan', value: 'company'}
|
||||
];
|
||||
|
||||
// Sinkronisasi dialog dengan prop modelValue
|
||||
watch(() => props.modelValue, (newVal) => {
|
||||
dialog.value = newVal;
|
||||
});
|
||||
watch(dialog, (newVal) => {
|
||||
emit('update:modelValue', newVal);
|
||||
});
|
||||
|
||||
|
||||
const defaultFormData = {
|
||||
nama: '',
|
||||
alamat: '',
|
||||
isActive: true,
|
||||
};
|
||||
const formData = ref({});
|
||||
|
||||
function closeDialog() {
|
||||
dialog.value = false;
|
||||
// Reset formulir setelah ditutup
|
||||
Object.assign(formData.value, defaultFormData);
|
||||
if (form.value) {
|
||||
form.value.resetValidation();
|
||||
}
|
||||
}
|
||||
|
||||
async function submitForm() {
|
||||
// Validasi manual
|
||||
const {valid} = await form.value.validate();
|
||||
|
||||
if (valid) {
|
||||
console.log('Data yang akan dikirim:', formData.value);
|
||||
|
||||
// TODO: Di sini Anda akan memanggil API untuk menyimpan data
|
||||
|
||||
// Emit event ke parent bahwa data telah tersimpan
|
||||
emit('data-saved', formData.value);
|
||||
|
||||
// Tutup dialog
|
||||
closeDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Ekspos fungsi closeDialog agar dapat dipanggil dari luar (jika diperlukan)
|
||||
defineExpose({
|
||||
closeDialog,
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,154 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, computed} from 'vue';
|
||||
import AddGuarantorModal from "~/components/master/guarantor/AddGuarantorModal.vue";
|
||||
import {EditIcon, EyeIcon, PlusIcon, TrashIcon} from "vue-tabler-icons";
|
||||
|
||||
const search = ref('');
|
||||
const guarantorTypeSelected = ref('');
|
||||
const isModalOpen = ref(false);
|
||||
const colorActive = ref('success');
|
||||
const colorNonActive = ref('danger');
|
||||
|
||||
const headers = [
|
||||
{title: 'Nama', key: 'name'},
|
||||
{title: 'Status', key: 'status', sortable: false},
|
||||
{title: 'Action', key: 'isActive', sortable: false},
|
||||
{title: '', key: 'dropdown', sortable: false},
|
||||
];
|
||||
|
||||
const listInsurance = ref([
|
||||
{id: 4, name: 'PT Bentoel', status: 'active', isActive: true},
|
||||
{id: 5, name: 'PT Outsuka', status: 'non_active', isActive: true},
|
||||
{id: 6, name: 'PT. Gandum', status: 'active', isActive: false},
|
||||
]);
|
||||
|
||||
const toggleStatus = (item) => {
|
||||
item.isActive = !item.isActive;
|
||||
};
|
||||
|
||||
function handleDataSaved(data) {
|
||||
console.log('Data baru diterima di parent:', data);
|
||||
|
||||
// Tampilkan data yang baru ditambahkan (simulasi penambahan data ke list)
|
||||
// lastAddedData.value = data;
|
||||
|
||||
// Di sini Anda akan memuat ulang data tabel utama (jika menggunakan API)
|
||||
}
|
||||
|
||||
const tableActionData = ref([
|
||||
{
|
||||
icon: EyeIcon,
|
||||
listtitle: 'View'
|
||||
},
|
||||
{
|
||||
icon: EditIcon,
|
||||
listtitle: 'Edit'
|
||||
},
|
||||
{
|
||||
icon: TrashIcon,
|
||||
listtitle: 'Delete'
|
||||
}
|
||||
]);
|
||||
|
||||
const handleAction = (action) => {
|
||||
console.log(action);
|
||||
};
|
||||
|
||||
const openModalGuarantor = (type) => {
|
||||
guarantorTypeSelected.value = type;
|
||||
isModalOpen.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card flat>
|
||||
<div class="d-sm-flex justify-space-between align-center my-7">
|
||||
<v-sheet width="255" class="mb-lg-0 mb-4">
|
||||
<v-text-field
|
||||
v-model="search"
|
||||
label="Cari Penjamin"
|
||||
density="comfortable"
|
||||
variant="outlined"
|
||||
clearable
|
||||
hide-details
|
||||
>
|
||||
<template v-slot:prepend-inner>
|
||||
<Icon icon="solar:magnifer-linear" height="18" width="25"/>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-sheet>
|
||||
<v-btn color="primary" v-bind="props" flat class="ml-auto"
|
||||
@click="openModalGuarantor('company')">
|
||||
<v-icon class="mr-2">mdi-plus</v-icon>
|
||||
Tambah Penjamin
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="listInsurance"
|
||||
:search="search"
|
||||
item-key="id"
|
||||
class="elevation-1"
|
||||
hide-default-footer
|
||||
>
|
||||
|
||||
<template v-slot:item.status="{ item }">
|
||||
<v-chip
|
||||
:color="item.isActive ? 'primary' : 'danger'"
|
||||
:text="item.isActive ? 'Aktif' : 'Tidak Aktif'"
|
||||
label
|
||||
size="small"
|
||||
></v-chip>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.isActive="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<v-switch
|
||||
v-model="item.isActive"
|
||||
hide-details
|
||||
density="compact"
|
||||
:color="item.isActive ? colorActive: colorNonActive"
|
||||
></v-switch>
|
||||
<span class="ml-2 text-caption">
|
||||
{{ item.isActive ? 'Aktif' : 'Tidak Aktif' }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.dropdown="{ item }">
|
||||
<v-avatar size="22">
|
||||
<DotsIcon size="20" color="grey100"/>
|
||||
</v-avatar>
|
||||
|
||||
<v-menu activator="parent">
|
||||
<v-list>
|
||||
<v-list-item value="action" v-for="list in tableActionData" :key="list.listtitle"
|
||||
hide-details min-height="38" @click="handleAction(list.listtitle)">
|
||||
<v-list-item-title>
|
||||
<v-avatar size="20" class="mr-2">
|
||||
<component :is="list.icon" stroke-width="2" size="20"/>
|
||||
</v-avatar>
|
||||
{{ list.listtitle }}
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:bottom></template>
|
||||
|
||||
</v-data-table>
|
||||
</v-card>
|
||||
|
||||
<AddGuarantorModal
|
||||
v-model="isModalOpen"
|
||||
:guarantor-type="guarantorTypeSelected"
|
||||
@data-saved="handleDataSaved"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,165 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, computed} from 'vue';
|
||||
import AddGuarantorModal from "~/components/master/guarantor/AddGuarantorModal.vue";
|
||||
import DialogConfirmModal from "~/components/ui-components/dialogs/DialogConfirmModal.vue";
|
||||
|
||||
const search = ref('');
|
||||
const guarantorTypeSelected = ref('');
|
||||
const dialogTitle = ref('');
|
||||
const dialogMessage = ref('');
|
||||
|
||||
const isModalOpen = ref(false);
|
||||
const isConfirmDelete = ref(false);
|
||||
const colorActive = ref('success');
|
||||
const colorNonActive = ref('danger');
|
||||
|
||||
const headers = [
|
||||
{title: 'Nama', key: 'name'},
|
||||
{title: 'Status', key: 'status', sortable: false},
|
||||
{title: 'Action', key: 'isActive', sortable: false},
|
||||
{title: '', key: 'dropdown', sortable: false},
|
||||
];
|
||||
|
||||
const listInsurance = ref([
|
||||
{id: 1, name: 'BPJS', status: 'active', isActive: true},
|
||||
{id: 2, name: 'Jiwasraya', status: 'non_active', isActive: false},
|
||||
{id: 3, name: 'Jasa Raharja', status: 'active', isActive: true},
|
||||
]);
|
||||
|
||||
function handleDataSaved(data) {
|
||||
console.log('Data baru diterima di parent:', data);
|
||||
lastAddedData.value = data;
|
||||
}
|
||||
|
||||
function handleConfirmDialog(data) {
|
||||
console.log('Data baru diterima di parent:', data);
|
||||
isConfirmDelete.value = false;
|
||||
}
|
||||
|
||||
const executeDelete = () => {
|
||||
console.log('executeDelete');
|
||||
};
|
||||
|
||||
const tableActionData = ref([
|
||||
{ title: 'View', action: 'view', icon: 'mdi-eye-outline', color: 'success' },
|
||||
{ title: 'Edit', action: 'edit', icon: 'mdi-pencil-outline', color: 'primary' },
|
||||
{ title: 'Delete', action: 'delete', icon: 'mdi-delete-outline', color: 'error' },
|
||||
]);
|
||||
|
||||
const handleAction = (action, item) => {
|
||||
switch (action) {
|
||||
case 'View':
|
||||
return console.log("View")
|
||||
break;
|
||||
case 'Edit':
|
||||
return console.log("Edit")
|
||||
break;
|
||||
case 'Delete':
|
||||
confirmDelete(1);
|
||||
break;
|
||||
default:
|
||||
console.warn('Aksi tidak dikenali');
|
||||
}
|
||||
};
|
||||
|
||||
const openModalGuarantor = (type) => {
|
||||
guarantorTypeSelected.value = type;
|
||||
isModalOpen.value = true;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card flat>
|
||||
<div class="d-sm-flex justify-space-between align-center my-7">
|
||||
<v-sheet width="255" class="mb-lg-0 mb-4">
|
||||
<v-text-field
|
||||
v-model="search"
|
||||
label="Cari Penjamin"
|
||||
density="comfortable"
|
||||
variant="outlined"
|
||||
clearable
|
||||
hide-details
|
||||
>
|
||||
<template v-slot:prepend-inner>
|
||||
<Icon icon="solar:magnifer-linear" height="18" width="25"/>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-sheet>
|
||||
<v-btn color="primary" v-bind="props" flat class="ml-auto"
|
||||
@click="openModalGuarantor('insurance')">
|
||||
<v-icon class="mr-2">mdi-plus</v-icon>
|
||||
Tambah Penjamin
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="listInsurance"
|
||||
:search="search"
|
||||
item-key="id"
|
||||
class="elevation-1"
|
||||
hide-default-footer
|
||||
>
|
||||
|
||||
<template v-slot:item.status="{ item }">
|
||||
<v-chip
|
||||
:color="item.isActive ? 'primary' : 'danger'"
|
||||
:text="item.isActive ? 'Aktif' : 'Tidak Aktif'"
|
||||
label
|
||||
size="small"
|
||||
></v-chip>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.isActive="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<v-switch
|
||||
v-model="item.isActive"
|
||||
hide-details
|
||||
density="compact"
|
||||
:color="item.isActive ? colorActive: colorNonActive"
|
||||
></v-switch>
|
||||
<span class="ml-2 text-caption">
|
||||
{{ item.isActive ? 'Aktif' : 'Tidak Aktif' }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.dropdown="{ item }">
|
||||
<v-avatar size="22">
|
||||
<DotsIcon size="20" color="grey100"/>
|
||||
</v-avatar>
|
||||
|
||||
<v-menu activator="parent">
|
||||
<v-list>
|
||||
<v-list-item value="action" v-for="list in tableActionData" :key="list.title"
|
||||
hide-details min-height="38" @click="handleAction(list.title, 0)">
|
||||
<v-list-item-title>
|
||||
<v-avatar size="20" class="mr-2">
|
||||
<v-icon :icon="list.icon" :color="list.color"></v-icon>
|
||||
</v-avatar>
|
||||
{{ list.title }}
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:bottom></template>
|
||||
|
||||
</v-data-table>
|
||||
</v-card>
|
||||
|
||||
<AddGuarantorModal
|
||||
v-model="isModalOpen"
|
||||
:guarantor-type="guarantorTypeSelected"
|
||||
@data-saved="handleDataSaved"
|
||||
/>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user