mod-portal-v2/app/pages/welcome/index.vue
2026-08-05 06:36:58 +02:00

163 lines
No EOL
5.3 KiB
Vue

<script setup>
import { ref, onMounted } from 'vue'
const route = useRoute()
const { userToken, isAuthenticated, initializeAuth } = useAuth()
const sfidInput = ref('')
const step = ref(1)
const foundUser = ref(null)
const isSearching = ref(false)
const isSubmitting = ref(false)
const errorMessage = ref('')
onMounted(async () => {
const isReady = await initializeAuth({ redirectTo: '/oauth', replace: true })
if (!isReady) {
return
}
if (!isAuthenticated.value) {
await navigateTo('/oauth', { replace: true })
return
}
if (route.query.redirect === 'home') {
await navigateTo('/', { replace: true })
}
})
const handleLookup = async () => {
if (!sfidInput.value.trim()) return
isSearching.value = true
errorMessage.value = ''
try {
const res = await $fetch('/api/user/lookup-nnas', {
method: 'POST',
body: { sfid: sfidInput.value }
})
foundUser.value = res
step.value = 2
} catch (err) {
errorMessage.value = err.data?.statusMessage || err.data?.message || 'Failed to locate user account.'
} finally {
isSearching.value = false
}
}
const handleConfirm = async () => {
if (!foundUser.value) return
isSubmitting.value = true
errorMessage.value = ''
try {
await $fetch('/api/user/complete-welcome', {
method: 'POST',
body: {
token: userToken.value,
sfid: foundUser.value.username
}
})
await navigateTo('/')
} catch (err) {
errorMessage.value = err.data?.statusMessage || err.data?.message || 'Failed to complete setup.'
} finally {
isSubmitting.value = false
}
}
const handleReset = () => {
step.value = 1
foundUser.value = null
errorMessage.value = ''
}
</script>
<template>
<div v-if="isAuthenticated" class="login-wrapper">
<section class="settings-panel" style="max-width: 480px; margin: 0 auto;">
<div class="panel-header archivo-black">
WELCOME
</div>
<div v-if="step === 1" class="panel-body" style="padding: 2rem; text-align: center;">
<img src="/welcome5-1.png" alt="Welcome Image"
style="max-width: 160px; margin-bottom: 1rem; object-fit: contain;" />
<h2 style="font-size: 1.25rem; font-weight: 600; margin-bottom: 0.5rem;">
First Time Setup
</h2>
<p style="color: #8b949e; font-size: 0.9rem; margin-bottom: 1.5rem; line-height: 1.4;">
Please enter your SFID to link your account. This wont be used for login.
</p>
<form @submit.prevent="handleLookup">
<div style="margin-bottom: 1.25rem; text-align: left;">
<label for="sfid" style="display: block; font-size: 0.85rem; color: #c9d1d9; margin-bottom: 0.5rem;">
SFID <span style="color: #f85149;">*</span>
</label>
<input id="sfid" v-model="sfidInput" type="text" placeholder="e.g. redbinderischud" required
style="width: 100%; padding: 0.6rem 0.8rem; background: #0d1117; border: 1px solid #30363d; border-radius: 6px; color: #c9d1d9; font-size: 0.95rem; outline: none;" />
</div>
<p v-if="errorMessage" style="color: #f85149; font-size: 0.85rem; margin-bottom: 1rem;">
{{ errorMessage }}
</p>
<button type="submit" class="btn-login-action" style="width: 100%;" :disabled="isSearching">
<span v-if="isSearching" class="spinner sm btn-spinner"></span>
<span style="vertical-align: middle;">
{{ isSearching ? 'Looking up...' : 'Find Account →' }}
</span>
</button>
</form>
</div>
<div v-else class="panel-body" style="padding: 2rem; text-align: center;">
<h2 style="font-size: 1.25rem; font-weight: 600; margin-bottom: 1.5rem;">
Is this you?
</h2>
<div
style="background: #0d1117; border: 1px solid #30363d; border-radius: 8px; padding: 1.5rem; margin-bottom: 1.5rem;">
<img :src="`https://mii.spfn.net/${foundUser.pid}/main.png`" :alt="foundUser.username"
style="width: 96px; height: 96px; border-radius: 50%; background: #161b22; object-fit: contain; margin-bottom: 0.75rem;"
@error="(e) => e.target.src = '/img_unknown_MiiIcon.png'" />
<div style="font-size: 1.1rem; font-weight: 600; color: #f0f6fc;">
{{ foundUser.username }}
</div>
<div style="font-size: 0.8rem; color: #8b949e; margin-top: 0.25rem;">
PID: {{ foundUser.pid }}
</div>
</div>
<p v-if="errorMessage" style="color: #f85149; font-size: 0.85rem; margin-bottom: 1rem;">
{{ errorMessage }}
</p>
<div style="display: flex; gap: 0.75rem;">
<button type="button"
style="flex: 1; padding: 0.6rem; background: #21262d; border: 1px solid #30363d; border-radius: 6px; color: #c9d1d9; font-weight: 500; cursor: pointer;"
:disabled="isSubmitting" @click="handleReset">
Not Me
</button>
<button type="button" class="btn-login-action" style="flex: 1;" :disabled="isSubmitting"
@click="handleConfirm">
<span v-if="isSubmitting" class="spinner sm btn-spinner"></span>
<span style="vertical-align: middle;">
{{ isSubmitting ? 'Linking...' : 'Yes, That\'s Me!' }}
</span>
</button>
</div>
</div>
</section>
</div>
</template>