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

Disclaimer #2097

Merged
merged 14 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions components/account/AccountButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const AccountButton: FC<{
const proxy = getProxyFor(activeAccount?.address);

const accountModals = useAccountModals();
const { locationAllowed, isUsingVPN } = useUserLocation();
const { locationAllowed } = useUserLocation();
const [hovering, setHovering] = useState<boolean>(false);
const [showOnboarding, setShowOnboarding] = useState(false);
const [showGetZtgModal, setShowGetZtgModal] = useState(false);
Expand Down Expand Up @@ -149,28 +149,23 @@ const AccountButton: FC<{
>
{hasWallet === true ? (
<HeaderActionButton
disabled={
locationAllowed !== true || isUsingVPN || !isRpcSdk(sdk)
}
disabled={locationAllowed !== true || !isRpcSdk(sdk)}
onClick={() => connect()}
>
Connect Wallet
</HeaderActionButton>
) : (
<HeaderActionButton
disabled={locationAllowed !== true || isUsingVPN}
disabled={locationAllowed !== true}
onClick={() => setShowOnboarding(true)}
>
Get Started
</HeaderActionButton>
)}

{hovering === true &&
(locationAllowed !== true || isUsingVPN === true) ? (
{hovering === true && locationAllowed !== true ? (
<div className="absolute bottom-0 right-0 rounded bg-white text-sm font-bold text-black">
{locationAllowed !== true
? "Your jurisdiction is not authorised to trade"
: "Trading over a VPN is not allowed due to legal restrictions"}
Your jurisdiction is not authorised to trade
</div>
) : (
<></>
Expand Down
51 changes: 51 additions & 0 deletions components/onboarding/DisclaimerModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Dialog } from "@headlessui/react";
import Modal from "components/ui/Modal";
import { useEffect, useRef } from "react";
import DisclaimerTerms from "./DisclaimerTerms";
import { useDisclaimer } from "lib/state/disclaimer";

export const DisclaimerModal = () => {
const { modalOpen, hideDisclaimer, setDisclaimerAccepted } = useDisclaimer();

const scrollableElementRef = useRef<HTMLDivElement | null>(null);

// hack to scroll component to top when it renders (by default it scrolls to the bottom as it's overflowing)
useEffect(() => {
setTimeout(() => {
if (scrollableElementRef.current) {
scrollableElementRef.current.scrollTop = 0;
}
}, 10);
}, [scrollableElementRef, modalOpen]);

return (
<Modal open={modalOpen} onClose={() => {}}>
<Dialog.Panel className="flex w-full max-w-[526px] flex-col gap-5 rounded-ztg-10 bg-white p-[30px]">
<h2 className="text-base">Terms of use</h2>
<div
ref={scrollableElementRef}
className="max-h-[300px] overflow-auto pr-2 text-sm"
>
<DisclaimerTerms />
</div>
<div className="flex items-center justify-end gap-3">
<button
className="rounded-md px-4 py-2 text-gray-400"
onClick={() => hideDisclaimer()}
>
Decline
</button>
<button
className="rounded-md bg-ztg-blue px-4 py-2 text-white"
onClick={() => {
hideDisclaimer();
setDisclaimerAccepted();
}}
>
Accept
</button>
</div>
</Dialog.Panel>
</Modal>
);
};
1,313 changes: 1,313 additions & 0 deletions components/onboarding/DisclaimerTerms.tsx

Large diffs are not rendered by default.

15 changes: 4 additions & 11 deletions components/ui/TransactionButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const TransactionButton: FC<PropsWithChildren<TransactionButtonProps>> = ({
const wallet = useWallet();
const [sdk] = useSdkv2();
const accountModals = useAccountModals();
const { locationAllowed, isUsingVPN } = useUserLocation();
const { locationAllowed } = useUserLocation();

const extrinsicBase = useMemo(() => {
return extrinsic && isRpcSdk(sdk) && wallet.activeAccount?.address
Expand All @@ -67,29 +67,22 @@ const TransactionButton: FC<PropsWithChildren<TransactionButtonProps>> = ({
};

const isDisabled = useMemo(() => {
if (
locationAllowed !== true ||
isUsingVPN ||
!isRpcSdk(sdk) ||
insufficientFeeBalance
) {
if (locationAllowed !== true || !isRpcSdk(sdk) || insufficientFeeBalance) {
return true;
} else if (!wallet.connected) {
return false;
}
return disabled;
}, [locationAllowed, isUsingVPN, sdk, wallet, insufficientFeeBalance]);
}, [locationAllowed, sdk, wallet, insufficientFeeBalance]);

const colorClass =
locationAllowed !== true || isUsingVPN || insufficientFeeBalance
locationAllowed !== true || insufficientFeeBalance
? "bg-vermilion"
: "bg-ztg-blue";

const getButtonChildren = () => {
if (locationAllowed !== true) {
return "Location Blocked";
} else if (isUsingVPN) {
return "VPN Blocked";
} else if (insufficientFeeBalance) {
return `Insufficient ${fee.symbol}`;
} else if (loading) {
Expand Down
2 changes: 2 additions & 0 deletions layouts/DefaultLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useRouter } from "next/router";

import { Account } from "components/account/Account";
import { ConfirmationProvider } from "components/confirmation/ConfirmationProvider";
import { DisclaimerModal } from "components/onboarding/DisclaimerModal";

const NOTIFICATION_MESSAGE = process.env.NEXT_PUBLIC_NOTIFICATION_MESSAGE;

Expand Down Expand Up @@ -89,6 +90,7 @@ const DefaultLayout: FC<PropsWithChildren> = ({ children }) => {
</div>
<NotificationCenter />
<ConfirmationProvider />
<DisclaimerModal />
</TradeItemContext.Provider>
<Account />
<Onboarding />
Expand Down
15 changes: 1 addition & 14 deletions lib/hooks/useUserLocation.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import ipRangeCheck from "ip-range-check";
import { useAtom } from "jotai";
import { atomsWithQuery } from "jotai-tanstack-query";

export type UserLocation = {
isUsingVPN: boolean;
locationAllowed: boolean;
};

Expand All @@ -13,7 +11,6 @@ export const [userLocationDataAtom, userLocationStatusAtom] =
atomsWithQuery<UserLocation>(() => ({
queryKey: [userLocationKey],
initialData: () => ({
isUsingVPN: false,
locationAllowed: true,
}),
keepPreviousData: true,
Expand All @@ -28,17 +25,7 @@ export const [userLocationDataAtom, userLocationStatusAtom] =
const userCountry: string = json.body.country;
const locationAllowed = !notAllowedCountries.includes(userCountry);

const ip = json.body.ip;

//source: https://raw.githubusercontent.com/X4BNet/lists_vpn/main/output/datacenter/ipv4.txt
const vpnIPsResponse = await fetch("/vpn-ips.txt");
const vpnIPs = await vpnIPsResponse.text();
const isUsingVPN = vpnIPs
.toString()
.split("\n")
.some((vpnIP) => ipRangeCheck(ip, vpnIP) === true);

return { isUsingVPN, locationAllowed };
return { locationAllowed };
},
}));

Expand Down
11 changes: 10 additions & 1 deletion lib/state/account.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { atom, useAtom } from "jotai";
import { useDisclaimer } from "./disclaimer";

const accountsAtom = atom({
accountSelectModalOpen: false,
Expand All @@ -8,13 +9,21 @@ const accountsAtom = atom({
export const useAccountModals = () => {
const [state, setState] = useAtom(accountsAtom);

const { showDisclaimer, disclaimerAccepted } = useDisclaimer(() => {
setState({ ...state, walletSelectModalOpen: true });
});

return {
...state,
openAccountSelect: () => {
setState({ ...state, accountSelectModalOpen: true });
},
openWalletSelect: () => {
setState({ ...state, walletSelectModalOpen: true });
if (disclaimerAccepted) {
setState({ ...state, walletSelectModalOpen: true });
} else {
showDisclaimer();
}
},
closeAccountSelect: () => {
setState({ ...state, accountSelectModalOpen: false });
Expand Down
46 changes: 46 additions & 0 deletions lib/state/disclaimer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { atom, useAtom } from "jotai";
import { persistentAtom } from "./util/persistent-atom";
import { useEffect, useMemo } from "react";

const disclaimerAcceptanceStateAtom = persistentAtom<boolean>({
key: "disclaimer-acceptance",
defaultValue: false,
});

const disclaimerDisplayed = atom<boolean>(false);

export const useDisclaimer = (onAccept?: () => void) => {
const [modalOpen, setModalOpen] = useAtom(disclaimerDisplayed);
const [disclaimerStatus, setDisclaimerStatus] = useAtom(
disclaimerAcceptanceStateAtom,
);

const initialDisclaimerStatus = useMemo(() => {
return disclaimerStatus;
}, []);

useEffect(() => {
if (!initialDisclaimerStatus && disclaimerStatus) {
onAccept?.();
}
}, [disclaimerStatus]);

const setDisclaimerAccepted = () => {
setDisclaimerStatus(true);
};

const showDisclaimer = () => {
setModalOpen(true);
};
const hideDisclaimer = () => {
setModalOpen(false);
};

return {
modalOpen,
hideDisclaimer,
showDisclaimer,
disclaimerAccepted: disclaimerStatus,
setDisclaimerAccepted,
};
};
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"fuse.js": "^6.6.2",
"graphql-request": "^5.0.0",
"groq": "^3.23.4",
"ip-range-check": "^0.2.0",
"jotai": "^2.0.4",
"jotai-tanstack-query": "^0.7.0",
"lodash.merge": "^4.6.2",
Expand Down
Binary file removed public/currencies/UX_UI_Workflow.zip
Binary file not shown.
Loading