Remove old JavaScript build stuff

This was neat and everything, but I'm committed to not building a
single-page app at this point, so I don't need to structure my tech this
way
This commit is contained in:
Eli Ribble 2016-06-09 10:20:08 -06:00
parent 0aecabea75
commit 3a6cb385ed
19 changed files with 0 additions and 743 deletions

View File

@ -1,14 +0,0 @@
import * as BS from 'react-bootstrap';
import React from 'react';
import Navbar from 'vanth/navbar';
module.exports = React.createClass({
render: function() {
return (
<div className='container-fluid'>
<Navbar/>
<p>You don't have any accounts yet!</p>
</div>
);
}
});

View File

@ -1,13 +0,0 @@
import { bindActionCreators } from 'redux';
import * as ActionsSession from 'vanth/actions/session';
import * as ActionsURL from 'vanth/actions/url';
import * as ActionsUser from 'vanth/actions/user';
import RootStore from 'vanth/store/root';
module.exports = {
Session : bindActionCreators(ActionsSession, RootStore.dispatch),
URL : bindActionCreators(ActionsURL, RootStore.dispatch),
User : bindActionCreators(ActionsUser, RootStore.dispatch),
}

View File

@ -1,35 +0,0 @@
import * as ActionTools from 'vanth/actions/tools';
export function createSession(username, password, nextPath=null) {
const payload = {
password: password,
username: username,
};
return ActionTools.fetchAndDispatch(
'/session/',
'SESSION_POST_BEGIN',
'SESSION_POST_COMPLETE',
'SESSION_POST_ERROR',
ActionTools.Methods.POST,
payload,
);
}
export function get() {
return ActionTools.fetchAndDispatch(
'/session/',
'SESSION_GET_BEGIN',
'SESSION_GET_COMPLETE',
'SESSION_GET_ERROR'
);
}
export function logout(uri) {
return ActionTools.fetchAndDispatch(
uri,
'SESSION_DELETE_BEGIN',
'SESSION_DELETE_COMPLETE',
'SESSION_DELETE_ERROR',
ActionTools.Methods.DELETE,
);
}

View File

@ -1,102 +0,0 @@
import _ from 'lodash';
import Config from 'vanth/config';
import { ActionType } from 'vanth/constants';
import * as Fetch from 'vanth/fetch';
export const Methods = {
DELETE : 'delete',
GET : 'get',
PATCH : 'patch',
POST : 'post',
PUT : 'put',
}
export function action(type) {
return function(data) {
let action = {
type: ActionType[type],
}
if(data != undefined) {
action.data = data;
}
if(!action.type) {
throw new Error(`An action type is required. Could not find an action type constant for ${type}`);
}
return action;
}
}
export function ensureConstantAction(constant) {
if(typeof constant === "string") {
if(!ActionType[constant]) {
let message = `${constant} is not a valid constant - you'll need to add it to constants.js`;
console.error(message)
throw new Error(message);
}
return action(constant);
}
return constant;
}
export function fetchAndDispatch(url, start, end, failed, method=Methods.GET, payload) {
let actionStart = ensureConstantAction(start);
let actionEnd = ensureConstantAction(end);
let actionFailed = ensureConstantAction(failed);
if(!Fetch[method]) {
throw new Error(`Invalid method for fetcher: ${method}`);
}
if(!payload && (method === Methods.POST || method === Methods.PUT)) {
throw new Error(`A payload is required for a ${method} method`);
}
let actionData = {};
if(method === Methods.PUT || method === Methods.DELETE) {
actionData.uri = url;
} else {
actionData.url = url;
}
return dispatch => {
dispatch(actionStart(actionData));
let fullURL = url.indexOf('://') >= 0 ? url : Config.API + url;
return Fetch[method].call(this, fullURL, payload)
.then(response => {
let result = response.json;
switch(method) {
case Methods.GET:
break;
case Methods.POST:
result = _.assign({}, payload, {
uri: response.headers.get('Location')
}, actionData);
break;
case Methods.PUT:
result = _.assign({}, payload, {
uri: url
});
break;
case Methods.DELETE:
result = actionData;
break;
}
let eventType = {
[Methods.DELETE] : 'RESOURCE_DELETE',
[Methods.GET] : 'RESOURCE_GET',
[Methods.PUT] : 'RESOURCE_PUT',
[Methods.POST] : 'RESOURCE_POST',
}[method];
dispatch(ensureConstantAction(eventType)(result));
dispatch(actionEnd(result));
return result;
})
.catch(data => {
actionData.errors = data.errors ? data.errors : [data];
dispatch(actionFailed(actionData));
throw data;
});
}
}

View File

@ -1,29 +0,0 @@
import { ActionType } from 'vanth/constants';
export function change(oldURL, newURL) {
return {
type : ActionType.URL_CHANGE,
data : {
oldURL : oldURL,
newURL : newURL,
}
}
}
export function replace(newURL) {
let oldURL = window.location.href;
history.replaceState(null, '', '#' + newURL);
return change(oldURL, window.location.href);
}
export function navigate(newURL, query) {
let oldURL = window.location.href;
let url = '#' + newURL;
if(query) {
url = "?nextPath=" + query + url;
} else {
url = "/" + url;
}
history.pushState(null, '', url);
return change(oldURL, window.location.href);
}

View File

@ -1,17 +0,0 @@
import * as ActionTools from 'vanth/actions/tools';
export function register(name, username, password) {
const payload = {
name : name,
password: password,
username: username,
}
return ActionTools.fetchAndDispatch(
'/user/',
'USER_REGISTER_BEGIN',
'USER_REGISTER_COMPLETE',
'USER_REGISTER_ERROR',
ActionTools.Methods.POST,
payload
);
}

View File

@ -1,38 +0,0 @@
import { connect, Provider } from 'react-redux';
import React from 'react';
import ReactDOM from 'react-dom';
import Actions from 'vanth/actions/root';
import RootStore from 'vanth/store/root';
import Routes from 'vanth/routes';
const App = connect(state => state)(React.createClass({
componentWillMount: function() {
window.onhashchange = function(event) {
if(!event) return;
Actions.URL.change(event.oldURL, event.newURL || window.location.hash);
}
},
render: function() {
let allProps = _.assign({}, this.props, this.state);
return (
<Routes {...allProps}/>
);
}
}));
ReactDOM.render((
<Provider store={RootStore}>
<App />
</Provider>
), document.getElementById('container'));
window.onload = function() {
let thing = Actions.Session.get()
thing.then(session => {
console.log(session);
}).catch(error => {
//Actions.URL.navigate('/login');
});
}
module.exports = App;

View File

@ -1,3 +0,0 @@
module.exports = {
API: 'http://www.vanth.com',
}

View File

@ -1,33 +0,0 @@
var make_constants = function(constants) {
let result = {};
for(var i = 0; i < constants.length; i++) {
let constant = constants[i];
result[constant] = constant;
}
return result;
}
export const ActionType = make_constants([
'RESOURCE_DELETE',
'RESOURCE_GET',
'RESOURCE_POST',
'RESOURCE_PUT',
'SESSION_DELETE_BEGIN',
'SESSION_DELETE_COMPLETE',
'SESSION_DELETE_ERROR',
'SESSION_GET_BEGIN',
'SESSION_GET_COMPLETE',
'SESSION_GET_ERROR',
'SESSION_POST_BEGIN',
'SESSION_POST_COMPLETE',
'SESSION_POST_ERROR',
'URL_CHANGE',
'URL_NAVIGATE',
'URL_REPLACE',
'USER_REGISTER_BEGIN',
'USER_REGISTER_COMPLETE',
'USER_REGISTER_ERROR',
]);

View File

@ -1,23 +0,0 @@
import * as BS from 'react-bootstrap';
import React from 'react';
import * as Actions from 'vanth/actions/root';
import Navbar from 'vanth/navbar';
var Dashboard = React.createClass({
logout: function() {
Actions.Session.logout(this.props.session.uri).then(() => {
Actions.URL.navigate('/login');
});
},
render: function() {
return (
<div className='container-fluid'>
<Navbar/>
<p>Welcome home</p>
</div>
);
}
});
module.exports = Dashboard

View File

@ -1,107 +0,0 @@
function FetchError(url, status, errors) {
this.errors = errors;
this.message = `Status code ${status} was returned from ${url}`;
this.name = 'FetchError';
this.status = status;
this.url = url;
}
let _handleResults = function(resolve, reject, url, fetchRequest) {
fetchRequest
.then(response => {
if(response.status == 204) {
resolve({
headers : response.headers,
json : null,
text : '',
});
} else if(response.status >= 400) {
console.error(`The request to ${url} failed with status ${response.status}`, response);
response.json()
.then(json => {
reject(new FetchError(url, response.status, json.errors));
})
.catch(reject);
} else {
if(response.headers.get('Content-Type') == 'application/json') {
response.json()
.then(json => {
resolve({
headers : response.headers,
json : json,
text : null,
});
}).catch(reject);
} else {
response.text()
.then(text => {
resolve({
headers : response.headers,
json : null,
text : text,
});
}).catch(reject);
}
}
})
.catch(error => {
if(error instanceof Error) {
reject(error);
} else {
console.error("Unrecognized error raised when fetching", error);
reject(new Error("Unknown error occurred during fetch"));
}
});
}
export function get(url) {
return new Promise(function(resolve, reject) {
_handleResults(resolve, reject, url,
fetch(url, {
credentials : 'include',
method : 'GET',
})
);
});
}
export function post(url, data) {
return new Promise(function(resolve, reject) {
_handleResults(resolve, reject, url,
fetch(url, {
credentials : 'include',
headers : {
"Content-Type": "application/json"
},
method : 'POST',
body : JSON.stringify(data),
})
);
});
}
export function put(url, data) {
return new Promise(function(resolve, reject) {
_handleResults(resolve, reject, url,
fetch(url, {
credentials : 'include',
headers : {
"Content-Type": "application/json"
},
method : 'PUT',
body : JSON.stringify(data),
})
);
});
}
module.exports.delete = function(url) {
return new Promise(function(resolve, reject) {
_handleResults(resolve, reject, url,
fetch(url, {
credentials : 'include',
method : 'DELETE',
})
);
});
}

View File

@ -1,76 +0,0 @@
import React from 'react';
import * as BS from 'react-bootstrap';
import { bindActionCreators } from 'redux';
import Actions from 'vanth/actions/root';
module.exports = React.createClass({
getInitialState() {
return {
password : null,
username : null,
}
},
handleChange: function(parameter) {
return (e) => {
this.setState({
[parameter] : e.target.value
});
}
},
handleSubmit: function(e) {
e.preventDefault();
Actions.Session.createSession(
this.state.username,
this.state.password,
this.props.url.search.nextPath || "/"
).then(result => {
Actions.Session.get();
Actions.URL.navigate('/');
}).catch(error => {
console.error(error);
});
},
render: function() {
const forgotPassword = <a href="#/forgot" className="pull-right"><small>Forgot Password</small></a>;
const pending = false;
return (
<BS.Grid>
<BS.Row>
<BS.Col xs={8} xsOffset={2}>
<h3 className="primary">Login</h3>
<hr />
<form onSubmit={this.handleSubmit} className='form-horizontal'>
<BS.FormGroup controlId="login">
<BS.ControlLabel>Username</BS.ControlLabel>
<BS.FormControl
disabled={pending}
onChange={this.handleChange('username')}
placeholder='Username'
required
type='text'
wrapperClassName='col-xs-10'
/>
<BS.ControlLabel>Password</BS.ControlLabel>
<BS.FormControl
disabled={pending}
onChange={this.handleChange('password')}
placeholder='Password'
required
type='password'
wrapperClassName='col-xs-10'
/>
<BS.Button bsStyle='primary' type='submit' className='col-xs-3 col-xs-offset-2' disabled={pending}>Login</BS.Button>
<BS.Button bsStyle='link' className='col-xs-1' href="#/register">Register</BS.Button>
</BS.FormGroup>
</form>
</BS.Col>
</BS.Row>
</BS.Grid>
);
}
});

View File

@ -1,12 +0,0 @@
import { applyMiddleware, createStore } from 'redux';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
const loggerMiddleware = createLogger();
var createStoreWithMiddleware = applyMiddleware(
thunkMiddleware, // lets us dispatch() functions
loggerMiddleware // neat middleware that logs actions
)(createStore);
module.exports = createStoreWithMiddleware;

View File

@ -1,22 +0,0 @@
import * as BS from 'react-bootstrap';
import React from 'react';
module.exports = React.createClass({
render: function() {
return (
<BS.Navbar>
<BS.Navbar.Header>
<BS.Navbar.Brand>
<a href="/">Vanth</a>
</BS.Navbar.Brand>
</BS.Navbar.Header>
<BS.Nav>
<BS.NavItem eventKey={1} href="#/accounts">Accounts</BS.NavItem>
<BS.NavDropdown eventKey={2} title="Account" id="account">
<BS.MenuItem eventKey={2.1} onClick={this.logout}>Logout</BS.MenuItem>
</BS.NavDropdown>
</BS.Nav>
</BS.Navbar>
);
}
});

View File

@ -1,87 +0,0 @@
import React from 'react';
import * as BS from 'react-bootstrap';
import { bindActionCreators } from 'redux';
import Actions from 'vanth/actions/root';
module.exports = React.createClass({
getInitialState() {
return {
name : null,
password : null,
username : null,
}
},
handleChange: function(parameter) {
return (e) => {
this.setState({
[parameter] : e.target.value
});
}
},
handleSubmit: function(e) {
e.preventDefault();
Actions.User.register(
this.state.name,
this.state.username,
this.state.password,
this.props.url.search.nextPath || "/"
).then(result => {
Actions.Session.get();
Actions.URL.navigate('/');
}).catch(error => {
console.error(error);
});
},
render: function() {
const pending = false;
return (
<BS.Grid>
<BS.Row>
<BS.Col xs={8} xsOffset={2}>
<h3 className="primary">Vanth - register a new user</h3>
<hr />
<form onSubmit={this.handleSubmit} className='form-horizontal'>
<BS.FormGroup controlId="register">
<BS.ControlLabel>Name</BS.ControlLabel>
<BS.FormControl
disabled={pending}
onChange={this.handleChange('name')}
placeholder='Name'
required
type='text'
wrapperClassName='col-xs-10'
/>
<BS.ControlLabel>Username</BS.ControlLabel>
<BS.FormControl
disabled={pending}
onChange={this.handleChange('username')}
placeholder='Username'
required
type='text'
wrapperClassName='col-xs-10'
/>
<BS.ControlLabel>Password</BS.ControlLabel>
<BS.FormControl
disabled={pending}
onChange={this.handleChange('password')}
placeholder='Password'
required
type='password'
wrapperClassName='col-xs-10'
/>
<BS.Button bsStyle='primary' type='submit' className='col-xs-3 col-xs-offset-2' disabled={pending}>Register</BS.Button>
<BS.Button bsStyle='link' className='col-xs-1' href="#/login">Login</BS.Button>
</BS.FormGroup>
</form>
</BS.Col>
</BS.Row>
</BS.Grid>
);
}
});

View File

@ -1,65 +0,0 @@
import React from 'react';
import PathToRegexp from 'path-to-regexp';
import Accounts from 'vanth/accounts';
import Dashboard from 'vanth/dashboard';
import Login from 'vanth/login';
import Register from 'vanth/register';
const Router = React.createClass({
routes: {
"/" : Dashboard,
"/accounts" : Accounts,
"/login" : Login,
"/register" : Register,
},
render: function() {
var toRender = null;
for(var path in this.routes) {
var element = this.routes[path];
var keys = [];
var pattern = PathToRegexp(path, keys);
var match = pattern.exec(this.props.hash);
if(match) {
if(!!toRender) {
console.warn("Matched more than one route. First route was", toRender.path, " this match is ", path);
}
var route = {};
for(var i = 0; i < keys.length; i++) {
let key = keys[i];
route[key.name] = match[i+1];
}
var props = _.assign({}, this.props, {route: route});
toRender = {
element : React.createElement(element, props),
path : path
}
}
}
if(!toRender) {
return (
<div className="router">
<p>You seem to have reached a link that doesn't go anywhere. Maybe you want <a href="#/">to go back to the beginning?</a></p>
</div>
);
} else {
return (
<div className="router">
{toRender.element}
</div>
);
}
}
});
var Routes = React.createClass({
render: function() {
var hash = this.props.url.location.hash.substr(1);
return (
<Router hash={hash} {...this.props}/>
);
}
});
module.exports = Routes

View File

@ -1,14 +0,0 @@
import { combineReducers } from 'redux';
import createStoreWithMiddleware from 'vanth/middleware';
import SessionReducer from 'vanth/store/session';
import URLReducer from 'vanth/store/url';
const root = combineReducers({
session : SessionReducer,
url : URLReducer,
});
const store = createStoreWithMiddleware(root);
module.exports = store;

View File

@ -1,19 +0,0 @@
import _ from 'lodash';
import * as Constants from 'vanth/constants';
const emptyState = {
name : null,
username : null,
uri : null,
};
var reducer = function(state = emptyState, action) {
switch (action.type) {
case Constants.ActionType.SESSION_GET_COMPLETE:
return _.assign({}, state, action.data);
default:
return state;
}
}
module.exports = reducer;

View File

@ -1,34 +0,0 @@
import urllite from 'urllite';
import { ActionType } from 'vanth/constants';
let _parseSearch = function(location) {
let search = {};
let query = location.search.substring(1);
let vars = query.split('&');
for(var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
search[pair[0]] = decodeURIComponent(pair[1]);
}
return search;
}
const initialState = {
location : urllite(window.location),
search : _parseSearch(urllite(window.location)),
};
var reducer = function(state = initialState, action) {
switch (action.type) {
case ActionType.URL_CHANGE:
let location = urllite(action.data.newURL);
return _.assign({}, state, {
location: location,
search: _parseSearch(location)
});
default:
return state;
}
}
module.exports = reducer;