Add in Pino logging and make UI consistent across the app.

This commit is contained in:
Cameron Redmore 2025-04-25 19:34:17 +01:00
parent 727746030c
commit 300040bd58
19 changed files with 590 additions and 235 deletions

View file

@ -1,96 +1,100 @@
<template>
<q-page padding>
<div class="q-mb-md row justify-between items-center">
<div class="text-h4">
Forms
</div>
<q-btn
outline
label="Create New Form"
color="primary"
:to="{ name: 'formCreate' }"
/>
</div>
<q-list
<q-card
flat
bordered
separator
v-if="forms.length > 0"
>
<q-item
v-for="form in forms"
:key="form.id"
>
<q-item-section>
<q-item-label>{{ form.title }}</q-item-label>
<q-item-label caption>
{{ form.description || 'No description' }}
</q-item-label>
<q-item-label caption>
Created: {{ formatDate(form.createdAt) }}
</q-item-label>
</q-item-section>
<q-item-section side>
<div class="q-gutter-sm">
<q-btn
flat
round
dense
icon="edit_note"
color="info"
:to="{ name: 'formFill', params: { id: form.id } }"
title="Fill Form"
/>
<q-btn
flat
round
dense
icon="visibility"
color="secondary"
:to="{ name: 'formResponses', params: { id: form.id } }"
title="View Responses"
/>
<q-btn
flat
round
dense
icon="edit"
color="warning"
:to="{ name: 'formEdit', params: { id: form.id } }"
title="Edit Form"
/>
<q-btn
flat
round
dense
icon="delete"
color="negative"
@click.stop="confirmDeleteForm(form.id)"
title="Delete Form"
/>
</div>
</q-item-section>
</q-item>
</q-list>
<q-banner
v-else
class="bg-info text-white"
>
<template #avatar>
<q-icon
name="info"
color="white"
<q-card-section class="row items-center justify-between">
<div class="text-h4">
Forms
</div>
<q-btn
label="Create New Form"
color="primary"
:to="{ name: 'formCreate' }"
/>
</template>
No forms created yet. Click the button above to create your first form.
</q-banner>
</q-card-section>
<q-inner-loading :showing="loading">
<q-spinner-gears
size="50px"
color="primary"
/>
</q-inner-loading>
<q-list
bordered
separator
v-if="forms.length > 0"
>
<q-item
v-for="form in forms"
:key="form.id"
>
<q-item-section>
<q-item-label>{{ form.title }}</q-item-label>
<q-item-label caption>
{{ form.description || 'No description' }}
</q-item-label>
<q-item-label caption>
Created: {{ formatDate(form.createdAt) }}
</q-item-label>
</q-item-section>
<q-item-section side>
<div class="q-gutter-sm">
<q-btn
flat
round
dense
icon="edit_note"
color="info"
:to="{ name: 'formFill', params: { id: form.id } }"
title="Fill Form"
/>
<q-btn
flat
round
dense
icon="visibility"
color="secondary"
:to="{ name: 'formResponses', params: { id: form.id } }"
title="View Responses"
/>
<q-btn
flat
round
dense
icon="edit"
color="warning"
:to="{ name: 'formEdit', params: { id: form.id } }"
title="Edit Form"
/>
<q-btn
flat
round
dense
icon="delete"
color="negative"
@click.stop="confirmDeleteForm(form.id)"
title="Delete Form"
/>
</div>
</q-item-section>
</q-item>
</q-list>
<q-banner
v-else
class="bg-info text-white"
>
<template #avatar>
<q-icon
name="info"
color="white"
/>
</template>
No forms created yet. Click the button above to create your first form.
</q-banner>
<q-inner-loading :showing="loading">
<q-spinner-gears
size="50px"
color="primary"
/>
</q-inner-loading>
</q-card>
</q-page>
</template>

View file

@ -45,7 +45,7 @@ const $q = useQuasar();
const currentYear = ref(new Date().getFullYear());
const features = ref([
'Auatomated Daily Reports',
'Automated Daily Reports',
'Deep Mantis Integration',
'Easy Authentication',
'And more..?'

View file

@ -80,12 +80,10 @@ async function handleLogin()
if (verificationRes.data.verified)
{
// Update the auth store on successful login
authStore.isAuthenticated = true;
authStore.user = verificationRes.data.user;
authStore.error = null; // Clear any previous errors
console.log('Login successful:', verificationRes.data.user);
router.push('/'); // Redirect to home page
authStore.error = null;
router.push('/');
}
else
{

View file

@ -5,7 +5,7 @@
bordered
>
<q-card-section class="row items-center justify-between">
<div class="text-h6">
<div class="text-h4">
Mantis Summaries
</div>
<q-btn

View file

@ -1,122 +1,143 @@
<template>
<q-page padding>
<div class="q-mb-md row justify-between items-center">
<div class="text-h4">
Passkey Management
</div>
<div>
<q-btn
label="Identify Passkey"
color="secondary"
class="q-mx-md q-mt-md"
@click="handleIdentify"
:loading="identifyLoading"
:disable="identifyLoading || !isLoggedIn"
outline
/>
<q-btn
label="Register New Passkey"
color="primary"
class="q-mx-md q-mt-md"
@click="handleRegister"
:loading="registerLoading"
:disable="registerLoading || !isLoggedIn"
outline
/>
</div>
</div>
<q-card
bordered
flat
>
<q-card-section class="row items-center justify-between">
<div class="text-h4">
Passkey Management
</div>
<div>
<q-btn
label="Identify Passkey"
color="secondary"
class="q-mx-md"
@click="handleIdentify"
:loading="identifyLoading"
:disable="identifyLoading || !isLoggedIn"
/>
<q-btn
label="Register New Passkey"
color="primary"
@click="handleRegister"
:loading="registerLoading"
:disable="registerLoading || !isLoggedIn"
/>
</div>
</q-card-section>
<q-card-section>
<h5>Your Registered Passkeys</h5>
<q-list
bordered
separator
v-if="passkeys.length > 0 && !fetchLoading"
>
<q-item v-if="registerSuccessMessage || registerErrorMessage">
<div
v-if="registerSuccessMessage"
class="text-positive q-mt-md"
>
{{ registerSuccessMessage }}
</div>
<div
v-if="registerErrorMessage"
class="text-negative q-mt-md"
>
{{ registerErrorMessage }}
</div>
</q-item>
<q-item
v-for="passkey in passkeys"
:key="passkey.credentialID"
:class="{ 'bg-info text-h6': identifiedPasskeyId === passkey.credentialID }"
<q-separator />
<q-card-section>
<div class="text-h6 q-mb-sm">
Registered Passkeys
</div>
<!-- Display registration messages above the grid -->
<div
v-if="registerSuccessMessage"
class="text-positive q-mb-md"
>
<q-item-section>
<q-item-label>Passkey ID: {{ passkey.credentialID }} </q-item-label>
<q-item-label
caption
v-if="identifiedPasskeyId === passkey.credentialID"
>
Verified just now!
</q-item-label>
</q-item-section>
{{ registerSuccessMessage }}
</div>
<div
v-if="registerErrorMessage"
class="text-negative q-mb-md"
>
{{ registerErrorMessage }}
</div>
<q-item-section
side
class="row no-wrap items-center"
<!-- Responsive Grid for Passkeys -->
<div
v-if="passkeys.length > 0 && !fetchLoading"
class="row q-col-gutter-md justify-center align-center"
>
<div
v-for="passkey in passkeys"
:key="passkey.credentialID"
class="col-12 col-sm-6 col-md-4 col-lg-3"
>
<q-btn
<q-card
bordered
flat
dense
round
color="negative"
icon="delete"
@click="handleDelete(passkey.credentialID)"
:loading="deleteLoading === passkey.credentialID"
:disable="!!deleteLoading || !!identifyLoading"
/>
</q-item-section>
</q-item>
</q-list>
<div
v-else-if="fetchLoading"
class="q-mt-md"
>
Loading passkeys...
</div>
<div
v-else
class="q-mt-md"
>
You have no passkeys registered yet.
</div>
:class="{ 'bg-info': identifiedPasskeyId === passkey.credentialID }"
>
<q-card-section>
<div class="text-subtitle2 ellipsis">
Passkey ID:
<q-tooltip>{{ passkey.credentialID }}</q-tooltip>
</div>
<div class="text-caption ellipsis">
{{ passkey.credentialID }}
</div>
<q-item-label
caption
class="text-positive"
v-if="identifiedPasskeyId === passkey.credentialID"
>
Verified just now!
</q-item-label>
</q-card-section>
<div
v-if="fetchErrorMessage"
class="text-negative q-mt-md"
>
{{ fetchErrorMessage }}
</div>
<div
v-if="deleteSuccessMessage"
class="text-positive q-mt-md"
>
{{ deleteSuccessMessage }}
</div>
<div
v-if="deleteErrorMessage"
class="text-negative q-mt-md"
>
{{ deleteErrorMessage }}
</div>
<div
v-if="identifyErrorMessage"
class="text-negative q-mt-md"
>
{{ identifyErrorMessage }}
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn
flat
dense
round
color="negative"
icon="delete"
@click="handleDelete(passkey.credentialID)"
:loading="deleteLoading === passkey.credentialID"
:disable="!!deleteLoading || !!identifyLoading"
>
<q-tooltip>Delete Passkey</q-tooltip>
</q-btn>
</q-card-actions>
</q-card>
</div>
</div>
<div
v-else-if="fetchLoading"
class="q-mt-md"
>
Loading passkeys...
</div>
<div
v-else
class="q-mt-md"
>
You have no passkeys registered yet.
</div>
<div
v-if="fetchErrorMessage"
class="text-negative q-mt-md"
>
{{ fetchErrorMessage }}
</div>
<div
v-if="deleteSuccessMessage"
class="text-positive q-mt-md"
>
{{ deleteSuccessMessage }}
</div>
<div
v-if="deleteErrorMessage"
class="text-negative q-mt-md"
>
{{ deleteErrorMessage }}
</div>
<div
v-if="identifyErrorMessage"
class="text-negative q-mt-md"
>
{{ identifyErrorMessage }}
</div>
</q-card-section>
</q-card>
</q-page>
</template>
@ -341,7 +362,6 @@ async function handleIdentify()
const authResp = await startAuthentication(options);
identifiedPasskeyId.value = authResp.id;
console.log('Identified Passkey ID:', identifiedPasskeyId.value);
setTimeout(() =>
{

View file

@ -1,8 +1,11 @@
<template>
<q-page padding>
<q-card class="q-mb-md">
<q-card-section>
<div class="text-h6">
<q-card
bordered
flat
>
<q-card-section class="row items-center justify-between">
<div class="text-h4">
Application Settings
</div>
</q-card-section>

View file

@ -1,8 +1,11 @@
<template>
<q-page padding>
<q-card class="q-mb-md">
<q-card
flat
bordered
>
<q-card-section>
<div class="text-h6">
<div class="text-h4">
User Preferences
</div>
</q-card-section>