Skip to content

feat(currency): add INR display support - #274

Open
heyIshwar wants to merge 2 commits into
xiufengsun:mainfrom
heyIshwar:feat/inr-currency
Open

feat(currency): add INR display support#274
heyIshwar wants to merge 2 commits into
xiufengsun:mainfrom
heyIshwar:feat/inr-currency

Conversation

@heyIshwar

@heyIshwar heyIshwar commented Jul 5, 2026

Copy link
Copy Markdown

Summary

Adds Indian Rupee (INR, ₹) as a first-class display currency across the dashboard, native tray/pet sync, and public embed/badge SVGs. Costs remain stored in USD; conversion happens at display time via existing exchange-rate flow.

Changes

  • Registry: INR in currency.ts with bundled default rate (83.5 USD→INR) and live fetch via open.er-api.com
  • Locale default: First-time visitors with India browser locales (en-IN, hi-IN, …) auto-select INR when no saved preference exists
  • Settings: INR option in Appearance currency dropdown + copy/i18n (en, zh, zh-TW, ja, ko, de)
  • Native: Windows Currency.cs fallback map includes INR
  • UI gaps: QualityPerDollarCard and leaderboard profile cost formatting respect useCurrency() (fixes hardcoded $)
  • Embeds: currency + optional rate query params on tokentracker-embed-svg and tokentracker-badge-svg; profile embed snippet passes user's current currency

Test plan

  • cd dashboard && npm test -- currency format exchange-rate
  • node --test test/embed-currency.test.js test/badge-svg-render.test.js
  • npm run validate:copy
  • npm run validate:ui-hardcode
  • Manual: Settings → Appearance → select INR → dashboard costs show ₹
  • Manual: browser locale en-IN + cleared tokentracker-currency → defaults to INR
  • Manual: embed URL ?currency=INR&rate=83.5 shows converted cost in SVG

Made with Cursor

Summary by CodeRabbit

  • New Features
    • Added Indian Rupee (INR) to currency options, symbols, and default exchange rates.
    • Embed and badge SVGs can now display cost in a chosen currency using currency and optional rate.
    • Currency preference now auto-infers from browser locale (preferring INR for India locales).
  • Bug Fixes
    • Fixed converted cost formatting for very small amounts (including correct rounding/threshold behavior).
  • Documentation
    • Updated embed badge snippet and guidance to include the new currency/rate parameters.
  • Tests
    • Expanded coverage for INR formatting, locale inference, and query-driven conversion/rounding.

… params.

Add Indian Rupee to the currency registry, Windows fallback rates, settings
copy/i18n, and India-locale auto-default when no preference is saved. Wire
QualityPerDollar and leaderboard cost formatting to useCurrency, and support
currency/rate query params on embed and badge SVG endpoints.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c34c24f2-1420-42a8-8668-85d781f95f45

📥 Commits

Reviewing files that changed from the base of the PR and between dde106c and 6d14c7f.

📒 Files selected for processing (2)
  • dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx
  • dashboard/src/ui/dashboard/components/QualityPerDollarCard.jsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx
  • dashboard/src/ui/dashboard/components/QualityPerDollarCard.jsx

📝 Walkthrough

Walkthrough

This PR adds INR support across currency data, locale-based defaults, edge SVG embed formatting, dashboard cost displays, and i18n labels, with matching updates to unit and render tests.

Changes

INR Currency Support

Layer / File(s) Summary
Windows app currency table update
TokenTrackerWin/Currency.cs
Adds INR symbol (₹) and default rate (83.5) to the lookup table.
Dashboard currency library and locale inference
dashboard/src/lib/currency.ts, dashboard/src/lib/currency.test.ts, dashboard/src/lib/exchange-rate.test.ts, dashboard/src/lib/format.test.ts
Adds INR to supported codes, metadata, and default rates; adds inferDefaultCurrencyFromLocale and getNavigatorLanguages; changes getInitialCurrency to infer default from browser locale when storage is empty; extends test coverage.
Shared embed-currency helper and mirrored tests
dashboard/edge-patches/embed-currency.ts, test/embed-currency.test.js
New Deno module exporting supported codes, default rates, normalization, parseEmbedCurrency, and formatEmbedCost; mirrored Node.js test suite validates the same logic.
Badge and embed SVG endpoints
dashboard/edge-patches/tokentracker-badge-svg.ts, dashboard/edge-patches/tokentracker-embed-svg.ts, test/badge-svg-render.test.js
Endpoints parse currency/rate query params and use formatEmbedCost instead of removed fixed-USD formatCost helpers; documentation and tests updated accordingly.
Dashboard UI cost formatting
dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx, dashboard/src/ui/dashboard/components/QualityPerDollarCard.jsx
Cost displays and badge embed URLs use dynamic currency symbols and conversion rates derived from useCurrency()/getCurrencySymbol.
i18n translations
dashboard/src/content/i18n/{de,ja,ko,zh-TW,zh}/core.json
Adds INR currency option label across five locales.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Related Issues: None found
Related PRs: None found
Suggested labels: enhancement, i18n
Suggested reviewers: None specified

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant tokentracker-badge-svg
  participant tokentracker-embed-svg
  participant embed-currency helper

  Client->>tokentracker-badge-svg: GET ?metric=cost&currency=INR&rate=83.5
  tokentracker-badge-svg->>embed-currency helper: parseEmbedCurrency(searchParams)
  embed-currency helper-->>tokentracker-badge-svg: currencyOpts
  tokentracker-badge-svg->>embed-currency helper: formatEmbedCost(cost, currencyOpts)
  embed-currency helper-->>tokentracker-badge-svg: formatted badge value
  tokentracker-badge-svg-->>Client: SVG badge

  Client->>tokentracker-embed-svg: GET ?currency=INR&rate=83.5
  tokentracker-embed-svg->>embed-currency helper: parseEmbedCurrency(searchParams)
  embed-currency helper-->>tokentracker-embed-svg: currencyOpts
  tokentracker-embed-svg->>embed-currency helper: formatEmbedCost(estimated_cost_usd, currencyOpts)
  embed-currency helper-->>tokentracker-embed-svg: formatted profile cost
  tokentracker-embed-svg-->>Client: profile card SVG
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the primary change: adding INR display support for currency rendering.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx (1)

22-30: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Sub-cent threshold uses raw USD value, not the converted amount.

n is the raw USD cost, but symbol reflects the target currency. For INR (rate ≈83.5), a value like $0.005 (raw n < 0.01) actually converts to ~₹0.42 — well above ₹0.01 — yet this still renders "<₹0.01", understating the true cost. The threshold should be compared against the converted amount for non-USD currencies.

🐛 Proposed fix
 function formatCost(value, currency, rate) {
   const n = Number(value);
   if (!Number.isFinite(n) || n < 0) return "—";
   const symbol = getCurrencySymbol(currency);
-  if (n > 0 && n < 0.01) {
+  const converted = currency === "USD" || !rate ? n : n * rate;
+  if (converted > 0 && converted < 0.01) {
     return `<${symbol}0.01`;
   }
   return formatUsdCurrency(n, { decimals: 2, currency, rate });
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx` around
lines 22 - 30, The sub-cent check in formatCost uses the raw USD value instead
of the target-currency amount, so small USD values can be mislabeled for non-USD
currencies. Update formatCost to base the “< 0.01” threshold on the converted
value (using the currency/rate inputs and the existing
getCurrencySymbol/formatUsdCurrency flow), while keeping the raw-value
formatting path for USD or when conversion is not needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@dashboard/src/ui/dashboard/components/QualityPerDollarCard.jsx`:
- Around line 9-13: The decimal precision in formatMoney is being chosen from
the pre-conversion USD value, which causes overly precise output after currency
conversion. Update formatMoney (and any related logic in QualityPerDollarCard
that uses it) so the decimals decision is based on the converted amount returned
by formatUsdCurrency for the target currency, not on n before conversion. Keep
the null/zero handling intact, but make the precision selection happen after
applying the currency multiplier so INR and similar currencies format
consistently.

---

Outside diff comments:
In `@dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx`:
- Around line 22-30: The sub-cent check in formatCost uses the raw USD value
instead of the target-currency amount, so small USD values can be mislabeled for
non-USD currencies. Update formatCost to base the “< 0.01” threshold on the
converted value (using the currency/rate inputs and the existing
getCurrencySymbol/formatUsdCurrency flow), while keeping the raw-value
formatting path for USD or when conversion is not needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0db9a72e-056b-4930-8f63-4fab44a1e2d1

📥 Commits

Reviewing files that changed from the base of the PR and between 1b71e2c and dde106c.

⛔ Files ignored due to path filters (1)
  • dashboard/src/content/copy.csv is excluded by !**/*.csv
📒 Files selected for processing (17)
  • TokenTrackerWin/Currency.cs
  • dashboard/edge-patches/embed-currency.ts
  • dashboard/edge-patches/tokentracker-badge-svg.ts
  • dashboard/edge-patches/tokentracker-embed-svg.ts
  • dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx
  • dashboard/src/content/i18n/de/core.json
  • dashboard/src/content/i18n/ja/core.json
  • dashboard/src/content/i18n/ko/core.json
  • dashboard/src/content/i18n/zh-TW/core.json
  • dashboard/src/content/i18n/zh/core.json
  • dashboard/src/lib/currency.test.ts
  • dashboard/src/lib/currency.ts
  • dashboard/src/lib/exchange-rate.test.ts
  • dashboard/src/lib/format.test.ts
  • dashboard/src/ui/dashboard/components/QualityPerDollarCard.jsx
  • test/badge-svg-render.test.js
  • test/embed-currency.test.js

Comment thread dashboard/src/ui/dashboard/components/QualityPerDollarCard.jsx
Pick decimal precision and sub-cent labels from the target-currency value
so non-USD displays like INR stay consistent after conversion.

Co-authored-by: Cursor <cursoragent@cursor.com>
@heyIshwar

Copy link
Copy Markdown
Author

Addressed both CodeRabbit findings in 6d14c7f:

  1. QualityPerDollarCardformatMoney and avgCostPerAcc now choose decimal precision from the converted target-currency amount (not raw USD).
  2. LeaderboardProfileModal — sub-cent <symbol>0.01 threshold now compares the converted amount for non-USD currencies.

Tests: npm test -- format currency (41 passed).

@xiufengsun

xiufengsun commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Great contribution! All 1,215 local tests passed successfully. However, we found a few issues that need to be addressed before merging. Most importantly, Issue #1 will cause runtime errors on the deployed Deno Edge environment because InsForge deploys edge patches as individual self-contained files and does not resolve local relative imports.

Code review

Found 3 issues:

  1. Edge functions deploy fail due to relative module import (bug due to relative import in edge environment)
    Please inline or duplicate the helper functions in embed-currency.ts directly inside the badge and embed scripts to keep them self-contained.

https://github.com/mm7894215/TokenTracker/blob/6d14c7f1611e7e60addb159a5109e41913db760c/dashboard/edge-patches/tokentracker-badge-svg.ts#L21-L25
https://github.com/mm7894215/TokenTracker/blob/6d14c7f1611e7e60addb159a5109e41913db760c/dashboard/edge-patches/tokentracker-embed-svg.ts#L20-L24

  1. Unclean parameter serialization for badge snippet (bug due to encoding potentially undefined rate)
    If rate is undefined (e.g. for USD), encodeURIComponent(rate) serializes to the string "undefined". Please guard parameter serialization.

https://github.com/mm7894215/TokenTracker/blob/6d14c7f1611e7e60addb159a5109e41913db760c/dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx#L452-L456

  1. Inconsistent USD string check vs CURRENCY_USD constant (style check in LeaderboardProfileModal.jsx)
    Use the imported CURRENCY_USD constant instead of the hardcoded "USD" string for checking currency inside formatCostCompact to maintain consistency.

https://github.com/mm7894215/TokenTracker/blob/6d14c7f1611e7e60addb159a5109e41913db760c/dashboard/src/components/leaderboard/LeaderboardProfileModal.jsx#L39-L45

@github-actions

Copy link
Copy Markdown

This PR has been inactive for 14 days and is now marked as stale. It will be closed in 7 days if there are no updates.

@github-actions github-actions Bot added the stale label Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants