Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
"graphql": "^16.7.1",
"graphql-request": "~6.1.0",
"moment": "^2.29.4",
"overlayscrollbars": "^2.3.0",
"overlayscrollbars-react": "^0.5.2",
"react": "^18.2.0",
"react-chartjs-2": "^4.3.1",
"react-dom": "^18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/Overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ export const Overlay = styled.div`
width: 100vw;
height: 100vh;
background-color: ${({ theme }) => theme.blackLowOpacity};
z-index: 1;
z-index: 0;
`;
3 changes: 3 additions & 0 deletions web/src/context/OverlayScrollContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createContext, MutableRefObject } from "react";

export const OverlayScrollContext = createContext<MutableRefObject<HTMLElement | null> | null>(null);
28 changes: 28 additions & 0 deletions web/src/hooks/useLockOverlayScroll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useContext, useEffect, useCallback } from "react";
import { OverlayScrollContext } from "context/OverlayScrollContext";

export const useLockOverlayScroll = (shouldLock: boolean) => {
const osInstanceRef = useContext(OverlayScrollContext);

const lockScroll = useCallback(() => {
const osInstance = osInstanceRef?.current?.osInstance();
if (osInstance) {
osInstance.options({ overflow: { x: "hidden", y: "hidden" } });
}
}, [osInstanceRef]);

const unlockScroll = useCallback(() => {
const osInstance = osInstanceRef?.current?.osInstance();
if (osInstance) {
osInstance.options({ overflow: { x: "scroll", y: "scroll" } });
}
}, [osInstanceRef]);

useEffect(() => {
if (shouldLock) {
lockScroll();
} else {
unlockScroll();
}
}, [shouldLock, lockScroll, unlockScroll]);
};
34 changes: 15 additions & 19 deletions web/src/layout/Header/navbar/DappList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Linguo from "svgs/icons/linguo.svg";
import POH from "svgs/icons/poh-image.png";
import Tokens from "svgs/icons/tokens.svg";
import Product from "./Product";
import { Overlay } from "components/Overlay";

const Header = styled.h1`
display: flex;
Expand All @@ -28,7 +27,7 @@ const Container = styled.div`
top: 5%;
left: 50%;
transform: translate(-50%);
z-index: 10;
z-index: 1;
flex-direction: column;
align-items: center;

Expand Down Expand Up @@ -58,10 +57,6 @@ const ItemsDiv = styled.div`
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
`;

interface IDappList {
toggleSolution: () => void;
}

const ITEMS = [
{
text: "Court v1",
Expand Down Expand Up @@ -105,24 +100,25 @@ const ITEMS = [
},
];

const DappList: React.FC<IDappList> = ({ toggleSolution }) => {
interface IDappList {
toggleIsDappListOpen: () => void;
}

const DappList: React.FC<IDappList> = ({ toggleIsDappListOpen }) => {
const containerRef = useRef(null);
useFocusOutside(containerRef, () => {
toggleSolution();
toggleIsDappListOpen();
});

return (
<>
<Overlay />
<Container ref={containerRef}>
<Header>Kleros Solutions</Header>
<ItemsDiv>
{ITEMS.map((item) => {
return <Product {...item} key={item.text} />;
})}
</ItemsDiv>
</Container>
</>
<Container ref={containerRef}>
<Header>Kleros Solutions</Header>
<ItemsDiv>
{ITEMS.map((item) => {
return <Product {...item} key={item.text} />;
})}
</ItemsDiv>
</Container>
);
};
export default DappList;
28 changes: 12 additions & 16 deletions web/src/layout/Header/navbar/Menu/Help.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import Bug from "svgs/icons/bug.svg";
import ETH from "svgs/icons/eth.svg";
import Faq from "svgs/menu-icons/help.svg";
import Telegram from "svgs/socialmedia/telegram.svg";
import { Overlay } from "components/Overlay";

const Container = styled.div`
display: flex;
Expand All @@ -16,7 +15,7 @@ const Container = styled.div`
top: 5%;
left: 50%;
transform: translate(-50%);
z-index: 10;
z-index: 1;
padding: 27px 10px;
gap: 23px;
border: 1px solid ${({ theme }) => theme.stroke};
Expand Down Expand Up @@ -83,27 +82,24 @@ const ITEMS = [
];

interface IHelp {
toggle: () => void;
toggleIsHelpOpen: () => void;
}

const Help: React.FC<IHelp> = ({ toggle }) => {
const Help: React.FC<IHelp> = ({ toggleIsHelpOpen }) => {
const containerRef = useRef(null);
useFocusOutside(containerRef, () => {
toggle();
toggleIsHelpOpen();
});

return (
<>
<Overlay />
<Container ref={containerRef}>
{ITEMS.map((item) => (
<ListItem href={item.url} key={item.text} target="_blank">
<Icon as={item.Icon} />
<small>{item.text}</small>
</ListItem>
))}
</Container>
</>
<Container ref={containerRef}>
{ITEMS.map((item) => (
<ListItem href={item.url} key={item.text} target="_blank">
<Icon as={item.Icon} />
<small>{item.text}</small>
</ListItem>
))}
</Container>
);
};
export default Help;
36 changes: 17 additions & 19 deletions web/src/layout/Header/navbar/Menu/Settings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React, { Dispatch, SetStateAction, useRef, useState } from "react";
import React, { useRef, useState } from "react";
import styled from "styled-components";
import { Tabs } from "@kleros/ui-components-library";
import General from "./General";
import SendMeNotifications from "./SendMeNotifications";
import { useFocusOutside } from "hooks/useFocusOutside";
import { Overlay } from "components/Overlay";

const Container = styled.div`
display: flex;
position: absolute;
max-height: 80vh;
overflow-y: auto;
z-index: 1;
background-color: ${({ theme }) => theme.whiteBackground};
flex-direction: column;
Expand Down Expand Up @@ -45,29 +46,26 @@ const TABS = [
];

interface ISettings {
setIsSettingsOpen: Dispatch<SetStateAction<boolean>>;
toggleIsSettingsOpen: () => void;
}

const Settings: React.FC<ISettings> = ({ setIsSettingsOpen }) => {
const Settings: React.FC<ISettings> = ({ toggleIsSettingsOpen }) => {
const [currentTab, setCurrentTab] = useState<number>(0);
const containerRef = useRef(null);
useFocusOutside(containerRef, () => setIsSettingsOpen(false));
useFocusOutside(containerRef, () => toggleIsSettingsOpen());

return (
<>
<Overlay />
<Container ref={containerRef}>
<StyledSettingsText>Settings</StyledSettingsText>
<StyledTabs
currentValue={currentTab}
items={TABS}
callback={(n: number) => {
setCurrentTab(n);
}}
/>
{currentTab === 0 ? <General /> : <SendMeNotifications />}
</Container>
</>
<Container ref={containerRef}>
<StyledSettingsText>Settings</StyledSettingsText>
<StyledTabs
currentValue={currentTab}
items={TABS}
callback={(n: number) => {
setCurrentTab(n);
}}
/>
{currentTab === 0 ? <General /> : <SendMeNotifications />}
</Container>
);
};

Expand Down
18 changes: 8 additions & 10 deletions web/src/layout/Header/navbar/Menu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import React, { useState } from "react";
import React from "react";
import styled from "styled-components";
import { useToggle } from "react-use";
import LightButton from "components/LightButton";
import Help from "./Help";
import DarkModeIcon from "svgs/menu-icons/dark-mode.svg";
import HelpIcon from "svgs/menu-icons/help.svg";
import LightModeIcon from "svgs/menu-icons/light-mode.svg";
import NotificationsIcon from "svgs/menu-icons/notifications.svg";
import SettingsIcon from "svgs/menu-icons/settings.svg";
import Settings from "./Settings";
import { useToggleTheme } from "hooks/useToggleThemeContext";

const Container = styled.div``;
Expand All @@ -19,18 +16,21 @@ const ButtonContainer = styled.div`
align-items: center;
`;

const Menu: React.FC = () => {
interface IMenu {
toggleIsSettingsOpen: () => void;
toggleIsHelpOpen: () => void;
}

const Menu: React.FC<IMenu> = ({ toggleIsHelpOpen, toggleIsSettingsOpen }) => {
const [theme, toggleTheme] = useToggleTheme();
const [isHelpOpen, toggleIsHelpOpen] = useToggle(true);
const [isSettingsOpen, setIsSettingsOpen] = useState(false);

const isLightTheme = theme === "light";
const buttons = [
{ text: "Notifications", Icon: NotificationsIcon },
{
text: "Settings",
Icon: SettingsIcon,
onClick: () => setIsSettingsOpen(true),
onClick: () => toggleIsSettingsOpen(),
},
{
text: "Help",
Expand All @@ -53,8 +53,6 @@ const Menu: React.FC = () => {
<LightButton {...{ text, onClick, Icon }} />
</ButtonContainer>
))}
{isHelpOpen && <Help toggle={toggleIsHelpOpen} />}
{isSettingsOpen && <Settings setIsSettingsOpen={setIsSettingsOpen} />}
</Container>
);
};
Expand Down
76 changes: 50 additions & 26 deletions web/src/layout/Header/navbar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,87 @@
import React from "react";
import styled from "styled-components";
import { useLockBodyScroll, useToggle } from "react-use";
import ConnectWallet from "components/ConnectWallet";
import LightButton from "components/LightButton";
import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg";
import { useToggle } from "react-use";
import { useOpenContext } from "../index";
import DappList from "./DappList";
import Explore from "./Explore";
import ConnectWallet from "components/ConnectWallet";
import LightButton from "components/LightButton";
import { Overlay } from "components/Overlay";
import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg";
import Menu from "./Menu";
import Debug from "./Debug";
import Help from "./Menu/Help";
import Settings from "./Menu/Settings";
import { useLockOverlayScroll } from "hooks/useLockOverlayScroll";

const Container = styled.div<{ isOpen: boolean }>`
position: absolute;
top: 64px;
left: 0;
right: 0;
max-height: calc(100vh - 64px);
overflow-y: auto;
z-index: 1;
background-color: ${({ theme }) => theme.whiteBackground};
border: 1px solid ${({ theme }) => theme.stroke};
box-shadow: 0px 2px 3px ${({ theme }) => theme.defaultShadow};

transform-origin: top;
transform: scaleY(${({ isOpen }) => (isOpen ? "1" : "0")});
visibility: ${({ isOpen }) => (isOpen ? "visible" : "hidden")};
transition-property: transform, visibility;
transition-duration: ${({ theme }) => theme.transitionSpeed};
transition-timing-function: ease;

padding: 24px;

hr {
margin: 24px 0;
}
`;

const PopupContainer = styled.div`
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
`;

const NavBar: React.FC = () => {
const [isSolutionsOpen, toggleSolution] = useToggle(false);
const [isDappListOpen, toggleIsDappListOpen] = useToggle(false);
const [isHelpOpen, toggleIsHelpOpen] = useToggle(false);
const [isSettingsOpen, toggleIsSettingsOpen] = useToggle(false);
const { isOpen } = useOpenContext();
useLockBodyScroll(isOpen);
useLockOverlayScroll(isOpen);

return (
<Container {...{ isOpen }}>
<LightButton
text="Kleros Solutions"
onClick={() => {
toggleSolution();
}}
Icon={KlerosSolutionsIcon}
/>
{isSolutionsOpen && <DappList toggleSolution={toggleSolution} />}
<hr />
<Explore />
<hr />
<ConnectWallet />
<hr />
<Menu />
<br />
<Debug />
</Container>
<>
<Container {...{ isOpen }}>
<LightButton
text="Kleros Solutions"
onClick={() => {
toggleIsDappListOpen();
}}
Icon={KlerosSolutionsIcon}
/>
<hr />
<Explore />
<hr />
<ConnectWallet />
<hr />
<Menu {...{ toggleIsHelpOpen, toggleIsSettingsOpen }} />
<br />
<Debug />
</Container>
{(isDappListOpen || isHelpOpen || isSettingsOpen) && (
<PopupContainer>
<Overlay />
{isDappListOpen && <DappList {...{ toggleIsDappListOpen }} />}
{isHelpOpen && <Help {...{ toggleIsHelpOpen }} />}
{isSettingsOpen && <Settings {...{ toggleIsSettingsOpen }} />}
</PopupContainer>
)}
</>
);
};

Expand Down
Loading