60 lines
1.6 KiB
Vue
60 lines
1.6 KiB
Vue
<script setup lang="ts">
|
|
import { Loader2 } from '@lucide/vue'
|
|
import { Button } from '@/components/ui/button'
|
|
import {
|
|
Dialog,
|
|
DialogClose,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@/components/ui/dialog'
|
|
|
|
const props = defineProps<{
|
|
open: boolean
|
|
title?: string
|
|
description?: string
|
|
itemName?: string
|
|
loading?: boolean
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
'update:open': [value: boolean]
|
|
confirm: []
|
|
}>()
|
|
|
|
const dialogTitle = computed(() => props.title ?? 'Hapus Item')
|
|
const dialogDescription = computed(() => {
|
|
if (props.description) return props.description
|
|
if (props.itemName) {
|
|
return `Apakah Anda yakin ingin menghapus "${props.itemName}"? Tindakan ini tidak dapat dibatalkan.`
|
|
}
|
|
return 'Apakah Anda yakin ingin menghapus item ini? Tindakan ini tidak dapat dibatalkan.'
|
|
})
|
|
|
|
function handleClose() {
|
|
emit('update:open', false)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<Dialog :open="open" @update:open="emit('update:open', $event)">
|
|
<DialogContent class="sm:max-w-[400px]">
|
|
<DialogHeader>
|
|
<DialogTitle>{{ dialogTitle }}</DialogTitle>
|
|
<DialogDescription>{{ dialogDescription }}</DialogDescription>
|
|
</DialogHeader>
|
|
<DialogFooter>
|
|
<DialogClose as-child>
|
|
<Button variant="outline" :disabled="loading">Batal</Button>
|
|
</DialogClose>
|
|
<Button variant="destructive" :disabled="loading" @click="emit('confirm')">
|
|
<Loader2 v-if="loading" class="h-4 w-4 mr-1 animate-spin" />
|
|
Hapus
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</template>
|