Files
web-antrean/components/common/SelectionDialog.vue
T

125 lines
2.7 KiB
Vue

<template>
<v-dialog v-model="dialogModel" max-width="800px">
<v-card>
<v-card-title class="dialog-header">
<v-btn icon size="small" @click="dialogModel = false">
<v-icon>mdi-close</v-icon>
</v-btn>
<span>{{ title }}</span>
</v-card-title>
<v-card-text class="pa-4">
<v-text-field
v-model="searchModel"
:placeholder="searchPlaceholder"
density="compact"
hide-details
class="mb-4"
prepend-inner-icon="mdi-magnify"
/>
<v-row dense>
<v-col
v-for="item in filteredItems"
:key="item.id"
cols="6"
sm="4"
>
<v-card
class="selection-card"
@click="handleSelect(item)"
elevation="0"
>
<v-card-text class="text-center pa-3">
<div class="selection-name">{{ item.name }}</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
modelValue: {
type: Boolean,
required: true
},
title: {
type: String,
default: 'Pilih Item'
},
items: {
type: Array,
default: () => []
},
searchQuery: {
type: String,
default: ''
},
searchPlaceholder: {
type: String,
default: 'Cari...'
}
});
const emit = defineEmits(['update:modelValue', 'update:searchQuery', 'select']);
const dialogModel = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
});
const searchModel = computed({
get: () => props.searchQuery,
set: (value) => emit('update:searchQuery', value)
});
const filteredItems = computed(() => {
if (!searchModel.value) return props.items;
const search = searchModel.value.toLowerCase();
return props.items.filter(item =>
item.name.toLowerCase().includes(search)
);
});
const handleSelect = (item) => {
emit('select', item);
dialogModel.value = false;
};
</script>
<style scoped lang="scss">
.dialog-header {
background: var(--color-neutral-300);
padding: 16px 20px;
display: flex;
align-items: center;
gap: 12px;
font-size: 18px;
font-weight: 700;
color: var(--color-neutral-900);
}
.selection-card {
cursor: pointer;
transition: all 0.2s;
border: 2px solid var(--color-neutral-500);
background: var(--color-neutral-100);
}
.selection-card:hover {
border-color: var(--color-secondary-600);
background: var(--color-secondary-200);
}
.selection-name {
font-size: 13px;
font-weight: 700;
color: var(--color-neutral-900);
}
</style>