diff --git a/client/coral-admin/src/components/Comment.js b/client/coral-admin/src/components/Comment.js
index 2b0b7561b..e5a753f80 100644
--- a/client/coral-admin/src/components/Comment.js
+++ b/client/coral-admin/src/components/Comment.js
@@ -3,7 +3,7 @@ import React from 'react';
import {Button, Icon} from 'react-mdl';
import timeago from 'timeago.js';
import styles from './CommentList.css';
-import I18n from 'coral-framework/i18n/i18n';
+import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
// Render a single comment for the list
diff --git a/client/coral-admin/src/components/ModerationKeysModal.js b/client/coral-admin/src/components/ModerationKeysModal.js
index 5cf9fe17e..b1282e5d6 100644
--- a/client/coral-admin/src/components/ModerationKeysModal.js
+++ b/client/coral-admin/src/components/ModerationKeysModal.js
@@ -1,4 +1,4 @@
-import I18n from 'coral-framework/i18n/i18n';
+import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
import React from 'react';
import Modal from 'components/Modal';
diff --git a/client/coral-admin/src/containers/Community/Community.js b/client/coral-admin/src/containers/Community/Community.js
index 8e0b955a4..5c1bb2e19 100644
--- a/client/coral-admin/src/containers/Community/Community.js
+++ b/client/coral-admin/src/containers/Community/Community.js
@@ -1,5 +1,5 @@
import React from 'react';
-import I18n from 'coral-framework/i18n/i18n';
+import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../../translations';
import {Grid, Cell} from 'react-mdl';
diff --git a/client/coral-admin/src/containers/Configure.js b/client/coral-admin/src/containers/Configure.js
index 229c4e948..952e2acd1 100644
--- a/client/coral-admin/src/containers/Configure.js
+++ b/client/coral-admin/src/containers/Configure.js
@@ -13,7 +13,7 @@ import {
Icon
} from 'react-mdl';
import styles from './Configure.css';
-import I18n from 'coral-framework/i18n/i18n';
+import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
class Configure extends React.Component {
diff --git a/client/coral-admin/src/containers/ModerationQueue.js b/client/coral-admin/src/containers/ModerationQueue.js
index 9178bda57..a92080c39 100644
--- a/client/coral-admin/src/containers/ModerationQueue.js
+++ b/client/coral-admin/src/containers/ModerationQueue.js
@@ -5,7 +5,7 @@ import CommentList from 'components/CommentList';
import {updateStatus} from 'actions/comments';
import styles from './ModerationQueue.css';
import key from 'keymaster';
-import I18n from 'coral-framework/i18n/i18n';
+import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
/*
diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js
index bfccf7cfc..31457787a 100644
--- a/client/coral-embed-stream/src/CommentStream.js
+++ b/client/coral-embed-stream/src/CommentStream.js
@@ -15,6 +15,7 @@ import {ReplyBox, ReplyButton} from '../../coral-plugin-replies';
import Pym from 'pym.js';
import FlagButton from '../../coral-plugin-flags/FlagButton';
import PermalinkButton from '../../coral-plugin-permalinks/PermalinkButton';
+import SignInContainer from '../../coral-sign-in/containers/SignInContainer';
const {addItem, updateItem, postItem, getStream, postAction, appendItemArray} = itemActions;
const {addNotification, clearNotification} = notificationActions;
@@ -111,6 +112,7 @@ class CommentStream extends Component {
id={rootItemId}
premod={this.props.config.moderation}
reply={false}/>
+
{
rootItem.comments.map((commentId) => {
diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js
new file mode 100644
index 000000000..9b1053161
--- /dev/null
+++ b/client/coral-framework/actions/auth.js
@@ -0,0 +1,61 @@
+import * as actions from '../constants/auth';
+import {base, handleResp} from '../helpers';
+
+export const loginFacebook = () => dispatch => {
+ dispatch(loginFacebookRequest());
+ window.open(
+ `${base}/auth/facebook`,
+ 'Continue with Facebook',
+ 'menubar=0,resizable=0,width=500,height=500,top=200,left=500'
+ );
+};
+
+export const loginFacebookCallback = (err, data) => {
+ let user;
+
+ if (err) {
+ console.error(err);
+ return;
+ }
+
+ try {
+ user = JSON.parse(data);
+ } catch (err) {
+ console.error('Can\'t parse the user json', err);
+ return;
+ }
+
+ console.log('User was loaded!', user);
+};
+
+export const logout = () => dispatch => {
+ dispatch(logoutRequest());
+ fetch(`${base}/api/v1/auth`, {
+ method: 'DELETE',
+ credentials: 'same-origin'
+ })
+ .then(handleResp)
+ .then(() => dispatch(dispatch(logoutSuccess())))
+ .catch(error => dispatch(logoutFailure(error)));
+};
+
+const logoutRequest = () => ({
+ type: actions.USER_LOGOUT_SUCCESS
+});
+
+const logoutSuccess = () => ({
+ type: actions.USER_LOGOUT_SUCCESS
+});
+
+const logoutFailure = (error) => ({
+ type: actions.USER_LOGOUT_SUCCESS,
+ error
+});
+
+export const loginFacebookRequest = () => ({
+ type: actions.USER_FACEBOOK_LOGIN_REQUEST
+});
+
+export const loginRequest = () => ({
+ type: actions.USER_SIGNIN_REQUEST
+});
diff --git a/client/coral-framework/store/actions/config.js b/client/coral-framework/actions/config.js
similarity index 98%
rename from client/coral-framework/store/actions/config.js
rename to client/coral-framework/actions/config.js
index f131b8c82..d8fd886be 100644
--- a/client/coral-framework/store/actions/config.js
+++ b/client/coral-framework/actions/config.js
@@ -1,5 +1,3 @@
-/* @flow */
-
import {fromJS} from 'immutable';
/**
diff --git a/client/coral-framework/store/actions/items.js b/client/coral-framework/actions/items.js
similarity index 100%
rename from client/coral-framework/store/actions/items.js
rename to client/coral-framework/actions/items.js
diff --git a/client/coral-framework/store/actions/notification.js b/client/coral-framework/actions/notification.js
similarity index 92%
rename from client/coral-framework/store/actions/notification.js
rename to client/coral-framework/actions/notification.js
index c34adc414..4edc17601 100644
--- a/client/coral-framework/store/actions/notification.js
+++ b/client/coral-framework/actions/notification.js
@@ -1,5 +1,3 @@
-/* Notification Actions */
-
export const ADD_NOTIFICATION = 'ADD_NOTIFICATION';
export const CLEAR_NOTIFICATION = 'CLEAR_NOTIFICATION';
diff --git a/client/coral-framework/constants/auth.js b/client/coral-framework/constants/auth.js
new file mode 100644
index 000000000..7f93a51fe
--- /dev/null
+++ b/client/coral-framework/constants/auth.js
@@ -0,0 +1,9 @@
+export const USER_LOGIN_REQUEST = 'USER_LOGIN_REQUEST';
+export const USER_LOGIN_SUCCESS = 'USER_LOGIN_SUCCESS';
+export const USER_LOGIN_FAILURE = 'USER_LOGIN_FAILURE';
+export const USER_FACEBOOK_LOGIN_REQUEST = 'USER_FACEBOOK_LOGIN_REQUEST';
+export const USER_FACEBOOK_SUCCESS = 'USER_FACEBOOK_SUCCESS';
+export const USER_FACEBOOK_FAILURE = 'USER_FACEBOOK_FAILURE';
+export const USER_LOGOUT_REQUEST = 'USER_LOGOUT_REQUEST';
+export const USER_LOGOUT_SUCCESS = 'USER_LOGOUT_SUCCESS';
+export const USER_LOGOUT_FAILURE = 'USER_LOGOUT_FAILURE';
diff --git a/client/coral-framework/helpers/index.js b/client/coral-framework/helpers/index.js
new file mode 100644
index 000000000..439ba5a8a
--- /dev/null
+++ b/client/coral-framework/helpers/index.js
@@ -0,0 +1,27 @@
+export const base = '/api/v1';
+
+export const getInit = (method, body) => {
+ const headers = new Headers({
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json'
+ });
+
+ const init = {method, headers};
+ if (method.toLowerCase() !== 'get') {
+ init.body = JSON.stringify(body);
+ }
+
+ return init;
+};
+
+export const handleResp = res => {
+ if (res.status === 401) {
+ throw new Error('Not Authorized to make this request');
+ } else if (res.status > 399) {
+ throw new Error('Error! Status ', res.status);
+ } else if (res.status === 204) {
+ return res.text();
+ } else {
+ return res.json();
+ }
+};
diff --git a/client/coral-framework/index.js b/client/coral-framework/index.js
index 118935c50..4c6ae741f 100644
--- a/client/coral-framework/index.js
+++ b/client/coral-framework/index.js
@@ -1,10 +1,10 @@
-import Notification from './notification/Notification';
-import store from './store/store';
-import {fetchConfig} from './store/actions/config';
-import * as itemActions from './store/actions/items';
-import I18n from './i18n/i18n';
-import * as notificationActions from './store/actions/notification';
-import * as authActions from './store/actions/auth';
+import Notification from './modules/notification/Notification';
+import store from './store';
+import {fetchConfig} from './actions/config';
+import * as itemActions from './actions/items';
+import I18n from './modules/i18n/i18n';
+import * as notificationActions from './actions/notification';
+import * as authActions from './actions/auth';
export {
Notification,
diff --git a/client/coral-framework/i18n/i18n.js b/client/coral-framework/modules/i18n/i18n.js
similarity index 96%
rename from client/coral-framework/i18n/i18n.js
rename to client/coral-framework/modules/i18n/i18n.js
index 43144f3a6..afe8606d1 100644
--- a/client/coral-framework/i18n/i18n.js
+++ b/client/coral-framework/modules/i18n/i18n.js
@@ -1,5 +1,5 @@
import timeago from 'timeago.js';
-import esTA from 'timeago.js/locales/es';
+import esTA from '../../../../node_modules/timeago.js/locales/es';
/**
* Default locales, this should be overriden by config file
diff --git a/client/coral-framework/notification/Notification.js b/client/coral-framework/modules/notification/Notification.js
similarity index 100%
rename from client/coral-framework/notification/Notification.js
rename to client/coral-framework/modules/notification/Notification.js
diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js
new file mode 100644
index 000000000..c585ea237
--- /dev/null
+++ b/client/coral-framework/reducers/auth.js
@@ -0,0 +1,22 @@
+import {Map} from 'immutable';
+//
+//import {
+// FETCH_COMMENTERS_REQUEST,
+// FETCH_COMMENTERS_FAILURE,
+// FETCH_COMMENTERS_SUCCESS,
+// SORT_UPDATE
+//} from '../constants/community';
+//
+const initialState = Map({
+ auth: Map(),
+ loggedIn: false,
+ error: '',
+ user: {}
+});
+
+export default function community (state = initialState, action) {
+ switch (action.type) {
+ default :
+ return state;
+ }
+}
diff --git a/client/coral-framework/store/reducers/config.js b/client/coral-framework/reducers/config.js
similarity index 100%
rename from client/coral-framework/store/reducers/config.js
rename to client/coral-framework/reducers/config.js
diff --git a/client/coral-framework/store/reducers/index.js b/client/coral-framework/reducers/index.js
similarity index 100%
rename from client/coral-framework/store/reducers/index.js
rename to client/coral-framework/reducers/index.js
diff --git a/client/coral-framework/store/reducers/items.js b/client/coral-framework/reducers/items.js
similarity index 100%
rename from client/coral-framework/store/reducers/items.js
rename to client/coral-framework/reducers/items.js
diff --git a/client/coral-framework/store/reducers/notification.js b/client/coral-framework/reducers/notification.js
similarity index 100%
rename from client/coral-framework/store/reducers/notification.js
rename to client/coral-framework/reducers/notification.js
diff --git a/client/coral-framework/store/store.js b/client/coral-framework/store.js
similarity index 99%
rename from client/coral-framework/store/store.js
rename to client/coral-framework/store.js
index 33cc9efb5..8c3f9edc1 100644
--- a/client/coral-framework/store/store.js
+++ b/client/coral-framework/store.js
@@ -1,4 +1,3 @@
-
import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import mainReducer from './reducers';
diff --git a/client/coral-framework/store/actions/auth.js b/client/coral-framework/store/actions/auth.js
deleted file mode 100644
index af1e3cb34..000000000
--- a/client/coral-framework/store/actions/auth.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Auth Actions */
-
-export const SET_LOGGED_IN_USER = 'SET_LOGGED_IN_USER';
-export const LOG_OUT_USER = 'LOG_OUT_USER';
-
-export const setLoggedInUser = (user_id) => {
- return {
- type: SET_LOGGED_IN_USER,
- user_id
- };
-};
-
-export const LogOutUser = () => {
- return {
- type: LOG_OUT_USER
- };
-};
diff --git a/client/coral-framework/store/reducers/auth.js b/client/coral-framework/store/reducers/auth.js
deleted file mode 100644
index b79444cc9..000000000
--- a/client/coral-framework/store/reducers/auth.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Auth */
-
-import * as actions from '../actions/auth';
-import {fromJS} from 'immutable';
-
-const initialState = fromJS({});
-
-export default (state = initialState, action) => {
- switch (action.type) {
- case actions.SET_LOGGED_IN_USER:
- return state.set('user', action.user_id);
- case actions.LOG_OUT_USER:
- return initialState;
- default:
- return state;
- }
-};
diff --git a/client/coral-plugin-permalinks/PermalinkButton.js b/client/coral-plugin-permalinks/PermalinkButton.js
index 978a6dd03..2372e2035 100644
--- a/client/coral-plugin-permalinks/PermalinkButton.js
+++ b/client/coral-plugin-permalinks/PermalinkButton.js
@@ -1,5 +1,5 @@
import React, {PropTypes} from 'react';
-import I18n from 'coral-framework/i18n/i18n';
+import I18n from 'coral-framework/modules/i18n/i18n';
import translations from './translations';
import onClickOutside from 'react-onclickoutside';
const name = 'coral-plugin-permalinks';
diff --git a/client/coral-sign-in/components/Button.js b/client/coral-sign-in/components/Button.js
new file mode 100644
index 000000000..fd8cc85c7
--- /dev/null
+++ b/client/coral-sign-in/components/Button.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import styles from './styles.css';
+
+const Button = ({type = 'local', children, ...props}) => (
+
+);
+
+export default Button;
diff --git a/client/coral-sign-in/components/SignIn.js b/client/coral-sign-in/components/SignIn.js
new file mode 100644
index 000000000..61f1e387e
--- /dev/null
+++ b/client/coral-sign-in/components/SignIn.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import Button from './Button';
+
+const SignIn = ({openFacebookWindow, logout}) => (
+
+);
+
+export default SignIn;
diff --git a/client/coral-sign-in/components/styles.css b/client/coral-sign-in/components/styles.css
new file mode 100644
index 000000000..6dbbd5b2f
--- /dev/null
+++ b/client/coral-sign-in/components/styles.css
@@ -0,0 +1,43 @@
+.button {
+ background: 0 0;
+ border: none;
+ border-radius: 2px;
+ color: #000;
+ display: block;
+ position: relative;
+ height: 36px;
+ min-width: 64px;
+ padding: 0 8px;
+ display: inline-block;
+ font-family: 'Roboto','Helvetica','Arial',sans-serif;
+ font-size: 14px;
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0;
+ overflow: hidden;
+ will-change: box-shadow,transform;
+ -webkit-transition: box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);
+ transition: box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);
+ outline: none;
+ cursor: pointer;
+ text-decoration: none;
+ text-align: center;
+ line-height: 36px;
+ vertical-align: middle;
+}
+
+.local {
+ background: #E0E0E0;
+ color: #212121;
+}
+
+.facebook {
+ background-color: #4267b2;
+ border-color: #4267b2;
+ color: rgb(255, 255, 255);
+}
+
+.facebook:hover {
+ background-color: #365899;
+ border-color: #365899;
+}
\ No newline at end of file
diff --git a/client/coral-sign-in/containers/SignInContainer.js b/client/coral-sign-in/containers/SignInContainer.js
new file mode 100644
index 000000000..72b46536e
--- /dev/null
+++ b/client/coral-sign-in/containers/SignInContainer.js
@@ -0,0 +1,37 @@
+import React, {Component} from 'react';
+import {connect} from 'react-redux';
+
+import SignIn from '../components/SignIn';
+
+import {
+ loginFacebookCallback,
+ loginFacebook,
+ logout
+} from '../../coral-framework/actions/auth';
+
+class SignInContainer extends Component {
+ constructor(props) {
+ super(props);
+
+ this.openFacebookWindow = this.openFacebookWindow.bind(this);
+ this.logout = this.logout.bind(this);
+ }
+
+ componentDidMount() {
+ window.authCallback = loginFacebookCallback;
+ }
+
+ openFacebookWindow() {
+ this.props.dispatch(loginFacebook());
+ }
+
+ logout() {
+ this.props.dispatch(logout());
+ }
+
+ render() {
+ return ;
+ }
+}
+
+export default connect(({auth}) => ({auth}))(SignInContainer);
diff --git a/tests/client/coral-framework/store/authReducer.js b/tests/client/coral-framework/store/authReducer.js
deleted file mode 100644
index aaebe1897..000000000
--- a/tests/client/coral-framework/store/authReducer.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import {Map} from 'immutable';
-import {expect} from 'chai';
-import authReducer from '../../../../client/coral-framework/store/reducers/auth';
-import * as actions from '../../../../client/coral-framework/store/actions/auth';
-
-describe ('authReducer', () => {
- describe('SET_LOGGED_IN_USER', () => {
- it('should set a logged in user', () => {
- const action = {
- type: actions.SET_LOGGED_IN_USER,
- user_id: '123'
- };
- const store = new Map({});
- const result = authReducer(store, action);
- expect(result.get('user')).to.equal(action.user_id);
- });
- });
-
- describe('LOG_OUT_USER', () => {
- it('should clear the user store', () => {
- const action = {
- type: actions.LOG_OUT_USER
- };
- const store = new Map({
- user: '123'
- });
- const result = authReducer(store, action);
- expect(result.get('user')).to.equal(undefined);
- });
- });
-});
diff --git a/tests/client/coral-framework/store/itemActions.spec.js b/tests/client/coral-framework/store/itemActions.spec.js
index d45212794..e50b82344 100644
--- a/tests/client/coral-framework/store/itemActions.spec.js
+++ b/tests/client/coral-framework/store/itemActions.spec.js
@@ -2,7 +2,7 @@ import 'react';
import 'redux';
import {expect} from 'chai';
import fetchMock from 'fetch-mock';
-import * as actions from '../../../../client/coral-framework/store/actions/items';
+import * as actions from '../../../../client/coral-framework/actions/items';
import {Map} from 'immutable';
import configureStore from 'redux-mock-store';
diff --git a/tests/client/coral-framework/store/itemReducer.spec.js b/tests/client/coral-framework/store/itemReducer.spec.js
index 9aea845f3..16377327b 100644
--- a/tests/client/coral-framework/store/itemReducer.spec.js
+++ b/tests/client/coral-framework/store/itemReducer.spec.js
@@ -1,6 +1,6 @@
import {Map, fromJS} from 'immutable';
import {expect} from 'chai';
-import itemsReducer from '../../../../client/coral-framework/store/reducers/items';
+import itemsReducer from '../../../../client/coral-framework/reducers/items';
describe ('itemsReducer', () => {
describe('ADD_ITEM', () => {
diff --git a/tests/client/coral-framework/store/notificationReducer.spec.js b/tests/client/coral-framework/store/notificationReducer.spec.js
index 60b944a33..960034119 100644
--- a/tests/client/coral-framework/store/notificationReducer.spec.js
+++ b/tests/client/coral-framework/store/notificationReducer.spec.js
@@ -1,7 +1,7 @@
import {Map} from 'immutable';
import {expect} from 'chai';
-import notificationReducer from '../../../../client/coral-framework/store/reducers/notification';
-import * as actions from '../../../../client/coral-framework/store/actions/notification';
+import notificationReducer from '../../../../client/coral-framework/reducers/notification';
+import * as actions from '../../../../client/coral-framework/actions/notification';
describe ('notificationsReducer', () => {
describe('ADD_NOTIFICATION', () => {