Permalink
Browse files

Create Sidebar

  • Loading branch information...
bnhansn committed Oct 21, 2016
1 parent 8334700 commit 79c41abe665e45b2c7d6ab744e8a514d884f0241
View
@@ -0,0 +1,31 @@
import api from '../api';
export function fetchRooms() {
return dispatch => api.fetch('/rooms')
.then((response) => {
dispatch({ type: 'FETCH_ROOMS_SUCCESS', response });
});
}
export function fetchUserRooms(userId) {
return dispatch => api.fetch(`/users/${userId}/rooms`)
.then((response) => {
dispatch({ type: 'FETCH_USER_ROOMS_SUCCESS', response });
});
}
export function createRoom(data, router) {
return dispatch => api.post('/rooms', data)
.then((response) => {
dispatch({ type: 'CREATE_ROOM_SUCCESS', response });
router.transitionTo(`/r/${response.data.id}`);
});
}
export function joinRoom(roomId, router) {
return dispatch => api.post(`/rooms/${roomId}/join`)
.then((response) => {
dispatch({ type: 'ROOM_JOINED', response });
router.transitionTo(`/r/${response.data.id}`);
});
}
@@ -1,9 +1,11 @@
import { reset } from 'redux-form';
import api from '../api';
import { fetchUserRooms } from './rooms';
function setCurrentUser(dispatch, response) {
localStorage.setItem('token', JSON.stringify(response.meta.token));
dispatch({ type: 'AUTHENTICATION_SUCCESS', response });
dispatch(fetchUserRooms(response.data.id));
}
export function login(data, router) {
@@ -0,0 +1,107 @@
// @flow
import React from 'react';
import { Link } from 'react-router';
import { css, StyleSheet } from 'aphrodite';
const styles = StyleSheet.create({
sidebar: {
display: 'flex',
flexDirection: 'column',
background: 'rgb(38,28,37)',
},
link: {
position: 'relative',
display: 'flex',
width: '65px',
color: 'rgba(255,255,255,.6)',
':hover': {
textDecoration: 'none',
},
':focus': {
textDecoration: 'none',
},
},
activeLink: {
color: '#fff',
':after': {
position: 'absolute',
top: '12px',
bottom: '12px',
left: '0',
width: '3px',
background: 'rgba(255,255,255,.2)',
borderTopRightRadius: '3px',
borderBottomRightRadius: '3px',
content: '""',
},
},
badge: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '45px',
height: '45px',
margin: '12px auto',
fontSize: '20px',
background: 'rgba(255,255,255,.2)',
borderRadius: '5px',
},
logoutButton: {
padding: '0',
background: 'transparent',
border: '0',
cursor: 'pointer',
},
});
type Room = {
id: number,
name: string,
}
type RoomLinkProps = {
room: Room
}
const RoomLink = ({ room }: RoomLinkProps) =>
<Link to={`/r/${room.id}`} className={css(styles.link)} activeClassName={css(styles.activeLink)}>
<div className={css(styles.badge)}>
<span>{room.name.charAt(0)}</span>
</div>
</Link>;
type Props = {
rooms: Array<Room>,
router: Object,
onLogoutClick: () => void,
}
const Sidebar = ({ rooms, router, onLogoutClick }: Props) =>
<div className={css(styles.sidebar)}>
{rooms.map(room => <RoomLink key={room.id} room={room} />)}
<Link
to="/"
activeOnlyWhenExact
className={css(styles.link)}
activeClassName={css(styles.activeLink)}
>
<div className={css(styles.badge)}>
<span className="fa fa-plus" />
</div>
</Link>
<div style={{ flex: '1' }} />
<button
onClick={() => onLogoutClick(router)}
className={css(styles.link, styles.logoutButton)}
>
<div className={css(styles.badge)}>
<span className="fa fa-sign-out" />
</div>
</button>
</div>;
export default Sidebar;
@@ -2,19 +2,23 @@
import React, { Component } from 'react';
import { BrowserRouter, Miss } from 'react-router';
import { connect } from 'react-redux';
import { authenticate, unauthenticate } from '../../actions/session';
import { authenticate, unauthenticate, logout } from '../../actions/session';
import Home from '../Home';
import NotFound from '../../components/NotFound';
import Login from '../Login';
import Signup from '../Signup';
import MatchAuthenticated from '../../components/MatchAuthenticated';
import RedirectAuthenticated from '../../components/RedirectAuthenticated';
import Sidebar from '../../components/Sidebar';
import Room from '../Room';
type Props = {
authenticate: () => void,
unauthenticate: () => void,
isAuthenticated: boolean,
willAuthenticate: boolean,
logout: () => void,
currentUserRooms: Array,
}
class App extends Component {
@@ -30,18 +34,30 @@ class App extends Component {
props: Props
handleLogout = router => this.props.logout(router);
render() {
const { isAuthenticated, willAuthenticate } = this.props;
const { isAuthenticated, willAuthenticate, currentUserRooms } = this.props;
const authProps = { isAuthenticated, willAuthenticate };
return (
<BrowserRouter>
<div style={{ display: 'flex', flex: '1' }}>
<MatchAuthenticated exactly pattern="/" component={Home} {...authProps} />
<RedirectAuthenticated pattern="/login" component={Login} {...authProps} />
<RedirectAuthenticated pattern="/signup" component={Signup} {...authProps} />
<Miss component={NotFound} />
</div>
{({ router }) => (
<div style={{ display: 'flex', flex: '1' }}>
{isAuthenticated &&
<Sidebar
router={router}
rooms={currentUserRooms}
onLogoutClick={this.handleLogout}
/>
}
<MatchAuthenticated exactly pattern="/" component={Home} {...authProps} />
<RedirectAuthenticated pattern="/login" component={Login} {...authProps} />
<RedirectAuthenticated pattern="/signup" component={Signup} {...authProps} />
<MatchAuthenticated pattern="/r/:id" component={Room} {...authProps} />
<Miss component={NotFound} />
</div>
)}
</BrowserRouter>
);
}
@@ -51,6 +67,7 @@ export default connect(
state => ({
isAuthenticated: state.session.isAuthenticated,
willAuthenticate: state.session.willAuthenticate,
currentUserRooms: state.rooms.currentUserRooms,
}),
{ authenticate, unauthenticate }
{ authenticate, unauthenticate, logout }
)(App);
@@ -0,0 +1,7 @@
// @flow
import React from 'react';
const Room = props =>
<div>Room {props.params.id}</div>;
export default Room;
@@ -1,10 +1,12 @@
import { combineReducers } from 'redux';
import { reducer as form } from 'redux-form';
import session from './session';
import rooms from './rooms';
const appReducer = combineReducers({
form,
session,
rooms,
});
export default function (state, action) {
View
@@ -0,0 +1,41 @@
const initialState = {
all: [],
currentUserRooms: [],
};
export default function (state = initialState, action) {
switch (action.type) {
case 'FETCH_ROOMS_SUCCESS':
return {
...state,
all: action.response.data,
};
case 'FETCH_USER_ROOMS_SUCCESS':
return {
...state,
currentUserRooms: action.response.data,
};
case 'CREATE_ROOM_SUCCESS':
return {
...state,
all: [
action.response.data,
...state.all,
],
currentUserRooms: [
...state.currentUserRooms,
action.response.data,
],
};
case 'ROOM_JOINED':
return {
...state,
currentUserRooms: [
...state.currentUserRooms,
action.response.data,
],
};
default:
return state;
}
}

0 comments on commit 79c41ab

Please sign in to comment.