From f779d000b481f30d7affcab4e6c1d825e3dfb393 Mon Sep 17 00:00:00 2001 From: padreug Date: Sun, 22 Jun 2025 13:07:23 +0200 Subject: [PATCH] Update client API and frontend for DCA dashboard: Modify API endpoints to correctly reference wallet user, enhance Vue.js component with loading and error states, and implement data fetching for dashboard summary and transactions. Update HTML template to reflect new client extension structure and improve user experience with dynamic content rendering. --- static/js/index.js | 66 ++++++++++++---- templates/satmachineclient/index.html | 106 +++++++++++++++++++++++++- views_api.py | 10 +-- 3 files changed, 162 insertions(+), 20 deletions(-) diff --git a/static/js/index.js b/static/js/index.js index cf2dd8d..c777980 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,25 +1,25 @@ window.app = Vue.createApp({ - el: '#vue', mixins: [windowMixin], delimiters: ['${', '}'], - data: function () { + data() { return { + dashboardData: null, + transactions: [], + analytics: null, + loading: true, + error: null } }, - /////////////////////////////////////////////////// - ////////////////METHODS FUNCTIONS////////////////// - /////////////////////////////////////////////////// - methods: { // Utility Methods formatCurrency(amount) { if (!amount) return 'Q 0.00'; - + // Convert centavos to quetzales return new Intl.NumberFormat('es-GT', { style: 'currency', currency: 'GTQ', - }).format(amount); + }).format(amount / 100); }, formatDate(dateString) { @@ -38,16 +38,54 @@ window.app = Vue.createApp({ return new Intl.NumberFormat('en-US').format(amount) + ' sats' }, + async loadDashboardData() { + try { + const {data} = await LNbits.api.request( + 'GET', + '/satmachineclient/api/v1/dashboard/summary', + this.g.user.wallets[0].inkey + ) + this.dashboardData = data + } catch (error) { + console.error('Error loading dashboard data:', error) + this.error = 'Failed to load dashboard data' + } + }, + + async loadTransactions() { + try { + const {data} = await LNbits.api.request( + 'GET', + '/satmachineclient/api/v1/dashboard/transactions?limit=10', + this.g.user.wallets[0].inkey + ) + this.transactions = data + } catch (error) { + console.error('Error loading transactions:', error) + } + } }, - /////////////////////////////////////////////////// - //////LIFECYCLE FUNCTIONS RUNNING ON PAGE LOAD///// - /////////////////////////////////////////////////// + async created() { - // Load DCA client data - await Promise.all([ - ]) + try { + this.loading = true + await Promise.all([ + this.loadDashboardData(), + this.loadTransactions() + ]) + } catch (error) { + console.error('Error initializing dashboard:', error) + this.error = 'Failed to initialize dashboard' + } finally { + this.loading = false + } }, computed: { + hasData() { + return this.dashboardData && !this.loading + } } }) + +window.app.mount('#dcaClient') diff --git a/templates/satmachineclient/index.html b/templates/satmachineclient/index.html index 117e5bf..6a10114 100644 --- a/templates/satmachineclient/index.html +++ b/templates/satmachineclient/index.html @@ -1,5 +1,5 @@ - + {% extends "base.html" %} {% from "macros.jinja" import window_vars with context @@ -7,6 +7,110 @@ {% endblock %} {% block page %}
+ +
+ + +
Loading your DCA dashboard...
+
+
+ +
+ + + ${error} + +
+ + +
+ +
+
+ +
${formatSats(dashboardData.total_sats_accumulated)}
+
Total Sats Accumulated
+
+
+
+ +
${formatCurrency(dashboardData.total_fiat_invested)}
+
Total Invested
+
+
+
+ +
${formatCurrency(dashboardData.current_fiat_balance)}
+
Available Balance
+
+
+
+ +
${dashboardData.total_transactions}
+
Total Transactions
+
+
+
+ + +
+
+ +
DCA Status
+
+
+
Mode: ${dashboardData.dca_mode}
+
+
+
Status: + + ${dashboardData.dca_status} + +
+
+
+
+
Average Cost Basis: ${Math.round(dashboardData.average_cost_basis)} sats/GTQ
+
+
+
+
+ + +
+
+ +
Recent Transactions
+
+ No transactions yet +
+ + + + ${formatSats(tx.amount_sats)} + ${formatCurrency(tx.amount_fiat)} • ${formatDate(tx.created_at)} + + + + ${tx.status} + + + + +
+
+
+
{% endblock %} diff --git a/views_api.py b/views_api.py index 4bcfffe..fc3e763 100644 --- a/views_api.py +++ b/views_api.py @@ -35,7 +35,7 @@ async def api_get_dashboard_summary( wallet: WalletTypeInfo = Depends(require_invoice_key), ) -> ClientDashboardSummary: """Get client dashboard summary metrics""" - summary = await get_client_dashboard_summary(wallet.user) + summary = await get_client_dashboard_summary(wallet.wallet.user) if not summary: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, @@ -55,7 +55,7 @@ async def api_get_client_transactions( ) -> List[ClientTransaction]: """Get client's DCA transaction history with filtering""" return await get_client_transactions( - wallet.user, + wallet.wallet.user, limit=limit, offset=offset, transaction_type=transaction_type, @@ -70,7 +70,7 @@ async def api_get_client_analytics( time_range: str = Query("30d", regex="^(7d|30d|90d|1y|all)$"), ) -> ClientAnalytics: """Get client performance analytics and cost basis data""" - analytics = await get_client_analytics(wallet.user, time_range) + analytics = await get_client_analytics(wallet.wallet.user, time_range) if not analytics: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, @@ -85,7 +85,7 @@ async def api_update_client_settings( wallet: WalletTypeInfo = Depends(require_invoice_key), ) -> dict: """Update client DCA settings (mode, limits, status)""" - client = await get_client_by_user_id(wallet.user) + client = await get_client_by_user_id(wallet.wallet.user) if not client: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, @@ -111,7 +111,7 @@ async def api_export_transactions( ): """Export client transaction history""" transactions = await get_client_transactions( - wallet.user, + wallet.wallet.user, limit=10000, # Large limit for export start_date=start_date, end_date=end_date