Skip to content
This repository has been archived by the owner on Feb 19, 2023. It is now read-only.

Commit

Permalink
fix(#104): refactored ui components
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Gasser committed Apr 15, 2019
1 parent a62be85 commit 3c45875
Show file tree
Hide file tree
Showing 18 changed files with 71,648 additions and 261 deletions.
58 changes: 13 additions & 45 deletions src/app/App.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component, Fragment } from 'react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Grommet, Box } from 'grommet';
Expand All @@ -19,7 +19,7 @@ import {

// base style components
import PrivateRoute from './PrivateRoute';
import AppMessage from '../ui/AppMessage';
import AppMessage from './AppMessage';
import AppHeader from './AppHeader';
import AppFooter from './AppFooter';

Expand All @@ -36,8 +36,6 @@ import NotFound from './NotFound';
import * as Paths from '../paths';

import { Theme } from '../styles';
import Button from '../ui/form/Button';
import ButtonGroup from '../ui/form/ButtonGroup';

const StyledAppContent = styled(Box)`
min-height: 100%;
Expand All @@ -63,33 +61,12 @@ class App extends Component {
return (
<Grommet theme={Theme} full={true}>
<AppMessage
message={message.text}
show={message.show}
>
<h1>{message.title}</h1>
<p>{message.text}</p>
{message.showRefresh && (
<Fragment>
<p>Please refresh page and try again. If error persists please try later.</p>
<ButtonGroup>
<Button
type="button"
buttonStyle="primary"
onClick={() => window.location.reload()}
>Refresh page</Button>
</ButtonGroup>
</Fragment>
)}
</AppMessage>
<Switch>
<Route path="*" component={(props) => (
<AppHeader
isAuthenticated={isAuthenticated}
username={username}
{...props}
/>
)} />
</Switch>
message={message}
/>
<AppHeader
isAuthenticated={isAuthenticated}
username={username}
/>
<StyledAppContent fill justify='between' direction='column'>
<Box flex fill pad="none">
<Switch>
Expand Down Expand Up @@ -121,20 +98,7 @@ class App extends Component {
<Route exact path={Paths.PRIVACY} component={Privacy} />
<Route path="*" component={NotFound} />
</Switch>
<Switch>
<Route exact path={Paths.GET_IMAGES_DETAIL(Paths.ID)} component={(props) => (
<AppFooter withSidebar {...props} />
)} />
<Route exact path={Paths.LOGIN} component={(props) => (
<AppFooter alternativeColor {...props} />
)} />
<Route exact path={Paths.REGISTER} component={(props) => (
<AppFooter alternativeColor {...props} />
)} />
<Route path="*" component={(props) => (
<AppFooter {...props} />
)} />
</Switch>
<AppFooter />
</Box>
</StyledAppContent>
</Grommet>
Expand All @@ -158,4 +122,8 @@ const mapDispatchToProps = ({
logOutUser,
});

export const __testables__ = {
App,
};

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));
81 changes: 36 additions & 45 deletions src/app/AppFooter.jsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,48 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Box, Anchor } from 'grommet';

import { Colors, MediaSize, Sizes } from '../styles';
import { withRouter } from 'react-router-dom';

const StyledAppFooter = styled(Box)`
color: ${(props) => props.alternativeColor ? Colors.ColorsPalette.White : Colors.ColorsPalette.TextFaded};
background-color: ${(props) => props.alternativeColor ? Colors.ColorsPalette.Background : 'inherit'};
import Footer from '../ui/Footer';

${props => props.withSidebar ? `
@media (min-width: ${MediaSize.Tablet}) {
padding-left: ${Sizes.LeftBar.width.Tablet};
}
@media (min-width: ${MediaSize.Notebook}) {
padding-left: ${Sizes.LeftBar.width.Notebook};
}
import * as Paths from '../paths';

@media (min-width: ${MediaSize.Desktop}) {
padding-left: ${Sizes.LeftBar.width.Desktop};
}
@media (min-width: ${MediaSize.Fullscreen}) {
padding-left: ${Sizes.LeftBar.width.Fullscreen};
}
` : ''}
const isAlternativeColor = (path) => {
if (path.includes(Paths.LOGIN)) {
return true;
}

a {
color: ${(props) => props.alternativeColor ? Colors.ColorsPalette.White : Colors.Neutrals.MidDark};
font-weight: 600;
if (path.includes(Paths.REGISTER)) {
return true;
}
`;

const AppFooter = ({ withSidebar, alternativeColor }) => (
<StyledAppFooter
tag='footer'
direction='column'
align='center'
pad={{ vertical: 'xsmall' }}
withSidebar={withSidebar}
alternativeColor={alternativeColor}
>
<span>Created by: <Anchor target="_blank" href="https://andreasgasser.com">Andreas Gasser</Anchor></span>
</StyledAppFooter>
);

AppFooter.propTypes = {
withSidebar: PropTypes.bool,
return false;
}

AppFooter.defaultProps = {
withSidebar: false,
}
const AppFooter = ({
history: {
location: {
pathname,
}
},
}) => {
const withSidebar = pathname.includes(Paths.GET_IMAGES_DETAIL(''));
const alternativeColor = isAlternativeColor(pathname);

return (
<Footer
withSidebar={withSidebar}
alternativeColor={alternativeColor}
/>
);
};

export default AppFooter;
AppFooter.propTypes = {
history: PropTypes.shape({
location: PropTypes.shape({
pathname: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
};

export default withRouter(AppFooter);
123 changes: 23 additions & 100 deletions src/app/AppHeader.jsx
Original file line number Diff line number Diff line change
@@ -1,114 +1,37 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import { withRouter } from 'react-router-dom';

import {
Box,
Heading,
} from 'grommet';
import Header from '../ui/Header';

import PreviousButton from '../ui/PreviousButton';
import { Colors, MediaSize, Sizes } from '../styles';
import * as Paths from '../paths';

const StyledPreviousButton = styled(PreviousButton)`
opacity: ${props => props.opacity};
@media (min-width: ${MediaSize.Tablet}) {
display: none;
visibility: none;
}
`;

const StyledHeading = styled(Heading)`
font-weight: 500;
margin-top: 0.85rem;
margin-bottom: 0.85rem;
`;

const StyledUserProfile = styled.div`
font-size: 1rem;
text-transform: capitalize;
`;

const UserProfile = (props) => (
<StyledUserProfile>
<Link to={Paths.USER}>
<span className="username">{props.username}</span>
</Link>
</StyledUserProfile>
);

const StyledHeader = styled(Box)`
${(props) => props.isAuthenticated ? `
color: ${Colors.ColorsPalette.Text};
background-color: ${Colors.ColorsPalette.White};
border-bottom: 1px solid #c9c9c9;
a {
color: ${Colors.ColorsPalette.Text};
&:hover {
color: ${Colors.ColorsPalette.TextFaded};
}
}
` : `
background-color: ${Colors.ColorsPalette.Background};
color: ${Colors.ColorsPalette.White};
a {
color: ${Colors.ColorsPalette.White};
&:hover {
color: ${Colors.Neutrals.LightDark};
}
}
`
}
height: ${Sizes.Header.height};
z-index: 100;
position: fixed;
top: 0;
left: 0;
right: 0;
a {
text-decoration: none;
}
`;

const AppHeader = (props) => {
const { isAuthenticated, username, match, history } = props;
const previousButtonOpacity = match.url === '/' ? 0 : 1;
const AppHeader = ({
isAuthenticated,
username,
history,
}) => {
const { location: { pathname } } = history;
const showPreviousButton = pathname !== '/';

return (
<StyledHeader
tag="header"
direction="row"
align='center'
justify='between'
<Header
isAuthenticated={isAuthenticated}
pad={{ horizontal: "large", vertical: "none" }}
>
{isAuthenticated && (
<StyledPreviousButton
onClick={() => history.push(Paths.HOME)}
opacity={previousButtonOpacity}
/>
)}
<Link to={Paths.HOME}>
<StyledHeading level={4}>AWS Rekognition</StyledHeading>
</Link>
{isAuthenticated && <UserProfile username={username} />}
</StyledHeader>
)
showPreviousButton={showPreviousButton}
username={username}
onGoToPrevious={() => history.push(Paths.HOME)}
/>
);
};

AppHeader.propTypes = {
isAuthenticated: PropTypes.bool.isRequired,
username: PropTypes.string,
}

AppHeader.defaultProps = {
username: '',
}
username: PropTypes.string.isRequired,
history: PropTypes.shape({
location: PropTypes.shape({
pathname: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
};

export default AppHeader;
export default withRouter(AppHeader);
43 changes: 43 additions & 0 deletions src/app/AppMessage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';

import ViewMessage from '../ui/ViewMessage';
import Button from '../ui/form/Button';
import ButtonGroup from '../ui/form/ButtonGroup';

const AppMessage = ({
message: {
text,
show,
title,
showRefresh,
},
}) => (
<ViewMessage
message={text}
show={show}
>
<h1>{title}</h1>
<p>{text}</p>
{showRefresh && (
<Fragment>
<p>Please refresh page and try again. If error persists please try later.</p>
<ButtonGroup>
<Button
type="button"
buttonStyle="primary"
onClick={() => window.location.reload()}
>Refresh page</Button>
</ButtonGroup>
</Fragment>
)}
</ViewMessage>
);

AppMessage.propTypes = {
message: PropTypes.shape({

})
}

export default AppMessage;
6 changes: 3 additions & 3 deletions src/images/AddImageButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Add } from 'grommet-icons';

import Button from '../ui/form/Button';
import ButtonGroup from '../ui/form/ButtonGroup';
import AppMessage from '../ui/AppMessage';
import ViewMessage from '../ui/ViewMessage';
import {
getImageCreationDateTime,
getFormattedFileSize,
Expand Down Expand Up @@ -154,7 +154,7 @@ const AddImageButton = ({
const { showMessage, image } = state;
return (
<Fragment>
<AppMessage show={showMessage}>
<ViewMessage show={showMessage}>
<Heading level="2">Image is too big</Heading>
<Box>
<p>Hey it seems your image to big for being uploaded. We only allow uploading images up to <strong>6 MB</strong>, please choose a different image.</p>
Expand Down Expand Up @@ -189,7 +189,7 @@ const AddImageButton = ({
>Change image</Button>
</ButtonGroup>
</Box>
</AppMessage>
</ViewMessage>
<Dropzone
onDrop={handleUploadImage}
ref={uploadRef}
Expand Down
Loading

0 comments on commit 3c45875

Please sign in to comment.