Add in Pino logging and make UI consistent across the app.
This commit is contained in:
parent
727746030c
commit
300040bd58
19 changed files with 590 additions and 235 deletions
|
@ -10,12 +10,13 @@
|
|||
clickable
|
||||
v-ripple
|
||||
@click="toggleLeftDrawer"
|
||||
class="relative"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="menu" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label class="text-h6">
|
||||
<q-item-section v-if="leftDrawerOpen">
|
||||
<q-item-label class="text-h4 absolute-center">
|
||||
StylePoint
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
|
@ -28,6 +29,20 @@
|
|||
class="q-ma-sm text-center relative"
|
||||
>
|
||||
<q-card-section>
|
||||
<q-btn
|
||||
class="absolute"
|
||||
style="top: 10px; left: 10px;"
|
||||
flat
|
||||
round
|
||||
:to="{ name: 'passkeys' }"
|
||||
>
|
||||
<q-icon
|
||||
name="key"
|
||||
/>
|
||||
<q-tooltip>
|
||||
Passkey Management
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
class="absolute"
|
||||
style="top: 10px; right: 10px;"
|
||||
|
@ -36,16 +51,16 @@
|
|||
:to="{ name: 'userPreferences' }"
|
||||
>
|
||||
<q-icon
|
||||
name="settings"
|
||||
name="mdi-account-cog"
|
||||
/>
|
||||
<q-tooltip>
|
||||
User Preferences
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-avatar
|
||||
class="bg-primary cursor-pointer text-white"
|
||||
>
|
||||
<q-icon name="mdi-account" />
|
||||
<q-tooltip>
|
||||
{{ authStore.user.username }}
|
||||
</q-tooltip>
|
||||
</q-avatar>
|
||||
<div class="text-h6">
|
||||
{{ authStore.user.username }}
|
||||
|
@ -65,6 +80,50 @@
|
|||
class="menu-list"
|
||||
v-else
|
||||
>
|
||||
<q-item
|
||||
clickable
|
||||
v-ripple
|
||||
dense
|
||||
:to="{ name: 'passkeys' }"
|
||||
class="q-mb-sm"
|
||||
>
|
||||
<q-tooltip
|
||||
anchor="center right"
|
||||
self="center left"
|
||||
>
|
||||
<span>Passkey Management</span>
|
||||
</q-tooltip>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="key" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label class="text-h6">
|
||||
Passkey Management
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
clickable
|
||||
v-ripple
|
||||
dense
|
||||
:to="{ name: 'userPreferences' }"
|
||||
class="q-mb-sm"
|
||||
>
|
||||
<q-tooltip
|
||||
anchor="center right"
|
||||
self="center left"
|
||||
>
|
||||
<span>User Preferences</span>
|
||||
</q-tooltip>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-account-cog" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label class="text-h6">
|
||||
User Preferences
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
clickable
|
||||
v-ripple
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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..?'
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(() =>
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -40,7 +40,6 @@ const routes = [
|
|||
component: () => import('pages/PasskeyManagementPage.vue'), // Assuming this page exists or will be created
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
navGroup: 'auth', // Show only when logged in
|
||||
icon: 'key',
|
||||
title: 'Passkeys',
|
||||
caption: 'Manage your passkeys'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue