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

Settings modal with language, mode and accent MVP #145

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
13 changes: 13 additions & 0 deletions components/SettingsModal/SettingsModal.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { style } from '@vanilla-extract/css';
import { vars } from 'degen';

export const select = style({
background: 'transparent',
color: vars.colors.accent,
padding: '3px 7px',
borderColor: vars.colors.accent,
borderRadius: vars.radii['large'],
outline: 'none',
cursor: 'pointer',
textTransform: 'capitalize'
});
103 changes: 103 additions & 0 deletions components/SettingsModal/SettingsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React, { useState } from 'react';
import { Box, Button, Stack, Text, useTheme } from 'degen';

import * as styles from './SettingsModal.css';
import { Accent, Mode } from 'degen/dist/types/tokens';
import { accents, modes } from 'helpers/theme-utils';
import { Language, languages } from 'helpers/languageUtils';
import { accentLocalKey, languageLocalKey, modeLocalKey } from 'constants/local-storage';

const SettingsModal = () => {
const { accent, setAccent, mode, setMode } = useTheme();
const [language, setLanguage] = useState<Language>(Language.EN_US);

const locallyStore = (key: string, value: string) => localStorage.setItem(key, value);

const setLanguageState = (lang: Language) => {
setLanguage(lang);
locallyStore(languageLocalKey, lang);
};

const setModeState = (mode: Mode) => {
setMode(mode);
locallyStore(modeLocalKey, mode);
};

const setAccentState = (accent: Accent) => {
setAccent(accent);
locallyStore(accentLocalKey, accent);
};

return (
<Box width="96">
<Box borderBottomWidth="0.375" paddingX="6" paddingY="4">
<Text variant="large" color="textPrimary" weight="bold" align="center">
Settings
</Text>
</Box>
<Box padding="6">
<Stack space="6">
<Stack direction="horizontal" justify="space-between">
<Text variant="small" color="textSecondary">
Language
</Text>
<Box>
<select
name="language"
value={language}
className={styles.select}
onChange={(event) =>
setLanguageState(event.target.value as Language)
}
>
{languages.map((languageValue, index) =>
<option value={languageValue} key={index}>{languageValue}</option>
)}
</select>
</Box>
</Stack>
<Stack direction="horizontal" justify="space-between">
<Text variant="small" color="textSecondary">
Mode
</Text>
<Box>
<select
name="mode"
value={mode}
className={styles.select}
onChange={(event) =>
setModeState(event.target.value as Mode)
}
>
{modes.map((modeValue, index) =>
<option value={modeValue} key={index}>{modeValue}</option>
)}
</select>
</Box>
</Stack>
<Stack direction="horizontal" justify="space-between">
<Text variant="small" color="textSecondary">
Color Scheme
</Text>
<Box>
<select
name="accent"
value={accent}
className={styles.select}
onChange={(event) =>
setAccentState(event.target.value as Accent)
}
>
{accents.map((accentValue, index) =>
<option value={accentValue} key={index}>{accentValue}</option>
)}
</select>
</Box>
</Stack>
</Stack>
</Box>
</Box>
);
};

export default SettingsModal;
3 changes: 2 additions & 1 deletion components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { MediumIcon } from 'icons/MediumIcon';
import { GithubIcon } from 'icons/GithubIcon';
import { useRouter } from 'next/router';
import { nextAccentMap } from 'helpers/theme-utils';
import { accentLocalKey } from 'constants/local-storage';

const feedbackUrl =
'https://feedback.honey.finance/';
Expand Down Expand Up @@ -88,7 +89,7 @@ const Sidebar = (props: SidebarProps) => {

const toggleAccent = React.useCallback(() => {
const nextAccent = nextAccentMap[accent];
localStorage.setItem('accent', nextAccent);
localStorage.setItem(accentLocalKey, nextAccent);
setAccent(nextAccent);
}, [accent, setAccent]);

Expand Down
102 changes: 59 additions & 43 deletions components/UserInfo/UserInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import React, {
FC,
useState,
useEffect,
useCallback,
useRef,
MutableRefObject
useState,
} from 'react';
import { Box, IconMenu } from 'degen';
import { Box, IconCog, IconMenu } from 'degen';
import { Stack } from 'degen';
import { Button } from 'degen';
import { Text } from 'degen';
import { useWalletKit } from '@gokiprotocol/walletkit';
import { useConnectedWallet, useSolana } from '@saberhq/use-solana';
import * as styles from './UserInfo.css';
import ModalContainer from 'components/ModalContainer/ModalContainer';
import SettingsModal from 'components/SettingsModal/SettingsModal';

interface UserInfoProps {
setShowMobileSidebar: Function;
Expand All @@ -25,6 +24,7 @@ const UserInfo = (props: UserInfoProps) => {
const btnRef = useRef<HTMLButtonElement>(null);
const btnTextRef = useRef<HTMLElement>(null);
const walletAddress = wallet?.publicKey.toString();
const [showSettingsModal, setShowSettingsModal] = useState(false);

useEffect(() => {
const btn = btnRef.current;
Expand All @@ -45,50 +45,66 @@ const UserInfo = (props: UserInfoProps) => {
}, [walletAddress]);

return (
<Box
borderRadius="large"
height="16"
backgroundColor="background"
className={styles.topbar}
>
<Stack
flex={1}
direction="horizontal"
space="3"
justify="flex-end"
align="center"
<>
<ModalContainer
onClose={() => setShowSettingsModal(false)}
isVisible={showSettingsModal}
>
<Box marginRight="auto" className={styles.menuIcon}>
<Button
onClick={() => props.setShowMobileSidebar(true)}
variant="transparent"
shape="square"
size="small"
>
<IconMenu size="8" color="accent" />
</Button>
</Box>
{wallet ? (
<SettingsModal />
</ModalContainer>
<Box
borderRadius="large"
height="16"
backgroundColor="background"
className={styles.topbar}
>
<Stack
flex={1}
direction="horizontal"
space="3"
justify="flex-end"
align="center"
>
<Box marginRight="auto" className={styles.menuIcon}>
<Button
onClick={() => props.setShowMobileSidebar(true)}
variant="transparent"
shape="square"
size="small"
>
<IconMenu size="8" color="accent" />
</Button>
</Box>
{wallet ? (
<Button
onClick={disconnect}
ref={btnRef}
variant="secondary"
size="small"
width="48"
>
<Box width="24">
<Text ref={btnTextRef} ellipsis>
{wallet?.publicKey?.toString()}
</Text>
</Box>
</Button>
) : (
<Button variant="primary" size="small" width="48" onClick={connect}>
Connect Wallet
</Button>
)}
<Button
onClick={disconnect}
ref={btnRef}
onClick={() => setShowSettingsModal(true)}
variant="secondary"
size="small"
width="48"
shape="square"
>
<Box width="24">
<Text ref={btnTextRef} ellipsis>
{wallet?.publicKey?.toString()}
</Text>
</Box>
</Button>
) : (
<Button variant="primary" size="small" width="48" onClick={connect}>
Connect Wallet
<IconCog />
</Button>
)}
</Stack>
</Box>
</Stack>
</Box>
</>
);
};

Expand Down
3 changes: 3 additions & 0 deletions constants/local-storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const languageLocalKey = 'language';
export const modeLocalKey = 'mode';
export const accentLocalKey = 'accent';
5 changes: 5 additions & 0 deletions helpers/languageUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum Language {
EN_US = 'English (US)'
}

export const languages: Language[] = Object.values(Language);
12 changes: 9 additions & 3 deletions helpers/theme-utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Accent } from 'degen/dist/types/tokens';
import { Accent, Mode } from 'degen/dist/types/tokens';

export type ThemeAccent = Accent | 'foreground';

export const accentSequence: ThemeAccent[] = [
export const accents: Accent[] = [
'orange',
'yellow',
'blue',
Expand All @@ -11,10 +11,16 @@ export const accentSequence: ThemeAccent[] = [
'pink',
'purple',
'red',
'teal',
'teal'
];

export const accentSequence: ThemeAccent[] = [
...accents,
'foreground'
];

export const modes: Mode[] = ['dark', 'light'];

//returns sequence in form of map {'orange': 'yellow', 'yellow': 'blue', ...}
export const nextAccentMap = accentSequence.reduce((acc, color, index) => {
const isLastColor = index + 1 === accentSequence.length;
Expand Down
20 changes: 18 additions & 2 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { PartialNetworkConfigMap } from '@saberhq/use-solana/src/utils/useConnec
import { useEffect, useState } from 'react';
import SecPopup from 'components/SecPopup';
import Script from 'next/script';
import { Mode, Accent } from 'degen/dist/types/tokens';
import { Language, languages } from 'helpers/languageUtils';
import { accentLocalKey, languageLocalKey, modeLocalKey } from 'constants/local-storage';

const network = process.env.NETWORK as Network;
const networkConfiguration = () => {
Expand All @@ -21,10 +24,23 @@ const networkConfiguration = () => {
}
};

const defaultMode: Mode = 'dark';
const storedMode =
typeof window !== 'undefined'
? (localStorage.getItem(modeLocalKey) as Mode)
: undefined;

const defaultAccent: ThemeAccent = accentSequence[0];
const storedAccent =
typeof window !== 'undefined'
? (localStorage.getItem('accent') as ThemeAccent)
? (localStorage.getItem(accentLocalKey) as ThemeAccent | Accent)
: undefined;

// TODO: Utilise language setting site wide with intl files
const defaultLanguage: Language = Language.EN_US;
const storedLanguage =
typeof window !== 'undefined'
? (localStorage.getItem(languageLocalKey) as Language)
: undefined;

function MyApp({ Component, pageProps }: AppProps) {
Expand All @@ -41,7 +57,7 @@ function MyApp({ Component, pageProps }: AppProps) {

return (
<ThemeProvider
defaultMode="dark"
defaultMode={storedMode || defaultMode}
defaultAccent={storedAccent || defaultAccent}
>
<Script
Expand Down