diff --git a/src/App.tsx b/src/App.tsx index 2a193de3..4cb247d4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,6 +15,7 @@ import { Header } from './sections/header/Header'; import { Footer } from './sections/footer/Footer'; import { BitcoinInfoProvider } from './context/BitcoinContext'; import { BitcoinFees } from './components/bitcoinInfo/BitcoinFees'; +import { LoadingCard } from './components/loading/LoadingCard'; const EntryView = React.lazy(() => import('./views/entry/Entry')); const MainView = React.lazy(() => import('./views/main/Main')); @@ -32,13 +33,15 @@ const client = new ApolloClient({ const ContextApp: React.FC = () => { const { theme } = useSettings(); - const { loggedIn, admin, read } = useAccount(); + const { loggedIn, admin, read, sessionAdmin } = useAccount(); const renderContent = () => ( - Loading...}> + } + > {!loggedIn && admin === '' ? ( - ) : admin !== '' && read === '' ? ( + ) : admin !== '' && read === '' && sessionAdmin === '' ? ( ) : ( diff --git a/src/components/adminSwitch/AdminSwitch.tsx b/src/components/adminSwitch/AdminSwitch.tsx index 55eed125..446c3dd8 100644 --- a/src/components/adminSwitch/AdminSwitch.tsx +++ b/src/components/adminSwitch/AdminSwitch.tsx @@ -1,13 +1,13 @@ +import { useAccount } from '../../context/AccountContext'; + interface AdminSwitchProps { children: any; } export const AdminSwitch = ({ children }: AdminSwitchProps) => { - const currentAuth = localStorage.getItem('account') || 'auth1'; - const adminMacaroon = localStorage.getItem(`${currentAuth}-admin`) || ''; - const sessionAdmin = sessionStorage.getItem('session') || ''; + const { admin, sessionAdmin } = useAccount(); - if (!adminMacaroon && !sessionAdmin) { + if (!admin && !sessionAdmin) { return null; } diff --git a/src/components/auth/BTCLogin.tsx b/src/components/auth/BTCLogin.tsx index 0bb65256..3d55ccf5 100644 --- a/src/components/auth/BTCLogin.tsx +++ b/src/components/auth/BTCLogin.tsx @@ -8,14 +8,21 @@ import { toast } from 'react-toastify'; import { useLazyQuery } from '@apollo/react-hooks'; import { GET_CAN_CONNECT } from '../../graphql/query'; import { getErrorContent } from '../../utils/error'; +import { useHistory } from 'react-router-dom'; interface AuthProps { available: number; callback?: () => void; + withRedirect?: boolean; } -export const BTCLoginForm = ({ available, callback }: AuthProps) => { +export const BTCLoginForm = ({ + available, + callback, + withRedirect, +}: AuthProps) => { const { setAccount } = useAccount(); + const { push } = useHistory(); const [isName, setName] = useState(''); const [isJson, setJson] = useState(''); @@ -63,6 +70,7 @@ export const BTCLoginForm = ({ available, callback }: AuthProps) => { toast.success('Connected!'); callback && callback(); + withRedirect && push('/'); } }, [ data, diff --git a/src/components/auth/ConnectLogin.tsx b/src/components/auth/ConnectLogin.tsx index 20aac445..466d17ea 100644 --- a/src/components/auth/ConnectLogin.tsx +++ b/src/components/auth/ConnectLogin.tsx @@ -6,6 +6,7 @@ import { getBase64CertfromDerFormat, saveUserAuth, getAuthString, + saveSessionAuth, } from '../../utils/auth'; import { LoginButton, PasswordInput } from './Password'; import CryptoJS from 'crypto-js'; @@ -13,14 +14,21 @@ import { useLazyQuery } from '@apollo/react-hooks'; import { GET_CAN_CONNECT } from '../../graphql/query'; import { toast } from 'react-toastify'; import { getErrorContent } from '../../utils/error'; +import { useHistory } from 'react-router-dom'; interface AuthProps { available: number; callback?: () => void; + withRedirect?: boolean; } -export const ConnectLoginForm = ({ available, callback }: AuthProps) => { +export const ConnectLoginForm = ({ + available, + callback, + withRedirect, +}: AuthProps) => { const { setAccount } = useAccount(); + const { push } = useHistory(); const [isName, setName] = useState(''); const [isUrl, setUrl] = useState(''); @@ -54,18 +62,20 @@ export const ConnectLoginForm = ({ available, callback }: AuthProps) => { cert: base64Cert, }); - sessionStorage.setItem('session', macaroon); + saveSessionAuth(macaroon); setAccount({ loggedIn: true, host: socket, admin: encryptedAdmin, + sessionAdmin: macaroon, read: macaroon, cert: base64Cert, }); toast.success('Connected!'); callback && callback(); + withRedirect && push('/'); } }, [data, loading, available, callback, isName, isPass, isUrl, setAccount]); diff --git a/src/components/auth/NormalLogin.tsx b/src/components/auth/NormalLogin.tsx index b6a3fa16..e46f4fa6 100644 --- a/src/components/auth/NormalLogin.tsx +++ b/src/components/auth/NormalLogin.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import { Input, SingleLine, Sub4Title } from '../generic/Styled'; import { useAccount } from '../../context/AccountContext'; -import { saveUserAuth, getAuthString } from '../../utils/auth'; +import { saveUserAuth, getAuthString, saveSessionAuth } from '../../utils/auth'; import CryptoJS from 'crypto-js'; import base64url from 'base64url'; import { PasswordInput, LoginButton } from './Password'; @@ -9,14 +9,17 @@ import { useLazyQuery } from '@apollo/react-hooks'; import { GET_CAN_CONNECT } from '../../graphql/query'; import { getErrorContent } from '../../utils/error'; import { toast } from 'react-toastify'; +import { useHistory } from 'react-router-dom'; interface AuthProps { available: number; callback?: () => void; + withRedirect?: boolean; } -export const LoginForm = ({ available, callback }: AuthProps) => { +export const LoginForm = ({ available, callback, withRedirect }: AuthProps) => { const { setAccount } = useAccount(); + const { push } = useHistory(); const [isName, setName] = useState(''); const [isHost, setHost] = useState(''); @@ -62,16 +65,21 @@ export const LoginForm = ({ available, callback }: AuthProps) => { cert, }); + saveSessionAuth(admin); + setAccount({ loggedIn: true, + name: isName, host: isHost, admin: encryptedAdmin, + ...(read === '' && { sessionAdmin: admin }), read, cert, }); toast.success('Connected!'); callback && callback(); + withRedirect && push('/'); } }, [ data, @@ -103,7 +111,10 @@ export const LoginForm = ({ available, callback }: AuthProps) => { const renderContent = () => { const canConnect = - isName !== '' && isHost !== '' && isRead !== '' && !!available; + isName !== '' && + isHost !== '' && + (isAdmin !== '' || isRead !== '') && + !!available; return ( <> diff --git a/src/components/closeChannel/CloseChannel.tsx b/src/components/closeChannel/CloseChannel.tsx index 14b6e362..3d6a132a 100644 --- a/src/components/closeChannel/CloseChannel.tsx +++ b/src/components/closeChannel/CloseChannel.tsx @@ -83,8 +83,8 @@ export const CloseChannel = ({ const [hour, setHour] = useState(0); const { theme } = useSettings(); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { data: feeData } = useQuery(GET_BITCOIN_FEES, { onError: error => toast.error(getErrorContent(error)), diff --git a/src/components/generic/Icons.ts b/src/components/generic/Icons.ts index 45f60f91..3b4f7aa2 100644 --- a/src/components/generic/Icons.ts +++ b/src/components/generic/Icons.ts @@ -7,6 +7,7 @@ import { ReactComponent as ZapOffIcon } from '../../icons/zap-off.svg'; import { ReactComponent as HelpIcon } from '../../icons/help-circle.svg'; import { ReactComponent as SunIcon } from '../../icons/sun.svg'; import { ReactComponent as MoonIcon } from '../../icons/moon.svg'; +import { ReactComponent as EyeIcon } from '../../icons/eye.svg'; import { ReactComponent as EyeOffIcon } from '../../icons/eye-off.svg'; import { ReactComponent as ChevronsUpIcon } from '../../icons/chevrons-up.svg'; import { ReactComponent as ChevronsDownIcon } from '../../icons/chevrons-down.svg'; @@ -35,11 +36,15 @@ import { ReactComponent as RadioIcon } from '../../icons/radio.svg'; import { ReactComponent as CopyIcon } from '../../icons/copy.svg'; import { ReactComponent as ShieldIcon } from '../../icons/shield.svg'; import { ReactComponent as CrosshairIcon } from '../../icons/crosshair.svg'; +import { ReactComponent as KeyIcon } from '../../icons/key.svg'; +import { ReactComponent as SlidersIcon } from '../../icons/sliders.svg'; +import { ReactComponent as UsersIcon } from '../../icons/users.svg'; interface IconProps { color?: string; size?: string; fillcolor?: string; + strokeWidth?: string; } const GenericStyles = css` @@ -47,6 +52,8 @@ const GenericStyles = css` width: ${({ size }: IconProps) => (size ? size : '18px')}; color: ${({ color }: IconProps) => (color ? color : '')}; fill: ${({ fillcolor }: IconProps) => (fillcolor ? fillcolor : '')}; + stroke-width: ${({ strokeWidth }: IconProps) => + strokeWidth ? strokeWidth : '2px'}; `; export const IconCircle = styled.div` @@ -77,6 +84,7 @@ export const UpArrow = styleIcon(UpIcon); export const DownArrow = styleIcon(DownIcon); export const Sun = styleIcon(SunIcon); export const Moon = styleIcon(MoonIcon); +export const Eye = styleIcon(EyeIcon); export const EyeOff = styleIcon(EyeOffIcon); export const ChevronsDown = styleIcon(ChevronsDownIcon); export const ChevronsUp = styleIcon(ChevronsUpIcon); @@ -102,3 +110,6 @@ export const Radio = styleIcon(RadioIcon); export const Copy = styleIcon(CopyIcon); export const Shield = styleIcon(ShieldIcon); export const Crosshair = styleIcon(CrosshairIcon); +export const Key = styleIcon(KeyIcon); +export const Sliders = styleIcon(SlidersIcon); +export const Users = styleIcon(UsersIcon); diff --git a/src/components/generic/Styled.tsx b/src/components/generic/Styled.tsx index c7c49849..904485dd 100644 --- a/src/components/generic/Styled.tsx +++ b/src/components/generic/Styled.tsx @@ -56,7 +56,7 @@ interface SubCardProps { export const SubCard = styled.div` margin-bottom: 10px; - padding: ${({ padding }) => (padding ? padding : '10px')}; + padding: ${({ padding }) => (padding ? padding : '16px')}; background: ${subCardColor}; border: 1px solid ${cardBorderColor}; border-left: ${({ color }: SubCardProps) => @@ -128,6 +128,13 @@ export const SingleLine = styled.div` align-items: center; `; +export const ColumnLine = styled.div` + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; +`; + export const SimpleButton = styled.button` cursor: pointer; outline: none; diff --git a/src/components/loading/LoadingCard.tsx b/src/components/loading/LoadingCard.tsx index b8e67ee4..3d2377d2 100644 --- a/src/components/loading/LoadingCard.tsx +++ b/src/components/loading/LoadingCard.tsx @@ -7,6 +7,8 @@ import { textColorMap } from '../../styles/Themes'; const Loading = styled.div` width: 100%; + height: ${({ loadingHeight }: { loadingHeight?: string }) => + loadingHeight ? loadingHeight : 'auto'}; display: flex; justify-content: center; align-items: center; @@ -17,6 +19,7 @@ interface LoadingCardProps { noCard?: boolean; color?: string; noTitle?: boolean; + loadingHeight?: string; } export const LoadingCard = ({ @@ -24,6 +27,7 @@ export const LoadingCard = ({ color, noCard = false, noTitle = false, + loadingHeight, }: LoadingCardProps) => { const { theme } = useSettings(); @@ -31,7 +35,7 @@ export const LoadingCard = ({ if (noCard) { return ( - + ); @@ -40,7 +44,7 @@ export const LoadingCard = ({ if (noTitle) { return ( - + @@ -53,7 +57,7 @@ export const LoadingCard = ({ {title} - + diff --git a/src/components/secureButton/LoginModal.tsx b/src/components/secureButton/LoginModal.tsx index da3b5da2..6358177e 100644 --- a/src/components/secureButton/LoginModal.tsx +++ b/src/components/secureButton/LoginModal.tsx @@ -13,7 +13,7 @@ import { LoginButton } from '../../components/auth/Password'; import { Circle, ChevronRight } from '../generic/Icons'; import styled from 'styled-components'; import { useAccount } from '../../context/AccountContext'; -import { getAuthString } from '../../utils/auth'; +import { getAuthString, saveSessionAuth } from '../../utils/auth'; import { useSettings } from '../../context/SettingsContext'; import { textColorMap } from '../../styles/Themes'; @@ -46,7 +46,7 @@ export const LoginModal = ({ const { theme } = useSettings(); const [pass, setPass] = useState(''); const [storeSession, setStoreSession] = useState(false); - const { host, cert } = useAccount(); + const { host, cert, refreshAccount } = useAccount(); const handleClick = () => { try { @@ -54,7 +54,8 @@ export const LoginModal = ({ const decrypted = bytes.toString(CryptoJS.enc.Utf8); if (storeSession) { - sessionStorage.setItem('session', decrypted); + saveSessionAuth(decrypted); + refreshAccount(); } const auth = getAuthString(host, decrypted, cert); callback({ variables: { ...variables, auth } }); diff --git a/src/components/secureButton/SecureButton.tsx b/src/components/secureButton/SecureButton.tsx index fbb942f2..9daf924b 100644 --- a/src/components/secureButton/SecureButton.tsx +++ b/src/components/secureButton/SecureButton.tsx @@ -24,13 +24,9 @@ export const SecureButton = ({ }: SecureButtonProps) => { const [modalOpen, setModalOpen] = useState(false); - const { host, cert } = useAccount(); + const { host, cert, admin, sessionAdmin } = useAccount(); - const currentAuth = localStorage.getItem('account') || 'auth1'; - const adminMacaroon = localStorage.getItem(`${currentAuth}-admin`) || ''; - const sessionAdmin = sessionStorage.getItem('session') || ''; - - if (!adminMacaroon && !sessionAdmin) { + if (!admin && !sessionAdmin) { return null; } @@ -55,7 +51,7 @@ export const SecureButton = ({ { const activeAccount = localStorage.getItem('account') || 'auth1'; const sessionAdmin = sessionStorage.getItem('session') || ''; const { name, host, admin, read, cert } = getAuthParams(activeAccount); - const readMacaroon = read ? read : sessionAdmin; - const loggedIn = host !== '' && readMacaroon !== ''; + const loggedIn = host !== '' && (read !== '' || sessionAdmin !== ''); const setAccount = ({ loggedIn, name, host, admin, + sessionAdmin, read, cert, }: ChangeProps) => { @@ -60,6 +60,7 @@ const AccountProvider = ({ children }: any) => { name, host, admin, + sessionAdmin, read, cert, }); @@ -90,8 +91,7 @@ const AccountProvider = ({ children }: any) => { const activeAccount = localStorage.getItem('account') || 'auth1'; const sessionAdmin = sessionStorage.getItem('session') || ''; const { name, host, admin, read, cert } = getAuthParams(activeAccount); - const readMacaroon = read ? read : sessionAdmin; - const loggedIn = host !== '' && readMacaroon !== ''; + const loggedIn = host !== '' && (read !== '' || sessionAdmin !== ''); updateAccount((prevState: any) => { const newState = { ...prevState }; @@ -101,7 +101,7 @@ const AccountProvider = ({ children }: any) => { host, admin, sessionAdmin, - read: readMacaroon, + read, cert, }); }); @@ -113,7 +113,7 @@ const AccountProvider = ({ children }: any) => { host, admin, sessionAdmin, - read: readMacaroon, + read, cert, setAccount, changeAccount, diff --git a/src/icons/eye.svg b/src/icons/eye.svg new file mode 100644 index 00000000..9cde2437 --- /dev/null +++ b/src/icons/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/key.svg b/src/icons/key.svg new file mode 100644 index 00000000..32fa1cde --- /dev/null +++ b/src/icons/key.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/sliders.svg b/src/icons/sliders.svg new file mode 100644 index 00000000..c8fa766f --- /dev/null +++ b/src/icons/sliders.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/users.svg b/src/icons/users.svg new file mode 100644 index 00000000..766d8569 --- /dev/null +++ b/src/icons/users.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/sections/header/Header.tsx b/src/sections/header/Header.tsx index 73eb4f52..ecb8b303 100644 --- a/src/sections/header/Header.tsx +++ b/src/sections/header/Header.tsx @@ -1,6 +1,9 @@ import React from 'react'; import styled from 'styled-components'; import { textColor, cardColor } from '../../styles/Themes'; +import { HomeButton } from '../../views/entry/HomePage.styled'; +import { Link } from 'react-router-dom'; +import { useAccount } from '../../context/AccountContext'; const HeaderStyle = styled.div` display: flex; @@ -28,11 +31,17 @@ const HeaderTitle = styled.div` `; export const Header = () => { + const { loggedIn } = useAccount(); + return ( ThunderHub - + {!loggedIn && ( + + Login + + )} ); diff --git a/src/sections/navigation/nodeInfo/NodeInfo.tsx b/src/sections/navigation/nodeInfo/NodeInfo.tsx index e6097e33..7b326736 100644 --- a/src/sections/navigation/nodeInfo/NodeInfo.tsx +++ b/src/sections/navigation/nodeInfo/NodeInfo.tsx @@ -45,8 +45,8 @@ const Alias = styled.div` `; export const NodeInfo = () => { - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { loading, data } = useQuery(GET_NODE_INFO, { variables: { auth }, diff --git a/src/utils/auth.ts b/src/utils/auth.ts index 1c51fdcb..0fb6b1e1 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -37,6 +37,9 @@ export const saveUserAuth = ({ cert && localStorage.setItem(`auth${available}-cert`, cert); }; +export const saveSessionAuth = (sessionAdmin: string) => + sessionStorage.setItem('session', sessionAdmin); + export const getAuthString = ( host: string, macaroon: string, diff --git a/src/views/backups/DownloadBackups.tsx b/src/views/backups/DownloadBackups.tsx index 30e191bd..30b6dbaf 100644 --- a/src/views/backups/DownloadBackups.tsx +++ b/src/views/backups/DownloadBackups.tsx @@ -14,8 +14,8 @@ import { getErrorContent } from '../../utils/error'; import ScaleLoader from 'react-spinners/ScaleLoader'; export const DownloadBackups = ({ color }: { color: string }) => { - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const [getBackups, { data, loading }] = useLazyQuery(GET_BACKUPS, { variables: { auth }, diff --git a/src/views/backups/RecoverFunds.tsx b/src/views/backups/RecoverFunds.tsx index e7a16d39..acb274ff 100644 --- a/src/views/backups/RecoverFunds.tsx +++ b/src/views/backups/RecoverFunds.tsx @@ -20,8 +20,8 @@ export const RecoverFunds = ({ color }: { color: string }) => { const [backupString, setBackupString] = useState(''); const [isPasting, setIsPasting] = useState(false); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const [recoverFunds, { data, loading }] = useLazyQuery(RECOVER_FUNDS, { onError: error => toast.error(getErrorContent(error)), diff --git a/src/views/backups/VerifyBackups.tsx b/src/views/backups/VerifyBackups.tsx index 20c0ebd9..af2ecfa9 100644 --- a/src/views/backups/VerifyBackups.tsx +++ b/src/views/backups/VerifyBackups.tsx @@ -24,8 +24,8 @@ export const VerifyBackups = ({ color }: { color: string }) => { const [backupString, setBackupString] = useState(''); const [isPasting, setIsPasting] = useState(false); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const [verifyBackup, { data, loading }] = useLazyQuery(VERIFY_BACKUPS, { onError: error => toast.error(getErrorContent(error)), diff --git a/src/views/channels/ChannelView.tsx b/src/views/channels/ChannelView.tsx index 52530bbc..3b5ce0cc 100644 --- a/src/views/channels/ChannelView.tsx +++ b/src/views/channels/ChannelView.tsx @@ -25,8 +25,8 @@ export const ChannelView = () => { }); const { theme } = useSettings(); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { data } = useQuery(GET_CHANNEL_AMOUNT_INFO, { variables: { auth }, diff --git a/src/views/channels/channels/Channels.tsx b/src/views/channels/channels/Channels.tsx index 3a2a69f0..0035c33e 100644 --- a/src/views/channels/channels/Channels.tsx +++ b/src/views/channels/channels/Channels.tsx @@ -12,8 +12,8 @@ import { LoadingCard } from '../../../components/loading/LoadingCard'; export const Channels = () => { const [indexOpen, setIndexOpen] = useState(0); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { loading, data } = useQuery(GET_CHANNELS, { variables: { auth }, diff --git a/src/views/channels/closedChannels/ClosedChannels.tsx b/src/views/channels/closedChannels/ClosedChannels.tsx index 0a4da881..cb716027 100644 --- a/src/views/channels/closedChannels/ClosedChannels.tsx +++ b/src/views/channels/closedChannels/ClosedChannels.tsx @@ -12,8 +12,8 @@ import { LoadingCard } from '../../../components/loading/LoadingCard'; export const ClosedChannels = () => { const [indexOpen, setIndexOpen] = useState(0); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { loading, data } = useQuery(GET_CLOSED_CHANNELS, { variables: { auth }, diff --git a/src/views/channels/pendingChannels/PendingChannels.tsx b/src/views/channels/pendingChannels/PendingChannels.tsx index 419b0181..b78684b9 100644 --- a/src/views/channels/pendingChannels/PendingChannels.tsx +++ b/src/views/channels/pendingChannels/PendingChannels.tsx @@ -12,8 +12,8 @@ import { LoadingCard } from '../../../components/loading/LoadingCard'; export const PendingChannels = () => { const [indexOpen, setIndexOpen] = useState(0); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { loading, data } = useQuery(GET_PENDING_CHANNELS, { variables: { auth }, diff --git a/src/views/entry/Entry.tsx b/src/views/entry/Entry.tsx index d94e0232..f909080b 100644 --- a/src/views/entry/Entry.tsx +++ b/src/views/entry/Entry.tsx @@ -1,7 +1,7 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import { LoginView } from './login/Login'; import { SessionLogin } from './login/SessionLogin'; -import { useHistory } from 'react-router'; +import { useHistory, Switch, Route, useLocation } from 'react-router'; import { HomePageView } from './HomePage'; interface HomeProps { @@ -9,21 +9,24 @@ interface HomeProps { } const EntryView = ({ session }: HomeProps) => { - const [login, setLogin] = useState(false); - const history = useHistory(); + const { push } = useHistory(); + const location = useLocation(); useEffect(() => { - if (history.location.pathname !== '/') { - history.push('/'); + if (location.pathname !== '/' && location.pathname !== '/login') { + push('/'); } - }, [history]); + }, [location, push]); - return session ? ( - - ) : login ? ( - - ) : ( - + const getView = () => { + return session ? : ; + }; + + return ( + + } /> + getView()} /> + ); }; diff --git a/src/views/entry/HomePage.styled.ts b/src/views/entry/HomePage.styled.ts new file mode 100644 index 00000000..b2d9b201 --- /dev/null +++ b/src/views/entry/HomePage.styled.ts @@ -0,0 +1,36 @@ +import styled from 'styled-components'; +import { ReactComponent as HeadlineImage } from '../../images/MoshingDoodle.svg'; + +export const Headline = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + padding: 32px 0; +`; + +export const LeftHeadline = styled.div` + width: 50%; + display: flex; + flex-direction: column; +`; + +export const StyledImage = styled(HeadlineImage)` + width: 500px; +`; + +export const HomeButton = styled.button` + cursor: pointer; + outline: none; + padding: 8px 24px; + text-decoration: 2px solid blue; + font-size: 16px; + background-image: linear-gradient(to right, #fe4928, #ffc700); + color: white; + border: none; + display: flex; + align-items: center; + justify-content: center; + border-radius: 24px; + white-space: nowrap; + min-width: 100px; +`; diff --git a/src/views/entry/HomePage.tsx b/src/views/entry/HomePage.tsx index 6ca8b5f5..1cca9be0 100644 --- a/src/views/entry/HomePage.tsx +++ b/src/views/entry/HomePage.tsx @@ -1,30 +1,65 @@ import React from 'react'; +import { + Wrapper, + Card, + SubTitle, + SingleLine, + ColumnLine, + Sub4Title, +} from '../../components/generic/Styled'; +import { + Headline, + LeftHeadline, + StyledImage, + HomeButton, +} from './HomePage.styled'; import styled from 'styled-components'; -import { ReactComponent as HeadlineImage } from '../../images/MoshingDoodle.svg'; -import { Wrapper } from '../../components/generic/Styled'; +import { + Zap, + Eye, + Send, + Key, + Server, + Sliders, + Users, +} from '../../components/generic/Icons'; +import { backgroundColor } from '../../styles/Themes'; +import { Link } from 'react-router-dom'; -const Headline = styled.div` +const DetailCard = styled(Card)` + width: 33%; + background-color: ${backgroundColor}; + margin-bottom: 0; + margin: 8px 16px; +`; + +const DetailLine = styled.div` + margin: 0 -16px; display: flex; + justify-content: center; align-items: center; - justify-content: space-between; - padding: 32px 0; `; -const LeftHeadline = styled.div` - width: 50%; - display: flex; - flex-direction: column; +const Padding = styled.div` + padding-right: ${({ padding }: { padding?: string }) => + padding ? padding : '16px'}; `; -const StyledImage = styled(HeadlineImage)` - width: 500px; -`; +const detailCardContent = (title: string, text: string, Icon: any) => ( + + + + + + + {title} + {text} + + + +); -interface HomePageProps { - setLogin: (login: boolean) => void; -} - -export const HomePageView = ({ setLogin }: HomePageProps) => { +export const HomePageView = () => { return ( <> @@ -36,16 +71,56 @@ export const HomePageView = ({ setLogin }: HomePageProps) => { something else to place here. Think Think Think
Available everywhere you can open a website.
- + + + + + + Control The Lightning + +
-
Hello
+ + {detailCardContent( + 'Make Payments', + 'Send and receive both Lightning and On-Chain payments.', + Send, + )} + {detailCardContent( + 'Multiple Nodes', + 'Connect to multiple nodes and quickly switch between them.', + Server, + )} + {detailCardContent( + 'View-Only Mode', + `Check the status of your node any time without risk.`, + Eye, + )} + + + {detailCardContent( + 'AES Encryption', + 'Your Macaroon is AES encrypted with a password only you know.', + Key, + )} + {detailCardContent( + 'Open Source', + `Don't trust anyone. Verify the code yourself.`, + Users, + )} + {detailCardContent( + 'Manage Channels', + 'Open, close and monitor channel status and liquidity', + Sliders, + )} +
-
Hello
+
Another Line
); diff --git a/src/views/entry/login/Login.tsx b/src/views/entry/login/Login.tsx index d58d1be2..2916587b 100644 --- a/src/views/entry/login/Login.tsx +++ b/src/views/entry/login/Login.tsx @@ -54,9 +54,15 @@ export const LoginView = () => { How do you want to connect? )} {isType === 'none' && renderButtons()} - {isType === 'login' && } - {isType === 'connect' && } - {isType === 'btcpay' && } + {isType === 'login' && ( + + )} + {isType === 'connect' && ( + + )} + {isType === 'btcpay' && ( + + )} ); diff --git a/src/views/entry/login/SessionLogin.tsx b/src/views/entry/login/SessionLogin.tsx index a36745ba..f3a3a7e8 100644 --- a/src/views/entry/login/SessionLogin.tsx +++ b/src/views/entry/login/SessionLogin.tsx @@ -12,6 +12,7 @@ import { import { LoginButton } from '../../../components/auth/Password'; import CryptoJS from 'crypto-js'; import { toast } from 'react-toastify'; +import { saveSessionAuth } from '../../../utils/auth'; export const SessionLogin = () => { const { name, admin, refreshAccount } = useAccount(); @@ -22,7 +23,7 @@ export const SessionLogin = () => { const bytes = CryptoJS.AES.decrypt(admin, pass); const decrypted = bytes.toString(CryptoJS.enc.Utf8); - sessionStorage.setItem('session', decrypted); + saveSessionAuth(decrypted); refreshAccount(); } catch (error) { toast.error('Wrong Password'); diff --git a/src/views/fees/Fees.tsx b/src/views/fees/Fees.tsx index 2b16c859..4a145f55 100644 --- a/src/views/fees/Fees.tsx +++ b/src/views/fees/Fees.tsx @@ -37,8 +37,8 @@ export const FeesView = () => { const [feeRate, setFeeRate] = useState(0); const { theme } = useSettings(); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { loading, data } = useQuery(CHANNEL_FEES, { variables: { auth }, diff --git a/src/views/home/account/AccountInfo.tsx b/src/views/home/account/AccountInfo.tsx index ced01795..d1f36942 100644 --- a/src/views/home/account/AccountInfo.tsx +++ b/src/views/home/account/AccountInfo.tsx @@ -48,8 +48,8 @@ const sectionColor = '#FFD300'; export const AccountInfo = () => { const [state, setState] = useState('none'); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { data, loading } = useQuery(GET_BALANCES, { variables: { auth }, diff --git a/src/views/home/account/sendOnChain/SendOnChain.tsx b/src/views/home/account/sendOnChain/SendOnChain.tsx index 64303441..d3a30c5c 100644 --- a/src/views/home/account/sendOnChain/SendOnChain.tsx +++ b/src/views/home/account/sendOnChain/SendOnChain.tsx @@ -43,7 +43,7 @@ export const SendOnChainCard = ({ color }: { color: string }) => { const [sendAll, setSendAll] = useState(false); const [isSent, setIsSent] = useState(false); - const canSend = address !== '' && tokens > 0 && amount > 0; + const canSend = address !== '' && (sendAll || tokens > 0) && amount > 0; const { theme } = useSettings(); const { price, symbol, currency } = useSettings(); diff --git a/src/views/home/connect/Connect.tsx b/src/views/home/connect/Connect.tsx index 29862f45..508da7b5 100644 --- a/src/views/home/connect/Connect.tsx +++ b/src/views/home/connect/Connect.tsx @@ -40,8 +40,8 @@ const TextPadding = styled.span` const sectionColor = '#fa541c'; export const ConnectCard = () => { - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { loading, data } = useQuery(GET_CONNECT_INFO, { variables: { auth }, diff --git a/src/views/home/networkInfo/NetworkInfo.tsx b/src/views/home/networkInfo/NetworkInfo.tsx index 66fb5bf6..09da14e4 100644 --- a/src/views/home/networkInfo/NetworkInfo.tsx +++ b/src/views/home/networkInfo/NetworkInfo.tsx @@ -38,8 +38,8 @@ const Title = styled.div` `; export const NetworkInfo = () => { - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { loading, data } = useQuery(GET_NETWORK_INFO, { variables: { auth }, diff --git a/src/views/home/quickActions/decode/Decode.tsx b/src/views/home/quickActions/decode/Decode.tsx index 837ce725..b3a70a0f 100644 --- a/src/views/home/quickActions/decode/Decode.tsx +++ b/src/views/home/quickActions/decode/Decode.tsx @@ -26,8 +26,8 @@ export const DecodeCard = ({ color }: { color: string }) => { const { price, symbol, currency } = useSettings(); const priceProps = { price, symbol, currency }; - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const [decode, { data, loading }] = useMutation(DECODE_REQUEST, { onError: error => toast.error(getErrorContent(error)), diff --git a/src/views/home/quickActions/openChannel/OpenChannel.tsx b/src/views/home/quickActions/openChannel/OpenChannel.tsx index e20a09c6..cb832775 100644 --- a/src/views/home/quickActions/openChannel/OpenChannel.tsx +++ b/src/views/home/quickActions/openChannel/OpenChannel.tsx @@ -57,8 +57,8 @@ export const OpenChannelCard = ({ color, setOpenCard }: OpenChannelProps) => { const { price, symbol, currency, theme } = useSettings(); const priceProps = { price, symbol, currency }; - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const [openChannel] = useMutation(OPEN_CHANNEL, { onError: error => toast.error(getErrorContent(error)), diff --git a/src/views/home/reports/flow/index.tsx b/src/views/home/reports/flow/index.tsx index 584a559a..8dbe037a 100644 --- a/src/views/home/reports/flow/index.tsx +++ b/src/views/home/reports/flow/index.tsx @@ -61,8 +61,8 @@ export const FlowBox = () => { const [isTime, setIsTime] = useState('month'); const [isType, setIsType] = useState('amount'); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { data, loading } = useQuery(GET_IN_OUT, { variables: { time: isTime, auth }, onError: error => toast.error(getErrorContent(error)), diff --git a/src/views/home/reports/forwardReport/ForwardChannelReport.tsx b/src/views/home/reports/forwardReport/ForwardChannelReport.tsx index ed2b72d1..11710bac 100644 --- a/src/views/home/reports/forwardReport/ForwardChannelReport.tsx +++ b/src/views/home/reports/forwardReport/ForwardChannelReport.tsx @@ -64,8 +64,8 @@ export const ForwardChannelsReport = ({ isTime, isType, color }: Props) => { const { price, symbol, currency } = useSettings(); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { data, loading } = useQuery(GET_FORWARD_CHANNELS_REPORT, { variables: { time: isTime, order: isType, auth, type }, diff --git a/src/views/home/reports/forwardReport/ForwardReport.tsx b/src/views/home/reports/forwardReport/ForwardReport.tsx index 6f48186b..f53f79f3 100644 --- a/src/views/home/reports/forwardReport/ForwardReport.tsx +++ b/src/views/home/reports/forwardReport/ForwardReport.tsx @@ -31,8 +31,8 @@ interface Props { export const ForwardReport = ({ isTime, isType }: Props) => { const { theme, price, symbol, currency } = useSettings(); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { data, loading } = useQuery(GET_FORWARD_REPORT, { variables: { time: isTime, auth }, diff --git a/src/views/home/reports/liquidReport/LiquidReport.tsx b/src/views/home/reports/liquidReport/LiquidReport.tsx index 216e3abf..9255ad1a 100644 --- a/src/views/home/reports/liquidReport/LiquidReport.tsx +++ b/src/views/home/reports/liquidReport/LiquidReport.tsx @@ -25,8 +25,8 @@ import { import { LoadingCard } from '../../../../components/loading/LoadingCard'; export const LiquidReport = () => { - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { theme, price, symbol, currency } = useSettings(); diff --git a/src/views/settings/Current.tsx b/src/views/settings/Current.tsx index 3b4605ff..2f9c6c2b 100644 --- a/src/views/settings/Current.tsx +++ b/src/views/settings/Current.tsx @@ -7,6 +7,7 @@ import { } from '../../components/generic/Styled'; import styled from 'styled-components'; import { unSelectedNavButton, chartLinkColor } from '../../styles/Themes'; +import { useAccount } from '../../context/AccountContext'; const CurrentField = styled.div` color: ${chartLinkColor}; @@ -21,12 +22,7 @@ const CurrentField = styled.div` `; export const CurrentSettings = () => { - const currentAuth = localStorage.getItem('account') || 'auth1'; - const currentName = localStorage.getItem(`${currentAuth}-name`); - const currentAdmin = localStorage.getItem(`${currentAuth}-admin`); - const currentRead = localStorage.getItem(`${currentAuth}-read`); - const currentCert = localStorage.getItem(`${currentAuth}-cert`); - const currentHost = localStorage.getItem(`${currentAuth}-host`); + const { name, host, admin, read, cert } = useAccount(); const renderField = (title: string, field: string | null) => { if (!field) return null; @@ -43,11 +39,11 @@ export const CurrentSettings = () => { Current Account: - {renderField('Name:', currentName)} - {renderField('AES Encrypted Admin Macaroon:', currentAdmin)} - {renderField('Read-only Macaroon:', currentRead)} - {renderField('Certificate:', currentCert)} - {renderField('Host:', currentHost)} + {renderField('Name:', name)} + {renderField('Host:', host)} + {renderField('AES Encrypted Admin Macaroon:', admin)} + {renderField('Read-only Macaroon:', read)} + {renderField('Certificate:', cert)} ); diff --git a/src/views/transactions/TransactionList.tsx b/src/views/transactions/TransactionList.tsx index 7b54ee5f..2c8dbea0 100644 --- a/src/views/transactions/TransactionList.tsx +++ b/src/views/transactions/TransactionList.tsx @@ -29,8 +29,8 @@ export const TransactionList = () => { const [fetching, setFetching] = useState(false); const { theme } = useSettings(); - const { host, read, cert } = useAccount(); - const auth = getAuthString(host, read, cert); + const { host, read, cert, sessionAdmin } = useAccount(); + const auth = getAuthString(host, read !== '' ? read : sessionAdmin, cert); const { loading, data, fetchMore } = useQuery(GET_RESUME, { variables: { auth, token: '' },