| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- <template>
- <q-dialog ref="dialogRef" @hide="onDialogHide">
- <q-card class="cancel-dialog-card bg-surface shadow-card" :flat="false">
- <div class="row justify-end q-pt-sm q-pr-sm">
- <q-btn flat round dense icon="close" color="grey-6" size="sm" @click="onDialogCancel" />
- </div>
- <q-card-section class="q-pt-none q-pb-sm q-px-lg text-center">
- <div class="cancel-title text-secondary text-weight-bold">
- {{ $t('provider.dashboard.cancel_schedule.title') }}
- </div>
- </q-card-section>
- <q-card-section class="q-pt-none q-pb-sm q-px-lg">
- <div class="text-body2 text-grey-8 text-weight-bold q-mb-xs">
- {{ $t('provider.dashboard.cancel_schedule.reason_label') }}
- </div>
- <q-input
- v-model="cancelText"
- type="textarea"
- outlined
- dense
- :placeholder="$t('provider.dashboard.cancel_schedule.reason_placeholder')"
- rows="4"
- color="secondary"
- input-class="text-black"
- :rules="[val => (val && val.trim().length >= 5) || ' ']"
- hide-bottom-space
- />
- </q-card-section>
- <q-card-section class="q-pt-xs q-pb-md q-px-lg">
- <div class="warning-box row no-wrap q-gutter-x-sm q-pa-sm">
- <q-icon name="mdi-alert-outline" color="secondary" size="22px" class="q-mt-xs flex-shrink-0" />
- <div>
- <span class="text-caption text-weight-bold text-grey-9">
- {{ $t('provider.dashboard.cancel_schedule.warning_title') }}
- </span>
- <span class="text-caption text-grey-8">
- {{ ' ' + $t('provider.dashboard.cancel_schedule.warning_free') }}
- </span>
- <br />
- <span class="text-caption text-grey-8">
- {{ $t('provider.dashboard.cancel_schedule.warning_fee') }}
- </span>
- </div>
- </div>
- </q-card-section>
- <q-card-section class="q-pt-none q-pb-lg q-px-lg">
- <div class="row justify-center q-gutter-x-md">
- <q-btn
- unelevated
- rounded
- no-caps
- class="btn-action bg-grey-3 text-grey-8"
- :label="$t('provider.dashboard.cancel_schedule.btn_back')"
- @click="onDialogCancel"
- />
- <q-btn
- unelevated
- rounded
- no-caps
- color="secondary"
- class="btn-action"
- :loading="loading"
- :disable="!cancelText || cancelText.trim().length < 5"
- :label="$t('provider.dashboard.cancel_schedule.btn_keep')"
- @click="confirmCancel"
- />
- </div>
- </q-card-section>
- </q-card>
- </q-dialog>
- </template>
- <script setup>
- import { ref } from 'vue'
- import { useDialogPluginComponent, useQuasar } from 'quasar'
- import { useI18n } from 'vue-i18n'
- import { cancelSchedule } from 'src/api/schedule'
- const props = defineProps({
- schedule: {
- type: Object,
- required: true
- }
- })
- const { t } = useI18n()
- const $q = useQuasar()
- const { dialogRef, onDialogHide, onDialogCancel } = useDialogPluginComponent()
- const cancelText = ref('')
- const loading = ref(false)
- const confirmCancel = async () => {
- if (!cancelText.value || cancelText.value.trim().length < 5) return
- loading.value = true
- try {
- await cancelSchedule(props.schedule.id, cancelText.value.trim())
- dialogRef.value.hide()
- } catch {
- $q.notify({ message: t('http.errors.failed'), color: 'negative' })
- } finally {
- loading.value = false
- }
- }
- </script>
- <style scoped lang="scss">
- .cancel-dialog-card {
- width: 340px;
- max-width: 94vw;
- border-radius: 20px !important;
- overflow: hidden;
- }
- .cancel-title {
- font-size: 18px;
- line-height: 1.35;
- }
- .warning-box {
- background: #e8f4fd;
- border-radius: 10px;
- }
- .btn-action {
- min-width: 110px;
- font-weight: 700;
- }
- .flex-shrink-0 {
- flex-shrink: 0;
- }
- </style>
|