koel/resources/assets/js/components/invitation/AcceptInvitation.vue

135 lines
3.1 KiB
Vue
Raw Normal View History

2023-08-20 22:35:58 +00:00
<template>
<div class="invitation-wrapper">
<form v-if="userProspect" autocomplete="off" @submit.prevent="submit">
<header>
Welcome to Koel! To accept the invitation, fill in the form below and click that button.
</header>
<div class="form-row">
<label>
Your email
<input type="text" :value="userProspect.email" disabled>
</label>
</div>
<div class="form-row">
<label>
Your name
2024-02-25 19:32:53 +00:00
<input
v-model="name"
v-koel-focus
data-testid="name"
placeholder="Erm… Bruce Dickinson?"
required
type="text"
>
2023-08-20 22:35:58 +00:00
</label>
</div>
<div class="form-row">
<label>
Password
2024-02-25 19:32:53 +00:00
<PasswordField v-model="password" data-testid="password" required />
2023-08-20 22:35:58 +00:00
<small>Min. 10 characters. Should be a mix of characters, numbers, and symbols.</small>
</label>
</div>
<div class="form-row">
2024-02-25 19:32:53 +00:00
<Btn type="submit" :disabled="loading">Accept &amp; Log In</Btn>
2023-08-20 22:35:58 +00:00
</div>
</form>
<p v-if="!validToken">Invalid or expired invite.</p>
</div>
</template>
<script setup lang="ts">
2024-02-25 19:32:53 +00:00
import { onMounted, ref } from 'vue'
2023-08-20 22:35:58 +00:00
import { invitationService } from '@/services'
import { useDialogBox, useRouter } from '@/composables'
import Btn from '@/components/ui/Btn.vue'
import PasswordField from '@/components/ui/PasswordField.vue'
import { parseValidationError } from '@/utils'
const { showErrorDialog } = useDialogBox()
const { getRouteParam, go } = useRouter()
2024-02-25 19:32:53 +00:00
const name = ref('')
const password = ref('')
2023-08-20 22:35:58 +00:00
const userProspect = ref<User>()
const validToken = ref(true)
2024-02-25 19:32:53 +00:00
const loading = ref(false)
2023-08-20 22:35:58 +00:00
const token = String(getRouteParam('token')!)
const submit = async () => {
try {
2024-02-25 19:32:53 +00:00
loading.value = true
await invitationService.accept(token, name.value, password.value)
2023-08-20 22:35:58 +00:00
window.location.href = '/'
} catch (err: any) {
const msg = err.response.status === 422 ? parseValidationError(err.response.data)[0] : 'Unknown error.'
showErrorDialog(msg, 'Error')
2024-02-25 19:32:53 +00:00
} finally {
loading.value = false
2023-08-20 22:35:58 +00:00
}
}
onMounted(async () => {
try {
userProspect.value = await invitationService.getUserProspect(token)
} catch (err: any) {
2024-02-25 19:32:53 +00:00
if (err.response?.status === 404) {
2023-08-20 22:35:58 +00:00
validToken.value = false
return
}
2024-02-25 19:32:53 +00:00
const msg = err.response?.status === 422 ? parseValidationError(err.response?.data)[0] : 'Unknown error.'
2023-08-20 22:35:58 +00:00
showErrorDialog(msg, 'Error')
}
})
</script>
<style scoped lang="scss">
.invitation-wrapper {
@include vertical-center();
display: flex;
height: 100vh;
flex-direction: column;
justify-content: center;
}
header {
margin-bottom: 1.2rem;
}
small {
margin-top: .8rem;
font-size: .9rem;
display: block;
line-height: 1.4;
color: var(--color-text-secondary);
}
form {
width: 320px;
padding: 1.8rem;
background: rgba(255, 255, 255, .08);
border-radius: .6rem;
display: flex;
flex-direction: column;
input {
width: 100%;
}
@media only screen and (max-width: 414px) {
border: 0;
background: transparent;
}
}
</style>