Skip to content
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

Added uniswap trade widget #10148

Merged
merged 13 commits into from
Dec 12, 2024
Merged
2 changes: 1 addition & 1 deletion packages/commonwealth/client/scripts/helpers/launchpad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const calculateTokenPricing = (
);
const marketCapCurrent = currentPrice * token.initial_supply;
const marketCapGoal = token.eth_market_cap_target * ethToUsdRate;
const isMarketCapGoalReached = false; // TODO: https://github.com/hicommonwealth/commonwealth/issues/9887
const isMarketCapGoalReached = marketCapCurrent >= marketCapGoal;

return {
currentPrice: parseFloat(`${currentPrice.toFixed(8)}`),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import './MarketCapProgress.scss';

interface MarketCapProgressProps {
currency?: SupportedCurrencies;
marketCap: { current: number; goal: number };
marketCap: { current: number; goal: number; isCapped: boolean };
onBodyClick?: (e: React.MouseEvent) => void;
}

Expand All @@ -18,15 +18,14 @@ const MarketCapProgress = ({
onBodyClick,
}: MarketCapProgressProps) => {
const currencySymbol = currencyNameToSymbolMap[currency];
const isCapped = marketCap.current === marketCap.goal;
const progressPercentage = Math.floor(
(marketCap.current / marketCap.goal) * 100,
);

return (
<div className="MarketCapProgress" onClick={onBodyClick}>
<progress
className={clsx('goal-progress', { isCapped })}
className={clsx('goal-progress', { isCapped: marketCap.isCapped })}
value={progressPercentage}
max={100}
/>
Expand All @@ -36,7 +35,7 @@ const MarketCapProgress = ({
{numeral(marketCap.current).format('0.0a')} | Goal {currencySymbol}
{numeral(marketCap.goal).format('0.0a')}
</CWText>
{isCapped && (
{marketCap.isCapped && (
<CWIcon iconName="rocketLaunch" className="token-capped-icon" />
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import clsx from 'clsx';
import { currencyNameToSymbolMap, SupportedCurrencies } from 'helpers/currency';
import React, { ReactNode } from 'react';
import { TradingMode } from '../../modals/TradeTokenModel';
import { CWText } from '../component_kit/cw_text';
import { CWButton } from '../component_kit/new_designs/CWButton';
import { CWTooltip } from '../component_kit/new_designs/CWTooltip';
Expand All @@ -14,12 +15,12 @@ interface TokenCardProps {
symbol: string;
iconURL: string;
currency?: SupportedCurrencies;
marketCap: { current: number; goal: number };
marketCap: { current: number; goal: number; isCapped: boolean };
price: number;
pricePercentage24HourChange: number;
mode: 'buy' | 'swap';
mode: TradingMode.Buy | TradingMode.Swap;
className?: string;
onCTAClick?: () => void;
onCTAClick?: (mode: TradingMode) => void;
onCardBodyClick?: () => void;
}

Expand Down Expand Up @@ -129,7 +130,7 @@ const TokenCard = ({
buttonWidth="full"
buttonType="secondary"
buttonAlt="green"
onClick={onCTAClick}
onClick={() => onCTAClick?.(mode)}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,18 @@

.action-btns {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
width: 100%;
padding: 8px;

&.cols-1 {
grid-template-columns: 1fr;
}

&.cols-2 {
grid-template-columns: 1fr 1fr;
}

button {
text-transform: capitalize;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { TokenView } from '@hicommonwealth/schemas';
import { ChainBase } from '@hicommonwealth/shared';
import clsx from 'clsx';
import { currencyNameToSymbolMap, SupportedCurrencies } from 'helpers/currency';
import { calculateTokenPricing } from 'helpers/launchpad';
import React, { useState } from 'react';
import app from 'state';
import { useFetchTokenUsdRateQuery } from 'state/api/communityStake';
import TradeTokenModal from 'views/modals/TradeTokenModel';
import {
import TradeTokenModal, {
TokenWithCommunity,
TradingMode,
} from 'views/modals/TradeTokenModel/TradeTokenForm';
} from 'views/modals/TradeTokenModel';
import { z } from 'zod';
import { CWDivider } from '../../../component_kit/cw_divider';
import { CWIconButton } from '../../../component_kit/cw_icon_button';
Expand Down Expand Up @@ -108,20 +108,36 @@ export const TokenTradeWidget = ({
marketCap={{
current: tokenPricing.marketCapCurrent,
goal: tokenPricing.marketCapGoal,
isCapped: tokenPricing.isMarketCapGoalReached,
}}
/>
<div className="action-btns">
{[TradingMode.Buy, TradingMode.Sell].map((mode) => (
<div
className={clsx('action-btns', {
[`cols-${tokenPricing.isMarketCapGoalReached ? 1 : 2}`]: true,
})}
>
{!tokenPricing.isMarketCapGoalReached ? (
[TradingMode.Buy, TradingMode.Sell].map((mode) => (
<CWButton
key={mode}
label={mode}
buttonAlt={mode === TradingMode.Buy ? 'green' : 'rorange'}
buttonWidth="full"
buttonType="secondary"
buttonHeight="sm"
onClick={() => handleCTAClick(mode)}
/>
))
) : (
<CWButton
key={mode}
label={mode}
buttonAlt={mode === TradingMode.Buy ? 'green' : 'rorange'}
label={TradingMode.Swap}
buttonAlt="green"
buttonWidth="full"
buttonType="secondary"
buttonHeight="sm"
onClick={() => handleCTAClick(mode)}
onClick={() => handleCTAClick(TradingMode.Swap)}
/>
))}
)}
</div>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import '../../../styles/shared.scss';
@import '../../../../styles/shared.scss';

.TradeTokenModal {
.CommonTradeModal {
overflow-y: scroll;
padding-left: 8px;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { SupportedCurrencies } from 'helpers/currency';
import useBeforeUnload from 'hooks/useBeforeUnload';
import React from 'react';
import { CWText } from '../../../components/component_kit/cw_text';
import {
CWModal,
CWModalBody,
CWModalFooter,
CWModalHeader,
} from '../../../components/component_kit/new_designs/CWModal';
import TokenIcon from '../TokenIcon';
import { TradeTokenModalProps } from '../types';
import './CommonTradeModal.scss';
import TradeTokenForm, {
useCommonTradeTokenForm,
} from './CommonTradeTokenForm';

const TRADING_CURRENCY = SupportedCurrencies.USD; // make configurable when needed

const CommonTradeModal = ({
isOpen,
onModalClose,
tradeConfig,
}: TradeTokenModalProps) => {
const { trading, addresses, isActionPending, onCTAClick } =
useCommonTradeTokenForm({
tradeConfig: {
...tradeConfig,
currency: TRADING_CURRENCY,
buyTokenPresetAmounts: [100, 300, 1000],
sellTokenPresetAmounts: ['Max'],
},
addressType: tradeConfig.addressType,
onTradeComplete: () => onModalClose?.(),
});

useBeforeUnload(isActionPending);

return (
<CWModal
open={isOpen}
onClose={() => !isActionPending && onModalClose?.()}
size="medium"
className="CommonTradeModal"
content={
<>
<CWModalHeader
label={
<CWText type="h4" className="token-info">
Trade Token - {tradeConfig.token.symbol}{' '}
{trading.token.icon_url && (
<TokenIcon size="large" url={trading.token.icon_url} />
)}
</CWText>
}
onModalClose={() => !isActionPending && onModalClose?.()}
/>
<CWModalBody>
<TradeTokenForm
trading={trading}
addresses={addresses}
onCTAClick={onCTAClick}
isActionPending={isActionPending}
/>
</CWModalBody>
<CWModalFooter>
<></>
</CWModalFooter>
</>
}
/>
);
};

export default CommonTradeModal;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '../../../../../styles/shared.scss';
@import '../../../../../../styles/shared.scss';

.AddressBalance {
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import React from 'react';
import { Skeleton } from 'views/components/Skeleton';
import { CWIcon } from 'views/components/component_kit/cw_icons/cw_icon';
import { CWText } from 'views/components/component_kit/cw_text';
import TokenIcon from '../../TokenIcon';
import { AddressBalanceProps, TradingMode } from '../types';
import TokenIcon from '../../../TokenIcon';
import { TradingMode } from '../../../types';
import { AddressBalanceProps } from '../types';
import './AddressBalance.scss';

const AddressBalance = ({ trading, addresses }: AddressBalanceProps) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '../../../../../styles/shared.scss';
@import '../../../../../../styles/shared.scss';

.AmountSelections {
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CWIcon } from 'views/components/component_kit/cw_icons/cw_icon';
import { CWText } from 'views/components/component_kit/cw_text';
import { CWTag } from 'views/components/component_kit/new_designs/CWTag';
import { CWTextInput } from 'views/components/component_kit/new_designs/CWTextInput';
import TokenIcon from '../../TokenIcon';
import TokenIcon from '../../../TokenIcon';
import { BuyAmountSelectionProps } from '../types';
import './AmountSelections.scss';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import '../../../../styles/shared.scss';
@import '../../../../../styles/shared.scss';

.TradeTokenForm {
.CommonTradeTokenForm {
display: flex;
flex-direction: column;
gap: 12px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,23 @@ import { CWTooltip } from 'views/components/component_kit/new_designs/CWTooltip'
import {
CustomAddressOption,
CustomAddressOptionElement,
} from '../../ManageCommunityStakeModal/StakeExchangeForm/CustomAddressOption';
} from '../../../ManageCommunityStakeModal/StakeExchangeForm/CustomAddressOption';
import { TradingMode } from '../../types';
import AddressBalance from './AddressBalance';
import BuyAmountSelection from './AmountSelections/BuyAmountSelection';
import SellAmountSelection from './AmountSelections/SellAmountSelection';
import './CommonTradeTokenForm.scss';
import BuyReceipt from './ReceiptDetails/BuyReceipt';
import SellReceipt from './ReceiptDetails/SellReceipt';
import './TradeTokenForm.scss';
import { convertAddressToDropdownOption } from './helpers';
import { TradeTokenFormProps, TradingMode } from './types';
import { CommonTradeTokenFormProps } from './types';

const TradeTokenForm = ({
const CommonTradeTokenForm = ({
trading,
addresses,
onCTAClick,
isActionPending,
}: TradeTokenFormProps) => {
}: CommonTradeTokenFormProps) => {
const [isReceiptDetailOpen, setIsReceiptDetailOpen] = useState(false);

const getCTADisabledTooltipText = () => {
Expand Down Expand Up @@ -78,7 +79,7 @@ const TradeTokenForm = ({
};

return (
<section className="TradeTokenForm">
<section className="CommonTradeTokenForm">
<CWTabsRow>
{Object.keys(TradingMode).map((mode) => (
<CWTab
Expand Down Expand Up @@ -181,4 +182,4 @@ const TradeTokenForm = ({
);
};

export default TradeTokenForm;
export default CommonTradeTokenForm;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '../../../../../styles/shared.scss';
@import '../../../../../../styles/shared.scss';

.ReceiptDetails {
display: flex;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import CommonTradeTokenForm from './CommonTradeTokenForm';
import useCommonTradeTokenForm from './useCommonTradeTokenForm';
export * from './types';
export * from './useCommonTradeTokenForm';
export { useCommonTradeTokenForm };
export default CommonTradeTokenForm;
Loading
Loading