feat(SPA): screens for Sites and Authors
This commit is contained in:
1 parent
b34a173d83
commit
3d81d2c717
82 files changed
+10676
-37
No files matched your search
@@ -0,0 +1,119 @@
|
||||
<script setup lang="ts">
|
||||
import { SHEET_CONTENT_CLASS, SHEET_FOOTER_CLASS } from '@/components/sheetClasses'
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import { computed } from 'vue'
|
||||
import type { DirectoryNotice } from '@/lib/directoryTypes'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
title: string
|
||||
description: string
|
||||
confirmLabel: string
|
||||
pendingLabel: string
|
||||
cancelLabel?: string
|
||||
tone?: 'danger' | 'neutral'
|
||||
pending?: boolean
|
||||
notice?: DirectoryNotice | null
|
||||
closable?: boolean
|
||||
confirmDisabled?: boolean
|
||||
}>(),
|
||||
{
|
||||
cancelLabel: '',
|
||||
tone: 'danger',
|
||||
pending: false,
|
||||
notice: null,
|
||||
closable: false,
|
||||
confirmDisabled: false,
|
||||
},
|
||||
)
|
||||
|
||||
const emit = defineEmits<{ confirm: []; close: [] }>()
|
||||
|
||||
const open = defineModel<boolean>('open', { default: true })
|
||||
|
||||
const confirmText = computed(() => (props.pending ? props.pendingLabel : props.confirmLabel))
|
||||
const closeButton = computed(() =>
|
||||
props.closable && !props.pending
|
||||
? { class: 'size-7 justify-center text-muted max-md:size-11' }
|
||||
: false,
|
||||
)
|
||||
|
||||
function onOpenChange(value: boolean) {
|
||||
if (!value && props.pending) {
|
||||
return
|
||||
}
|
||||
open.value = value
|
||||
if (!value) {
|
||||
emit('close')
|
||||
}
|
||||
}
|
||||
|
||||
function onCancel() {
|
||||
onOpenChange(false)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal
|
||||
:open="open"
|
||||
:title="title"
|
||||
:description="description"
|
||||
:dismissible="!pending"
|
||||
:close="closeButton"
|
||||
:content="{ role: 'alertdialog', 'aria-busy': pending ? 'true' : undefined }"
|
||||
:ui="{
|
||||
content: `${SHEET_CONTENT_CLASS} sm:top-35 sm:max-w-115`,
|
||||
header: 'min-h-0 px-6 pt-5 pb-0 sm:px-6',
|
||||
title: 'text-lg/6 font-semibold',
|
||||
description: 'mt-1 text-sm text-muted text-pretty',
|
||||
body: 'px-6 pt-5 pb-0 sm:px-6 sm:pt-5 sm:pb-0',
|
||||
footer: SHEET_FOOTER_CLASS,
|
||||
}"
|
||||
@update:open="onOpenChange"
|
||||
>
|
||||
<template #body>
|
||||
<div class="flex flex-col gap-4">
|
||||
<UAlert
|
||||
v-if="notice"
|
||||
role="alert"
|
||||
color="error"
|
||||
variant="soft"
|
||||
icon="i-lucide-circle-x"
|
||||
:title="notice.title"
|
||||
:description="notice.description"
|
||||
:ui="{
|
||||
root: 'items-start gap-2.5 px-3.5 py-3',
|
||||
title: 'font-semibold',
|
||||
description: 'text-toned',
|
||||
}"
|
||||
/>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="flex w-full flex-col-reverse gap-2 sm:flex-row sm:justify-end">
|
||||
<UButton
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
block
|
||||
class="h-11 justify-center text-sm text-highlighted disabled:text-dimmed disabled:opacity-100 sm:h-8 sm:w-auto sm:px-3"
|
||||
:disabled="pending"
|
||||
@click="onCancel"
|
||||
>
|
||||
{{ cancelLabel || t('Cancel') }}
|
||||
</UButton>
|
||||
<UButton
|
||||
:color="tone === 'danger' ? 'error' : 'primary'"
|
||||
:loading="pending"
|
||||
:disabled="pending || confirmDisabled"
|
||||
block
|
||||
class="h-11 justify-center text-sm sm:h-8 sm:w-auto sm:px-3"
|
||||
@click="emit('confirm')"
|
||||
>
|
||||
{{ confirmText }}
|
||||
</UButton>
|
||||
</div>
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
Reference in new issue
Block a user