Files
RenewCMS/web/src/components/UpdateBanner.vue
T

85 lines
2.0 KiB
Vue

<script setup lang="ts">
import { t } from '@/i18n'
import { computed } from 'vue'
export type UpdateBannerState = 'available' | 'ready'
const props = defineProps<{
state: UpdateBannerState
version: string
}>()
const COPY = {
available: {
icon: 'i-lucide-circle-arrow-up',
get title() {
return (version: string) => t('Version {0} is available', [version])
},
get description() {
return t('Update it from Settings. It takes about 2 minutes and the site stays online.')
},
},
ready: {
icon: 'i-lucide-circle-check',
get title() {
return (version: string) => t('Version {0} is ready to install', [version])
},
get description() {
return t(
'Restart from Settings to finish. The site is unavailable for about 10 seconds.',
)
},
},
} as const
const copy = computed(() => COPY[props.state])
const emit = defineEmits<{
'go-to-settings': []
dismiss: []
}>()
</script>
<template>
<UAlert
role="region"
:aria-label="t('Update available')"
color="info"
variant="soft"
orientation="horizontal"
:icon="copy.icon"
:title="copy.title(version)"
:description="copy.description"
:ui="{
root: 'flex-wrap items-start gap-x-2.5 gap-y-3 border border-default py-3 ring-0 md:flex-nowrap md:items-center',
wrapper: 'basis-0 gap-0.5',
title: 'text-sm text-highlighted',
description: 'mt-0 text-sm/5 text-toned',
actions: 'max-md:w-full max-md:basis-full',
}"
>
<template #actions>
<div class="flex w-full items-center gap-2">
<UButton
color="neutral"
variant="outline"
class="h-11 flex-1 justify-center border border-accented bg-default px-3 text-highlighted ring-0 md:h-8 md:flex-none"
@click="emit('go-to-settings')"
>
{{ t('Go to Settings') }}
</UButton>
<UButton
color="neutral"
variant="ghost"
icon="i-lucide-x"
:aria-label="t('Dismiss')"
class="size-11 shrink-0 justify-center text-muted md:size-8"
:ui="{ leadingIcon: 'size-4' }"
@click="emit('dismiss')"
/>
</div>
</template>
</UAlert>
</template>