-
Notifications
You must be signed in to change notification settings - Fork 141
feat: Add BillingSettingsThree & i18n Multi-Currency Support #362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d0e84aa
e2f445d
3d3a1db
b36b5fc
1ed8fc9
98a7320
d6ac92b
407335f
72a0e02
08b9e48
9e48596
3d812ac
4eeeb6b
7a35d90
0730e23
9fcd9cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
|
|
||
| > billingsdk@0.0.0 build | ||
| > next build | ||
|
|
||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| ÔÜá Warning: Next.js inferred your workspace root, but it may not be correct. | ||
| We detected multiple lockfiles and selected the directory of C:\Users\srini\package-lock.json as the root directory. | ||
| To silence this warning, set `turbopack.root` in your Next.js config, or consider removing one of the lockfiles if it's not needed. | ||
| See https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#root-directory for more information. | ||
| Detected additional lockfiles: | ||
| * C:\Users\srini\Downloads\billingsdk\package-lock.json | ||
|
|
||
| Ôû▓ Next.js 16.0.10 (Turbopack) | ||
|
|
||
| [MDX] generated files in 89.94050000000061ms | ||
| Creating an optimized production build ... | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| Ô£ô Compiled successfully in 63s | ||
| Running TypeScript ... | ||
| Collecting page data using 7 workers ... | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| ÔÜá Using edge runtime on a page currently disables static generation for that page | ||
| Generating static pages using 7 workers (0/94) ... | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| Error occurred prerendering page "/llms.mdx/components/payment-details-two". Read more: https://nextjs.org/docs/messages/prerender-error | ||
| Error: ENOENT: no such file or directory, open 'C:\Users\srini\Downloads\billingsdk\contentdocs\components\payment-details-two\index.mdx' | ||
| at async Object.getText (C:\Users\srini\Downloads\billingsdk\.next\server\chunks\Downloads_billingsdk_e35021e6._.js:1:4375435) | ||
| at async l (C:\Users\srini\Downloads\billingsdk\.next\server\chunks\Downloads_billingsdk_f9402a61._.js:21:167137) | ||
| at async l (C:\Users\srini\Downloads\billingsdk\.next\server\chunks\Downloads_billingsdk_745e94af._.js:1:9951) { | ||
| errno: -4058, | ||
| code: 'ENOENT', | ||
| syscall: 'open', | ||
| path: 'C:\\Users\\srini\\Downloads\\billingsdk\\contentdocs\\components\\payment-details-two\\index.mdx' | ||
| } | ||
| Export encountered an error on /llms.mdx/[[...slug]]/route: /llms.mdx/components/payment-details-two, exiting the build. | ||
| Error occurred prerendering page "/llms.mdx/cli". Read more: https://nextjs.org/docs/messages/prerender-error | ||
| Ô¿» Next.js build worker exited with code: 1 and signal: null |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for this |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
|
|
||
| > billingsdk@0.0.0 build | ||
| > next build | ||
|
|
||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| ÔÜá Warning: Next.js inferred your workspace root, but it may not be correct. | ||
| We detected multiple lockfiles and selected the directory of C:\Users\srini\package-lock.json as the root directory. | ||
| To silence this warning, set `turbopack.root` in your Next.js config, or consider removing one of the lockfiles if it's not needed. | ||
| See https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#root-directory for more information. | ||
| Detected additional lockfiles: | ||
| * C:\Users\srini\Downloads\billingsdk\package-lock.json | ||
|
|
||
| Ôû▓ Next.js 16.0.10 (Turbopack) | ||
|
|
||
| [MDX] generated files in 40.96280000000024ms | ||
| Creating an optimized production build ... | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| Ô£ô Compiled successfully in 37.2s | ||
| Running TypeScript ... | ||
| Collecting page data using 7 workers ... | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| ÔÜá Using edge runtime on a page currently disables static generation for that page | ||
| Generating static pages using 7 workers (0/94) ... | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` | ||
| Error occurred prerendering page "/llms-full.txt". Read more: https://nextjs.org/docs/messages/prerender-error | ||
| Error: ENOENT: no such file or directory, open 'C:\Users\srini\Downloads\billingsdk\contentdocs\cli.mdx' | ||
| at async Object.getText (C:\Users\srini\Downloads\billingsdk\.next\server\chunks\Downloads_billingsdk_16fdf67a._.js:1:4375200) | ||
| at async l (C:\Users\srini\Downloads\billingsdk\.next\server\chunks\Downloads_billingsdk_f9402a61._.js:21:167137) | ||
| at async i (C:\Users\srini\Downloads\billingsdk\.next\server\chunks\[root-of-the-server]__742aafed._.js:1:1513) { | ||
| errno: -4058, | ||
| code: 'ENOENT', | ||
| syscall: 'open', | ||
| path: 'C:\\Users\\srini\\Downloads\\billingsdk\\contentdocs\\cli.mdx' | ||
| } | ||
| Export encountered an error on /llms-full.txt/route: /llms-full.txt, exiting the build. | ||
| Ô¿» Next.js build worker exited with code: 1 and signal: null |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| --- | ||
| title: Billing Settings 3 | ||
| description: A user-centric billing dashboard featuring wallet balance, spend visualization, and liquid UI payment methods. | ||
| --- | ||
|
|
||
| import { BillingSettingsThree } from "@/components/billingsdk/billing-settings-three"; | ||
| import BillingSettingsThreeDemo from "@/registry/billingsdk/demo/billing-settings-three-demo"; | ||
|
Comment on lines
+6
to
+7
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: fd 'index.mdx' --full-path 'content/docs/components/billing-settings-three' --type fRepository: dodopayments/billingsdk Length of output: 123 🏁 Script executed: cat -n content/docs/components/billing-settings-three/index.mdxRepository: dodopayments/billingsdk Length of output: 4943 Remove unused import: Only ✏️ Proposed fix-import { BillingSettingsThree } from "@/components/billingsdk/billing-settings-three";
import BillingSettingsThreeDemo from "@/registry/billingsdk/demo/billing-settings-three-demo";🤖 Prompt for AI Agents |
||
|
|
||
| A user-facing dashboard component `BillingSettingsThree` for managing billing, wallet balance, and payment methods. | ||
|
|
||
| ## Preview | ||
|
|
||
| <Tabs items={['Preview', 'Code']} className="bg-transparent border-none"> | ||
| <Tab value="Preview" className="border-none bg-transparent p-0 mt-3"> | ||
| <PreviewComponents registryName="billing-settings-3"> | ||
| <BillingSettingsThreeDemo /> | ||
| </PreviewComponents> | ||
| </Tab> | ||
|
|
||
| <Tab value="Code" className="mt-3"> | ||
| <include cwd lang="tsx" meta='title="src/registry/billingsdk/demo/billing-settings-three-demo.tsx"'>src/registry/billingsdk/demo/billing-settings-three-demo.tsx</include> | ||
| </Tab> | ||
| </Tabs> | ||
|
|
||
| ## Features | ||
|
|
||
| - **Minimalist Metrics**: Clean, static display of wallet balances, spend amounts, and trend percentages for maximum stability and clarity. | ||
| - **Trend Indicators**: Built-in support for displaying positive/negative trends with automatic color coding and icons. | ||
| - **Liquid Payment Methods**: Smooth, animated "liquid" list for adding/removing payment methods with high-fidelity transitions. | ||
| - **Smart Brand Recognition**: Automatically displays high-quality icons for Visa, Mastercard, AMEX, and Rupay, with a fallback to standard card icons if external assets fail to load. | ||
| - **Flexible "Add New" Logic**: Support for both in-app modal callbacks (`onAddNew`) and direct external redirects (`addNewHref`). | ||
| - **Minimalist Aesthetic**: Features a zero-animation `minimal` mode that removes background decorative elements for a clean dashboard look. | ||
|
Comment on lines
+27
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentation contradicts PR description regarding animations. Line 29 describes "Smooth, animated 'liquid' list… with high-fidelity transitions," while line 32 mentions "zero-animation 🤖 Prompt for AI Agents |
||
|
|
||
| ## Usage | ||
|
|
||
| ```tsx | ||
| import { BillingSettingsThree } from "@/components/billingsdk/billing-settings-three"; | ||
| import { BillingProvider } from "@/lib/i18n-provider"; | ||
|
|
||
| export default function BillingPage() { | ||
| const handleAddNew = () => { | ||
| console.log("Open payment method modal"); | ||
| }; | ||
|
|
||
| return ( | ||
| <BillingProvider> | ||
| <BillingSettingsThree | ||
| balance={1250.00} | ||
| balanceTrend={15.4} | ||
| spend={432.50} | ||
| spendTrend={-5.2} | ||
| theme="classic" | ||
| onAddNew={handleAddNew} | ||
| // Or use addNewHref="/billing/payment-methods/new" | ||
| /> | ||
| </BillingProvider> | ||
| ); | ||
| } | ||
| ``` | ||
|
|
||
| ## Props | ||
|
|
||
| | Prop | Type | Default | Description | | ||
| | ---- | ---- | ------- | ----------- | | ||
| | `balance` | `number` | `1250.00` | The current wallet balance to display. | | ||
| | `balanceTrend` | `number` | `12.5` | Percentage change in balance (e.g., `15.4` for +15.4%). | | ||
| | `balanceTrendLabel` | `string` | `"from last month"` | Label shown next to the balance trend. | | ||
| | `spend` | `number` | `432.50` | The total spend for the current period. | | ||
| | `spendTrend` | `number` | `-2.4` | Percentage change in spend (e.g., `-5.2` for -5.2%). | | ||
| | `spendTrendLabel` | `string` | `"Current billing cycle"` | Label shown next to the spend trend. | | ||
| | `currency` | `string` | `"USD"` | The currency code (e.g., "USD", "EUR"). | | ||
| | `theme` | `"minimal" \| "classic"` | `"minimal"` | The visual theme variant. | | ||
| | `paymentMethods` | `PaymentMethod[]` | `[...]` | Array of payment objects: `{ id, type, last4, expiry, isDefault }`. | | ||
| | `transactions` | `Transaction[]` | `[...]` | Array of transactions: `{ id, description, amount, date, status }`. | | ||
| | `onAddNew` | `() => void` | `undefined` | Callback for "Add New" button (e.g., to open a modal). | | ||
| | `addNewHref` | `string` | `undefined` | URL for "Add New" button redirect (fallback if `onAddNew` is not provided). | | ||
|
|
||
| ## Installation | ||
|
|
||
| <Tabs defaultValue="manual"> | ||
|
|
||
| <TabsList> | ||
| <TabsTrigger value="manual">Manual</TabsTrigger> | ||
| <TabsTrigger value="cli">CLI</TabsTrigger> | ||
| </TabsList> | ||
|
|
||
| <TabsContent value="manual"> | ||
|
|
||
| Copy the code from `src/components/billingsdk/billing-settings-three.tsx` into your project. | ||
|
|
||
| </TabsContent> | ||
|
|
||
| <TabsContent value="cli"> | ||
|
|
||
| ```bash | ||
| npx shadcn@latest add "https://billingsdk.com/r/billing-settings-3.json" | ||
| ``` | ||
|
|
||
| </TabsContent> | ||
|
|
||
| </Tabs> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| --- | ||
| title: i18n Provider | ||
| description: Global currency conversion and localized formatting for billing components. | ||
| --- | ||
|
|
||
| import I18nDemo from "@/registry/billingsdk/demo/i18n-demo"; | ||
|
|
||
| The `BillingProvider` is the core of the SDK's internationalization system. It manages global state for locales, currencies, and real-time exchange rates. | ||
|
|
||
| ## Interactive Demo | ||
|
|
||
| <Tabs items={['Preview', 'Code']} className="bg-transparent border-none"> | ||
| <Tab value="Preview" className="border-none bg-transparent p-0 mt-3"> | ||
| <PreviewComponents registryName="i18n-provider"> | ||
| <I18nDemo /> | ||
| </PreviewComponents> | ||
| </Tab> | ||
|
|
||
| <Tab value="Code" className="mt-3"> | ||
| <include cwd lang="tsx" meta='title="src/registry/billingsdk/demo/i18n-demo.tsx"'>src/registry/billingsdk/demo/i18n-demo.tsx</include> | ||
| </Tab> | ||
| </Tabs> | ||
|
|
||
| ## Features | ||
|
|
||
| - **Real-time Conversion**: Fetches latest rates from the Frankfurter API and caches them. | ||
| - **Static Fallbacks**: Includes a robust set of initial exchange rates to ensure functionality works offline or before the first fetch. | ||
| - **Localized Formatting**: Leverages the native `Intl.NumberFormat` API for accurate currency symbols, grouping, and decimal placement. | ||
| - **Auto-Conversion**: Components can automatically convert values from a base currency (e.g., USD) to the user's active currency. | ||
|
|
||
| ## Setup | ||
|
|
||
| Wrap your application with the `BillingProvider` at the root level. | ||
|
|
||
| ```tsx title="app/layout.tsx" | ||
| import { BillingProvider } from "@/lib/i18n-provider"; | ||
|
|
||
| export default function RootLayout({ children }) { | ||
| return ( | ||
| <BillingProvider defaultCurrency="USD" defaultLocale="en-US"> | ||
| {children} | ||
| </BillingProvider> | ||
| ); | ||
| } | ||
| ``` | ||
|
Comment on lines
+35
to
+45
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setup code example is missing TypeScript types. The ✏️ Suggested fix-export default function RootLayout({ children }) {
+export default function RootLayout({ children }: { children: React.ReactNode }) {🤖 Prompt for AI Agents |
||
|
|
||
| ## useBilling Hook | ||
|
|
||
| Use the `useBilling` hook to access formatting utilities and currency state. | ||
|
|
||
| ### Properties | ||
|
|
||
| | Property | Type | Description | | ||
| | :--- | :--- | :--- | | ||
| | `currency` | `string` | The currently active currency code (e.g., "EUR"). | | ||
| | `locale` | `string` | The active locale (e.g., "de-DE"). | | ||
| | `setCurrency` | `(c: string) => void` | Updates the active currency and triggers re-renders. | | ||
| | `formatCurrency` | `(val, opts) => string` | Formats a number with currency symbols and local rules. | | ||
| | `convert` | `(val, from, to) => number` | Low-level utility for converting numbers between currencies. | | ||
|
|
||
| ### Example: Manual Formatting | ||
|
|
||
| ```tsx | ||
| import { useBilling } from "@/lib/i18n-provider"; | ||
|
|
||
| export function CustomPrice({ amount }) { | ||
| const { formatCurrency } = useBilling(); | ||
|
|
||
| return ( | ||
| <p> | ||
| Trial ends in: {formatCurrency(amount, { from: "USD" })} | ||
| </p> | ||
| ); | ||
| } | ||
| ``` | ||
|
Comment on lines
+63
to
+75
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same missing types in the ✏️ Suggested fix-export function CustomPrice({ amount }) {
+export function CustomPrice({ amount }: { amount: number }) {🤖 Prompt for AI Agents |
||
|
|
||
| ## Static Rates Fallback | ||
|
|
||
| The provider ships with a `STATIC_RATES` map to ensure reliable performance. These rates are used as a fallback if the API is unreachable or while rates are being fetched. | ||
|
|
||
| ```json | ||
| { | ||
| "AUD": 1.4312, | ||
| "BRL": 5.2372, | ||
| "CAD": 1.3666, | ||
| "EUR": 0.84789, | ||
| "GBP": 0.73588, | ||
| "INR": 90.66, | ||
| "JPY": 157.09, | ||
| ... | ||
| } | ||
| ``` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CodenRust why do we have to commit these files?