Dwayne Harris 5 years ago
parent
commit
7c6f45730d
  1. 28
      src/components/app/app.scss
  2. 23
      src/components/app/app.tsx
  3. 2
      src/components/app/index.ts
  4. 21
      src/components/pages/about/index.tsx
  5. 13
      src/components/pages/developers/index.tsx
  6. 0
      src/components/pages/directory/directory.scss
  7. 5
      src/components/pages/directory/directory.tsx
  8. 2
      src/components/pages/home/index.tsx
  9. 9
      src/components/pages/login/index.tsx
  10. 0
      src/components/pages/login/login.scss
  11. 2
      src/components/pages/register-group/register-group.tsx
  12. 12
      src/components/pages/register/index.ts
  13. 33
      src/components/pages/register/register.tsx
  14. 18
      src/components/pages/test/index.ts
  15. 30
      src/components/pages/test/test.tsx
  16. 2
      src/components/register-form/index.ts
  17. 5
      src/components/register-form/register-form.tsx
  18. 14
      src/components/text-field/text-field.tsx
  19. 11
      src/components/user-info/user-info.scss
  20. 33
      src/components/user-info/user-info.tsx
  21. 4
      src/selectors/index.ts

28
src/components/app/app.scss

@ -2,9 +2,19 @@
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700&display=swap');
$primary-color: #6a5acd;
// Colors
$orange: hsl(14, 100%, 53%);
$yellow: hsl(48, 100%, 67%);
$green: hsl(141, 71%, 48%);
$turquoise: hsl(171, 100%, 41%);
$cyan: hsl(204, 86%, 53%);
$blue: hsl(217, 72%, 30%);
$purple: hsl(271, 63%, 32%);
$red: hsl(348, 82%, 30%);
$family-sans-serif: "Open Sans", sans-serif;
$primary: $primary-color;
$primary: $blue;
$title-weight: 400;
@import "../../../node_modules/bulma/sass/utilities/_all.sass";
@import "../../../node_modules/bulma/sass/base/_all.sass";
@ -14,13 +24,11 @@ $primary: $primary-color;
@import "../../../node_modules/bulma/sass/elements/notification.sass";
@import "../../../node_modules/bulma/sass/elements/other.sass";
@import "../../../node_modules/bulma/sass/elements/title.sass";
@import "../../../node_modules/bulma/sass/layout/hero.sass";
@import "../../../node_modules/bulma/sass/components/media.sass";
$main-menu-padding: 1rem;
$main-column-padding: $main-menu-padding;
div#main-menu {
background-color: $primary-color;
background-color: $primary;
bottom: 0;
display: flex;
flex-direction: column;
@ -30,11 +38,11 @@ div#main-menu {
}
div#header, div#navigation {
padding: $main-menu-padding;
padding: $size-normal;
}
div#main-column {
padding: $main-column-padding;
div.main-content {
padding: $size-normal;
}
div#navigation {
@ -42,5 +50,5 @@ div#navigation {
}
footer {
padding: $main-menu-padding;
padding: $size-normal;
}

23
src/components/app/app.tsx

@ -5,29 +5,34 @@ import NotificationContainer from '../notification-container'
import Spinner from '../spinner'
import UserInfo from '../user-info'
import About from '../pages/about'
import Developers from '../pages/developers'
import Home from '../pages/home'
import Login from '../pages/login'
import Register from '../pages/register'
import RegisterGroup from '../pages/register-group'
import Directory from '../pages/directory'
import Test from '../pages/test'
import './app.scss'
interface Props {
menuCollapsed: boolean
collapsed: boolean
fetching: boolean
}
const Divider: FC = () => <>&nbsp;&nbsp;&#9900;&nbsp;&nbsp;</>
const App: FC<Props> = ({ menuCollapsed, fetching }) => {
const App: FC<Props> = ({ collapsed, fetching }) => {
const mainMenuWidth = 300
const mainColumnLeftMargin = menuCollapsed ? 0 : mainMenuWidth
const mainColumnLeftMargin = collapsed ? 0 : mainMenuWidth
return (
<Router>
<div>
<div id="main-menu" style={{ width: mainMenuWidth }}>
<div id="header">
<Link className="has-text-white is-size-2" to="/">flxr</Link>
<Link className="has-text-white is-size-4" to="/">Flexor</Link>
<hr className="has-background-grey-lighter" />
</div>
@ -45,9 +50,9 @@ const App: FC<Props> = ({ menuCollapsed, fetching }) => {
<div className="content has-text-centered has-text-white is-size-7">
<Link className="has-text-white is-inline-block" to="/">Home</Link>
<Divider />
<Link className="has-text-white is-inline-block" to="/">Developers</Link>
<Link className="has-text-white is-inline-block" to="/developers">Developers</Link>
<Divider />
<Link className="has-text-white is-inline-block" to="/">About</Link>
<Link className="has-text-white is-inline-block" to="/about">About</Link>
<p>&copy; 2019 Flexor.cc</p>
</div>
@ -56,9 +61,13 @@ const App: FC<Props> = ({ menuCollapsed, fetching }) => {
<div id="main-column" style={{ marginLeft: mainColumnLeftMargin }}>
<Route exact path="/" component={Home} />
<Route path="/login" component={Home} />
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
<Route path="/c/:id/register" component={RegisterGroup} />
<Route path="/communities" component={Directory} />
<Route path="/developers" component={Developers} />
<Route path="/about" component={About} />
<Route path="/test" component={Test} />
</div>
<NotificationContainer />

2
src/components/app/index.ts

@ -6,7 +6,7 @@ import { AppState } from 'src/types'
import App from './app'
const mapStateToProps = (state: AppState) => ({
menuCollapsed: getMenuCollapsed(state),
collapsed: getMenuCollapsed(state),
fetching: getFetching(state),
})

21
src/components/pages/about/index.tsx

@ -0,0 +1,21 @@
import React, { FC } from 'react'
const About: FC = () => (
<div>
<section className="hero is-dark is-bold">
<div className="hero-body">
<div className="container">
<h1 className="title">About Flexor</h1>
</div>
</div>
</section>
<div className="main-content">
<p>
Flexor is a website.
</p>
</div>
</div>
)
export default About

13
src/components/pages/developers/index.tsx

@ -0,0 +1,13 @@
import React, { FC } from 'react'
const Developers: FC = () => (
<div className="main-content">
<h1 className="title">Developers</h1>
<p>
Developer documentation coming soon.
</p>
</div>
)
export default Developers

0
src/components/pages/directory/directory.scss

5
src/components/pages/directory/directory.tsx

@ -1,7 +1,6 @@
import React, { FC, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { Entity } from 'src/types'
import './directory.scss'
interface Props {
groups: Entity[]
@ -14,13 +13,13 @@ const Directory: FC<Props> = ({ groups, fetchGroups }) => {
}, [])
return (
<div>
<div className="main-content">
<h1 className="title">Communities</h1>
{groups.length === 0 && <p>No Communities</p>}
<p className="has-text-centered">
<Link className="has-text-weight-bold has-text-primary" to="/register">Create your own Community</Link>
<Link className="has-text-primary" to="/register">Create your own Community</Link>
</p>
</div>
)

2
src/components/pages/home/index.tsx

@ -1,7 +1,7 @@
import React, { FC } from 'react'
const Home: FC = () => (
<div>
<div className="main-content">
<h1 className="title">Home</h1>
</div>
)

9
src/components/pages/login/index.tsx

@ -1,11 +1,14 @@
import React, { FC } from 'react'
import './login.scss'
import TextField from 'src/components/text-field'
const Login: FC = () => {
return (
<div>
<div className="main-content">
<h1 className="title">Login</h1>
<div>
<TextField name="username" label="Username" placeholder="Your Username/ID" />
</div>
</div>
)
}

0
src/components/pages/login/login.scss

2
src/components/pages/register-group/register-group.tsx

@ -19,7 +19,7 @@ const RegisterGroup: FC<Props> = ({ group, fetchGroup }) => {
if (!group) {
return (
<div>
<div className="main-content">
<h1 className="title">Community Not Found</h1>
</div>
)

12
src/components/pages/register/index.ts

@ -0,0 +1,12 @@
import { connect } from 'react-redux'
import { AppState, AppThunkDispatch } from 'src/types'
import Register from './register'
const mapStateToProps = (state: AppState) => ({})
const mapDispatchToProps = (dispatch: AppThunkDispatch) => ({})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Register)

33
src/components/pages/register/register.tsx

@ -0,0 +1,33 @@
import React, { FC } from 'react'
import TextField from '../../text-field'
import RegisterForm from '../../register-form'
export interface Props {
}
const Register: FC<Props> = () => {
return (
<div className="main-content">
<h1 className="title">Create a new Community and Account</h1>
<div className="columns">
<div className="column">
<h1 className="subtitle has-text-primary">Community</h1>
<div>
<TextField name="group-name" label="Name" placeholder="Community Name" />
</div>
</div>
<div className="column">
<h1 className="subtitle has-text-primary">You</h1>
<RegisterForm />
</div>
</div>
</div>
)
}
export default Register

18
src/components/pages/test/index.ts

@ -0,0 +1,18 @@
import { connect } from 'react-redux'
import { showNotification } from 'src/actions/notifications'
import { AppThunkDispatch, NotificationType } from 'src/types'
import Test from './test'
const mapStateToProps = () => ({})
const mapDispatchToProps = (dispatch: AppThunkDispatch) => ({
show: async (type: NotificationType, content: string) => {
dispatch(showNotification(type, content))
},
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Test)

30
src/components/pages/test/test.tsx

@ -0,0 +1,30 @@
import React, { FC } from 'react'
import { NotificationType } from 'src/types'
interface Props {
show: (type: NotificationType, content: string) => void
}
const Test: FC<Props> = ({ show }) => (
<div>
<section className="hero is-dark is-bold">
<div className="hero-body">
<div className="container">
<h1 className="title">Test Page</h1>
</div>
</div>
</section>
<div className="main-content">
<p>
<button className="button is-success" onClick={() => show('success', 'You did it!!!!!')}>Show Success</button>
<br /><br />
<button className="button is-info" onClick={() => show('info', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')}>Show Info</button>
<br /><br />
<button className="button is-danger" onClick={() => show('error', 'Fuck')}>Show Error</button>
</p>
</div>
</div>
)
export default Test

2
src/components/register-form/index.ts

@ -11,7 +11,7 @@ const mapStateToProps = (state: AppState) => ({
const mapDispatchToProps = (dispatch: Dispatch) => ({
initForm: () => {
dispatch(initForm())
// dispatch(initForm())
dispatch(initField('username'))
dispatch(initField('name'))
dispatch(initField('email'))

5
src/components/register-form/register-form.tsx

@ -1,6 +1,5 @@
import React, { FC, useEffect } from 'react'
import TextField from '../text-field'
import './register-form.scss'
interface Props {
initForm: () => void
@ -13,7 +12,9 @@ const RegisterForm: FC<Props> = ({ initForm }) => {
return (
<div className="container">
<TextField name="username" label="Username" />
<TextField name="username" label="Username" placeholder="Your Username/ID" />
<TextField name="name" label="Display Name" placeholder="Whatever you want to go by" />
<TextField name="email" label="Email Address" placeholder="Your email address" />
</div>
)
}

14
src/components/text-field/text-field.tsx

@ -6,18 +6,24 @@ import { IconDefinition } from '@fortawesome/fontawesome-common-types'
import { notificationTypeToClassName } from 'src/utils'
import { FormNotification } from 'src/types'
import './register-form.scss'
export interface Props {
name: string
label: string
type?: 'text' | 'email'
placeholder?: string
icon?: IconDefinition
value?: string
notification?: FormNotification
}
const RegisterForm: FC<Props> = ({ label, placeholder, icon, value, notification }) => {
const RegisterForm: FC<Props> = ({
label,
type = 'text',
placeholder,
icon,
value,
notification,
}) => {
const controlClassNames = classNames({ control: true, 'has-icons-left': !!icon })
let helpClassNames: string | undefined
@ -32,7 +38,7 @@ const RegisterForm: FC<Props> = ({ label, placeholder, icon, value, notification
<div className="field">
<label className="label">{label}</label>
<div className={controlClassNames}>
<input className="input" type="text" placeholder={placeholder} value={value} />
<input className="input" type={type} placeholder={placeholder} value={value} />
{icon &&
<span className="icon is-small is-left">
<FontAwesomeIcon icon={icon} />

11
src/components/user-info/user-info.scss

@ -1,14 +1,3 @@
$image-size: 64px;
div.empty-image {
background-color: #eeeeee;
background-image: linear-gradient(145deg, #eeeeee, #aaaaaa);
border: solid 1px #cccccc;
border-radius: $image-size;
height: $image-size;
width: $image-size;
}
article#user-info {
padding: 20px;
}

33
src/components/user-info/user-info.tsx

@ -11,29 +11,28 @@ interface Props {
}
const UserInfo: FC<Props> = ({ authenticated, user }) => {
const getAvatar = () => {
if (authenticated && user && user.imageUrl) {
return <img src={user.imageUrl} />
}
return <div className="empty-image"></div>
}
const hasAvatar = authenticated && user && user.imageUrl
const imageUrl = hasAvatar ? user!.imageUrl : undefined
return (
<article id="user-info" className="media has-background-black">
<figure className="media-left">
<p className="image is-64x64">
{getAvatar()}
</p>
</figure>
{hasAvatar &&
<figure className="media-left">
<p className="image is-64x64">
<img src={imageUrl} />
</p>
</figure>
}
<div className="media-content">
<div className="content">
<p>
<Link to="/login" className="is-size-5 has-text-white has-text-weight-bold">Log In</Link>
<br />
<Link to="/communities" className="is-size-7 has-text-light">Register</Link>
</p>
<div className="has-text-centered">
<Link to="/login" className="is-size-6 has-text-white">Log In to Flexor</Link>
<p className="is-size-7 has-text-primary is-uppercase">
or
</p>
<Link to="/communities" className="is-size-7 has-text-light">Create an Account</Link>
</div>
</div>
</div>
</article>

4
src/selectors/index.ts

@ -18,12 +18,12 @@ export const getForm = (state: AppState) => state.forms.form
export const getFieldValue = (state: AppState, name: string) => {
const field = getForm(state)[name]
return field.value
return field ? field.value : undefined
}
export const getFieldNotification = (state: AppState, name: string) => {
const field = getForm(state)[name]
return field.notification
return field ? field.notification : undefined
}
export const getMenuCollapsed = (state: AppState) => state.menu.collapsed

Loading…
Cancel
Save