79 lines
2.4 KiB
Vue
79 lines
2.4 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
import FormFeedback from '@/components/FormFeedback.vue';
|
|
import { Button } from '@/components/ui/button';
|
|
import { useLocalization } from '@/composables/useLocalization';
|
|
import type { FormFeedbackState } from '@/lib/form-feedback';
|
|
import { login } from '@/routes/index';
|
|
|
|
const props = defineProps<{
|
|
state: FormFeedbackState;
|
|
responseStatus?: number | null;
|
|
loadingTitle?: string;
|
|
successTitle?: string;
|
|
}>();
|
|
defineEmits<{ retry: [] }>();
|
|
const { t } = useLocalization();
|
|
const expired = computed(
|
|
() => props.state === 'server' && props.responseStatus === 419,
|
|
);
|
|
const limited = computed(
|
|
() => props.state === 'server' && props.responseStatus === 429,
|
|
);
|
|
const title = computed(() => {
|
|
if (expired.value) {
|
|
return t('auth.feedback.expiredTitle');
|
|
}
|
|
if (limited.value) {
|
|
return t('auth.feedback.limitedTitle');
|
|
}
|
|
if (props.state === 'loading') {
|
|
return props.loadingTitle ?? t('auth.feedback.pending');
|
|
}
|
|
if (props.state === 'success') {
|
|
return props.successTitle ?? t('auth.feedback.completed');
|
|
}
|
|
if (props.state === 'validation') {
|
|
return t('auth.feedback.validationTitle');
|
|
}
|
|
return undefined;
|
|
});
|
|
const description = computed(() => {
|
|
if (expired.value) {
|
|
return t('auth.feedback.expiredDescription');
|
|
}
|
|
if (limited.value) {
|
|
return t('auth.feedback.limitedDescription');
|
|
}
|
|
if (props.state === 'validation') {
|
|
return t('auth.feedback.validationDescription');
|
|
}
|
|
if (props.state === 'network') {
|
|
return t('auth.feedback.networkDescription');
|
|
}
|
|
if (props.state === 'server') {
|
|
return t('auth.feedback.serverDescription');
|
|
}
|
|
if (props.state === 'cancelled') {
|
|
return t('auth.feedback.cancelledDescription');
|
|
}
|
|
return undefined;
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="gap-card grid" v-show="state !== 'idle'">
|
|
<FormFeedback
|
|
:state="state"
|
|
:title="title"
|
|
:description="description"
|
|
:retryable="!expired"
|
|
@retry="$emit('retry')"
|
|
/>
|
|
<Button v-if="expired" as-child variant="outline">
|
|
<!-- A fresh document renews the session/CSRF state and drops in-memory secrets. -->
|
|
<a :href="login.url()">{{ t('auth.backToLogin') }}</a>
|
|
</Button>
|
|
</div>
|
|
</template>
|