Refactor DCA client registration form: Update wallet selection to use walletOptions computed property for better data handling. Change element ID from 'dcaClient' to 'vue' for consistency. Improve error handling and data validation in chart loading and registration processes.

This commit is contained in:
padreug 2025-06-27 00:28:49 +02:00
parent 306549a656
commit 03179647ec
2 changed files with 85 additions and 89 deletions

View file

@ -1,5 +1,5 @@
window.app = Vue.createApp({
el: '#dcaClient',
el: '#vue',
mixins: [windowMixin],
delimiters: ['${', '}'],
data: function () {
@ -88,7 +88,7 @@ window.app = Vue.createApp({
this.showRegistrationDialog = true
// Pre-fill username and default wallet if available
this.registrationForm.username = this.g.user.username || ''
this.registrationForm.selectedWallet = this.g.user.wallets[0] || null
this.registrationForm.selectedWallet = this.g.user.wallets[0]?.id || null
}
return data
@ -108,10 +108,16 @@ window.app = Vue.createApp({
username: this.registrationForm.username || this.g.user.username || `user_${this.g.user.id.substring(0, 8)}`
}
// Find the selected wallet object to get the adminkey
const selectedWallet = this.g.user.wallets.find(w => w.id === this.registrationForm.selectedWallet)
if (!selectedWallet) {
throw new Error('Selected wallet not found')
}
const { data } = await LNbits.api.request(
'POST',
'/satmachineclient/api/v1/register',
this.registrationForm.selectedWallet.adminkey,
selectedWallet.adminkey,
registrationData
)
@ -308,7 +314,7 @@ window.app = Vue.createApp({
this.dcaChart = null
}
const {data} = await LNbits.api.request(
const { data } = await LNbits.api.request(
'GET',
`/satmachineclient/api/v1/dashboard/analytics?time_range=${this.chartTimeRange}`,
this.g.user.wallets[0].adminkey
@ -463,7 +469,7 @@ window.app = Vue.createApp({
borderWidth: 2,
cornerRadius: 8,
callbacks: {
label: function(context) {
label: function (context) {
return `${context.parsed.y.toLocaleString()} sats`
}
}
@ -486,7 +492,7 @@ window.app = Vue.createApp({
ticks: {
color: '#666666',
font: { size: 12, weight: '500' },
callback: function(value) {
callback: function (value) {
return value.toLocaleString() + ' sats'
}
}
@ -530,8 +536,8 @@ window.app = Vue.createApp({
date = new Date(point.date);
// For display purposes, use the date part only to avoid timezone shifts
const localDateStr = date.getFullYear() + '-' +
String(date.getMonth() + 1).padStart(2, '0') + '-' +
String(date.getDate()).padStart(2, '0');
String(date.getMonth() + 1).padStart(2, '0') + '-' +
String(date.getDate()).padStart(2, '0');
date = new Date(localDateStr + 'T00:00:00'); // Force local midnight
} else {
date = new Date(point.date);
@ -662,7 +668,7 @@ window.app = Vue.createApp({
cornerRadius: 8,
displayColors: false,
callbacks: {
title: function(context) {
title: function (context) {
return `📅 ${context[0].label}`
},
label: function (context) {
@ -781,6 +787,14 @@ window.app = Vue.createApp({
computed: {
hasData() {
return this.dashboardData && !this.loading && this.isRegistered
},
walletOptions() {
if (!this.g.user?.wallets) return []
return this.g.user.wallets.map(wallet => ({
label: `${wallet.name} (${Math.round(wallet.balance_msat / 1000)} sats)`,
value: wallet.id
}))
}
},

View file

@ -7,7 +7,7 @@
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
<script src="{{ static_url_for('satmachineclient/static', path='js/index.js') }}"></script>
{% endblock %} {% block page %}
<div class="row q-col-gutter-md" id="dcaClient">
<div class="row q-col-gutter-md" id="vue">
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
<!-- Loading State -->
@ -542,49 +542,32 @@
label="Username (Optional)"
placeholder="Enter a friendly name"
hint="How you'd like to be identified in the system"
/>
></q-input>
<q-select
filled
dense
emit-value
v-model="registrationForm.selectedWallet"
:options="g.user.wallets"
option-label="name"
:options="walletOptions"
label="DCA Wallet *"
hint="Choose which wallet will receive your Bitcoin DCA purchases"
>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section>
<q-item-label>
${scope.opt.name} (ID: ${scope.opt.id.substring(0, 8)}... • ${Math.round(scope.opt.balance_msat / 1000)} sats)
</q-item-label>
</q-item-section>
</q-item>
</template>
</q-select>
></q-select>
<q-select
filled
dense
emit-value
v-model="registrationForm.dca_mode"
:options="[
{ label: 'Flow Mode (Recommended)', value: 'flow', description: 'Proportional distribution based on your balance' },
{ label: 'Fixed Mode', value: 'fixed', description: 'Set daily purchase limits' }
{ label: 'Flow Mode (Recommended)', value: 'flow' },
{ label: 'Fixed Mode', value: 'fixed' }
]"
option-label="label"
option-value="value"
label="DCA Strategy *"
hint="Choose how your Bitcoin purchases will be distributed"
>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section>
<q-item-label>${scope.opt.label} - ${scope.opt.description}</q-item-label>
</q-item-section>
</q-item>
</template>
</q-select>
></q-select>
<q-input
v-if="registrationForm.dca_mode === 'fixed'"
@ -598,7 +581,7 @@
:rules="[
val => registrationForm.dca_mode !== 'fixed' || (val && val > 0) || 'Daily limit is required for fixed mode'
]"
/>
></q-input>
<q-banner class="bg-blue-1 text-blue-9 q-mt-md">
<template v-slot:avatar>
@ -619,8 +602,7 @@
class="full-width"
size="lg"
>
<q-icon name="rocket_launch" class="q-mr-sm" />
Start My DCA Journey
🚀 Start My DCA Journey
</q-btn>
</div>
</q-form>