handleSelect(true)}
- onBlur={(e) => {
- // Only blur if we're not clicking inside the component
- if (!e.currentTarget.contains(e.relatedTarget)) {
- handleSelect(false);
- }
- }}
- tabIndex={0}
- >
-
-
-
- Stake ({currency})
-
-
-
-
-
-
-
+ {error && errorMessage && (
+
+
+ {errorMessage}
+
+
+ )}
-
-
+ );
+ }
+
+ return (
+
+
+ handleSelect(true)}
+ onBlur={(e) => {
+ // Only blur if we're not clicking inside the component
+ if (!e.currentTarget.contains(e.relatedTarget)) {
+ handleSelect(false);
+ }
+ }}
+ tabIndex={0}
+ >
+
+
+
+ Stake ({currency})
+
+
+ handleSelect(true)}
+ className="text-left font-ibm-plex text-base leading-6 font-normal bg-transparent w-24 outline-none text-gray-900"
+ aria-label="Stake amount"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- );
+ );
};
diff --git a/src/components/Stake/__tests__/StakeField.test.tsx b/src/components/Stake/__tests__/StakeField.test.tsx
index 1693475..6dfd46a 100644
--- a/src/components/Stake/__tests__/StakeField.test.tsx
+++ b/src/components/Stake/__tests__/StakeField.test.tsx
@@ -8,218 +8,193 @@ import { useTooltipStore } from "@/stores/tooltipStore";
// Mock components
jest.mock("@/components/ui/tooltip", () => ({
- Tooltip: () =>
,
+ Tooltip: () =>
,
}));
jest.mock("@/components/ui/desktop-trade-field-card", () => ({
- DesktopTradeFieldCard: ({ children, isSelected, error }: any) => (
-
- {children}
-
- ),
+ DesktopTradeFieldCard: ({ children, isSelected, error }: any) => (
+
+ {children}
+
+ ),
}));
jest.mock("@/components/TradeFields/TradeParam", () => ({
- __esModule: true,
- default: ({ label, value, onClick }: any) => (
-
- ),
+ __esModule: true,
+ default: ({ label, value, onClick }: any) => (
+
+ ),
}));
// Mock stores
jest.mock("@/stores/tradeStore", () => ({
- useTradeStore: jest.fn(),
+ useTradeStore: jest.fn(),
}));
jest.mock("@/stores/orientationStore", () => ({
- useOrientationStore: jest.fn(),
+ useOrientationStore: jest.fn(),
}));
jest.mock("@/stores/clientStore", () => ({
- useClientStore: jest.fn(),
+ useClientStore: jest.fn(),
}));
jest.mock("@/stores/bottomSheetStore", () => ({
- useBottomSheetStore: jest.fn(),
+ useBottomSheetStore: jest.fn(),
}));
jest.mock("@/stores/tooltipStore", () => ({
- useTooltipStore: jest.fn(),
+ useTooltipStore: jest.fn(),
}));
describe("StakeField", () => {
- const mockShowTooltip = jest.fn();
- const mockHideTooltip = jest.fn();
- const mockSetBottomSheet = jest.fn();
-
- beforeEach(() => {
- jest.clearAllMocks();
-
- // Default store mocks
- (
- useTooltipStore as jest.MockedFunction
- ).mockReturnValue({
- showTooltip: mockShowTooltip,
- hideTooltip: mockHideTooltip,
- });
- (
- useTradeStore as jest.MockedFunction
- ).mockReturnValue({
- stake: "100",
- setStake: jest.fn(),
- isConfigLoading: false,
- });
-
- (
- useOrientationStore as jest.MockedFunction
- ).mockReturnValue({
- isLandscape: false,
- });
-
- (
- useClientStore as jest.MockedFunction
- ).mockReturnValue({
- currency: "USD",
- });
-
- (
- useBottomSheetStore as jest.MockedFunction
- ).mockReturnValue({
- setBottomSheet: mockSetBottomSheet,
- });
- });
-
- describe("Loading State", () => {
- it("should show skeleton loader when config is loading", () => {
- (
- useTradeStore as jest.MockedFunction
- ).mockReturnValue({
- stake: "100",
- setStake: jest.fn(),
- isConfigLoading: true,
- });
-
- render();
-
- const skeleton = screen.getByTestId("stake-field-skeleton");
- expect(skeleton).toBeInTheDocument();
- expect(screen.queryByTestId("trade-param")).not.toBeInTheDocument();
- });
-
- it("should show stake value when not loading", () => {
- render();
-
- const param = screen.getByTestId("trade-param");
- expect(param).toBeInTheDocument();
- expect(param).toHaveAttribute("data-label", "Stake");
- expect(param).toHaveAttribute("data-value", "100 USD");
- expect(
- screen.queryByTestId("stake-field-skeleton")
- ).not.toBeInTheDocument();
- });
- });
-
- describe("Portrait Mode", () => {
- beforeEach(() => {
- (
- useOrientationStore as jest.MockedFunction
- ).mockReturnValue({
- isLandscape: false,
- });
- });
-
- it("should open bottom sheet when clicked", () => {
- render();
-
- fireEvent.click(screen.getByTestId("trade-param"));
+ const mockShowTooltip = jest.fn();
+ const mockHideTooltip = jest.fn();
+ const mockSetBottomSheet = jest.fn();
- expect(mockSetBottomSheet).toHaveBeenCalledWith(true, "stake", "400px");
- });
- });
-
- describe("Landscape Mode", () => {
beforeEach(() => {
- (
- useOrientationStore as jest.MockedFunction
- ).mockReturnValue({
- isLandscape: true,
- });
+ jest.clearAllMocks();
+
+ // Default store mocks
+ (useTooltipStore as jest.MockedFunction).mockReturnValue({
+ showTooltip: mockShowTooltip,
+ hideTooltip: mockHideTooltip,
+ });
+ (useTradeStore as jest.MockedFunction).mockReturnValue({
+ stake: "100",
+ setStake: jest.fn(),
+ isConfigLoading: false,
+ });
+
+ (useOrientationStore as jest.MockedFunction).mockReturnValue({
+ isLandscape: false,
+ });
+
+ (useClientStore as jest.MockedFunction).mockReturnValue({
+ currency: "USD",
+ });
+
+ (useBottomSheetStore as jest.MockedFunction).mockReturnValue({
+ setBottomSheet: mockSetBottomSheet,
+ });
});
- it("should show input field and increment/decrement buttons", () => {
- render();
-
- expect(screen.getByLabelText("Stake amount")).toBeInTheDocument();
- expect(screen.getByLabelText("Decrease stake")).toBeInTheDocument();
- expect(screen.getByLabelText("Increase stake")).toBeInTheDocument();
+ describe("Loading State", () => {
+ it("should show skeleton loader when config is loading", () => {
+ (useTradeStore as jest.MockedFunction).mockReturnValue({
+ stake: "100",
+ setStake: jest.fn(),
+ isConfigLoading: true,
+ });
+
+ render();
+
+ const skeleton = screen.getByTestId("stake-field-skeleton");
+ expect(skeleton).toBeInTheDocument();
+ expect(screen.queryByTestId("trade-param")).not.toBeInTheDocument();
+ });
+
+ it("should show stake value when not loading", () => {
+ render();
+
+ const param = screen.getByTestId("trade-param");
+ expect(param).toBeInTheDocument();
+ expect(param).toHaveAttribute("data-label", "Stake");
+ expect(param).toHaveAttribute("data-value", "100 USD");
+ expect(screen.queryByTestId("stake-field-skeleton")).not.toBeInTheDocument();
+ });
});
- it("should update isSelected state when clicked", () => {
- render();
+ describe("Portrait Mode", () => {
+ beforeEach(() => {
+ (
+ useOrientationStore as jest.MockedFunction
+ ).mockReturnValue({
+ isLandscape: false,
+ });
+ });
- const container = screen.getByTestId("desktop-trade-field-card")
- .firstChild as HTMLElement;
- expect(container.parentElement).toHaveAttribute("data-selected", "false");
+ it("should open bottom sheet when clicked", () => {
+ render();
- fireEvent.click(container);
- expect(container.parentElement).toHaveAttribute("data-selected", "true");
+ fireEvent.click(screen.getByTestId("trade-param"));
- // Blur should unselect
- fireEvent.blur(container);
- expect(container.parentElement).toHaveAttribute("data-selected", "false");
+ expect(mockSetBottomSheet).toHaveBeenCalledWith(true, "stake", "400px");
+ });
});
- it("should handle increment/decrement with validation", () => {
- const mockSetStake = jest.fn();
- (
- useTradeStore as jest.MockedFunction
- ).mockReturnValue({
- stake: "100",
- setStake: mockSetStake,
- isConfigLoading: false,
- });
-
- render();
-
- // Test increment (step = 1)
- fireEvent.click(screen.getByLabelText("Increase stake"));
- expect(mockSetStake).toHaveBeenCalledWith("101"); // 100 + 1
-
- // Test decrement (step = 1)
- fireEvent.click(screen.getByLabelText("Decrease stake"));
- expect(mockSetStake).toHaveBeenCalledWith("99"); // 100 - 1
- });
-
- it("should show error state and tooltip when validation fails", () => {
- render();
-
- const input = screen.getByLabelText("Stake amount");
- fireEvent.change(input, { target: { value: "" } }); // Empty value triggers error
-
- const card = screen.getByTestId("desktop-trade-field-card");
- expect(card).toHaveAttribute("data-error", "true");
-
- // Verify tooltip is shown with error message
- expect(mockShowTooltip).toHaveBeenCalledWith(
- "Please enter an amount",
- expect.any(Object),
- "error"
- );
-
- // Verify tooltip is hidden when valid value is entered
- fireEvent.change(input, { target: { value: "100" } });
- expect(mockHideTooltip).toHaveBeenCalled();
+ describe("Landscape Mode", () => {
+ beforeEach(() => {
+ (
+ useOrientationStore as jest.MockedFunction
+ ).mockReturnValue({
+ isLandscape: true,
+ });
+ });
+
+ it("should show input field and increment/decrement buttons", () => {
+ render();
+
+ expect(screen.getByLabelText("Stake amount")).toBeInTheDocument();
+ expect(screen.getByLabelText("Decrease stake")).toBeInTheDocument();
+ expect(screen.getByLabelText("Increase stake")).toBeInTheDocument();
+ });
+
+ it("should update isSelected state when clicked", () => {
+ render();
+
+ const container = screen.getByTestId("desktop-trade-field-card")
+ .firstChild as HTMLElement;
+ expect(container.parentElement).toHaveAttribute("data-selected", "false");
+
+ fireEvent.click(container);
+ expect(container.parentElement).toHaveAttribute("data-selected", "true");
+
+ // Blur should unselect
+ fireEvent.blur(container);
+ expect(container.parentElement).toHaveAttribute("data-selected", "false");
+ });
+
+ it("should handle increment/decrement with validation", () => {
+ const mockSetStake = jest.fn();
+ (useTradeStore as jest.MockedFunction).mockReturnValue({
+ stake: "100",
+ setStake: mockSetStake,
+ isConfigLoading: false,
+ });
+
+ render();
+
+ // Test increment (step = 1)
+ fireEvent.click(screen.getByLabelText("Increase stake"));
+ expect(mockSetStake).toHaveBeenCalledWith("101"); // 100 + 1
+
+ // Test decrement (step = 1)
+ fireEvent.click(screen.getByLabelText("Decrease stake"));
+ expect(mockSetStake).toHaveBeenCalledWith("99"); // 100 - 1
+ });
+
+ it("should show error state and tooltip when validation fails", () => {
+ render();
+
+ const input = screen.getByLabelText("Stake amount");
+ fireEvent.change(input, { target: { value: "" } }); // Empty value triggers error
+
+ const card = screen.getByTestId("desktop-trade-field-card");
+ expect(card).toHaveAttribute("data-error", "true");
+
+ // Verify tooltip is shown with error message
+ expect(mockShowTooltip).toHaveBeenCalledWith(
+ "Please enter an amount",
+ expect.any(Object),
+ "error"
+ );
+
+ // Verify tooltip is hidden when valid value is entered
+ fireEvent.change(input, { target: { value: "100" } });
+ expect(mockHideTooltip).toHaveBeenCalled();
+ });
});
- });
});
diff --git a/src/components/Stake/components/StakeInput.tsx b/src/components/Stake/components/StakeInput.tsx
index 56f73a3..d36b404 100644
--- a/src/components/Stake/components/StakeInput.tsx
+++ b/src/components/Stake/components/StakeInput.tsx
@@ -6,124 +6,120 @@ import { incrementStake, decrementStake } from "@/utils/stake";
import { useClientStore } from "@/stores/clientStore";
interface StakeInputProps {
- value: string;
- onChange: (value: string) => void;
- onBlur?: () => void;
- isDesktop?: boolean;
- error?: boolean;
- errorMessage?: string;
- maxPayout?: number;
+ value: string;
+ onChange: (value: string) => void;
+ onBlur?: () => void;
+ isDesktop?: boolean;
+ error?: boolean;
+ errorMessage?: string;
+ maxPayout?: number;
}
export const StakeInput: React.FC = ({
- value,
- onChange,
- onBlur,
- isDesktop,
- error,
- errorMessage,
- maxPayout,
+ value,
+ onChange,
+ onBlur,
+ isDesktop,
+ error,
+ errorMessage,
+ maxPayout,
}) => {
- const { currency } = useClientStore();
+ const { currency } = useClientStore();
- const handleIncrement = () => {
- onChange(incrementStake(value || "0"));
- };
+ const handleIncrement = () => {
+ onChange(incrementStake(value || "0"));
+ };
- const handleDecrement = () => {
- onChange(decrementStake(value || "0"));
- };
+ const handleDecrement = () => {
+ onChange(decrementStake(value || "0"));
+ };
- const handleChange = (e: React.ChangeEvent) => {
- const numericValue = e.target.value.replace(/[^0-9.]/g, "");
- const currentAmount = value ? value.split(" ")[0] : "";
- const amount = parseFloat(numericValue);
+ const handleChange = (e: React.ChangeEvent) => {
+ const numericValue = e.target.value.replace(/[^0-9.]/g, "");
+ const currentAmount = value ? value.split(" ")[0] : "";
+ const amount = parseFloat(numericValue);
- // Only prevent adding more numbers if there's a max error
- if (
- error &&
- maxPayout &&
- amount > maxPayout &&
- e.target.value.length > currentAmount.length
- ) {
- return;
- }
+ // Only prevent adding more numbers if there's a max error
+ if (
+ error &&
+ maxPayout &&
+ amount > maxPayout &&
+ e.target.value.length > currentAmount.length
+ ) {
+ return;
+ }
- if (numericValue === "") {
- onChange("");
- return;
- }
+ if (numericValue === "") {
+ onChange("");
+ return;
+ }
- if (!isNaN(amount)) {
- onChange(amount.toString());
- }
- };
+ if (!isNaN(amount)) {
+ onChange(amount.toString());
+ }
+ };
- const amount = value ? value.split(" ")[0] : "";
+ const amount = value ? value.split(" ")[0] : "";
- const inputRef = useRef(null);
+ const inputRef = useRef(null);
- useEffect(() => {
- // Focus input when component mounts
- inputRef.current?.focus();
- }, []);
+ useEffect(() => {
+ // Focus input when component mounts
+ inputRef.current?.focus();
+ }, []);
- return (
-
- {isDesktop ? (
- <>
-
-
- −
-
-
- }
- rightIcon={
-
- }
- type="text"
- inputMode="decimal"
- aria-label="Stake amount"
- />
- >
- ) : (
-
- )}
-
- );
+ return (
+
+ {isDesktop ? (
+ <>
+
+ −
+
+ }
+ rightIcon={
+
+ }
+ type="text"
+ inputMode="decimal"
+ aria-label="Stake amount"
+ />
+ >
+ ) : (
+
+ )}
+
+ );
};
diff --git a/src/components/Stake/hooks/useStakeField.ts b/src/components/Stake/hooks/useStakeField.ts
index 9ef23f6..b60c0c7 100644
--- a/src/components/Stake/hooks/useStakeField.ts
+++ b/src/components/Stake/hooks/useStakeField.ts
@@ -1,163 +1,155 @@
import { useState, useRef, useEffect } from "react";
import { useTradeStore } from "@/stores/tradeStore";
import { useClientStore } from "@/stores/clientStore";
-import {
- incrementStake,
- decrementStake,
- parseStakeAmount,
-} from "@/utils/stake";
+import { incrementStake, decrementStake, parseStakeAmount } from "@/utils/stake";
import { getStakeConfig } from "@/adapters/stake-config-adapter";
import { useBottomSheetStore } from "@/stores/bottomSheetStore";
import { useTooltipStore } from "@/stores/tooltipStore";
import { validateStake } from "../utils/validation";
export const useStakeField = () => {
- const { stake, setStake, isConfigLoading } = useTradeStore();
- const { currency } = useClientStore();
- const { setBottomSheet } = useBottomSheetStore();
- const { showTooltip, hideTooltip } = useTooltipStore();
- const [isStakeSelected, setIsStakeSelected] = useState(false);
- const [error, setError] = useState(false);
- const [errorMessage, setErrorMessage] = useState();
- const [localValue, setLocalValue] = useState(stake);
- const inputRef = useRef(null);
- const containerRef = useRef(null);
-
- useEffect(() => {
- setLocalValue(stake);
- }, [stake]);
-
- const showError = (message: string) => {
- if (containerRef.current) {
- const rect = containerRef.current.getBoundingClientRect();
- showTooltip(
- message,
- { x: rect.left - 8, y: rect.top + rect.height / 2 },
- "error"
- );
- }
- };
-
- const validateAndUpdateStake = (value: string) => {
- const amount = parseStakeAmount(value || "0");
- const validation = validateStake({
- amount,
- minStake: getStakeConfig().min,
- maxStake: getStakeConfig().max,
- currency,
- });
-
- setError(validation.error);
- setErrorMessage(validation.message);
- if (validation.error && validation.message) {
- showError(validation.message);
- }
- return !validation.error;
- };
-
- const handleIncrement = () => {
- const newValue = incrementStake(stake || "0");
- if (validateAndUpdateStake(newValue)) {
- setStake(newValue);
- hideTooltip();
- }
- };
-
- const handleDecrement = () => {
- const newValue = decrementStake(stake || "0");
- if (validateAndUpdateStake(newValue)) {
- setStake(newValue);
- hideTooltip();
- }
- };
-
- const handleSelect = (selected: boolean) => {
- setIsStakeSelected(selected);
-
- // Show error tooltip if there's an error
- if (error && errorMessage) {
- showError(errorMessage);
- }
- };
-
- const handleChange = (e: React.ChangeEvent) => {
- // Get cursor position before update
- const cursorPosition = e.target.selectionStart;
-
- // Extract only the number part
- let value = e.target.value;
-
- // If backspace was pressed and we're at the currency part, ignore it
- if (value.length < localValue.length && value.endsWith(currency)) {
- return;
- }
-
- // Remove currency and any non-numeric characters except decimal point
- value = value.replace(new RegExp(`\\s*${currency}$`), "").trim();
- value = value.replace(/[^\d.]/g, "");
-
- // Ensure only one decimal point
- const parts = value.split(".");
- if (parts.length > 2) {
- value = parts[0] + "." + parts.slice(1).join("");
- }
-
- // Remove leading zeros unless it's just "0"
- if (value !== "0") {
- value = value.replace(/^0+/, "");
- }
-
- // If it starts with a decimal, add leading zero
- if (value.startsWith(".")) {
- value = "0" + value;
- }
-
- setLocalValue(value);
-
- if (value === "") {
- setError(true);
- const message = "Please enter an amount";
- setErrorMessage(message);
- showError(message);
- setStake("");
- return;
- }
-
- const numValue = parseFloat(value);
- if (!isNaN(numValue)) {
- if (validateAndUpdateStake(value)) {
- setStake(value);
- hideTooltip();
- }
-
- // Restore cursor position after React updates the input
- setTimeout(() => {
- if (inputRef.current && cursorPosition !== null) {
- inputRef.current.selectionStart = cursorPosition;
- inputRef.current.selectionEnd = cursorPosition;
+ const { stake, setStake, isConfigLoading } = useTradeStore();
+ const { currency } = useClientStore();
+ const { setBottomSheet } = useBottomSheetStore();
+ const { showTooltip, hideTooltip } = useTooltipStore();
+ const [isStakeSelected, setIsStakeSelected] = useState(false);
+ const [error, setError] = useState(false);
+ const [errorMessage, setErrorMessage] = useState();
+ const [localValue, setLocalValue] = useState(stake);
+ const inputRef = useRef(null);
+ const containerRef = useRef(null);
+
+ useEffect(() => {
+ setLocalValue(stake);
+ }, [stake]);
+
+ const showError = (message: string) => {
+ if (containerRef.current) {
+ const rect = containerRef.current.getBoundingClientRect();
+ showTooltip(message, { x: rect.left - 8, y: rect.top + rect.height / 2 }, "error");
}
- }, 0);
- }
- };
-
- const handleMobileClick = () => {
- setBottomSheet(true, "stake", "400px");
- };
-
- return {
- stake,
- currency,
- isStakeSelected,
- isConfigLoading,
- error,
- errorMessage,
- localValue,
- inputRef,
- containerRef,
- handleSelect,
- handleChange,
- handleIncrement,
- handleDecrement,
- handleMobileClick,
- };
+ };
+
+ const validateAndUpdateStake = (value: string) => {
+ const amount = parseStakeAmount(value || "0");
+ const validation = validateStake({
+ amount,
+ minStake: getStakeConfig().min,
+ maxStake: getStakeConfig().max,
+ currency,
+ });
+
+ setError(validation.error);
+ setErrorMessage(validation.message);
+ if (validation.error && validation.message) {
+ showError(validation.message);
+ }
+ return !validation.error;
+ };
+
+ const handleIncrement = () => {
+ const newValue = incrementStake(stake || "0");
+ if (validateAndUpdateStake(newValue)) {
+ setStake(newValue);
+ hideTooltip();
+ }
+ };
+
+ const handleDecrement = () => {
+ const newValue = decrementStake(stake || "0");
+ if (validateAndUpdateStake(newValue)) {
+ setStake(newValue);
+ hideTooltip();
+ }
+ };
+
+ const handleSelect = (selected: boolean) => {
+ setIsStakeSelected(selected);
+
+ // Show error tooltip if there's an error
+ if (error && errorMessage) {
+ showError(errorMessage);
+ }
+ };
+
+ const handleChange = (e: React.ChangeEvent) => {
+ // Get cursor position before update
+ const cursorPosition = e.target.selectionStart;
+
+ // Extract only the number part
+ let value = e.target.value;
+
+ // If backspace was pressed and we're at the currency part, ignore it
+ if (value.length < localValue.length && value.endsWith(currency)) {
+ return;
+ }
+
+ // Remove currency and any non-numeric characters except decimal point
+ value = value.replace(new RegExp(`\\s*${currency}$`), "").trim();
+ value = value.replace(/[^\d.]/g, "");
+
+ // Ensure only one decimal point
+ const parts = value.split(".");
+ if (parts.length > 2) {
+ value = parts[0] + "." + parts.slice(1).join("");
+ }
+
+ // Remove leading zeros unless it's just "0"
+ if (value !== "0") {
+ value = value.replace(/^0+/, "");
+ }
+
+ // If it starts with a decimal, add leading zero
+ if (value.startsWith(".")) {
+ value = "0" + value;
+ }
+
+ setLocalValue(value);
+
+ if (value === "") {
+ setError(true);
+ const message = "Please enter an amount";
+ setErrorMessage(message);
+ showError(message);
+ setStake("");
+ return;
+ }
+
+ const numValue = parseFloat(value);
+ if (!isNaN(numValue)) {
+ if (validateAndUpdateStake(value)) {
+ setStake(value);
+ hideTooltip();
+ }
+
+ // Restore cursor position after React updates the input
+ setTimeout(() => {
+ if (inputRef.current && cursorPosition !== null) {
+ inputRef.current.selectionStart = cursorPosition;
+ inputRef.current.selectionEnd = cursorPosition;
+ }
+ }, 0);
+ }
+ };
+
+ const handleMobileClick = () => {
+ setBottomSheet(true, "stake", "400px");
+ };
+
+ return {
+ stake,
+ currency,
+ isStakeSelected,
+ isConfigLoading,
+ error,
+ errorMessage,
+ localValue,
+ inputRef,
+ containerRef,
+ handleSelect,
+ handleChange,
+ handleIncrement,
+ handleDecrement,
+ handleMobileClick,
+ };
};
diff --git a/src/components/Stake/utils/validation.ts b/src/components/Stake/utils/validation.ts
index 39219bf..1065a68 100644
--- a/src/components/Stake/utils/validation.ts
+++ b/src/components/Stake/utils/validation.ts
@@ -1,34 +1,34 @@
interface ValidateStakeParams {
- amount: number;
- minStake: number;
- maxStake: number;
- currency: string;
+ amount: number;
+ minStake: number;
+ maxStake: number;
+ currency: string;
}
interface ValidationResult {
- error: boolean;
- message?: string;
+ error: boolean;
+ message?: string;
}
export const validateStake = ({
- amount,
- minStake,
- maxStake,
- currency
+ amount,
+ minStake,
+ maxStake,
+ currency,
}: ValidateStakeParams): ValidationResult => {
- if (amount < minStake) {
- return {
- error: true,
- message: `Minimum stake is ${minStake} ${currency}`
- };
- }
+ if (amount < minStake) {
+ return {
+ error: true,
+ message: `Minimum stake is ${minStake} ${currency}`,
+ };
+ }
- if (amount > maxStake) {
- return {
- error: true,
- message: `Minimum stake of ${minStake} ${currency} and maximum stake of ${maxStake} ${currency}. Current stake is ${amount} ${currency}.`
- };
- }
+ if (amount > maxStake) {
+ return {
+ error: true,
+ message: `Minimum stake of ${minStake} ${currency} and maximum stake of ${maxStake} ${currency}. Current stake is ${amount} ${currency}.`,
+ };
+ }
- return { error: false };
+ return { error: false };
};
diff --git a/src/components/TradeFields/TradeParam.tsx b/src/components/TradeFields/TradeParam.tsx
index f03feac..01fac0c 100644
--- a/src/components/TradeFields/TradeParam.tsx
+++ b/src/components/TradeFields/TradeParam.tsx
@@ -1,64 +1,56 @@
import React from "react";
import { formatDurationDisplay } from "@/utils/duration";
interface TradeParamProps {
- label: string;
- value: string;
- onClick?: () => void;
- className?: string;
+ label: string;
+ value: string;
+ onClick?: () => void;
+ className?: string;
}
-const TradeParam: React.FC = ({
- label,
- value,
- onClick,
- className,
-}) => {
- const formattedValue =
- label === "Duration" ? formatDurationDisplay(value) : value;
+const TradeParam: React.FC = ({ label, value, onClick, className }) => {
+ const formattedValue = label === "Duration" ? formatDurationDisplay(value) : value;
- const labelClasses =
- "text-left font-ibm-plex text-xs leading-[18px] font-normal text-primary";
- const valueClasses =
- "text-left font-ibm-plex text-base leading-6 font-normal text-gray-900";
+ const labelClasses = "text-left font-ibm-plex text-xs leading-[18px] font-normal text-primary";
+ const valueClasses = "text-left font-ibm-plex text-base leading-6 font-normal text-gray-900";
+
+ if (onClick) {
+ return (
+
+ );
+ }
- if (onClick) {
return (
-