Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
34a27f8
feat: dual currency input supports fiat input
riccardobl Mar 16, 2024
a630949
feat: prefix dual currency input with main symbol, add currency to in…
riccardobl Mar 23, 2024
cc5f8e7
fix: amount in Satoshis -> amount in sats
riccardobl Apr 1, 2024
8de6297
fix: attempt at making unit tests happy
riccardobl Apr 1, 2024
86f3cc6
fix: fix some unit tests
riccardobl Apr 2, 2024
b5cfbdc
fix: dual currency input event wrapping
riccardobl Apr 3, 2024
ddaee2f
fix: more unit tests fixing
riccardobl Apr 3, 2024
79540ea
fix: currency toggle issue for default values, improve some naming
riccardobl Apr 10, 2024
c50f288
fix: input value
riccardobl Apr 14, 2024
341759d
fix: naming, empty input, do not change component to uncontrolled whe…
riccardobl May 5, 2024
f949d06
fix: fixes and improvements
riccardobl May 24, 2024
70372ce
fix: light theme
riccardobl May 25, 2024
72fe5e8
fix: dualcurrency component test
pavanjoshi914 May 30, 2024
9adebc4
fix: clone target to avoid side-effects when changing value
riccardobl Jun 19, 2024
a3f8e47
fix: tests and implementation
riccardobl Jul 1, 2024
3c449b2
fix: allow 4 decimals in fiat input and add some comments
riccardobl Jul 8, 2024
45f58be
fix: preset workaround
riccardobl Jul 14, 2024
a5d8147
test(ConfirmPayment): mock getFormattedInCurrency to fix tests
Dunsin-cyber Jun 25, 2025
7272d62
fix: prevent redundant re-renders when value prop matches current input
Dunsin-cyber Jun 26, 2025
03216ea
test(SitePreferences): revamp 'set new budget' test with formatting c…
Dunsin-cyber Jun 26, 2025
572616b
fix(SendToBitcoinAddress): fix linting issue in the page
Dunsin-cyber Jul 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/app/components/BudgetControl/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,22 @@ type Props = {
onRememberChange: ChangeEventHandler<HTMLInputElement>;
budget: string;
onBudgetChange: ChangeEventHandler<HTMLInputElement>;
fiatAmount: string;
disabled?: boolean;
showFiat?: boolean;
};

function BudgetControl({
remember,
onRememberChange,
budget,
onBudgetChange,
fiatAmount,
disabled = false,
showFiat = false,
}: Props) {
const { t } = useTranslation("components", {
keyPrefix: "budget_control",
});

const { t: tCommon } = useTranslation("common");

return (
<div className="mb-4">
<div className={`flex items-center`}>
Expand Down Expand Up @@ -60,12 +58,11 @@ function BudgetControl({

<div>
<DualCurrencyField
showFiat={showFiat}
autoFocus
fiatValue={fiatAmount}
id="budget"
min={0}
label={t("budget.label")}
placeholder={tCommon("sats", { count: 0 })}
value={budget}
onChange={onBudgetChange}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/PaymentSummary/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jest.mock("~/common/lib/api", () => {
return {
...original,
getSettings: jest.fn(() => Promise.resolve(mockSettings)),
getCurrencyRate: jest.fn(() => Promise.resolve({ rate: 11 })),
getCurrencyRate: jest.fn(() => 11),
};
});

Expand Down
26 changes: 14 additions & 12 deletions src/app/components/SitePreferences/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import { settingsFixture as mockSettings } from "~/../tests/fixtures/settings";
import type { Props } from "./index";
import SitePreferences from "./index";

const mockGetFiatValue = jest.fn(() => Promise.resolve("$1,22"));
const mockGetFormattedFiat = jest.fn(() => "$1,22");
const mockGetFormattedInCurrency = jest.fn((v, curr) => v + " " + curr);

jest.mock("~/app/context/SettingsContext", () => ({
useSettings: () => ({
settings: mockSettings,
isLoading: false,
updateSetting: jest.fn(),
getFormattedFiat: mockGetFiatValue,
getFormattedFiat: mockGetFormattedFiat,
getFormattedNumber: jest.fn(),
getFormattedSats: jest.fn(),
getCurrencyRate: jest.fn(() => 1),
getCurrencySymbol: jest.fn(() => "β‚Ώ"),
getFormattedInCurrency: mockGetFormattedInCurrency,
}),
}));

Expand Down Expand Up @@ -53,7 +57,7 @@ describe("SitePreferences", () => {

await renderComponent();

expect(mockGetFiatValue).not.toHaveBeenCalled();
expect(mockGetFormattedFiat).not.toHaveBeenCalled();

const settingsButton = await screen.getByRole("button");

Expand All @@ -66,26 +70,24 @@ describe("SitePreferences", () => {
name: "Save",
});

// update fiat value when modal is open
expect(mockGetFiatValue).toHaveBeenCalledWith(
defaultProps.allowance.totalBudget.toString()
);
expect(mockGetFiatValue).toHaveBeenCalledTimes(1);

// Budget input
await act(async () => {
await user.clear(screen.getByLabelText("One-click payments budget"));
mockGetFormattedInCurrency.mockClear();
await user.type(
screen.getByLabelText("One-click payments budget"),
"250"
);
});

// update fiat value
expect(screen.getByLabelText("One-click payments budget")).toHaveValue(250);

// update fiat value
expect(mockGetFiatValue).toHaveBeenCalledWith("250");
expect(mockGetFiatValue).toHaveBeenCalledTimes(4); // plus 3 times for each input value 2, 5, 0
// Final formatting check β€” just once each
expect(mockGetFormattedInCurrency).toHaveBeenCalledWith(250, "BTC");
expect(mockGetFormattedInCurrency).toHaveBeenCalledWith(250, "USD");

// Save
await act(async () => {
await user.click(saveButton);
});
Expand Down
21 changes: 2 additions & 19 deletions src/app/components/SitePreferences/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,12 @@ export type Props = {
};

function SitePreferences({ launcherType, allowance, onEdit, onDelete }: Props) {
const {
isLoading: isLoadingSettings,
settings,
getFormattedFiat,
} = useSettings();
const { isLoading: isLoadingSettings, settings } = useSettings();
const showFiat = !isLoadingSettings && settings.showFiat;
const { account } = useAccount();
const [modalIsOpen, setIsOpen] = useState(false);
const [budget, setBudget] = useState("");
const [lnurlAuth, setLnurlAuth] = useState(false);
const [fiatAmount, setFiatAmount] = useState("");

const [originalPermissions, setOriginalPermissions] = useState<
Permission[] | null
Expand Down Expand Up @@ -83,17 +78,6 @@ function SitePreferences({ launcherType, allowance, onEdit, onDelete }: Props) {
fetchPermissions();
}, [account?.id, allowance.id]);

useEffect(() => {
if (budget !== "" && showFiat) {
const getFiat = async () => {
const res = await getFormattedFiat(budget);
setFiatAmount(res);
};

getFiat();
}
}, [budget, showFiat, getFormattedFiat]);

function openModal() {
setBudget(allowance.totalBudget.toString());
setLnurlAuth(allowance.lnurlAuth);
Expand Down Expand Up @@ -238,10 +222,9 @@ function SitePreferences({ launcherType, allowance, onEdit, onDelete }: Props) {
label={t("new_budget.label")}
min={0}
autoFocus
placeholder={tCommon("sats", { count: 0 })}
value={budget}
hint={t("hint")}
fiatValue={fiatAmount}
showFiat={showFiat}
onChange={(e) => setBudget(e.target.value)}
/>
</div>
Expand Down
23 changes: 20 additions & 3 deletions src/app/components/form/DualCurrencyField/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import { render, screen } from "@testing-library/react";
import { render, screen, waitFor } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import { settingsFixture as mockSettings } from "~/../tests/fixtures/settings";

import type { Props } from "./index";
import DualCurrencyField from "./index";

const props: Props = {
fiatValue: "$10.00",
showFiat: true,
label: "Amount",
};
jest.mock("~/app/context/SettingsContext", () => ({
useSettings: () => ({
settings: mockSettings,
isLoading: false,
updateSetting: jest.fn(),
getFormattedFiat: jest.fn(() => "$10.00"),
getFormattedNumber: jest.fn(),
getFormattedSats: jest.fn(),
getCurrencyRate: jest.fn(() => 1),
getCurrencySymbol: jest.fn(() => "β‚Ώ"),
getFormattedInCurrency: jest.fn(() => "$10.00"),
}),
}));

describe("DualCurrencyField", () => {
test("render", async () => {
Expand All @@ -20,6 +34,9 @@ describe("DualCurrencyField", () => {
const input = screen.getByLabelText("Amount");

expect(input).toBeInTheDocument();
expect(await screen.getByText("~$10.00")).toBeInTheDocument();

await waitFor(() => {
expect(screen.getByText("~$10.00")).toBeInTheDocument();
});
});
});
Loading