Skip to content

Commit f06ef86

Browse files
committed
feat: switchchain modal, modularize overlay
1 parent e5e27eb commit f06ef86

File tree

8 files changed

+159
-131
lines changed

8 files changed

+159
-131
lines changed

web/src/app.tsx

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Routes, Route } from "react-router-dom";
55
import "react-loading-skeleton/dist/skeleton.css";
66
import Web3Provider from "context/Web3Provider";
77
import StyledComponentsProvider from "context/StyledComponentsProvider";
8-
import WrongChainBoundary from "components/WrongChainBoundary";
98
import Layout from "layout/index";
109
import Home from "./pages/Home";
1110
import Cases from "./pages/Cases";
@@ -31,17 +30,15 @@ const App: React.FC = () => {
3130
}}
3231
>
3332
<Web3Provider>
34-
<WrongChainBoundary>
35-
<Routes>
36-
<Route path="/" element={<Layout />}>
37-
<Route index element={<Home />} />
38-
<Route path="cases/*" element={<Cases />} />
39-
<Route path="courts/*" element={<Courts />} />
40-
<Route path="dashboard" element={<Dashboard />} />
41-
<Route path="*" element={<h1>Justice not found here ¯\_( ͡° ͜ʖ ͡°)_/¯</h1>} />
42-
</Route>
43-
</Routes>
44-
</WrongChainBoundary>
33+
<Routes>
34+
<Route path="/" element={<Layout />}>
35+
<Route index element={<Home />} />
36+
<Route path="cases/*" element={<Cases />} />
37+
<Route path="courts/*" element={<Courts />} />
38+
<Route path="dashboard" element={<Dashboard />} />
39+
<Route path="*" element={<h1>Justice not found here ¯\_( ͡° ͜ʖ ͡°)_/¯</h1>} />
40+
</Route>
41+
</Routes>
4542
</Web3Provider>
4643
</SWRConfig>
4744
</StyledComponentsProvider>

web/src/components/ConnectButton.tsx

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,39 @@
11
import React from "react";
22
import styled from "styled-components";
3-
import { useAccount, useNetwork, useSwitchNetwork } from "wagmi";
3+
import { useToggle } from "react-use";
4+
import { useAccount, useNetwork } from "wagmi";
45
import { arbitrumGoerli } from "wagmi/chains";
56
import { useWeb3Modal } from "@web3modal/react";
67
import { shortenAddress } from "utils/shortenAddress";
78
import { Button } from "@kleros/ui-components-library";
8-
import { DEFAULT_CHAIN, SUPPORTED_CHAINS } from "consts/chains";
9+
import { DEFAULT_CHAIN } from "consts/chains";
10+
import SwitchChainModal from "./SwitchChainModal";
11+
12+
const StyledContainer = styled.div`
13+
width: fit-content;
14+
height: 34px;
15+
padding: 16px;
16+
gap: 0.5rem;
17+
border-radius: 300px;
18+
background-color: ${({ theme }) => theme.whiteLowOpacity};
19+
display: flex;
20+
align-items: center;
21+
> label {
22+
color: ${({ theme }) => theme.primaryText};
23+
}
24+
:before {
25+
content: "";
26+
width: 8px;
27+
height: 8px;
28+
border-radius: 50%;
29+
background-color: ${({ theme }) => theme.success};
30+
}
31+
`;
32+
33+
const StyledSwitchChainButton = styled(Button)`
34+
width: fit-content;
35+
height: 34px;
36+
`;
937

1038
const AccountDisplay: React.FC = () => {
1139
return (
@@ -27,49 +55,15 @@ export const AddressDisplay: React.FC = () => {
2755
};
2856

2957
export const SwitchChainButton: React.FC = () => {
30-
const { switchNetwork, isLoading } = useSwitchNetwork();
31-
const handleSwitch = () => {
32-
if (!switchNetwork) {
33-
console.error("Cannot switch network. Please do it manually.");
34-
return;
35-
}
36-
try {
37-
switchNetwork(DEFAULT_CHAIN);
38-
} catch (err) {
39-
console.error(err);
40-
}
41-
};
58+
const [isSwitchChainModalOpen, toggleIsSwitchChainModalOpen] = useToggle(false);
4259
return (
43-
<Button
44-
isLoading={isLoading}
45-
disabled={isLoading}
46-
text={`Switch to ${SUPPORTED_CHAINS[DEFAULT_CHAIN].chainName}`}
47-
onClick={handleSwitch}
48-
/>
60+
<>
61+
<StyledSwitchChainButton text={`Switch chain`} onClick={toggleIsSwitchChainModalOpen} />
62+
{isSwitchChainModalOpen && <SwitchChainModal toggle={toggleIsSwitchChainModalOpen} />}
63+
</>
4964
);
5065
};
5166

52-
const StyledContainer = styled.div`
53-
width: fit-content;
54-
height: 34px;
55-
padding: 16px;
56-
gap: 0.5rem;
57-
border-radius: 300px;
58-
background-color: ${({ theme }) => theme.whiteLowOpacity};
59-
display: flex;
60-
align-items: center;
61-
> label {
62-
color: ${({ theme }) => theme.primaryText};
63-
}
64-
:before {
65-
content: "";
66-
width: 8px;
67-
height: 8px;
68-
border-radius: 50%;
69-
background-color: ${({ theme }) => theme.success};
70-
}
71-
`;
72-
7367
const ConnectButton: React.FC = () => {
7468
const { chain } = useNetwork();
7569
const { isConnected } = useAccount();

web/src/components/Overlay.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import styled from "styled-components";
2+
3+
export const Overlay = styled.div`
4+
position: fixed;
5+
top: 0;
6+
left: 0;
7+
width: 100vw;
8+
height: 100vh;
9+
background-color: ${({ theme }) => theme.blackLowOpacity};
10+
z-index: 1;
11+
`;
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import React, { useRef } from "react";
2+
import styled from "styled-components";
3+
import { useFocusOutside } from "hooks/useFocusOutside";
4+
import { Overlay } from "components/Overlay";
5+
import { useSwitchNetwork } from "wagmi";
6+
import { Button } from "@kleros/ui-components-library";
7+
import { SUPPORTED_CHAINS } from "consts/chains";
8+
9+
const Container = styled.div`
10+
display: flex;
11+
position: absolute;
12+
z-index: 1;
13+
background-color: ${({ theme }) => theme.whiteBackground};
14+
flex-direction: column;
15+
border: 1px solid ${({ theme }) => theme.stroke};
16+
border-radius: 3px;
17+
overflow-y: auto;
18+
top: 5%;
19+
left: 50%;
20+
transform: translateX(-50%);
21+
padding: 0 calc(8px + (32 - 8) * ((100vw - 300px) / (1250 - 300)));
22+
width: calc(300px + (424 - 300) * ((100vw - 300px) / (1250 - 300)));
23+
`;
24+
25+
const HeaderContainer = styled.div`
26+
display: flex;
27+
justify-content: center;
28+
font-size: 24px;
29+
color: ${({ theme }) => theme.primaryText};
30+
margin-top: 24px;
31+
`;
32+
33+
const StyledButton = styled(Button)`
34+
display: flex;
35+
justify-content: center;
36+
margin-top: 16px;
37+
width: fit-content;
38+
height: 36px;
39+
`;
40+
41+
const BodyContainer = styled.div`
42+
display: flex;
43+
flex-direction: column;
44+
align-items: center;
45+
margin-top: 8px;
46+
margin-bottom: 24px;
47+
`;
48+
49+
interface IChainButton {
50+
chainId: number;
51+
}
52+
53+
export const ChainButton: React.FC<IChainButton> = ({ chainId }) => {
54+
const { switchNetwork, isLoading } = useSwitchNetwork();
55+
const handleSwitch = () => {
56+
if (!switchNetwork) {
57+
console.error("Cannot switch network. Please do it manually.");
58+
return;
59+
}
60+
try {
61+
switchNetwork(chainId);
62+
} catch (err) {
63+
console.error(err);
64+
}
65+
};
66+
return (
67+
<StyledButton
68+
isLoading={isLoading}
69+
disabled={isLoading}
70+
text={`${SUPPORTED_CHAINS[chainId].chainName}`}
71+
onClick={handleSwitch}
72+
/>
73+
);
74+
};
75+
76+
interface ISwitchChainModal {
77+
toggle: () => void;
78+
}
79+
80+
const SwitchChainModal: React.FC<ISwitchChainModal> = ({ toggle }) => {
81+
const containerRef = useRef(null);
82+
useFocusOutside(containerRef, () => {
83+
toggle();
84+
});
85+
86+
return (
87+
<>
88+
<Overlay />
89+
<Container ref={containerRef}>
90+
<HeaderContainer>Switch to</HeaderContainer>
91+
<BodyContainer>
92+
{Object.keys(SUPPORTED_CHAINS).map((chainId) => (
93+
<ChainButton key={chainId} chainId={Number(chainId)} />
94+
))}
95+
</BodyContainer>
96+
</Container>
97+
</>
98+
);
99+
};
100+
101+
export default SwitchChainModal;

web/src/components/WrongChainBoundary.tsx

Lines changed: 0 additions & 48 deletions
This file was deleted.

web/src/layout/Header/navbar/DappList.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Linguo from "svgs/icons/linguo.svg";
1010
import POH from "svgs/icons/poh-image.png";
1111
import Tokens from "svgs/icons/tokens.svg";
1212
import Product from "./Product";
13+
import { Overlay } from "components/Overlay";
1314

1415
interface IDappList {
1516
toggleSolution: () => void;
@@ -104,16 +105,6 @@ const ItemsDiv = styled.div`
104105
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
105106
`;
106107

107-
const Overlay = styled.div`
108-
position: fixed;
109-
top: 0;
110-
left: 0;
111-
width: 100vw;
112-
height: 100vh;
113-
background-color: ${({ theme }) => theme.blackLowOpacity};
114-
z-index: 1;
115-
`;
116-
117108
const DappList: React.FC<IDappList> = ({ toggleSolution }) => {
118109
const containerRef = useRef(null);
119110
useFocusOutside(containerRef, () => {

web/src/layout/Header/navbar/Menu/Help.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Bug from "svgs/icons/bug.svg";
77
import ETH from "svgs/icons/eth.svg";
88
import Faq from "svgs/menu-icons/help.svg";
99
import Telegram from "svgs/socialmedia/telegram.svg";
10+
import { Overlay } from "components/Overlay";
1011

1112
const ITEMS = [
1213
{
@@ -85,16 +86,6 @@ const Icon = styled.svg`
8586
fill: ${({ theme }) => theme.secondaryPurple};
8687
`;
8788

88-
const Overlay = styled.div`
89-
position: fixed;
90-
top: 0;
91-
left: 0;
92-
width: 100vw;
93-
height: 100vh;
94-
background-color: ${({ theme }) => theme.blackLowOpacity};
95-
z-index: 1;
96-
`;
97-
9889
const Help: React.FC<IHelp> = ({ toggle }) => {
9990
const containerRef = useRef(null);
10091
useFocusOutside(containerRef, () => {

web/src/layout/Header/navbar/Menu/Settings/index.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Tabs } from "@kleros/ui-components-library";
44
import General from "./General";
55
import SendMeNotifications from "./SendMeNotifications";
66
import { useFocusOutside } from "hooks/useFocusOutside";
7+
import { Overlay } from "components/Overlay";
78

89
const Container = styled.div`
910
display: flex;
@@ -32,16 +33,6 @@ const StyledTabs = styled(Tabs)`
3233
width: calc(300px + (424 - 300) * ((100vw - 300px) / (1250 - 300)));
3334
`;
3435

35-
const Overlay = styled.div`
36-
position: fixed;
37-
top: 0;
38-
left: 0;
39-
width: 100vw;
40-
height: 100vh;
41-
background-color: ${({ theme }) => theme.blackLowOpacity};
42-
z-index: 1;
43-
`;
44-
4536
const TABS = [
4637
{
4738
text: "General",

0 commit comments

Comments
 (0)