chore(client): Move client app to /client

This commit is contained in:
Bouncey
2018-08-31 12:52:49 +01:00
committed by mrugesh mohapatra
parent 0e4f588a1c
commit e59ad6ebda
172 changed files with 13171 additions and 14 deletions

View File

@@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from 'react-bootstrap';
import { Link } from 'gatsby';
import './login.css';
function Login({ children, ...restProps }) {
return (
<Link to='/signin'>
<Button
{...restProps}
bsStyle='default'
className={
(restProps.block ? 'btn-cta-big' : '') + ' signup-btn btn-cta'
}
>
{children || 'Sign In'}
</Button>
</Link>
);
}
Login.displayName = 'Login';
Login.propTypes = {
children: PropTypes.any
};
export default Login;

View File

@@ -0,0 +1,31 @@
import React from 'react';
import Media from 'react-media';
const fCClogo = 'https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg';
const fCCglyph = 'https://s3.amazonaws.com/freecodecamp/FFCFire.png';
function NavLogo() {
return (
<Media query='(min-width: 735px)'>
{matches =>
matches ? (
<img
alt='learn to code at freeCodeCamp logo'
className='nav-logo logo'
src={fCClogo}
/>
) : (
<img
alt='learn to code at freeCodeCamp logo'
className='nav-logo logo'
src={fCCglyph}
/>
)
}
</Media>
);
}
NavLogo.displayName = 'NavLogo';
export default NavLogo;

View File

@@ -0,0 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { userSelector } from '../../../redux';
const mapStateToProps = createSelector(userSelector, ({ picture }) => ({
picture
}));
function SignedIn({ picture }) {
return (
<a href='https://www.freecodecamp.org/settings'>
<img height='38px' src={picture} />
</a>
);
}
SignedIn.displayName = 'SignedIn';
SignedIn.propTypes = {
picture: PropTypes.string
};
export default connect(mapStateToProps)(SignedIn);

View File

@@ -0,0 +1,50 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import Spinner from 'react-spinkit';
import { isSignedInSelector, userFetchStateSelector } from '../../../redux';
import Login from './Login';
import SignedIn from './SignedIn';
const mapStateToProps = createSelector(
userFetchStateSelector,
isSignedInSelector,
(fetchState, isSignedIn) => ({
isSignedIn,
showLoading: fetchState.pending
})
);
const propTypes = {
disableSettings: PropTypes.bool,
email: PropTypes.string,
isSignedIn: PropTypes.bool,
name: PropTypes.string,
showLoading: PropTypes.bool
};
function UserState(props) {
const { isSignedIn, showLoading, disableSettings } = props;
if (disableSettings) {
return <Login />;
}
if (showLoading) {
return (
<Spinner
className='user-state-spinner'
color='white'
fadeIn='none'
height='40px'
name='line-scale'
/>
);
}
return isSignedIn ? <SignedIn /> : <Login />;
}
UserState.displayName = 'UserState';
UserState.propTypes = propTypes;
export default connect(mapStateToProps)(UserState);

View File

@@ -0,0 +1,31 @@
.btn-cta {
background-color: #ffac33;
background-image: linear-gradient(#ffcc4d, #ffac33);
border-color: #f1a02a;
color: #292f33 !important;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
max-height: 38px;
padding: 4px 12px;
}
.signup-btn.btn {
background-color: #ffac33;
background-image: linear-gradient(#ffcc4d, #ffac33);
-ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffcc4d, endColorstr=#ffac33, GradientType=0)';
border-color: #f1a02a;
color: #292f33 !important;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
}
.signup-btn:hover,
.signup-btn:focus {
background-color: #e99110;
background-image: linear-gradient(#ffcc4d, #e99110);
-ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffcc4d, endColorstr=#e99110, GradientType=0)';
border-color: #ec8b11;
color: #292f33 !important;
}
.signup-btn:active {
background-color: #f2a330;
background-image: none;
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
}

View File

@@ -0,0 +1,95 @@
header {
top: 0;
position: fixed;
width: 100%;
z-index: 200;
}
#top-nav {
background: #006400;
margin-bottom: 0.45rem;
height: 38px;
margin-bottom: 0px;
border-radius: 0;
border: none;
display: flex;
justify-content: space-between;
padding: 0 30px 0 15px;
}
@media screen, (max-width: 630px) {
#top-nav {
padding: 0;
}
}
#top-nav .home-link {
display: flex;
align-items: center;
}
#top-nav img {
max-height: 25px;
min-width: 35px;
margin: 0 5px 0 10px;
}
#top-right-nav {
display: flex;
width: 270px;
margin: 0;
list-style: none;
justify-content: space-around;
}
#top-right-nav a, #top-right-nav img {
max-height: 40px;
}
#top-right-nav a.btn-cta {
background-color: #ffac33;
background-image: linear-gradient(#ffcc4d, #ffac33);
border-color: #f1a02a;
color: #292f33 !important;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
max-height: 38px;
padding: 4px 12px;
}
#top-right-nav li {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
margin: 0 3px;
}
#top-right-nav li > a, #top-right-nav li > span {
color:#fff;
font-size: 17px;
}
#top-right-nav li > a:hover, #top-right-nav li > a:focus {
text-decoration: none;
}
.user-state-spinner {
height: 40px;
}
.user-state-spinner > div {
animation-duration: 1.5s !important;
}
/* Search bar */
.fcc_searchBar {
flex-grow: 0.8;
padding: 2px 10px 0;
}
.ais-SearchBox-form {
margin-bottom: 0;
}
.ais-Hits {
background-color: #fff;
}

View File

@@ -0,0 +1,40 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'gatsby';
import FCCSearch from 'react-freecodecamp-search';
import NavLogo from './components/NavLogo';
import UserState from './components/UserState';
import './header.css';
function Header({ disableSettings }) {
return (
<header>
<nav id='top-nav'>
<a className='home-link' href='https://www.freecodecamp.org'>
<NavLogo />
</a>
{disableSettings ? null : <FCCSearch />}
<ul id='top-right-nav'>
<li>
<Link to='/'>Curriculum</Link>
</li>
<li>
<a href='https://forum.freecodecamp.org' target='_blank'>
Forum
</a>
</li>
<li>
<UserState disableSettings={disableSettings} />
</li>
</ul>
</nav>
</header>
);
}
Header.propTypes = {
disableSettings: PropTypes.bool
};
export default Header;