feat: Add financial position, holdings, and intent tagging UI#94
Conversation
Code Review SummaryThis PR introduces significant financial tracking features including a new Financial Position view, Holdings management with live crypto pricing, and transaction intent tagging. It also refines navigation and onboarding defaults. 🚀 Key Improvements
💡 Minor Suggestions
|
| }; | ||
|
|
||
| const toRow = (txn: ApiTransaction): Row => { | ||
| const currency = txn.wallet?.currency || 'XAF'; |
There was a problem hiding this comment.
Hardcoded fallback currency 'XAF' might result in incorrect data visualization for users with different base currencies if the wallet object is missing.
| const currency = txn.wallet?.currency || 'XAF'; | |
| const currency = txn.wallet?.currency || props.group?.metric?.split(' ').pop() || 'USD'; |
ddf9b1a to
7cfae35
Compare
Deploying trakli-dev with
|
| Latest commit: |
b4013ea
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://ac042af9.trakli-dev.pages.dev |
| Branch Preview URL: | https://feat-issue-233-transaction-i.trakli-dev.pages.dev |
| if (q.length < 2) { | ||
| results.value = []; | ||
| return; | ||
| } | ||
| searchTimer = setTimeout(async () => { |
There was a problem hiding this comment.
The search logic does not handle potential race conditions if multiple requests are fired in quick succession. Using an AbortController or checking a timestamp/request ID would ensure the results ref is only updated by the latest triggered search.
| if (q.length < 2) { | |
| results.value = []; | |
| return; | |
| } | |
| searchTimer = setTimeout(async () => { | |
| searchTimer = setTimeout(async () => { | |
| try { | |
| const fetchedResults = await holdingsApi.search(q); | |
| if (q === coinQuery.value.trim()) { | |
| results.value = fetchedResults; | |
| } | |
| } catch (e) { | |
| results.value = []; | |
| } | |
| }, 300); |
| ); | ||
|
|
||
| const money = (n: number) => | ||
| formatShortAmount(`${Math.round((n || 0) * 100) / 100} ${currency.value}`); |
There was a problem hiding this comment.
Using Math.round(n * 100) / 100 can lead to floating point precision errors (e.g., 1.005 rounding to 1 instead of 1.01). Use toFixed(2) for financial display logic.
| formatShortAmount(`${Math.round((n || 0) * 100) / 100} ${currency.value}`); | |
| formatShortAmount(`${(n || 0).toFixed(2)} ${currency.value}`); |
Deploying webui with
|
| Latest commit: |
b4013ea
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://89ce987e.webui-9fh.pages.dev |
| Branch Preview URL: | https://feat-issue-233-transaction-i.webui-9fh.pages.dev |
- Add the Financial Position screen: net worth, a money in/out ledger by intent, and a drill-down into the underlying transactions. - Add a Holdings screen and form backed by the holdings API, with live crypto pricing and manual assets; holdings feed total net worth. - Add an intent selector to the transaction form so income and expenses can be tagged as loans, debt, investments or gifts. - Refine navigation: the dashboard is the default landing, the AI assistant is one entry with a Discussions sub-item, and less-used items move down. - Let budgets be created in any supported currency, not just the currencies of existing wallets. - Use Solar duotone icons (via Iconify) for the assistant landing stat cards so the large art reads richly instead of as thin lines.
7cfae35 to
b4013ea
Compare
What
/financial-position, also a Reports tab): net worth, a money in / money out ledger by intent, each row drilling into its transactions. Greyed rows mark cash that moves but doesn't change net worth./holdings) and form: list assets with value and a live/manual badge; add crypto via CoinGecko search (auto-priced) or any asset manually. Total net worth = cash + holdings.Why
Notes
owner_type/owner_idon holding create.unplugin-iconsand@iconify-json/solar(build-time inlined, offline).Tests