Skip to content

Commit

Permalink
Settings modal with language, day/night mode and accent MVP (#145)
Browse files Browse the repository at this point in the history
Initial draft settings modal with language, day/night mode and accent
Styling will be improved upon by completing issue #155 
Closes #151
  • Loading branch information
tinybigideas authored Jun 29, 2022
1 parent dc92dcc commit a02bf21
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 49 deletions.
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

0 comments on commit a02bf21

Please sign in to comment.