feat: refine account connections & update nuxt
Some checks failed
Build and Publish Docker Image / Build and Publish (amd64) (push) Has been cancelled
Build and Publish Docker Image / Build and Publish (arm64) (push) Has been cancelled

This commit is contained in:
niko 2025-11-11 17:53:22 -05:00
parent 0f5da1dba1
commit b9dcac0061
No known key found for this signature in database
GPG Key ID: C3B29CF2BA3406AD
4 changed files with 3592 additions and 1301 deletions

4807
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
"discord-oauth2": "^2.12.1",
"eslint": "^9.24.0",
"feed": "^4.2.2",
"nuxt": "^3.16.2",
"nuxt": "^3.17.4",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},

View File

@ -1,4 +1,6 @@
<script setup lang="ts">
import { FetchError } from 'ofetch';
interface InfoCCResponse {
username: string;
access_level: number;
@ -31,32 +33,49 @@ interface DiscordInfoResponse {
const route = useRoute();
const router = useRouter();
const account = await useFetch<InfoCCResponse>('/api/account/info'); // TODO: easy way to share this between navbar and account page? is that a good idea?
const showingEditingDisabledModal = ref(false);
if (route.params.connection) { // my nightmares are made of this logic
if (import.meta.server) {
switch (route.params.connection) { // future proofing for more connections?
case 'discord': {
if (route.query.code) {
await useFetch('/api/account/connections/discord/add', {
const errorMessage = useState<string | null>('errorMsg');
const successMessage = useState<string | null>('successMsg');
await callOnce(async () => {
const headers = useRequestHeaders(['cookie']);
switch (route.params.connection) { // future proofing for more connections?
case 'discord': {
if (typeof route.query.code == 'string') {
try {
await $fetch('/api/account/connections/discord/add', {
method: 'POST',
body: {
code: route.query.code
}
},
headers
});
}
break;
}
default:
break;
}
}
router.replace('/account');
}
const discordInfo = await useFetch<DiscordInfoResponse>('/api/account/connections/discord/info');
successMessage.value = 'Successfully connected to Discord'; // TODO: replace this toast + localize
} catch (error: unknown) {
if (error instanceof FetchError) {
if (error.statusText) {
errorMessage.value = error.statusText;
}
} else {
errorMessage.value = `Error during registration: ${error}`; // TODO: localize
}
}
}
break;
}
default:
break;
}
});
router.replace('/account'); // always smash the query parameters when we're done with them
const discordInfo = await useFetch<DiscordInfoResponse>('/api/account/connections/discord/info'); // lazy to prevent scrollbar from snapping
const account = await useFetch<InfoCCResponse>('/api/account/info'); // TODO: easy way to share this between navbar and account page? is that a good idea?
async function handleUnlinkDiscord() {
try {
@ -406,9 +425,11 @@ async function handleUnlinkDiscord() {
</div>
</div>
</div>
<div
v-if="showingEditingDisabledModal"
id="edit-settings"
:class="`modal-wrapper${showingEditingDisabledModal ? '' : ' hidden'}`"
class="modal-wrapper"
>
<div class="modal">
<h1 class="title dot">
@ -428,6 +449,24 @@ async function handleUnlinkDiscord() {
</div>
</div>
</div>
<div
v-if="errorMessage"
class="banner-notice error"
>
<div>
<p>{{ errorMessage }}</p>
</div>
</div>
<div
v-if="successMessage"
class="banner-notice success"
>
<div>
<p>{{ successMessage }}</p>
</div>
</div>
</div>
</template>
@ -701,7 +740,8 @@ fieldset {
.banner-notice {
display: flex;
justify-content: center;
position: fixed;
position: absolute;
left: 0;
top: -150px;
width: 100%;
animation: banner-notice 5s;

View File

@ -33,7 +33,9 @@ export default defineEventHandler(async (event) => {
}
});
return { success: true }; // TODO: figure out why $fetch doesn't send cookies but useFetch does so this dumb fix can be removed
event.node.res.end();
return;
} catch (error: unknown) {
console.log(error);
if (error instanceof FetchError) {