Skip to content

Commit

Permalink
Merge branch 'master' of github.com:ruby-journal/cricos_api
Browse files Browse the repository at this point in the history
  • Loading branch information
Trung Lê committed Nov 28, 2015
2 parents 4b1699f + 6fe1970 commit c724ace
Show file tree
Hide file tree
Showing 43 changed files with 3,249 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.bundle
.DS_Store
.env.development
18 changes: 18 additions & 0 deletions client/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"optional": ["runtime"],
"stage": 0,
"env": {
"development": {
"plugins": ["react-transform"],
"extra": {
"react-transform": {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}]
}
}
}
}
}
10 changes: 10 additions & 0 deletions client/.babelrc.i18n
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"optional": ["runtime"],
"stage": 0,
"plugins": ["react-intl"],
"extra": {
"react-intl": {
"messagesDir": "_translations"
}
}
}
3 changes: 3 additions & 0 deletions client/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
webpack.*
server.js
dist
60 changes: 60 additions & 0 deletions client/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
parser: 'babel-eslint'

plugins: [ 'react' ]

ecmaFeatures:
jsx: true

env:
es6: true
browser: true
jasmine: true
node: true

rules:
array-bracket-spacing: 0
camelcase: 2
computed-property-spacing: [ 2, 'never' ]
consistent-return: 2
curly: [ 2, 'multi' ]
dot-notation: 0
eol-last: 2
eqeqeq: 2
max-len: [ 2, 80, 4 ]
new-cap: [ 2, { capIsNew: false } ]
no-eq-null: 2
no-mixed-spaces-and-tabs: 2
no-multiple-empty-lines: [ 2, { max: 2 } ]
no-trailing-spaces: 2
no-use-before-define: [ 2, 'nofunc' ]
no-undef: 2
no-underscore-dangle: 0
no-unused-vars: 2
no-var: 2
object-curly-spacing: [ 2, 'always' ]
quotes: [ 2, 'single' ]
semi: [ 2, 'never' ]
space-after-keywords: [ 2, 'always' ]
space-before-blocks: [ 2, 'always' ]
space-before-function-paren: [ 2, 'always' ]
no-warning-comments: [1, { terms: [ 'todo', 'fixme' ], location: 'anywhere' }]
space-return-throw-case: 2
strict: 0
vars-on-top: 2
indent: [ 2, 2, { SwitchCase: 1 } ]

# React stuff.
react/display-name: 0
react/jsx-boolean-value: 2
react/jsx-no-undef: 2
react/jsx-sort-props: 0
react/jsx-uses-react: 2
react/jsx-uses-vars: 2
react/no-did-mount-set-state: 2
react/no-did-update-set-state: 2
react/no-multi-comp: 0
react/no-unknown-property: 2
react/prop-types: 2
react/react-in-jsx-scope: 2
react/self-closing-comp: 2
react/wrap-multilines: 2
5 changes: 5 additions & 0 deletions client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.DS_Store
npm-debug.log
node_modules
dist
_translations
6 changes: 6 additions & 0 deletions client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Development

```bash
$ npm install
$ npm start
```
Binary file added client/assets/images/favicon.ico
Binary file not shown.
Binary file added client/assets/images/logo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions client/assets/stylesheets/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
Use `border-box` properly:
https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/
*/
html { box-sizing: border-box; }
*, *:before, *:after { box-sizing: inherit; }

/* External CSS */
@import "purecss/build/pure-min.css";
@import "purecss/build/grids-responsive-min.css";

/* Global CSS */
@import "page.css";
143 changes: 143 additions & 0 deletions client/assets/stylesheets/page.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/* custom properties */
:root {
--fontFamily: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
--bkgColor: #FFF;
--fontColor: #999;
--colorWhite: #FFF;
--colorRed: #DD514C;
}

/* custom selectors */
@custom-selector :--layout #layout;
@custom-selector :--menu #menu;
@custom-selector :--header .header;
@custom-selector :--content .content;
@custom-selector :--footer .footer;
@custom-selector :--stargazers .stargazers;

/* custom media queries */
@custom-media --viewport-small (max-width: 58em);
@custom-media --viewport-medium (min-width: 58em);

/* styleguide */
html, button, input, select, textarea, .pure-g [class *= "pure-u"] {
font-family: sans-serif; font-weight: 100; letter-spacing: 0.01em;
}

body { min-width: 320px; color: #777; line-height: 1.6; }

h1, h2, h3, h4, h5, h6 { font-weight: bold; color: rgb(75, 75, 75); }

h2 { margin: 2em 0 1em 0; font-weight: 300; color: #888; position: relative; }

a:visited { color: #265778; }

.ellipsis { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }

.link a i { font-size: 200%; color: var(--fontColor); }

.pure-form legend { color: var(--fontColor); }

.error-message { margin-left: 45px; width: 100%; }
.error-message > div {
padding: 20px; padding-right: 60px; color: var(--colorWhite);
width: 100%; position: relative; background-color: var(--colorRed);
}
.error-message p { margin: 0; }
.error-message .close-button {
float: right; font-size: 21px; line-height: 1; border: 0;
background: none; color: var(--colorWhite); font-size: 1em;
}

/* scaffolding */
:--layout { position: relative; padding-left: 0; }
:--layout, #menu, .menu-link { transition: all 0.2s ease-out; }

:--menu { margin-left: -160px; width: 160px; position: fixed; top: 0; left: 0;
bottom: 0; z-index: 1000; overflow-y: auto; -webkit-overflow-scrolling: touch;
border-right: 1px solid #ccc;
}
:--menu a { color: var(--fontColor); border: none; white-space: normal; padding: 0.625em 1em; }
:--menu .pure-menu-heading { font-size: 125%; font-weight: 300; letter-spacing: 0.1em;
color: #222; margin-top: 0; padding: 0.5em 0.8em; text-transform: uppercase;
}
:--menu .pure-menu-heading:hover,
:--menu .pure-menu-heading:focus { color: var(--fontColor); }

.menu-link { position: fixed; display: block; top: 0; left: 0;
width: 4em; height: 4em; background: #ccc;
font-size: 11px; z-index: 10; padding: 1em;
}
.menu-link span { position: relative; display: block; margin-top: 0.9em; }
.menu-link span,
.menu-link span:before,
.menu-link span:after { background-color: #fff; width: 100%; height: .2em;
transition: all 0.4s;
}
.menu-link span:before,
.menu-link span:after { position: absolute; top: -.55em; content: " "; }
.menu-link span:after { top: .55em; }
.menu-link.active span { background: transparent; }
.menu-link.active span:after { transform: rotate(-45deg) translate(.4em, -.3em); }
.menu-link.active span:before { transform: rotate(45deg) translate(.5em, .4em); }

:--menu .language-switcher { padding: 0.625em 1em; border-top: 1px solid #ccc; }

:--header {
font-family: var(--fontFamily); background: var(--bkgColor);
max-width: 768px; margin: 0 auto; padding: 1em; text-align: center;
border-bottom: 1px solid #eee; letter-spacing: 0.05em;
}
:--header h1 { font-size: 300%; font-weight: 100; margin: 0; }
:--header h2 { font-size: 125%; font-weight: 100; line-height: 1.5; margin: 0;
color: #666; letter-spacing: -0.02em;
}

#main { min-height: 500px; }

:--content { margin-left: auto; margin-right: auto; padding-left: 1em;
padding-right: 1em; max-width: 768px;
}

:--footer { font-size: 87.5%; border-top: 1px solid #eee; margin-top: 3.4286em;
padding: 1.1429em;
}

:--stargazers { background: rgb(250, 250, 250); margin: 2em auto;
border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;
}

.l-box { padding: 1em; }
.l-box-top { border-right: 1px solid var(--fontColor); }
.l-box-top a { margin-right: 15px; float: left; }
.l-box-top .repo-info { text-align: right; margin-right: 5px; }

.explore { margin: 50px 0; text-align: center; }

.section-user { text-align: center; }
.section-repo { margin: 0 auto; max-width: 300px; }

.pagination { text-align: center; }
.pagination ul { margin: 0; padding: 0; list-style: none; }
.pagination li { display: inline-block; margin-right: 10px; cursor: pointer; }
.pagination .disabled { color: #ddd; }

/* media queries */
@media (--viewport-small) {
:--layout.active { position: relative; left: 160px; }
}

@media (--viewport-medium) {
:--layout { padding-left: 0; left: 0; }
:--menu { left: 160px; }
.menu-link { position: fixed; left: 160px; display: none; }
.error-message { margin-left: 0; }
.error-message > div { padding-right: 20px; }
}

@media screen and (min-width: 48em) {
:--header, .content { padding-left: 2em; padding-right: 2em; }
:--header h1 { font-size: 320%; }
:--header h2 { font-size: 128%; }
}

28 changes: 28 additions & 0 deletions client/index.template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{%=o.htmlWebpackPlugin.options.title || 'Redux React Router Async Example'%}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

{% if (o.htmlWebpackPlugin.files.favicon) { %}
<link rel="shortcut icon" href="{%=o.htmlWebpackPlugin.files.favicon%}">
{% } %}

<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Raleway:200">
<!--[if lt IE 9]>
<script src="http://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.js"></script>
<![endif]-->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

{% for (var css in o.htmlWebpackPlugin.files.css) { %}
<link href="{%=o.htmlWebpackPlugin.files.css[css] %}" rel="stylesheet">
{% } %}
</head>
<body>
<div id="app"></div>
{% for (var chunk in o.htmlWebpackPlugin.files.chunks) { %}
<script type="text/javascript" src="{%=o.htmlWebpackPlugin.files.chunks[chunk].entry%}"></script>
{% } %}
</body>
</html>
57 changes: 57 additions & 0 deletions client/lib/Root.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* global __DEVTOOLS__ */
import '../assets/stylesheets/index.css'

import React, { PropTypes } from 'react'
import { Redirect, Route } from 'react-router'
import { ReduxRouter } from 'redux-router'
import { connect } from 'react-redux'
import configureStore from './utils/configure-store'
import * as components from './components'
import * as constants from './constants'

const {
About,
Application,
Home
} = components

export const store = configureStore()

function getRootChildren (props) {
const rootChildren = [
<div key='Root'>
{renderRoutes()}
</div>
]

if (__DEVTOOLS__) {
const DevTools = require('./components/DevTools')
rootChildren.push(<DevTools key="devtools" />)
}

return rootChildren
}

function renderRoutes () {
return (
<ReduxRouter>
<Route component={Application}>
<Route path="/" component={Home} />
<Route path="about" component={About} />
</Route>
</ReduxRouter>
)
}

@connect(({ application }) => ({ application }))
export default class Root extends React.Component {
static propTypes = {
application: PropTypes.object.isRequired
}

render () {
return (
<div>{getRootChildren(this.props)}</div>
)
}
}
22 changes: 22 additions & 0 deletions client/lib/actions/application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'whatwg-fetch'
import handleActionError from '../utils/handle-action-error'
import * as constants from '../constants'

// http://localhost:2300/api/v1/institutions
const API = 'http://localhost:2300/api/v1'

export function fetchData (options = {}) {
return dispatch => {
fetch(`${API}/institutions`)
.then(res => dispatch({
type: FETCH_DATA,
data: res
}))
.catch(error => handleActionError(dispatch, error, FETCH_DATA))
}
}

export function hideError () {
return { type: constants.HIDE_ERROR }
}

Loading

0 comments on commit c724ace

Please sign in to comment.