Skip to content

Commit 5f3c86b

Browse files
committed
auth: create AuthPage with password field
1 parent 5db443b commit 5f3c86b

File tree

9 files changed

+151
-8
lines changed

9 files changed

+151
-8
lines changed

app/src/assets/images/logo.svg

Lines changed: 6 additions & 0 deletions
Loading

app/src/components/Pages.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import { observer } from 'mobx-react-lite';
33
import { useStore } from 'store';
4+
import AuthPage from './auth/AuthPage';
45
import HistoryPage from './history/HistoryPage';
56
import LoopPage from './loop/LoopPage';
67
import SettingsPage from './settings/SettingsPage';
@@ -9,12 +10,15 @@ const Pages: React.FC = () => {
910
const { uiStore } = useStore();
1011

1112
switch (uiStore.page) {
13+
case 'loop':
14+
return <LoopPage />;
1215
case 'history':
1316
return <HistoryPage />;
1417
case 'settings':
1518
return <SettingsPage />;
19+
case 'auth':
1620
default:
17-
return <LoopPage />;
21+
return <AuthPage />;
1822
}
1923
};
2024

app/src/components/auth/AuthPage.tsx

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import React, { useState } from 'react';
2+
import { observer } from 'mobx-react-lite';
3+
import { ReactComponent as LogoImage } from 'assets/images/logo.svg';
4+
import { usePrefixedTranslation } from 'hooks';
5+
import { useStore } from 'store';
6+
import { Button, HeaderOne, Input } from 'components/base';
7+
import { styled } from 'components/theme';
8+
9+
const Styled = {
10+
Wrapper: styled.div`
11+
display: flex;
12+
flex-direction: column;
13+
justify-content: center;
14+
align-items: center;
15+
width: 100vw;
16+
height: 100vh;
17+
`,
18+
Logo: styled(LogoImage)`
19+
color: ${props => props.theme.colors.offWhite};
20+
width: 80px;
21+
height: 156px;
22+
margin-bottom: 30px;
23+
`,
24+
Title: styled(HeaderOne)`
25+
font-size: 75px;
26+
margin-bottom: 30px;
27+
text-transform: uppercase;
28+
`,
29+
Subtitle: styled.div`
30+
width: 100%;
31+
max-width: 500px;
32+
margin-bottom: 80px;
33+
text-align: center;
34+
`,
35+
Form: styled.form`
36+
display: flex;
37+
flex-direction: column;
38+
align-items: center;
39+
`,
40+
Label: styled.label`
41+
margin: 10px 0 80px;
42+
`,
43+
ErrMessage: styled.div`
44+
width: 100%;
45+
margin: 0 0 80px;
46+
padding: 5px 0;
47+
background-color: ${props => props.theme.colors.pink};
48+
color: ${props => props.theme.colors.offWhite};
49+
text-align: center;
50+
`,
51+
Submit: styled(Button)`
52+
background-color: transparent;
53+
`,
54+
};
55+
56+
const AuthPage: React.FC = () => {
57+
const { l } = usePrefixedTranslation('cmps.auth.AuthPage');
58+
const { uiStore } = useStore();
59+
const [pass, setPass] = useState('');
60+
const [error, setError] = useState('');
61+
62+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
63+
setPass(e.target.value);
64+
setError('');
65+
};
66+
67+
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
68+
e.preventDefault();
69+
try {
70+
if (!pass) throw new Error('oops, password is required');
71+
// TODO: send password to backend to validate
72+
uiStore.goToLoop();
73+
} catch (e) {
74+
setError(e.message);
75+
}
76+
};
77+
78+
const { Wrapper, Logo, Title, Subtitle, Form, Label, ErrMessage, Submit } = Styled;
79+
return (
80+
<Wrapper>
81+
<Logo />
82+
<Title>{l('title')}</Title>
83+
<Subtitle>{l('subtitle')}</Subtitle>
84+
<Form onSubmit={handleSubmit}>
85+
<Input type="password" autoFocus value={pass} onChange={handleChange} />
86+
{error ? <ErrMessage>{error}</ErrMessage> : <Label>{l('passLabel')}</Label>}
87+
<Submit>{l('submitBtn')}</Submit>
88+
</Form>
89+
</Wrapper>
90+
);
91+
};
92+
93+
export default observer(AuthPage);

app/src/components/base/shared.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import { styled } from 'components/theme';
55
// Misc
66
//
77

8-
export const Background = styled.div`
8+
export const Background = styled.div<{ gradient?: boolean }>`
99
min-height: 100vh;
1010
color: ${props => props.theme.colors.white};
11-
background-color: ${props => props.theme.colors.blue};
11+
background: ${props =>
12+
props.gradient ? props.theme.colors.gradient : props.theme.colors.blue};
1213
font-family: ${props => props.theme.fonts.open.regular};
1314
font-size: ${props => props.theme.sizes.m};
1415
`;
@@ -105,6 +106,24 @@ export const Button = styled.button<ButtonProps>`
105106
}
106107
`;
107108

109+
export const Input = styled.input`
110+
font-family: ${props => props.theme.fonts.work.light};
111+
font-weight: 300;
112+
font-size: ${props => props.theme.sizes.xxl};
113+
color: ${props => props.theme.colors.offWhite};
114+
background-color: transparent;
115+
border-width: 0;
116+
border-bottom: 3px solid ${props => props.theme.colors.offWhite};
117+
padding: 5px;
118+
text-align: center;
119+
120+
&:active,
121+
&:focus {
122+
outline: none;
123+
background-color: ${props => props.theme.colors.overlay};
124+
}
125+
`;
126+
108127
//
109128
// Radio Button
110129
//

app/src/components/base/text.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ interface HeaderProps {
55
}
66

77
export const HeaderOne = styled.h1`
8-
font-family: ${props => props.theme.fonts.work.medium};
8+
font-family: ${props => props.theme.fonts.work.light};
9+
font-weight: 300;
910
font-size: ${props => props.theme.sizes.xxl};
1011
line-height: 52px;
1112
`;

app/src/components/layout/Layout.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ const Styled = {
5656
`,
5757
};
5858

59-
const Layout: React.FC = ({ children }) => {
59+
const AuthLayout: React.FC = ({ children }) => (
60+
<Background gradient>{children}</Background>
61+
);
62+
63+
const StandardLayout: React.FC = observer(({ children }) => {
6064
const { settingsStore } = useStore();
6165

6266
const { Container, Hamburger, Aside, Content } = Styled;
@@ -75,6 +79,16 @@ const Layout: React.FC = ({ children }) => {
7579
</Container>
7680
</Background>
7781
);
82+
});
83+
84+
const Layout: React.FC = ({ children }) => {
85+
const { uiStore } = useStore();
86+
87+
return uiStore.page === 'auth' ? (
88+
<AuthLayout>{children}</AuthLayout>
89+
) : (
90+
<StandardLayout>{children}</StandardLayout>
91+
);
7892
};
7993

8094
export default observer(Layout);

app/src/components/theme.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface Theme {
3838
orange: string;
3939
purple: string;
4040
overlay: string;
41+
gradient: string;
4142
};
4243
}
4344

@@ -77,6 +78,7 @@ const theme: Theme = {
7778
orange: '#f66b1c',
7879
purple: '#57038d',
7980
overlay: 'rgba(245,245,245,0.04)',
81+
gradient: 'linear-gradient(325.53deg, #252F4A 0%, #46547B 100%);',
8082
},
8183
};
8284

app/src/i18n/locales/en-US.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
"enums.BalanceMode.receive": "Receiving",
33
"enums.BalanceMode.send": "Sending",
44
"enums.BalanceMode.routing": "Routing",
5+
"cmps.auth.AuthPage.title": "Shushtar",
6+
"cmps.auth.AuthPage.subtitle": "A tool to help you more effectively and efficiently manage inbound and outbound liquidity on your Lightning node",
7+
"cmps.auth.AuthPage.passLabel": "Enter your password in the field above",
8+
"cmps.auth.AuthPage.submitBtn": "Submit",
59
"cmps.common.Tile.maximizeTip": "Maximize",
610
"cmps.common.PageHeader.historyTip": "Loop History",
711
"cmps.common.PageHeader.exportTip": "Download CSV",
@@ -38,7 +42,7 @@
3842
"cmps.loop.swap.SwapProcessingStep.loadingMsg": "Configuring Loops",
3943
"cmps.loop.swap.SwapReviewStep.title": "Step 2 of 2",
4044
"cmps.loop.swap.SwapReviewStep.heading": "Review the quote",
41-
"cmps.loop.swap.SwapReviewStep.description": "Confirm. the invoice total for increasing your inbound liquidity. If you'd like to make adjustments, click the back arrow above.",
45+
"cmps.loop.swap.SwapReviewStep.description": "Confirm the invoice total for increasing your inbound liquidity. If you'd like to make adjustments, click the back arrow above.",
4246
"cmps.loop.swap.SwapReviewStep.amount": "{{type}} Amount",
4347
"cmps.loop.swap.SwapReviewStep.fees": "Fees",
4448
"cmps.loop.swap.SwapReviewStep.total": "Invoice Total",

app/src/store/stores/uiStore.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import { action, observable, toJS } from 'mobx';
22
import { Alert } from 'types/state';
33
import { Store } from 'store';
44

5-
type PageName = 'loop' | 'history' | 'settings';
5+
type PageName = 'auth' | 'loop' | 'history' | 'settings';
66

77
type SettingName = 'general' | 'unit' | 'balance';
88

99
export default class UiStore {
1010
private _store: Store;
1111

1212
/** the current page being displayed */
13-
@observable page: PageName = 'loop';
13+
@observable page: PageName = 'auth';
1414
/** indicates if the Processing Loops section is displayed on the Loop page */
1515
@observable processingSwapsVisible = false;
1616
/** the selected setting on the Settings page */

0 commit comments

Comments
 (0)