-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1003 from mrgnlabs/feat/tradingbox-v2
feat(mfi-trading): tradingbox v2
- Loading branch information
Showing
54 changed files
with
2,745 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
...-v2-trading/src/components/common/trade-box-v2/components/action-button/action-button.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { IconLoader2 } from "@tabler/icons-react"; | ||
import React from "react"; | ||
|
||
import { WalletButton } from "~/components/wallet-v2"; | ||
import { Button } from "~/components/ui/button"; | ||
import { cn } from "@mrgnlabs/mrgn-utils"; | ||
|
||
type ActionButtonProps = { | ||
isLoading: boolean; | ||
isEnabled: boolean; | ||
buttonLabel: string; | ||
connected?: boolean; | ||
handleAction: () => void; | ||
tradeState: "long" | "short"; | ||
}; | ||
|
||
export const ActionButton = ({ | ||
isLoading, | ||
isEnabled, | ||
buttonLabel, | ||
connected = false, | ||
handleAction, | ||
tradeState, | ||
}: ActionButtonProps) => { | ||
if (!connected) { | ||
return <WalletButton className="w-full py-5 bg-muted-foreground" showWalletInfo={false} />; | ||
} | ||
|
||
return ( | ||
<Button | ||
disabled={isLoading || !isEnabled} | ||
className={cn("w-full", tradeState === "long" && "bg-success", tradeState === "short" && "bg-error")} | ||
onClick={handleAction} | ||
> | ||
{isLoading ? <IconLoader2 className="animate-spin" /> : buttonLabel} | ||
</Button> | ||
); | ||
}; |
1 change: 1 addition & 0 deletions
1
.../marginfi-v2-trading/src/components/common/trade-box-v2/components/action-button/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./action-button"; |
76 changes: 76 additions & 0 deletions
76
...nents/common/trade-box-v2/components/action-simulation-status/action-simuation-status.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import React from "react"; | ||
|
||
import { IconCheck, IconX } from "@tabler/icons-react"; | ||
|
||
import { IconLoader } from "~/components/ui/icons"; | ||
import { SimulationStatus } from "~/components/common/trade-box-v2/utils"; | ||
|
||
type ActionSimulationStatusProps = { | ||
simulationStatus: SimulationStatus; | ||
hasErrorMessages: boolean; | ||
isActive: boolean; | ||
}; | ||
|
||
enum SimulationCompleteStatus { | ||
NULL = "NULL", | ||
LOADING = "LOADING", | ||
SUCCESS = "SUCCESS", | ||
ERROR = "ERROR", | ||
} | ||
|
||
const ActionSimulationStatus = ({ | ||
simulationStatus, | ||
hasErrorMessages = false, | ||
isActive = false, | ||
}: ActionSimulationStatusProps) => { | ||
const [simulationCompleteStatus, setSimulationCompleteStatus] = React.useState<SimulationCompleteStatus>( | ||
SimulationCompleteStatus.NULL | ||
); | ||
const [isNewSimulation, setIsNewSimulation] = React.useState(false); | ||
|
||
React.useEffect(() => { | ||
if (simulationStatus === SimulationStatus.SIMULATING || simulationStatus === SimulationStatus.PREPARING) { | ||
setSimulationCompleteStatus(SimulationCompleteStatus.LOADING); | ||
setIsNewSimulation(false); | ||
} else if (hasErrorMessages && !isNewSimulation) { | ||
setSimulationCompleteStatus(SimulationCompleteStatus.ERROR); | ||
} else if (simulationStatus === SimulationStatus.COMPLETE && !isNewSimulation) { | ||
setSimulationCompleteStatus(SimulationCompleteStatus.SUCCESS); | ||
} | ||
}, [simulationStatus, hasErrorMessages, isNewSimulation]); | ||
|
||
React.useEffect(() => { | ||
if (!isActive) { | ||
setIsNewSimulation(true); | ||
setSimulationCompleteStatus(SimulationCompleteStatus.NULL); | ||
} | ||
}, [isActive]); | ||
|
||
if (!isActive) { | ||
return <div />; // Return empty div to align the settings button | ||
} | ||
|
||
return ( | ||
<div> | ||
{simulationCompleteStatus === SimulationCompleteStatus.LOADING && ( | ||
<p className="text-xs text-muted-foreground/75 flex items-center gap-1 mr-auto"> | ||
<IconLoader size={14} /> Simulating transaction... | ||
</p> | ||
)} | ||
|
||
{simulationCompleteStatus === SimulationCompleteStatus.SUCCESS && ( | ||
<p className="text-xs flex items-center gap-1 mr-auto text-success"> | ||
<IconCheck size={14} /> Simulation complete! | ||
</p> | ||
)} | ||
|
||
{simulationCompleteStatus === SimulationCompleteStatus.ERROR && ( | ||
<p className="text-xs flex items-center gap-1 mr-auto text-error"> | ||
<IconX size={14} /> Simulation failed | ||
</p> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export { ActionSimulationStatus }; |
1 change: 1 addition & 0 deletions
1
...2-trading/src/components/common/trade-box-v2/components/action-simulation-status/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./action-simuation-status"; |
27 changes: 27 additions & 0 deletions
27
...-v2-trading/src/components/common/trade-box-v2/components/action-toggle/action-toggle.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { TradeSide } from "~/components/common/trade-box-v2/utils"; | ||
import { ToggleGroup, ToggleGroupItem } from "~/components/ui/toggle-group"; | ||
|
||
interface ActionToggleProps { | ||
tradeState: TradeSide; | ||
setTradeState: (value: TradeSide) => void; | ||
} | ||
|
||
export const ActionToggle = ({ tradeState, setTradeState }: ActionToggleProps) => { | ||
return ( | ||
<ToggleGroup | ||
type="single" | ||
className="w-full gap-4 p-0" | ||
value={tradeState} | ||
onValueChange={(value) => { | ||
value && setTradeState(value as TradeSide); | ||
}} | ||
> | ||
<ToggleGroupItem className="w-full border" value="long" aria-label="Toggle long"> | ||
Long | ||
</ToggleGroupItem> | ||
<ToggleGroupItem className="w-full border" value="short" aria-label="Toggle short"> | ||
Short | ||
</ToggleGroupItem> | ||
</ToggleGroup> | ||
); | ||
}; |
1 change: 1 addition & 0 deletions
1
.../marginfi-v2-trading/src/components/common/trade-box-v2/components/action-toggle/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./action-toggle"; |
54 changes: 54 additions & 0 deletions
54
...fi-v2-trading/src/components/common/trade-box-v2/components/amount-input/amount-input.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import React from "react"; | ||
import Image from "next/image"; | ||
import { Input } from "~/components/ui/input"; | ||
import { MaxAction } from "./components"; | ||
import { ArenaBank } from "~/store/tradeStoreV2"; | ||
|
||
interface AmountInputProps { | ||
maxAmount: number; | ||
amount: string; | ||
collateralBank: ArenaBank | null; | ||
|
||
handleAmountChange: (value: string) => void; | ||
} | ||
|
||
export const AmountInput = ({ | ||
amount, | ||
collateralBank, | ||
maxAmount, | ||
|
||
handleAmountChange, | ||
}: AmountInputProps) => { | ||
const amountInputRef = React.useRef<HTMLInputElement>(null); | ||
|
||
return ( | ||
<div className="bg-accent p-2.5 border border-accent/150 rounded-lg"> | ||
<div className="flex justify-center gap-1 items-center font-medium "> | ||
<span className="w-full flex items-center gap-1 max-w-[162px] text-muted-foreground text-base"> | ||
{collateralBank?.meta.tokenLogoUri && ( | ||
<Image | ||
src={collateralBank?.meta.tokenLogoUri} | ||
alt={collateralBank?.meta.tokenSymbol} | ||
width={24} | ||
height={24} | ||
className="bg-background border rounded-full" | ||
/> | ||
)} | ||
{collateralBank?.meta.tokenSymbol.toUpperCase()} | ||
</span> | ||
<div> | ||
<Input | ||
type="text" | ||
ref={amountInputRef} | ||
inputMode="decimal" | ||
value={amount} | ||
onChange={(e) => handleAmountChange(e.target.value)} | ||
placeholder="0" | ||
className="bg-transparent shadow-none min-w-[130px] h-auto py-0 pr-0 text-right outline-none focus-visible:outline-none focus-visible:ring-0 border-none text-base font-medium" | ||
/> | ||
</div> | ||
</div> | ||
<MaxAction maxAmount={maxAmount} collateralBank={collateralBank} setAmount={handleAmountChange} /> | ||
</div> | ||
); | ||
}; |
2 changes: 2 additions & 0 deletions
2
...v2-trading/src/components/common/trade-box-v2/components/amount-input/components/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./token-select"; | ||
export * from "./max-action"; |
1 change: 1 addition & 0 deletions
1
...src/components/common/trade-box-v2/components/amount-input/components/max-action/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./max-action"; |
57 changes: 57 additions & 0 deletions
57
...mponents/common/trade-box-v2/components/amount-input/components/max-action/max-action.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { dynamicNumeralFormatter } from "@mrgnlabs/mrgn-common"; | ||
import React from "react"; | ||
import { ArenaBank } from "~/store/tradeStoreV2"; | ||
|
||
interface TradeActionProps { | ||
maxAmount: number; | ||
collateralBank: ArenaBank | null; | ||
|
||
setAmount: (amount: string) => void; | ||
} | ||
|
||
export const MaxAction = ({ maxAmount, collateralBank, setAmount }: TradeActionProps) => { | ||
const maxLabel = React.useMemo((): { | ||
amount: string; | ||
showWalletIcon?: boolean; | ||
label?: string; | ||
} => { | ||
if (!collateralBank) { | ||
return { | ||
amount: "-", | ||
showWalletIcon: false, | ||
}; | ||
} | ||
|
||
const formatAmount = (maxAmount?: number, symbol?: string) => | ||
maxAmount !== undefined ? `${dynamicNumeralFormatter(maxAmount)} ${symbol?.toUpperCase()}` : "-"; | ||
|
||
return { | ||
amount: formatAmount(maxAmount, collateralBank.meta.tokenSymbol), | ||
label: "Wallet: ", | ||
}; | ||
}, [collateralBank, maxAmount]); | ||
return ( | ||
<> | ||
{collateralBank && ( | ||
<ul className="flex flex-col gap-0.5 mt-2 text-xs w-full text-muted-foreground"> | ||
<li className="flex justify-between items-center gap-1.5"> | ||
<strong className="mr-auto">{maxLabel.label}</strong> | ||
<div className="flex space-x-1"> | ||
<div>{maxLabel.amount}</div> | ||
|
||
<button | ||
className="cursor-pointer border-b border-transparent transition text-mfi-action-box-highlight hover:border-mfi-action-box-highlight" | ||
disabled={maxAmount === 0} | ||
onClick={() => { | ||
setAmount(maxAmount.toString()); | ||
}} | ||
> | ||
MAX | ||
</button> | ||
</div> | ||
</li> | ||
</ul> | ||
)} | ||
</> | ||
); | ||
}; |
1 change: 1 addition & 0 deletions
1
...c/components/common/trade-box-v2/components/amount-input/components/token-select/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./token-select"; |
3 changes: 3 additions & 0 deletions
3
...ents/common/trade-box-v2/components/amount-input/components/token-select/token-select.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const TokenSelect = () => { | ||
return <div>TokenSelect</div>; | ||
}; |
1 change: 1 addition & 0 deletions
1
apps/marginfi-v2-trading/src/components/common/trade-box-v2/components/amount-input/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./amount-input"; |
44 changes: 44 additions & 0 deletions
44
...2-trading/src/components/common/trade-box-v2/components/amount-preview/amount-preview.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React from "react"; | ||
|
||
import { dynamicNumeralFormatter } from "@mrgnlabs/mrgn-common"; | ||
import { cn } from "@mrgnlabs/mrgn-utils"; | ||
|
||
import { IconLoader } from "~/components/ui/icons"; | ||
import { ArenaBank } from "~/store/tradeStoreV2"; | ||
|
||
interface AmountPreviewProps { | ||
tradeSide: "long" | "short"; | ||
selectedBank: ArenaBank | null; | ||
amount: number; | ||
isLoading?: boolean; | ||
} | ||
|
||
export const AmountPreview = ({ tradeSide, amount, isLoading, selectedBank }: AmountPreviewProps) => { | ||
return ( | ||
<div className="flex flex-col gap-6"> | ||
<dl className="grid grid-cols-2 gap-y-2 text-sm"> | ||
<Stat label={`Size of ${tradeSide}`}> | ||
{isLoading ? <IconLoader size={16} /> : dynamicNumeralFormatter(amount)}{" "} | ||
{selectedBank?.meta.tokenSymbol.toUpperCase()} | ||
</Stat> | ||
</dl> | ||
</div> | ||
); | ||
}; | ||
|
||
interface StatProps { | ||
label: string; | ||
classNames?: string; | ||
children: React.ReactNode; | ||
style?: React.CSSProperties; | ||
} | ||
const Stat = ({ label, classNames, children, style }: StatProps) => { | ||
return ( | ||
<> | ||
<dt className="text-muted-foreground">{label}</dt> | ||
<dd className={cn("flex justify-end text-right items-center gap-2", classNames)} style={style}> | ||
{children} | ||
</dd> | ||
</> | ||
); | ||
}; |
1 change: 1 addition & 0 deletions
1
...marginfi-v2-trading/src/components/common/trade-box-v2/components/amount-preview/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./amount-preview"; |
Oops, something went wrong.