Skip to content

Commit 7dfff96

Browse files
feat(layout): move footer items to sidebar and header
1 parent 9d9cb16 commit 7dfff96

File tree

8 files changed

+211
-5
lines changed

8 files changed

+211
-5
lines changed

packages/apps/tools/src/components/Common/Layout/partials/Header/Header.tsx

+22-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ import routes from '@/constants/routes';
66
import { useWalletConnectClient } from '@/context/connect-wallet-context';
77
import type { IMenuItem } from '@/types/Layout';
88
import type { INetworkData } from '@/utils/network';
9-
import { NavHeader, useModal } from '@kadena/react-ui';
9+
import {IconButton, NavHeader, Tooltip, useModal} from '@kadena/react-ui';
1010
import useTranslation from 'next-translate/useTranslation';
1111
import Link from 'next/link';
1212
import { useRouter } from 'next/router';
1313
import type { FC, ReactNode } from 'react';
1414
import React from 'react';
15+
import {MenuButton} from "@/components/Common/Layout/partials/Sidebar/MenuButton";
16+
import {useTheme} from "next-themes";
17+
import classNames from "classnames";
18+
import {gridMiniMenuListButtonStyle} from "@/components/Common/Layout/partials/Sidebar/styles.css";
19+
import {HeaderMenuButton} from "@/components/Common/Layout/partials/Header/HeaderMenuButton";
1520

1621
export interface IHeaderProps {
1722
logo?: ReactNode;
@@ -27,6 +32,11 @@ const Header: FC<IHeaderProps> = () => {
2732
const { pathname, push } = useRouter();
2833
const { renderModal } = useModal();
2934

35+
const { systemTheme, theme, setTheme } = useTheme();
36+
37+
const currentTheme = theme === 'system' ? systemTheme : theme;
38+
39+
3040
const navItems = [
3141
{
3242
label: t('Faucet'),
@@ -60,6 +70,11 @@ const Header: FC<IHeaderProps> = () => {
6070
setSelectedNetwork((e.target as HTMLSelectElement).value as Network);
6171
};
6272

73+
const toggleTheme = (): void => {
74+
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
75+
setTheme(newTheme);
76+
};
77+
6378
return (
6479
<NavHeader.Root brand="DevTools">
6580
<NavHeader.Navigation activeHref={pathname}>
@@ -75,6 +90,12 @@ const Header: FC<IHeaderProps> = () => {
7590
))}
7691
</NavHeader.Navigation>
7792
<NavHeader.Content>
93+
<HeaderMenuButton
94+
title={'Links'}
95+
href={'#'}
96+
icon={'ThemeLightDark'}
97+
onClick={() => toggleTheme()}
98+
/>
7899
<NavHeader.Select
79100
id="network-select"
80101
ariaLabel={t('Select Network')}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { SystemIcon, Tooltip } from '@kadena/react-ui';
2+
import classNames from 'classnames';
3+
import Link from 'next/link';
4+
import type { ButtonHTMLAttributes, FC } from 'react';
5+
import React, { useRef } from 'react';
6+
import {
7+
headerButtonStyle,
8+
} from './styles.css';
9+
10+
export interface IHeaderMenuButtonProps
11+
extends ButtonHTMLAttributes<HTMLButtonElement> {
12+
title?: string;
13+
href?: string;
14+
icon: keyof typeof SystemIcon;
15+
}
16+
17+
export const HeaderMenuButton: FC<IHeaderMenuButtonProps> = ({
18+
title,
19+
href,
20+
icon,
21+
...rest
22+
}) => {
23+
const Icon = SystemIcon[icon];
24+
25+
const button = (
26+
<>
27+
<button
28+
className={headerButtonStyle}
29+
{...rest}
30+
aria-label={title}
31+
>
32+
<Icon />
33+
</button>
34+
</>
35+
);
36+
37+
if (href) return <Link href={href}>{button}</Link>;
38+
return button;
39+
};

packages/apps/tools/src/components/Common/Layout/partials/Header/styles.css.ts

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { sprinkles } from '@kadena/react-ui/theme';
1+
import {darkThemeClass, sprinkles, vars} from '@kadena/react-ui/theme';
22
import { style } from '@vanilla-extract/css';
33

44
export const walletConnectWrapperStyle = style([
@@ -11,3 +11,38 @@ export const addCustomNetworkWrapperStyle = style([
1111
marginLeft: '$4',
1212
}),
1313
]);
14+
15+
export const headerButtonStyle = style([
16+
sprinkles({
17+
outline: 'none',
18+
background: 'none',
19+
border: 'none',
20+
cursor: 'pointer',
21+
padding: '$5',
22+
color: '$gray40',
23+
}),
24+
{
25+
transition: 'all 0.1s ease',
26+
width: '100%',
27+
selectors: {
28+
[`${darkThemeClass} &:hover`]: {
29+
color: vars.colors.$white,
30+
},
31+
[`&:hover`]: {
32+
color: vars.colors.$white,
33+
},
34+
[`${darkThemeClass} &.active`]: {
35+
backgroundColor: vars.colors.$blue80,
36+
},
37+
[`&.active`]: {
38+
backgroundColor: vars.colors.$blue20,
39+
},
40+
[`${darkThemeClass} &.active:hover`]: {
41+
color: vars.colors.$blue20,
42+
},
43+
['&.active:hover']: {
44+
color: vars.colors.$blue60,
45+
},
46+
},
47+
},
48+
])

packages/apps/tools/src/components/Common/Layout/partials/Sidebar/Menu.tsx

+46-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,39 @@
11
import { useLayoutContext } from '@/context';
2-
import { Accordion, IconButton } from '@kadena/react-ui';
2+
import {Accordion, Box, Heading, IconButton} from '@kadena/react-ui';
33
import { useRouter } from 'next/router';
44
import type { FC } from 'react';
55
import React from 'react';
66
import { MenuLinkButton } from './MenuLinkButton';
7-
import { gridItemMenuStyle, subMenuTitleClass } from './styles.css';
7+
import {gridItemMenuStyle, linksContainerStyle, linksMenuTitleClass, subMenuTitleClass} from './styles.css';
8+
import useTranslation from "next-translate/useTranslation";
89

910
export const Menu: FC = () => {
1011
const router = useRouter();
12+
const { t } = useTranslation('common');
13+
14+
15+
const links = [
16+
{
17+
title: t('Tutorial'),
18+
href: 'https://kadena.io/',
19+
target: '_blank',
20+
},
21+
{
22+
title: t('Documentation'),
23+
href: 'https://kadena.io/',
24+
target: '_blank',
25+
},
26+
{
27+
title: t('Privacy & Policy'),
28+
href: 'https://kadena.io/',
29+
target: '_blank',
30+
},
31+
{
32+
title: 'Terms of use',
33+
href: 'https://kadena.io/',
34+
target: '_blank',
35+
},
36+
];
1137

1238
const { activeMenu, setActiveMenuIndex } = useLayoutContext();
1339
if (!activeMenu) return null;
@@ -32,6 +58,24 @@ export const Menu: FC = () => {
3258
/>
3359
))}
3460
</Accordion.Root>
61+
<div className={linksContainerStyle}>
62+
<div className={linksMenuTitleClass}>
63+
<span>{'Links'}</span>
64+
</div>
65+
<ul>
66+
{links.map(link => (
67+
<li key={link.title}>
68+
<a
69+
href={link.href}
70+
target={link.target}
71+
rel="noreferrer"
72+
>
73+
{link.title}
74+
</a>
75+
</li>
76+
))}
77+
</ul>
78+
</div>
3579
</div>
3680
);
3781
};

packages/apps/tools/src/components/Common/Layout/partials/Sidebar/Toolbar.tsx

+35-1
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@ import {
1212
gridMiniMenuListItemStyle,
1313
gridMiniMenuListStyle,
1414
} from './styles.css';
15+
import {OptionsModal} from "@/components/Global/OptionsModal";
16+
import {useModal} from "@kadena/react-ui";
1517

1618
export interface IMiniMenuProps {}
1719

1820
export const Toolbar: FC<IMiniMenuProps> = () => {
19-
const { toolbar, setActiveMenuIndex, activeMenuIndex, isMenuOpen } =
21+
const { toolbar, setActiveMenuIndex, activeMenuIndex, isMenuOpen, visibleLinks, setVisibleLinks } =
2022
useLayoutContext();
2123
const router = useRouter();
24+
const { renderModal } = useModal();
2225

2326
const handleItemClick = (index: number): void => {
2427
if (toolbar[index]?.items?.length) {
@@ -55,6 +58,17 @@ export const Toolbar: FC<IMiniMenuProps> = () => {
5558
return index === activeMenuIndex || isUrlParam;
5659
};
5760

61+
const handleLinksClick = (): void => {
62+
handleOpenCloseDrawer();
63+
if(!visibleLinks) {
64+
setVisibleLinks(true);
65+
}
66+
};
67+
68+
const handleDevOptionsClick = (): void => {
69+
renderModal(<OptionsModal />, 'Settings');
70+
};
71+
5872
return (
5973
<nav className={gridItemMiniMenuStyle}>
6074
<ul className={classNames(gridMiniMenuListStyle)}>
@@ -72,6 +86,26 @@ export const Toolbar: FC<IMiniMenuProps> = () => {
7286
<ul
7387
className={classNames(gridMiniMenuListStyle, bottomIconsContainerStyle)}
7488
>
89+
<li key={String('links')} className={gridMiniMenuListItemStyle}>
90+
<div>
91+
<MenuButton
92+
title={'Links'}
93+
href={'#'}
94+
icon={'Link'}
95+
onClick={() => handleLinksClick()}
96+
/>
97+
</div>
98+
</li>
99+
<li key={String('Dev Options')} className={gridMiniMenuListItemStyle}>
100+
<div>
101+
<MenuButton
102+
title={'DevOptions'}
103+
href={'#'}
104+
icon={'ApplicationBrackets'}
105+
onClick={() => handleDevOptionsClick()}
106+
/>
107+
</div>
108+
</li>
75109
<li key={String('openDrawer')} className={gridMiniMenuListItemStyle}>
76110
<div>
77111
<MenuButton

packages/apps/tools/src/components/Common/Layout/partials/Sidebar/styles.css.ts

+25
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,28 @@ export const iconRightStyle = style([
150150
transform: 'rotate(90deg)',
151151
},
152152
]);
153+
154+
export const linksContainerStyle = style([
155+
sprinkles({
156+
position: 'absolute',
157+
bottom: 0,
158+
159+
padding: '$xs',
160+
display: 'flex',
161+
flexDirection: 'column'
162+
}),
163+
{
164+
borderTop: `1px solid ${vars.colors.$borderSubtle}`,
165+
width: 'auto',
166+
},
167+
]);
168+
169+
export const linksMenuTitleClass = style([
170+
sprinkles({
171+
fontSize: '$md',
172+
display: 'flex',
173+
justifyContent: 'space-between',
174+
alignItems: 'center',
175+
marginBottom: '$4',
176+
}),
177+
]);

packages/apps/tools/src/components/Common/Layout/styles.css.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const headerStyle = style([
77
top: 0,
88
width: '100%',
99
height: '$16',
10+
alignItems: 'center'
1011
}),
1112
]);
1213

packages/apps/tools/src/context/layout-context.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ interface ILayoutContext {
1111
setActiveMenuIndex: (index?: number) => void;
1212
activeMenu?: ISidebarToolbarItem;
1313
resetLayout: () => void;
14+
visibleLinks: boolean;
15+
setVisibleLinks: (value: boolean) => void;
1416
}
1517

1618
const LayoutContext = createContext<ILayoutContext>({
@@ -20,6 +22,8 @@ const LayoutContext = createContext<ILayoutContext>({
2022
setActiveMenuIndex: () => {},
2123
activeMenu: undefined,
2224
resetLayout: () => {},
25+
visibleLinks: false,
26+
setVisibleLinks: () => {},
2327
});
2428

2529
const useLayoutContext = (): ILayoutContext => {
@@ -61,6 +65,7 @@ const LayoutContextProvider = (props: PropsWithChildren): JSX.Element => {
6165
const [toolbar, setToolbar] = useState<ISidebarToolbarItem[]>([]);
6266
const [activeMenuIndex, setActiveMenuIndex] = useState<number | undefined>();
6367
const isMenuOpen = Number.isInteger(activeMenuIndex);
68+
const [visibleLinks, setVisibleLinks] = useState(false);
6469

6570
const resetLayout = (): void => {
6671
setToolbar([]);
@@ -79,6 +84,8 @@ const LayoutContextProvider = (props: PropsWithChildren): JSX.Element => {
7984
activeMenu:
8085
activeMenuIndex !== undefined ? toolbar[activeMenuIndex] : undefined,
8186
resetLayout,
87+
visibleLinks,
88+
setVisibleLinks,
8289
}}
8390
>
8491
{props.children}

0 commit comments

Comments
 (0)