feat: register T1 (pending, verify)
This commit is contained in:
1 parent
3c3f7c6194
commit
4e41d60142
29 files changed
+2162
-42
No files matched your search
@@ -1,9 +1,135 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useOverlay, useToast } from '@nuxt/ui/composables'
|
||||
import AuthShell from '@/components/AuthShell.vue'
|
||||
import ConfirmDialog from '@/components/ConfirmDialog.vue'
|
||||
import ResultPanel from '@/components/ResultPanel.vue'
|
||||
import { ApiError, useApi } from '@/composables/useApi'
|
||||
import { registrationCancelledToast } from '@/lib/registrationToasts'
|
||||
import { useSessionStore } from '@/stores/session'
|
||||
|
||||
const router = useRouter()
|
||||
const api = useApi()
|
||||
const session = useSessionStore()
|
||||
const overlay = useOverlay()
|
||||
const toast = useToast()
|
||||
|
||||
const pendingEmail = ref<string | null>(null)
|
||||
const loggingOut = ref(false)
|
||||
const cancelOutcome = ref<'cancelled' | 'alreadyVerified' | null>(null)
|
||||
|
||||
onMounted(() => {
|
||||
pendingEmail.value = sessionStorage.getItem('renewcms:pendingEmail')
|
||||
document.title = 'Check your email · RenewCMS'
|
||||
})
|
||||
|
||||
const description = computed(() =>
|
||||
pendingEmail.value
|
||||
? `We sent a verification link to ${pendingEmail.value}. It expires in 2 hours.`
|
||||
: 'We sent a verification link to the email you registered with. It expires in 2 hours.',
|
||||
)
|
||||
|
||||
async function logOut() {
|
||||
loggingOut.value = true
|
||||
try {
|
||||
await api.request('/v1/auth/logout', { method: 'POST' })
|
||||
} finally {
|
||||
loggingOut.value = false
|
||||
}
|
||||
session.clear()
|
||||
await router.push('/login')
|
||||
}
|
||||
|
||||
async function deleteRegistration() {
|
||||
try {
|
||||
await api.request('/v1/auth/register', {
|
||||
method: 'DELETE',
|
||||
onForbidden: 'passthrough',
|
||||
})
|
||||
cancelOutcome.value = 'cancelled'
|
||||
} catch (error) {
|
||||
if (error instanceof ApiError && error.status === 403) {
|
||||
await session.retry()
|
||||
cancelOutcome.value = 'alreadyVerified'
|
||||
return
|
||||
}
|
||||
throw new Error(
|
||||
"Couldn't cancel registration, so it's still pending. Try again in a moment.",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function cancelRegistration() {
|
||||
cancelOutcome.value = null
|
||||
const confirmed = await overlay
|
||||
.create(ConfirmDialog, {
|
||||
props: {
|
||||
title: 'Cancel your registration?',
|
||||
description:
|
||||
'Your account will be deleted. You can register again with the same or a different email.',
|
||||
confirmLabel: 'Cancel registration',
|
||||
cancelLabel: 'Keep my account',
|
||||
pendingLabel: 'Cancelling…',
|
||||
tone: 'danger',
|
||||
action: deleteRegistration,
|
||||
},
|
||||
})
|
||||
.open()
|
||||
|
||||
if (!confirmed) {
|
||||
return
|
||||
}
|
||||
|
||||
if (cancelOutcome.value === 'cancelled') {
|
||||
await router.push('/register')
|
||||
toast.add(registrationCancelledToast)
|
||||
return
|
||||
}
|
||||
|
||||
if (cancelOutcome.value === 'alreadyVerified') {
|
||||
await router.push('/home')
|
||||
toast.add({
|
||||
color: 'info',
|
||||
icon: 'i-lucide-info',
|
||||
title: 'Your account is already verified',
|
||||
description: "There's nothing to cancel.",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const actions = computed(() => [
|
||||
{
|
||||
label: 'Log out',
|
||||
color: 'neutral' as const,
|
||||
variant: 'outline' as const,
|
||||
disabled: loggingOut.value,
|
||||
onClick: logOut,
|
||||
},
|
||||
{
|
||||
label: 'Cancel registration',
|
||||
color: 'neutral' as const,
|
||||
variant: 'outline' as const,
|
||||
disabled: loggingOut.value,
|
||||
onClick: cancelRegistration,
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthShell title="Check your inbox">
|
||||
<p>Pending verification placeholder.</p>
|
||||
<AuthShell title="">
|
||||
<ResultPanel
|
||||
tone="success"
|
||||
icon="i-lucide-mail-check"
|
||||
title="Check your email"
|
||||
:description="description"
|
||||
:actions="actions"
|
||||
>
|
||||
<p class="text-toned text-sm">
|
||||
Opened it on another device? That works too; you'll log in there first. Can't find
|
||||
it? Check your spam folder. If the link has expired, cancel your registration and
|
||||
start again.
|
||||
</p>
|
||||
</ResultPanel>
|
||||
</AuthShell>
|
||||
</template>
|
||||
Reference in new issue
Block a user