Skip to content

Commit 3e586de

Browse files
authored
Sign out link in header and authenticated routes (#159)
* remove unused router stuff * clean up header and add logout page * lint * functional log out route * better * add protection for file manager page * show dashboard link instead of log out if logged in and on landing page * redo agreement page * remove header from screen container * lint * fix * fix again
1 parent e1f9a3b commit 3e586de

File tree

22 files changed

+265
-119
lines changed

22 files changed

+265
-119
lines changed

d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
declare module "*.json";
2+
declare module "*.md";
Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
import React, { Component } from "react";
1+
import React, { useState, useEffect } from "react";
22
import styled, { ThemeProvider } from "styled-components";
33
import Markdown from "react-markdown";
44

55
import ScreenContainer from "../shared/screen-container";
6+
import Header from "../shared/header";
67

7-
import { AGREEMENT_TYPES, theme } from "../../config";
8+
import { HEADER_TYPES, AGREEMENT_TYPES, theme } from "../../config";
89
import TOS_MARKDOWN from "./terms-of-service.md";
910
import PRIVACY_POLICY from "./privacy-policy.md";
1011

12+
const Container = styled.div``;
13+
1114
const AgreementMarkdownComponent = props => (
1215
<div>
1316
<Markdown {...props} />
@@ -23,33 +26,37 @@ const AgreementMarkdown = styled(AgreementMarkdownComponent)`
2326
}
2427
`;
2528

26-
class Agreement extends Component {
27-
state = { text: "" };
29+
const Contents = ({ type, title, isLoggedIn }) => {
30+
const [text, setText] = useState("");
2831

29-
componentDidMount () {
32+
useEffect(() => {
3033
const file = (type => {
3134
switch (type) {
32-
case AGREEMENT_TYPES.TERMS_OF_SERVICE:
33-
return TOS_MARKDOWN;
3435
case AGREEMENT_TYPES.PRIVACY_POLICY:
3536
return PRIVACY_POLICY;
37+
default:
38+
return TOS_MARKDOWN;
3639
}
37-
})(this.props.type);
40+
})(type);
3841

3942
fetch(file)
4043
.then(resp => resp.text())
41-
.then(text => this.setState({ text }));
42-
}
43-
44-
render () {
45-
const { title } = this.props;
46-
return (
47-
<ThemeProvider theme={theme}>
44+
.then(text => setText(text))
45+
.catch(() =>
46+
setText("There was a problem with the file. Please try again later!")
47+
);
48+
}, []);
49+
50+
return (
51+
<ThemeProvider theme={theme}>
52+
<Container>
53+
<Header type={HEADER_TYPES.SCREEN_CONTAINER} />
4854
<ScreenContainer title={title}>
49-
<AgreementMarkdown source={this.state.text} />
55+
<AgreementMarkdown source={text} />
5056
</ScreenContainer>
51-
</ThemeProvider>
52-
);
53-
}
54-
}
55-
export default Agreement;
57+
</Container>
58+
</ThemeProvider>
59+
);
60+
};
61+
62+
export default Contents;

src/components/agreement/index.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from "react";
2+
import { connect } from "react-redux";
3+
4+
import Contents from "./contents";
5+
6+
import { AUTHENTICATION_STATUSES } from "../../config";
7+
8+
const mapStateToProps = state => ({
9+
authenticationStatus: state.authentication.status
10+
});
11+
12+
const mapDispatchToProps = dispatch => ({});
13+
14+
const Agreement = ({ authenticationStatus, type, title }) => (
15+
<Contents
16+
type={type}
17+
title={title}
18+
isLoggedIn={authenticationStatus === AUTHENTICATION_STATUSES.LOGGED_IN}
19+
/>
20+
);
21+
22+
export default connect(
23+
mapStateToProps,
24+
mapDispatchToProps
25+
)(Agreement);

src/components/brokers-down/brokers-down-slide.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ import styled, { ThemeProvider } from "styled-components";
33

44
import ScreenContainer from "../shared/screen-container";
55
import ScreenDescription from "../shared/screen-description";
6+
import Header from "../shared/header";
67

7-
import { theme } from "../../config";
8+
import { HEADER_TYPES, theme } from "../../config";
9+
10+
const Container = styled.div`
11+
width: 100%;
12+
`;
813

914
const Link = styled.a`
1015
color: ${props => props.theme.title.color};
@@ -13,14 +18,17 @@ const Link = styled.a`
1318

1419
const BrokersDownSlide = () => (
1520
<ThemeProvider theme={theme}>
16-
<ScreenContainer title={"Broker Nodes Offline"}>
17-
<ScreenDescription>
18-
Opacity Storage’s broker nodes are currently offline. Uploads are
19-
unavailable at this time. Please visit our{" "}
20-
<Link href="https://t.me/OpacityStorage">Telegram Channel</Link> for
21-
more information. We apologize for the inconvenience.
22-
</ScreenDescription>
23-
</ScreenContainer>
21+
<Container>
22+
<Header type={HEADER_TYPES.SCREEN_CONTAINER} />
23+
<ScreenContainer title={"Broker Nodes Offline"}>
24+
<ScreenDescription>
25+
Opacity Storage’s broker nodes are currently offline. Uploads are
26+
unavailable at this time. Please visit our{" "}
27+
<Link href="https://t.me/OpacityStorage">Telegram Channel</Link> for
28+
more information. We apologize for the inconvenience.
29+
</ScreenDescription>
30+
</ScreenContainer>
31+
</Container>
2432
</ThemeProvider>
2533
);
2634

src/components/file-manager/file-manager-slide.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@ import backend from "../../services/backend";
55
import { NativeTypes } from "react-dnd-html5-backend";
66
import { DropTarget } from "react-dnd";
77

8-
import {
9-
HEADER_FILE_MANAGER,
10-
DESKTOP_WIDTH,
11-
MOBILE_WIDTH,
12-
theme
13-
} from "../../config";
8+
import { HEADER_TYPES, DESKTOP_WIDTH, MOBILE_WIDTH, theme } from "../../config";
149

1510
import Header from "../shared/header";
1611
import UploadButton from "./upload-button";
@@ -317,7 +312,7 @@ const FileManagerSlide = ({
317312
<DroppableZone innerRef={instance => connectDropTarget(instance)}>
318313
<ThemeProvider theme={theme}>
319314
<Container>
320-
<Header type={HEADER_FILE_MANAGER} />
315+
<Header type={HEADER_TYPES.FILE_MANAGER} />
321316
<Contents>
322317
<LeftSideNav>
323318
<StorageInfo>

src/components/landing-page/index.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@ import { connect } from "react-redux";
33

44
import LandingPageSlide from "./landing-page-slide";
55

6-
const mapStateToProps = state => ({});
6+
import { AUTHENTICATION_STATUSES } from "../../config";
7+
8+
const mapStateToProps = state => ({
9+
authenticationStatus: state.authentication.status
10+
});
711

812
const mapDispatchToProps = dispatch => ({});
913

10-
const LandingPage = ({}) => <LandingPageSlide />;
14+
const LandingPage = ({ authenticationStatus }) => (
15+
<LandingPageSlide
16+
isLoggedIn={authenticationStatus === AUTHENTICATION_STATUSES.LOGGED_IN}
17+
/>
18+
);
1119

1220
export default connect(
1321
mapStateToProps,

src/components/landing-page/landing-page-slide.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import styled, { ThemeProvider } from "styled-components";
33
import { withRouter } from "react-router";
44

55
import {
6-
HEADER_TEAM_PAGE,
6+
HEADER_TYPES,
77
MOBILE_WIDTH,
88
LANDING_PAGE_MOBILE_WIDTH,
99
LANDING_PAGE_VIDEO,
@@ -313,10 +313,10 @@ const ContentPurchase = styled.a`
313313
display: block;
314314
`;
315315

316-
const LandingPageSlide = ({ history }) => (
316+
const LandingPageSlide = ({ history, isLoggedIn }) => (
317317
<ThemeProvider theme={theme}>
318318
<ContainerWrapper>
319-
<Header type={HEADER_TEAM_PAGE} />
319+
<Header type={HEADER_TYPES.TEAM_PAGE} isLoggedIn={isLoggedIn} />
320320
<HeaderContainer>
321321
<Title>Secure. Anonymous. Opaque.</Title>
322322
<ContentWrapper>

src/components/login/login-slide.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import styled, { ThemeProvider } from "styled-components";
33

44
import {
55
AUTHENTICATION_STATUSES,
6-
HEADER_SCREEEN_CONTAINER,
6+
HEADER_TYPES,
77
DESKTOP_WIDTH,
88
MOBILE_WIDTH,
99
theme
@@ -13,7 +13,9 @@ import Header from "../shared/header";
1313

1414
const ICON_LOGO = require("../../assets/images/logo-login.svg");
1515

16-
const LoginContainer = styled.div``;
16+
const Container = styled.div`
17+
width: 100%;
18+
`;
1719

1820
const ErrorMessage = styled.p`
1921
color: ${props => props.theme.error.color};
@@ -66,7 +68,7 @@ const Input = styled.input<InputProps>`
6668
props.hasError ? props.theme.error.color : props.theme.input.content};
6769
`;
6870

69-
const Container = styled.div`
71+
const Column = styled.div`
7072
flex: 1;
7173
@media only screen and (max-width: ${MOBILE_WIDTH}px) {
7274
text-align: center;
@@ -191,14 +193,14 @@ class LoginOrRegisterSlide extends Component<
191193

192194
return (
193195
<ThemeProvider theme={theme}>
194-
<LoginContainer>
195-
<Header type={HEADER_SCREEEN_CONTAINER} />
196+
<Container>
197+
<Header type={HEADER_TYPES.SCREEN_CONTAINER} />
196198
<StorageContainer>
197199
<Storage>
198-
<Container>
200+
<Column>
199201
<Icon src={ICON_LOGO} />
200-
</Container>
201-
<Container>
202+
</Column>
203+
<Column>
202204
<Title>Sign in Opacity</Title>
203205
<Underline />
204206
<Label>Account Handle</Label>
@@ -233,10 +235,10 @@ class LoginOrRegisterSlide extends Component<
233235
<ForgotStorage href="/forgot-page">
234236
Forgot Account Handle?
235237
</ForgotStorage>
236-
</Container>
238+
</Column>
237239
</Storage>
238240
</StorageContainer>
239-
</LoginContainer>
241+
</Container>
240242
</ThemeProvider>
241243
);
242244
}

src/components/logout/index.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { useEffect } from "react";
2+
import { connect } from "react-redux";
3+
import { withRouter } from "react-router";
4+
5+
import authenticationActions from "../../redux/actions/authentication-actions";
6+
7+
const mapStateToProps = state => ({});
8+
9+
const mapDispatchToProps = dispatch => ({
10+
logout: () => dispatch(authenticationActions.logout())
11+
});
12+
13+
const Logout = ({ history, logout }) => {
14+
useEffect(() => {
15+
logout();
16+
history.push("/");
17+
}, []);
18+
19+
return null;
20+
};
21+
22+
export default connect(
23+
mapStateToProps,
24+
mapDispatchToProps
25+
)(withRouter(Logout));
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from "react";
2+
import { Route, Redirect } from "react-router";
3+
import { connect } from "react-redux";
4+
5+
import { AUTHENTICATION_STATUSES } from "../../config";
6+
7+
const mapStateToProps = state => ({
8+
authenticationStatus: state.authentication.status
9+
});
10+
11+
const mapDispatchToProps = dispatch => ({});
12+
13+
const AuthenticatedRoute = ({
14+
path,
15+
component: ProtectedComponent,
16+
authenticationStatus
17+
}) => {
18+
const isLoggedIn = authenticationStatus === AUTHENTICATION_STATUSES.LOGGED_IN;
19+
20+
return (
21+
<Route
22+
path={path}
23+
render={() =>
24+
isLoggedIn ? (
25+
<ProtectedComponent />
26+
) : (
27+
<Redirect to={{ pathname: "/login" }} />
28+
)
29+
}
30+
/>
31+
);
32+
};
33+
34+
export default connect(
35+
mapStateToProps,
36+
mapDispatchToProps
37+
)(AuthenticatedRoute);

0 commit comments

Comments
 (0)