Complete OnboardingDialog.vue Enhanced Triple Migration Pattern (3.5 minutes)

• Database Migration: Replace databaseUtil with PlatformServiceMixin methods
• SQL Abstraction: Replace raw SQL with $getAllContacts() and $accountSettings()
• Template Streamlining: Add 5 computed properties for consistent styling
• Vue Syntax Fix: Correct vue-facing-decorator mixin and computed property syntax

Migration Details:
- Removed: databaseUtil imports and PlatformServiceFactory usage
- Added: PlatformServiceMixin with $accountSettings(), $getAllContacts(), $updateSettings()
- Created: 5 computed properties (primaryButtonClasses, secondaryButtonClasses, etc.)
- Fixed: Proper @Component mixin declaration and class getter syntax
- Quality: Zero linting errors, full TypeScript compliance

Component provides 3-page onboarding flow (Home, Discover, Create) with
dynamic content based on user registration and contact status.
Ready for human testing across all platforms.
This commit is contained in:
Matthew Raymer
2025-07-08 02:32:15 +00:00
parent 071a3c59ce
commit 7d0486a4cf
6 changed files with 343 additions and 112 deletions

View File

@@ -1,6 +1,6 @@
<template>
<QuickNav selected="Contacts" />
<section class="p-6 pb-24 max-w-3xl mx-auto">
<!-- Header -->
<div class="mb-8">
@@ -10,7 +10,7 @@
>
<font-awesome icon="chevron-left" class="fa-fw" />
</router-link>
<h1 class="text-4xl text-center font-light pt-4">
Transferred with {{ contact?.name }}
</h1>
@@ -19,11 +19,15 @@
<!-- Info Messages -->
<div class="text-center text-sm text-slate-600 mb-6 space-y-1">
<p>(Only 50 most recent)</p>
<p>(This does not include claims by them if they're not visible to you.)</p>
<p>
(This does not include claims by them if they're not visible to you.)
</p>
</div>
<!-- Transfer History Table -->
<table class="table-auto w-full border-t border-slate-300 text-sm sm:text-base text-center">
<table
class="table-auto w-full border-t border-slate-300 text-sm sm:text-base text-center"
>
<thead class="bg-slate-100">
<tr class="border-b border-slate-300">
<th class="px-1 py-2">Date</th>
@@ -42,7 +46,7 @@
<td class="p-1 text-xs sm:text-sm text-left text-slate-500">
{{ new Date(record.issuedAt).toLocaleString() }}
</td>
<!-- From Them -->
<td class="p-1">
<div v-if="record.agentDid === contact?.did">
@@ -54,11 +58,7 @@
class="text-green-600 fa-fw"
title="Confirmed"
/>
<button
v-else
@click="confirm(record)"
title="Unconfirmed"
>
<button v-else title="Unconfirmed" @click="confirm(record)">
<font-awesome icon="circle" class="text-blue-600 fa-fw" />
</button>
</div>
@@ -67,15 +67,17 @@
</div>
</div>
</td>
<!-- Direction Arrow -->
<td class="p-1">
<font-awesome
:icon="record.agentDid === contact?.did ? 'arrow-left' : 'arrow-right'"
:icon="
record.agentDid === contact?.did ? 'arrow-left' : 'arrow-right'
"
class="text-slate-400 fa-fw"
/>
</td>
<!-- To Them -->
<td class="p-1">
<div v-if="record.agentDid !== contact?.did">
@@ -89,8 +91,8 @@
/>
<button
v-else
@click="cannotConfirmMessage()"
title="Unconfirmed"
@click="cannotConfirmMessage()"
>
<font-awesome icon="circle" class="text-slate-600 fa-fw" />
</button>
@@ -116,10 +118,10 @@ import QuickNav from "../components/QuickNav.vue";
import { NotificationIface } from "../constants/app";
import { PlatformServiceMixin } from "../utils/PlatformServiceMixin";
import { createNotifyHelpers, TIMEOUTS } from "../utils/notify";
import {
import {
NOTIFY_SETTINGS_RETRIEVAL_ERROR,
NOTIFY_SERVER_RETRIEVAL_ERROR,
NOTIFY_CONFIRMATION_RESTRICTION
NOTIFY_CONFIRMATION_RESTRICTION,
} from "../constants/notifications";
import { Contact } from "../db/tables/contacts";
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
@@ -164,7 +166,7 @@ import { retrieveAccountCount } from "../libs/util";
* - Unconfirmed: Transfer pending confirmation
* - Cannot Confirm: User is not the recipient of the transfer
*/
@Component({
@Component({
components: { QuickNav },
mixins: [PlatformServiceMixin],
})
@@ -215,7 +217,7 @@ export default class ContactAmountssView extends Vue {
*/
async created() {
this.notify = createNotifyHelpers(this.$notify);
try {
const contactDid = this.$route.query["contactDid"] as string;
const contact = await this.$getContact(contactDid);
@@ -232,9 +234,8 @@ export default class ContactAmountssView extends Vue {
} catch (err: any) {
await this.$logError("Error retrieving settings or gives.");
this.notify.error(
err.userMessage ||
NOTIFY_SETTINGS_RETRIEVAL_ERROR.message,
TIMEOUTS.LONG
err.userMessage || NOTIFY_SETTINGS_RETRIEVAL_ERROR.message,
TIMEOUTS.LONG,
);
}
}
@@ -265,12 +266,9 @@ export default class ContactAmountssView extends Vue {
result = resp.data.data;
} else {
await this.$logError(
`Got bad response status & data of ${resp.status} ${JSON.stringify(resp.data)}`
);
this.notify.error(
NOTIFY_SERVER_RETRIEVAL_ERROR.message,
TIMEOUTS.LONG
`Got bad response status & data of ${resp.status} ${JSON.stringify(resp.data)}`,
);
this.notify.error(NOTIFY_SERVER_RETRIEVAL_ERROR.message, TIMEOUTS.LONG);
}
const url2 =
@@ -285,12 +283,9 @@ export default class ContactAmountssView extends Vue {
result = R.concat(result, resp2.data.data);
} else {
await this.$logError(
`Got bad response status & data of ${resp2.status} ${JSON.stringify(resp2.data)}`
);
this.notify.error(
NOTIFY_SERVER_RETRIEVAL_ERROR.message,
TIMEOUTS.LONG
`Got bad response status & data of ${resp2.status} ${JSON.stringify(resp2.data)}`,
);
this.notify.error(NOTIFY_SERVER_RETRIEVAL_ERROR.message, TIMEOUTS.LONG);
}
const sortedResult: Array<GiveSummaryRecord> = R.sort(
@@ -300,10 +295,7 @@ export default class ContactAmountssView extends Vue {
);
this.giveRecords = sortedResult;
} catch (error) {
this.notify.error(
error as string,
TIMEOUTS.LONG
);
this.notify.error(error as string, TIMEOUTS.LONG);
}
}
@@ -361,10 +353,7 @@ export default class ContactAmountssView extends Vue {
userMessage = error as string;
}
// Now set that error for the user to see.
this.notify.error(
userMessage,
TIMEOUTS.LONG
);
this.notify.error(userMessage, TIMEOUTS.LONG);
}
}
@@ -380,7 +369,7 @@ export default class ContactAmountssView extends Vue {
cannotConfirmMessage() {
this.notify.error(
NOTIFY_CONFIRMATION_RESTRICTION.message,
TIMEOUTS.STANDARD
TIMEOUTS.STANDARD,
);
}
}