Skip to content

Commit

Permalink
Merge pull request #10148 from hicommonwealth/malik.9887.launchpad-un…
Browse files Browse the repository at this point in the history
…iswap-widget

Added uniswap trade widget
  • Loading branch information
mzparacha authored Dec 12, 2024
2 parents 2516e57 + acf0098 commit 807071c
Show file tree
Hide file tree
Showing 38 changed files with 3,739 additions and 646 deletions.
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,18 @@
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 useDeferredConditionTriggerCallback from 'hooks/useDeferredConditionTriggerCallback';
import React, { useState } from 'react';
import app from 'state';
import { useFetchTokenUsdRateQuery } from 'state/api/communityStake';
import TradeTokenModal from 'views/modals/TradeTokenModel';
import {
import useUserStore from 'state/ui/user';
import { AuthModal } from 'views/modals/AuthModal';
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 All @@ -32,6 +35,7 @@ export const TokenTradeWidget = ({
token,
currency = SupportedCurrencies.USD,
}: TokenTradeWidgetProps) => {
const user = useUserStore();
const currencySymbol = currencyNameToSymbolMap[currency];

const [isWidgetExpanded, setIsWidgetExpanded] = useState(true);
Expand All @@ -44,6 +48,11 @@ export const TokenTradeWidget = ({
};
}>({ isOpen: false, tradeConfig: undefined });

const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
const { register, trigger } = useDeferredConditionTriggerCallback({
shouldRunTrigger: user.isLoggedIn,
});

const { data: ethToCurrencyRateData, isLoading: isLoadingETHToCurrencyRate } =
useFetchTokenUsdRateQuery({
tokenSymbol: 'ETH',
Expand All @@ -53,7 +62,19 @@ export const TokenTradeWidget = ({
);
const tokenPricing = calculateTokenPricing(token, ethToUsdRate);

const openAuthModalOrTriggerCallback = () => {
if (user.isLoggedIn) {
trigger();
} else {
setIsAuthModalOpen(!user.isLoggedIn);
}
};

const handleCTAClick = (mode: TradingMode) => {
if (!user.isLoggedIn) {
setIsAuthModalOpen(true);
}

setTokenLaunchModalConfig({
isOpen: true,
tradeConfig: {
Expand Down Expand Up @@ -108,23 +129,57 @@ 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={() => {
register({
cb: () => {
handleCTAClick(mode);
},
});
openAuthModalOrTriggerCallback();
}}
/>
))
) : (
<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={() => {
register({
cb: () => {
handleCTAClick(TradingMode.Swap);
},
});
openAuthModalOrTriggerCallback();
}}
/>
))}
)}
</div>
</>
)}
<AuthModal
isOpen={isAuthModalOpen}
onClose={() => setIsAuthModalOpen(false)}
/>
{tokenLaunchModalConfig.tradeConfig && (
<TradeTokenModal
isOpen={tokenLaunchModalConfig.isOpen}
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,10 +1,16 @@
@import '../../../../styles/shared.scss';
@import '../../../../../styles/shared.scss';

.TradeTokenForm {
.CommonTradeTokenForm {
display: flex;
flex-direction: column;
gap: 12px;

.Tab {
.Text {
text-transform: capitalize;
}
}

.balance-row {
display: flex;
justify-content: space-between;
Expand Down
Loading

0 comments on commit 807071c

Please sign in to comment.