Skip to content

Commit

Permalink
Merge pull request deriv-com#11 from mayuran-deriv/mayuran/globalstor…
Browse files Browse the repository at this point in the history
…e-and-price-validation

Mayuran/globalstore and price validation
  • Loading branch information
mayuran-deriv authored Jan 5, 2025
2 parents 8c1277d + 3dd5c15 commit 91e7562
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 116 deletions.
38 changes: 25 additions & 13 deletions src/components/TradingComponents/Chart/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,42 @@ import { getDerivAPI } from "../../../services/deriv-api.instance";
import { SmartChart, ChartTitle } from "@deriv/deriv-charts";
import { isBrowser } from "../../../common/utils";
import "@deriv/deriv-charts/dist/smartcharts.css";
import { ChartSettings, ChartProps } from "../types";
import { ChartSettings } from "../types";
import { observer } from "mobx-react-lite";
import { chartStore } from "../../../stores/ChartStore";
import { ReconnectingLoader } from "../../ReconnectingLoader/ReconnectingLoader";
import "./Chart.scss";

export const Chart = ({
symbol,
chartStatus,
showChart,
onChartStatusChange,
onSymbolChange,
}: ChartProps) => {
export const Chart = observer(() => {
const {
symbol,
chartStatus,
showChart,
setChartStatus,
setSymbol,
setShowChart,
} = chartStore;
const derivAPI = getDerivAPI();
const [isConnected, setIsConnected] = useState(derivAPI.isConnected());

// Initialize chart store
useEffect(() => {
setSymbol("1HZ10V");
setChartStatus(true);
setShowChart(isBrowser());
}, []);

// Handle connection changes
useEffect(() => {
const cleanup = derivAPI.onConnectionChange((connected: boolean) => {
setIsConnected(connected);
onChartStatusChange(connected && isBrowser());
setChartStatus(connected && isBrowser());
});

// Initial state
const initialConnected = derivAPI.isConnected();
setIsConnected(initialConnected);
onChartStatusChange(initialConnected && isBrowser());
setChartStatus(initialConnected && isBrowser());

return cleanup;
}, [derivAPI]);
Expand Down Expand Up @@ -82,7 +94,7 @@ export const Chart = ({
barriers={barriers}
chartControlsWidgets={null}
enabledChartFooter={true}
chartStatusListener={(v: boolean) => onChartStatusChange(!v)}
chartStatusListener={(v: boolean) => setChartStatus(!v)}
toolbarWidget={() => <></>}
chartType={"line"}
isMobile={false}
Expand All @@ -94,12 +106,12 @@ export const Chart = ({
requestSubscribe={requestSubscribe}
settings={settings}
symbol={symbol}
topWidgets={() => <ChartTitle onChange={onSymbolChange} />}
topWidgets={() => <ChartTitle onChange={setSymbol} />}
isConnectionOpened={is_connection_opened}
isLive
/>
)}
</div>
</div>
);
};
});
88 changes: 55 additions & 33 deletions src/components/TradingComponents/TradingPanel/TradingPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,39 @@ import {
TextFieldWithSteppers,
} from "@deriv-com/quill-ui";
import { Tab } from "../Tab";
import { LabelPairedBackwardSmBoldIcon, TradeTypesUpsAndDownsRiseIcon, TradeTypesUpsAndDownsFallIcon, LabelPairedCircleInfoSmBoldIcon } from "@deriv/quill-icons";
import { TradingPanelProps, DurationTabValue, StakeTabValue } from "../types";
import {
LabelPairedBackwardSmBoldIcon,
TradeTypesUpsAndDownsRiseIcon,
TradeTypesUpsAndDownsFallIcon,
LabelPairedCircleInfoSmBoldIcon,
} from "@deriv/quill-icons";
import { DurationTabValue, StakeTabValue } from "../types";
import { observer } from "mobx-react-lite";
import { tradingPanelStore } from "../../../stores/TradingPanelStore";
import "./TradingPanel.scss";

export const TradingPanel = ({
duration,
stake,
allowEquals,
selectedDurationTab,
selectedStakeTab,
onDurationChange,
onStakeChange,
onAllowEqualsChange,
onDurationTabChange,
onStakeTabChange,
}: TradingPanelProps) => {
export const TradingPanel = observer(() => {
const {
duration,
price,
allowEquals,
selectedDurationTab,
selectedStakeTab,
setDuration,
setPrice,
setAllowEquals,
setSelectedDurationTab,
setSelectedStakeTab,
} = tradingPanelStore;

const durationTabs: Array<{ label: string; value: DurationTabValue }> = [
{ label: "Duration", value: "duration" },
{ label: "End time", value: "endtime" }
{ label: "End time", value: "endtime" },
];

const stakeTabs: Array<{ label: string; value: StakeTabValue }> = [
{ label: "Stake", value: "stake" },
{ label: "Payout", value: "payout" }
{ label: "Payout", value: "payout" },
];

return (
Expand Down Expand Up @@ -64,21 +73,21 @@ export const TradingPanel = ({
<Tab
tabs={durationTabs}
activeTab={selectedDurationTab}
onChange={onDurationTabChange}
onChange={setSelectedDurationTab}
/>
{selectedDurationTab === "duration" ? (
<div className="duration-input">
<Text as="span" size="sm" className="text-bold">
Minutes
</Text>
<TextFieldWithSteppers
value={duration.toString()}
onChange={(e) => onDurationChange(e.target.value)}
className="duration-field"
/>
<Text as="span" size="sm" className="text-less-prominent">
Range: 1 - 1,440 minutes
</Text>
<Text as="span" size="sm" className="text-bold">
Minutes
</Text>
<TextFieldWithSteppers
value={duration.toString()}
onChange={(e) => setDuration(e.target.value)}
className="duration-field"
/>
<Text as="span" size="sm" className="text-less-prominent">
Range: 1 - 1,440 minutes
</Text>
</div>
) : (
<div className="endtime-inputs">
Expand All @@ -102,11 +111,22 @@ export const TradingPanel = ({
<Tab
tabs={stakeTabs}
activeTab={selectedStakeTab}
onChange={onStakeTabChange}
onChange={setSelectedStakeTab}
/>
<TextFieldWithSteppers
value={stake.toString()}
onChange={(e) => onStakeChange(e.target.value)}
type="text"
allowDecimals
allowSign={false}
regex={/[^0-9.,]/g}
inputMode="decimal"
shouldRound={false}
customType="commaRemoval"
decimals={2}
textAlignment="center"
minusDisabled={Number(price) - 1 <= 0}
variant="fill"
value={price}
onChange={(e) => setPrice(e.target.value)}
unitRight="USD"
className="stake-field"
/>
Expand All @@ -117,7 +137,9 @@ export const TradingPanel = ({
<Checkbox
name="allow-equals"
checked={allowEquals}
onChange={onAllowEqualsChange}
onChange={(e) =>
setAllowEquals((e.target as HTMLInputElement).checked)
}
label="Allow equals"
/>
<Tooltip tooltipContent="Allow equals tooltip">
Expand Down Expand Up @@ -172,4 +194,4 @@ export const TradingPanel = ({
</div>
</div>
);
};
});
18 changes: 11 additions & 7 deletions src/components/TradingComponents/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,26 @@ export interface ChartProps {
onSymbolChange: (symbol: string) => void;
}

export type DurationTabValue = 'duration' | 'endtime';
export type StakeTabValue = 'stake' | 'payout';
export type DurationTabValue = "duration" | "endtime";
export type StakeTabValue = "stake" | "payout";

export interface TradingPanelProps {
duration: number;
stake: number;
price: number;
allowEquals: boolean;
selectedDurationTab: DurationTabValue;
selectedStakeTab: StakeTabValue;
onDurationChange: (value: string) => void;
onStakeChange: (value: string) => void;
onAllowEqualsChange: (e: React.ChangeEvent<HTMLInputElement> | React.KeyboardEvent<HTMLSpanElement>) => void;
onPriceChange: (value: string) => void;
onAllowEqualsChange: (
e:
| React.ChangeEvent<HTMLInputElement>
| React.KeyboardEvent<HTMLSpanElement>
) => void;
onDurationTabChange: (tab: DurationTabValue) => void;
onStakeTabChange: (tab: StakeTabValue) => void;
onDurationIncrement: () => void;
onDurationDecrement: () => void;
onStakeIncrement: () => void;
onStakeDecrement: () => void;
onPriceIncrement: () => void;
onPriceDecrement: () => void;
}
68 changes: 5 additions & 63 deletions src/features/DerivTrading.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,13 @@
import { useEffect, useState } from "react";
import { isBrowser } from "../common/utils";
import { Chart } from "../components/TradingComponents/Chart/Chart";
import { TradingPanel } from "../components/TradingComponents/TradingPanel/TradingPanel";
import { DurationTabValue, StakeTabValue } from "../components/TradingComponents/types";
import "@deriv/deriv-charts/dist/smartcharts.css";
import "./DerivTrading.scss";

export default function DerivTrading() {
const [symbol, setSymbol] = useState<string>("1HZ10V");
const [chartStatus, setChartStatus] = useState<boolean>(true);
const [showChart, setShowChart] = useState<boolean>(false);
const [duration, setDuration] = useState(1);
const [stake, setStake] = useState(50);
const [allowEquals, setAllowEquals] = useState(false);
const [selectedDurationTab, setSelectedDurationTab] = useState<DurationTabValue>('duration');
const [selectedStakeTab, setSelectedStakeTab] = useState<StakeTabValue>('stake');

useEffect(() => {
setShowChart(isBrowser());
}, []);

const handleDurationChange = (value: string) => {
const numValue = parseInt(value);
if (!isNaN(numValue)) {
setDuration(Math.min(Math.max(numValue, 1), 1440));
}
};

const handleStakeChange = (value: string) => {
const numValue = parseFloat(value);
if (!isNaN(numValue)) {
setStake(numValue);
}
};

const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement> | React.KeyboardEvent<HTMLSpanElement>) => {
if (e.target instanceof HTMLInputElement) {
setAllowEquals(e.target.checked);
}
};

import { observer } from "mobx-react-lite";
export default observer(function DerivTrading() {
return (
<div className="trading-container">
<Chart
symbol={symbol}
chartStatus={chartStatus}
showChart={showChart}
onChartStatusChange={setChartStatus}
onSymbolChange={setSymbol}
/>

<TradingPanel
duration={duration}
stake={stake}
allowEquals={allowEquals}
selectedDurationTab={selectedDurationTab}
selectedStakeTab={selectedStakeTab}
onDurationChange={handleDurationChange}
onStakeChange={handleStakeChange}
onAllowEqualsChange={handleCheckboxChange}
onDurationTabChange={setSelectedDurationTab}
onStakeTabChange={setSelectedStakeTab}
onDurationIncrement={() => setDuration(Math.min(1440, duration + 1))}
onDurationDecrement={() => setDuration(Math.max(1, duration - 1))}
onStakeIncrement={() => setStake(stake + 1)}
onStakeDecrement={() => setStake(Math.max(0, stake - 1))}
/>
<Chart />
<TradingPanel />
</div>
);
}
});
25 changes: 25 additions & 0 deletions src/stores/ChartStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { makeAutoObservable } from "mobx";

export class ChartStore {
symbol: string = "";
chartStatus: boolean = false;
showChart: boolean = false;

constructor() {
makeAutoObservable(this);
}

setSymbol = (symbol: string) => {
this.symbol = symbol;
};

setChartStatus = (status: boolean) => {
this.chartStatus = status;
};

setShowChart = (show: boolean) => {
this.showChart = show;
};
}

export const chartStore = new ChartStore();
41 changes: 41 additions & 0 deletions src/stores/TradingPanelStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { makeAutoObservable } from "mobx";

export class TradingPanelStore {
duration = 1;
price = "0";
allowEquals = false;
selectedDurationTab: "duration" | "endtime" = "duration";
selectedStakeTab: "stake" | "payout" = "stake";

constructor() {
makeAutoObservable(this);
}

setDuration = (value: string) => {
const numValue = parseInt(value);
if (!isNaN(numValue)) {
this.duration = Math.min(Math.max(numValue, 1), 1440);
}
};

setPrice = (value: string) => {
const numValue = parseFloat(value);
if (!isNaN(numValue)) {
this.price = numValue.toString();
}
};

setAllowEquals = (value: boolean) => {
this.allowEquals = value;
};

setSelectedDurationTab = (value: "duration" | "endtime") => {
this.selectedDurationTab = value;
};

setSelectedStakeTab = (value: "stake" | "payout") => {
this.selectedStakeTab = value;
};
}

export const tradingPanelStore = new TradingPanelStore();

0 comments on commit 91e7562

Please sign in to comment.