elearning/frontend_management/components/common/AppModal.vue

102 lines
2.2 KiB
Vue
Raw Normal View History

2026-01-14 13:58:25 +07:00
<template>
<q-dialog
:model-value="modelValue"
@update:model-value="$emit('update:modelValue', $event)"
:persistent="persistent"
>
<q-card :style="{ width: width, maxWidth: maxWidth }">
<!-- Modal Header -->
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">{{ title }}</div>
<q-space />
<q-btn
v-if="showClose"
icon="close"
flat
round
dense
@click="handleClose"
/>
</q-card-section>
<!-- Modal Content -->
<q-card-section :class="contentClass">
<slot></slot>
</q-card-section>
<!-- Modal Actions -->
<q-card-actions v-if="$slots.actions || showDefaultActions" align="right" class="q-px-md q-pb-md">
<slot name="actions">
<q-btn
v-if="showDefaultActions"
flat
:label="cancelLabel"
color="grey"
@click="handleCancel"
/>
<q-btn
v-if="showDefaultActions"
unelevated
:label="confirmLabel"
:color="confirmColor"
:loading="loading"
@click="handleConfirm"
/>
</slot>
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script setup lang="ts">
interface Props {
modelValue: boolean;
title?: string;
width?: string;
maxWidth?: string;
persistent?: boolean;
showClose?: boolean;
showDefaultActions?: boolean;
cancelLabel?: string;
confirmLabel?: string;
confirmColor?: string;
loading?: boolean;
contentClass?: string;
}
withDefaults(defineProps<Props>(), {
title: '',
width: '500px',
maxWidth: '90vw',
persistent: false,
showClose: true,
showDefaultActions: true,
cancelLabel: 'ยกเลิก',
confirmLabel: 'ยืนยัน',
confirmColor: 'primary',
loading: false,
contentClass: ''
});
const emit = defineEmits<{
'update:modelValue': [value: boolean];
'confirm': [];
'cancel': [];
'close': [];
}>();
const handleClose = () => {
emit('update:modelValue', false);
emit('close');
};
const handleCancel = () => {
emit('update:modelValue', false);
emit('cancel');
};
const handleConfirm = () => {
emit('confirm');
};
</script>