Skip to content

Commit

Permalink
progress wizard
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitindenis1 committed Aug 28, 2023
1 parent 50b10a0 commit 1cdb773
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 10 deletions.
12 changes: 8 additions & 4 deletions packages/lib/src/components/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
useToken,
useSwitchTokens,
} from "../hooks";
import { useTwapStore, handleFillDelayText } from "../store";
import { useTwapStore, handleFillDelayText, useWizardStore } from "../store";
import { StyledText, StyledRowFlex, StyledColumnFlex, StyledOneLineText, StyledOverflowContainer, textOverflow } from "../styles";
import TokenDisplay from "./base/TokenDisplay";
import TokenSelectButton from "./base/TokenSelectButton";
Expand Down Expand Up @@ -384,7 +384,7 @@ export const SubmitButton = ({ className = "", isMain }: { className?: string; i
const { mutate: unwrap, isLoading: unwrapLoading } = useUnwrapToken();
const { mutate: wrap, isLoading: wrapLoading } = useWrapToken();
const connect = useTwapContext().connect;

const wizardStore = useWizardStore();
const { loading: changeNetworkLoading, changeNetwork } = useChangeNetwork();

const getArgs = () => {
Expand Down Expand Up @@ -427,11 +427,15 @@ export const SubmitButton = ({ className = "", isMain }: { className?: string; i
return {
text: "",
onClick: () => {
setShowConfirmation(true);
if (!showConfirmation) {
setShowConfirmation(true);
} else {
wizardStore.setOpen(true);
}
analytics.onOpenConfirmationModal();
},
loading: true,
disabled: showConfirmation,
disabled: false,
};
}
if (allowance.isLoading || srcUsdLoading || dstUsdLoading) {
Expand Down
175 changes: 175 additions & 0 deletions packages/lib/src/components/Wizard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { styled } from "@mui/material";
import React, { useCallback, useMemo } from "react";
import { BsFillCheckCircleFill } from "react-icons/bs";
import { useWizardStore, WizardAction, WizardActionStatus } from "../store";
import { StyledColumnFlex, StyledText } from "../styles";
import { Modal, Spinner } from "./base";
import { BiSolidErrorCircle } from "react-icons/bi";
export function Wizard() {
const store = useWizardStore();
const content = useContent();

const onClose = useCallback(() => {
store.setOpen(false);
}, []);

return (
<StyledModal open={store.open} onClose={onClose}>
<StyledContainer>{content}</StyledContainer>
</StyledModal>
);
}

const useContent = () => {
const store = useWizardStore();
return useMemo(() => {
if (store.action === WizardAction.APPROVE) {
return <Approval status={store.status} error={store.error} />;
}

if (store.action === WizardAction.CREATE_ORDER) {
return <CreateOrder status={store.status} error={store.error} />;
}
if (store.action === WizardAction.WRAP) {
return <Wrap status={store.status} error={store.error} />;
}
}, [store.action, store.status]);
};

const Wrap = ({ status, error }: { status?: WizardActionStatus; error?: string }) => {
if (status === WizardActionStatus.PENDING) {
return (
<>
<StyledSpinner />
<StyledTitle>Wrapping</StyledTitle>
</>
);
}

if (status === WizardActionStatus.SUCCESS) {
return (
<>
<StyledSuccessIcon className="twap-icon" />
<StyledTitle>Wrap successful</StyledTitle>
</>
);
}

if (status === WizardActionStatus.ERROR) {
return (
<>
<StyledErrorIcon className="twap-icon" />
<StyledTitle>Wrap failed</StyledTitle>
<StyledMessage>{error}</StyledMessage>
</>
);
}

return null;
};

const Approval = ({ status, error }: { status?: WizardActionStatus; error?: string }) => {
if (status === WizardActionStatus.PENDING) {
return (
<>
<StyledSpinner />
<StyledTitle>Approving</StyledTitle>
</>
);
}

if (status === WizardActionStatus.SUCCESS) {
return (
<>
<StyledSuccessIcon className="twap-icon" />
<StyledTitle>Approval successful</StyledTitle>
</>
);
}

if (status === WizardActionStatus.ERROR) {
return (
<>
<StyledErrorIcon className="twap-icon" />
<StyledTitle>Approval failed</StyledTitle>
<StyledMessage>{error}</StyledMessage>
</>
);
}

return null;
};

const CreateOrder = ({ status, error }: { status?: WizardActionStatus; error?: string }) => {
if (status === WizardActionStatus.PENDING) {
return (
<>
<StyledSpinner />
<StyledTitle>Submitting order</StyledTitle>
</>
);
}

if (status === WizardActionStatus.SUCCESS) {
return (
<>
<StyledSuccessIcon className="twap-icon" />
<StyledTitle>Order submitted successfully</StyledTitle>
</>
);
}

if (status === WizardActionStatus.ERROR) {
return (
<>
<StyledErrorIcon className="twap-icon" />
<StyledTitle>Submit order failed</StyledTitle>
<StyledMessage>{error}</StyledMessage>
</>
);
}

return null;
};

const StyledSpinner = styled(Spinner)({
width: "50px!important",
height: "50px!important",
});

const StyledSuccessIcon = styled(BsFillCheckCircleFill)({
"*": {
color: "#28a745!important",
},
});

const StyledErrorIcon = styled(BiSolidErrorCircle)({
"*": {
color: "#FF3233!important",
},
});

const StyledTitle = styled(StyledText)({
fontSize: 23,
fontWeight: 600,
textAlign: "center",
width: "100%",
});

const StyledContainer = styled(StyledColumnFlex)({
alignItems: "center",
gap: 12,
".twap-icon": {
width: 60,
height: 60,
},
});

const StyledMessage = styled(StyledText)({
fontSize: 16,
textAlign: "center",
width: "100%",
marginTop: 10,
});

const StyledModal = styled(Modal)({});
8 changes: 8 additions & 0 deletions packages/lib/src/components/base/Spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { CircularProgress } from "@mui/material";
import React from "react";

function Spinner({ className }: { className?: string }) {
return <CircularProgress className={`twap-spinner ${className}`} />;
}

export default Spinner;
1 change: 1 addition & 0 deletions packages/lib/src/components/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ export { default as SwipeContainer } from "./SwipeContainer";
export { default as Radio } from "./Radio";
export { default as Portal } from "./Portal";
export { default as Odnp } from "./Odnp";
export { default as Spinner } from "./Spinner";
2 changes: 2 additions & 0 deletions packages/lib/src/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { analytics } from "./analytics";
import { TokenData } from "@orbs-network/twap";
import { useTwapStore } from "./store";
import { TwapErrorWrapper } from "./ErrorHandling";
import { Wizard } from "./components/Wizard";

analytics.onModuleLoad();

Expand Down Expand Up @@ -71,6 +72,7 @@ const WrappedTwap = (props: TwapLibProps) => {
return (
<TwapErrorWrapper>
<Listener />
<Wizard />
{props.children}
</TwapErrorWrapper>
);
Expand Down
19 changes: 16 additions & 3 deletions packages/lib/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { InitLibProps, OrdersData, OrderUI, State } from "./types";
import _ from "lodash";
import { analytics } from "./analytics";
import { eqIgnoreCase, setWeb3Instance, switchMetaMaskNetwork, zeroAddress, estimateGasPrice, getPastEvents, findBlock, block } from "@defi.org/web3-candies";
import { amountUi, getTokenFromTokensList, parseOrderUi, useTwapStore } from "./store";
import { amountUi, getTokenFromTokensList, parseOrderUi, useTwapStore, useWizardStore, WizardAction, WizardActionStatus } from "./store";
import { REFETCH_BALANCE, REFETCH_GAS_PRICE, REFETCH_ORDER_HISTORY, REFETCH_USD, STALE_ALLOWANCE } from "./consts";
import { QueryKeys } from "./enums";
import moment from "moment";
Expand Down Expand Up @@ -44,6 +44,7 @@ export const useWrapToken = () => {
const srcAmount = useTwapStore((state) => state.getSrcAmount());
const srcToken = useTwapStore((state) => state.srcToken);
const dstToken = useTwapStore((state) => state.dstToken);
const wizardStore = useWizardStore();

const { priorityFeePerGas, maxFeePerGas } = useGasPriceQuery();

Expand All @@ -52,6 +53,8 @@ export const useWrapToken = () => {

return useMutation(
async () => {
wizardStore.setAction(WizardAction.WRAP);
wizardStore.setStatus(WizardActionStatus.PENDING);
analytics.onWrapClick(srcAmount);
return lib!.wrapNativeToken(srcAmount, priorityFeePerGas, maxFeePerGas);
},
Expand All @@ -60,12 +63,14 @@ export const useWrapToken = () => {
analytics.onWrapSuccess();
if (lib?.validateTokens(srcToken!, dstToken!) === TokensValidation.wrapOnly) {
reset();
wizardStore.setStatus(WizardActionStatus.SUCCESS);
return;
}
setSrcToken(lib!.config.wToken);
},
onError: (error: Error) => {
console.log(error.message);
wizardStore.setStatus(WizardActionStatus.ERROR, error.message);
analytics.onWrapError(error.message);
},
}
Expand Down Expand Up @@ -94,20 +99,23 @@ export const useApproveToken = () => {
const { priorityFeePerGas, maxFeePerGas } = useGasPriceQuery();
const srcToken = useTwapStore((state) => state.srcToken);
const { refetch } = useHasAllowanceQuery();

const wizardStore = useWizardStore();
return useMutation(
async () => {
wizardStore.setAction(WizardAction.APPROVE);
wizardStore.setStatus(WizardActionStatus.PENDING);
analytics.onApproveClick(srcAmount);
await lib?.approve(srcToken!, srcAmount, priorityFeePerGas, maxFeePerGas);
await refetch();
},
{
onSuccess: async () => {
analytics.onApproveSuccess();
wizardStore.setStatus(WizardActionStatus.SUCCESS);
},
onError: (error: Error) => {
console.log(error.message);

wizardStore.setStatus(WizardActionStatus.ERROR, error.message);
analytics.onApproveError(error.message);
},
}
Expand All @@ -130,11 +138,14 @@ export const useCreateSimpleLimitOrder = () => {
export const useCreateOrder = () => {
const { maxFeePerGas, priorityFeePerGas } = useGasPriceQuery();
const store = useTwapStore();
const wizardStore = useWizardStore();
const reset = useReset();
const { askDataParams } = useTwapContext();
const setTokensFromDapp = useSetTokensFromDapp();
return useMutation(
async () => {
wizardStore.setAction(WizardAction.CREATE_ORDER);
wizardStore.setStatus(WizardActionStatus.PENDING);
const fillDelayMillis = (store.getFillDelayUiMillis() - store.lib!.estimatedDelayBetweenChunksMillis()) / 1000;

console.log({
Expand Down Expand Up @@ -177,12 +188,14 @@ export const useCreateOrder = () => {
reset();
store.setOrderCreatedTimestamp(Date.now());
setTokensFromDapp();
wizardStore.setStatus(WizardActionStatus.SUCCESS);
},
onError: (error: Error) => {
analytics.onCreateOrderError(error.message);
if ((error as any).code === 4001) {
analytics.onCreateOrderRejected();
}
wizardStore.setStatus(WizardActionStatus.ERROR, error.message);
},

onSettled: () => {
Expand Down
33 changes: 33 additions & 0 deletions packages/lib/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,39 @@ export const useOrdersStore = create<OrdersStore>((set) => ({
setTab: (value: number) => set({ tab: value }),
}));

export enum WizardAction {
CREATE_ORDER = "CREATE_ORDER",
CANCEL_ORDER = "CANCEL_ORDER",
WRAP = "WRAP",
APPROVE = "APPROVE",
}

export enum WizardActionStatus {
PENDING = "PENDING",
SUCCESS = "SUCCESS",
ERROR = "ERROR",
}

interface WizardStore {
error?: string;
action?: WizardAction;
status?: WizardActionStatus;
open: boolean;
setAction: (value?: WizardAction) => void;
setStatus: (value?: WizardActionStatus, error?: string) => void;
setOpen: (value: boolean) => void;
}

export const useWizardStore = create<WizardStore>((set) => ({
action: undefined,
status: undefined,
error: undefined,
open: false,
setAction: (action) => set({ action, open: !!action }),
setStatus: (status, error) => set({ status, error, open: !!status }),
setOpen: (value) => set({ open: value }),
}));

export const getTokenFromTokensList = (tokensList?: any, addressOrSymbol?: any) => {
if (!tokensList || !addressOrSymbol) return;

Expand Down
6 changes: 5 additions & 1 deletion packages/pangolin/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,11 @@ export const configureStyles = (theme: any) => {
color: "rgb(113, 113, 113)",
},
},

".twap-modal": {
".MuiBackdrop-root": {
backdropFilter: "blur(15px)",
},
},
".twap-modal-content": {
background: styles.containerBackground,
maxHeight: "85vh",
Expand Down
Loading

0 comments on commit 1cdb773

Please sign in to comment.