Dynavera/site/src/views/InviteAccept.vue

93 lines
2.5 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Card, Button, Spin, message, Result } from 'ant-design-vue'
import { apiClient, isAxiosError, API } from '../router/api'
const route = useRoute()
const router = useRouter()
const token = route.params.token as string
const loading = ref(false)
const accepting = ref(false)
const accepted = ref(false)
const error = ref<string | null>(null)
const acceptInvite = async () => {
accepting.value = true
error.value = null
try {
const response = await apiClient.post<{ message: string; success: boolean; uuid: string }>(
API.organizationJoin(token),
)
message.success(response.data?.message || 'Successfully joined organization')
accepted.value = true
setTimeout(() => {
if (response.data?.uuid) router.push(`/organization/${response.data.uuid}`)
else router.push('/')
}, 1500)
} catch (err) {
console.error('Failed to accept invite:', err)
if (isAxiosError(err)) {
const respErr = err.response?.data?.error || err.response?.data?.detail
error.value = respErr ? String(respErr) : 'Failed to accept invite'
} else {
error.value = 'Failed to accept invite'
}
} finally {
accepting.value = false
}
}
onMounted(() => {
acceptInvite()
})
</script>
<template>
<div class="page">
<Spin :spinning="loading" tip="Loading invite...">
<Card class="panel" :bordered="false">
<div v-if="error">
<Result status="error" :title="error">
<template #extra>
<Button type="primary" @click="router.push('/')">Go Home</Button>
</template>
</Result>
</div>
<div v-else-if="accepted">
<Result
status="success"
title="Successfully Joined Organization"
sub-title="Redirecting to organization page..."
/>
</div>
</Card>
</Spin>
</div>
</template>
<style scoped>
.page {
max-width: 800px;
padding: 2rem 1rem;
}
.invite-content {
text-align: center;
padding: 2rem;
}
.org-info {
background: #1f2937;
border-radius: 8px;
padding: 1.5rem;
margin: 2rem 0;
}
.actions {
margin-top: 2rem;
}
</style>