├── docs ├── .gitkeep └── images │ └── atom-eslint-autofix.png ├── public └── .gitkeep ├── app ├── common │ ├── helpers │ │ ├── .gitkeep │ │ ├── url.test.js │ │ ├── url.js │ │ ├── tests │ │ │ └── mount.js │ │ └── validate.js │ ├── locales │ │ ├── .gitkeep │ │ ├── en.po │ │ ├── uk.po │ │ ├── source.pot │ │ └── ru.po │ ├── redux │ │ ├── .gitkeep │ │ ├── language.js │ │ ├── data │ │ │ ├── index.js │ │ │ └── movies.js │ │ ├── ui │ │ │ └── loading.js │ │ ├── api.js │ │ └── index.js │ ├── routes │ │ ├── .gitkeep │ │ └── index.js │ ├── schemas │ │ ├── .gitkeep │ │ └── index.js │ ├── services │ │ ├── .gitkeep │ │ ├── validations.js │ │ └── i18next.js │ ├── store │ │ ├── .gitkeep │ │ └── index.js │ ├── components │ │ ├── .gitkeep │ │ ├── Form │ │ │ ├── styles.scss │ │ │ ├── FormRow │ │ │ │ ├── styles.scss │ │ │ │ └── index.js │ │ │ ├── index.story.js │ │ │ └── index.js │ │ ├── FormField │ │ │ ├── styles.scss │ │ │ └── index.js │ │ ├── Poster │ │ │ ├── styles.scss │ │ │ ├── index.story.js │ │ │ └── index.js │ │ ├── _Component_ │ │ │ ├── styles.scss │ │ │ ├── index.story.js │ │ │ └── index.js │ │ ├── Icon │ │ │ ├── icons │ │ │ │ ├── arrow-down.svg │ │ │ │ ├── add.svg │ │ │ │ ├── arrow-left-large.svg │ │ │ │ ├── arrow-left.svg │ │ │ │ ├── arrow-right.svg │ │ │ │ ├── check-right.svg │ │ │ │ ├── trash.svg │ │ │ │ ├── eye.svg │ │ │ │ ├── arrows-expand.svg │ │ │ │ ├── arrows-reduce.svg │ │ │ │ └── doc.svg │ │ │ ├── icons.font.js │ │ │ ├── templates │ │ │ │ └── css.hbs │ │ │ ├── index.js │ │ │ └── index.story.js │ │ ├── TextInput │ │ │ ├── styles.scss │ │ │ ├── index.story.js │ │ │ └── index.js │ │ ├── TextareaInput │ │ │ ├── styles.scss │ │ │ ├── index.story.js │ │ │ └── index.js │ │ ├── Button │ │ │ ├── index.story.js │ │ │ ├── styles.scss │ │ │ └── index.js │ │ └── ErrorMessages │ │ │ └── index.js │ ├── containers │ │ ├── blocks │ │ │ ├── .gitkeep │ │ │ └── MovieCard │ │ │ │ ├── index.story.js │ │ │ │ ├── index.js │ │ │ │ └── styles.scss │ │ ├── forms │ │ │ ├── .gitkeep │ │ │ └── MovieForm │ │ │ │ └── index.js │ │ ├── layouts │ │ │ ├── .gitkeep │ │ │ ├── Main │ │ │ │ ├── styles.scss │ │ │ │ └── index.js │ │ │ └── App │ │ │ │ ├── styles.scss │ │ │ │ └── index.js │ │ └── pages │ │ │ ├── .gitkeep │ │ │ ├── MoviesCreatePage │ │ │ ├── styles.scss │ │ │ └── index.js │ │ │ ├── NotFoundPage │ │ │ └── index.js │ │ │ ├── MoviesListPage │ │ │ ├── styles.scss │ │ │ └── index.js │ │ │ └── MoviesDetailsPage │ │ │ ├── styles.scss │ │ │ └── index.js │ ├── styles │ │ └── variables.scss │ ├── WithStylesContext.js │ └── config.js ├── server │ ├── __dev.js │ ├── views │ │ └── index.ejs │ ├── sitemap.js │ ├── server.js │ ├── api │ │ └── index.js │ └── page.js └── client │ ├── index.js │ └── root.js ├── cypress.json ├── .dockerignore ├── cypress ├── integration │ ├── movies_list.js │ └── creating_new_post.js ├── fixtures │ └── example.json ├── plugins │ └── index.js └── support │ ├── index.js │ └── commands.js ├── .stylelintrc ├── .gitignore ├── .storybook ├── webpack.config.js └── config.js ├── .babelrc ├── app.json ├── Dockerfile ├── LICENSE.md ├── bin ├── ci │ └── push.sh ├── build.sh ├── start.sh ├── version-increment.sh └── release.sh ├── webpack.server.js ├── postcss.config.js ├── .eslintrc ├── .travis.yml ├── webpack.config.js ├── package.json ├── webpack └── parts.js └── README.md /docs/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/helpers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/locales/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/redux/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/routes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/schemas/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/services/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/store/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/components/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/containers/blocks/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/containers/forms/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/containers/layouts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/common/containers/pages/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseUrl": "http://localhost:8080" 3 | } 4 | -------------------------------------------------------------------------------- /app/common/containers/layouts/Main/styles.scss: -------------------------------------------------------------------------------- 1 | 2 | .main { 3 | padding: 40px; 4 | } 5 | -------------------------------------------------------------------------------- /app/common/components/Form/styles.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: block; 3 | width: 100%; 4 | } 5 | -------------------------------------------------------------------------------- /app/common/schemas/index.js: -------------------------------------------------------------------------------- 1 | import { schema } from 'normalizr'; 2 | 3 | export const movie = new schema.Entity('movies'); 4 | -------------------------------------------------------------------------------- /docs/images/atom-eslint-autofix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontBand/react-boilerplate/HEAD/docs/images/atom-eslint-autofix.png -------------------------------------------------------------------------------- /app/common/redux/language.js: -------------------------------------------------------------------------------- 1 | 2 | export const changeLanguage = lang => (dispatch, getState, { i18n }) => 3 | i18n.changeLanguage(lang); 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | confs 3 | bin 4 | scripts 5 | tests 6 | .md 7 | *.log 8 | .git 9 | .dockerignore 10 | Dockerfile 11 | docs/ 12 | -------------------------------------------------------------------------------- /app/common/components/FormField/styles.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .error { 4 | margin-top: 8px; 5 | color: $red; 6 | font-size: 10px; 7 | } 8 | -------------------------------------------------------------------------------- /app/common/components/Poster/styles.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | background-size: cover; 3 | background-position: top center; 4 | width: 300px; 5 | height: 400px; 6 | } 7 | -------------------------------------------------------------------------------- /app/common/components/_Component_/styles.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | padding: 20px; 3 | box-shadow: 0 2px 4px 1px rgba(0, 0, 0, 0.3); 4 | } 5 | 6 | .bold { 7 | font-weight: 600; 8 | } 9 | -------------------------------------------------------------------------------- /app/common/redux/data/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | 3 | import movies from './movies'; 4 | 5 | export default combineReducers({ 6 | movies, 7 | }); 8 | -------------------------------------------------------------------------------- /app/common/services/validations.js: -------------------------------------------------------------------------------- 1 | import { addValidation } from 'react-nebo15-validate'; 2 | 3 | addValidation('custom', (value, params, allValues) => false); // eslint-disable-line 4 | -------------------------------------------------------------------------------- /cypress/integration/movies_list.js: -------------------------------------------------------------------------------- 1 | describe('Display movies list', () => { 2 | it('should display list', () => { 3 | cy.visit('/movies'); 4 | cy.screenshot(); 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } -------------------------------------------------------------------------------- /app/common/styles/variables.scss: -------------------------------------------------------------------------------- 1 | $breakpoint-desktop: 1024px; 2 | $breakpoint-tablet: 768px; 3 | 4 | $breakpoint-mobile-max: resolve($breakpoint-tablet - 1px); 5 | 6 | $blue-grey: #e4e8ec; 7 | $blue: #20adfc; 8 | $red: red; 9 | -------------------------------------------------------------------------------- /app/common/components/Icon/icons/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/common/components/Form/FormRow/styles.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | margin-top: 20px; 3 | 4 | &:first-child { 5 | margin-top: 0; 6 | } 7 | } 8 | 9 | .label { 10 | margin-bottom: 10px; 11 | font-size: 14px; 12 | font-weight: 400; 13 | } 14 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard", 3 | "rules": { 4 | "selector-pseudo-class-no-unknown": [true, { 5 | ignorePseudoClasses: [ 6 | "global", 7 | "local" 8 | ], 9 | }] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .tmp 3 | .idea 4 | .DS_Store 5 | *.log 6 | static 7 | .env 8 | coverage 9 | lcov.info 10 | tests_output 11 | !Icon 12 | !icon 13 | browserstack.err 14 | *.mo 15 | public/sitemap*.xml 16 | logs 17 | stats.json 18 | cypress/screenshots 19 | -------------------------------------------------------------------------------- /app/common/containers/pages/MoviesCreatePage/styles.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | max-width: 400px; 3 | } 4 | 5 | .title { 6 | font-size: 25px; 7 | font-weight: bold; 8 | } 9 | 10 | .form { 11 | margin-top: 40px; 12 | } 13 | 14 | .back { 15 | margin-top: 10px; 16 | } 17 | -------------------------------------------------------------------------------- /app/common/helpers/url.test.js: -------------------------------------------------------------------------------- 1 | import { createUrl } from './url'; 2 | 3 | describe('createUrl', () => { 4 | test('add query params', () => { 5 | const url = createUrl('http://localhost', { test: 1 }); 6 | expect(url).toBe('http://localhost/?test=1'); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /app/common/components/TextInput/styles.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .input { 4 | padding: 8px 12px; 5 | border: 1px solid $blue-grey; 6 | border-radius: 3px; 7 | width: 100%; 8 | display: block; 9 | } 10 | 11 | .isError { 12 | border-color: $red; 13 | } 14 | -------------------------------------------------------------------------------- /app/common/components/TextareaInput/styles.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .root { 4 | padding: 8px 12px; 5 | border: 1px solid $blue-grey; 6 | border-radius: 3px; 7 | width: 100%; 8 | display: block; 9 | } 10 | 11 | .isError { 12 | border-color: $red; 13 | } 14 | -------------------------------------------------------------------------------- /app/common/components/_Component_/index.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | 4 | import Component from './index'; 5 | 6 | storiesOf('components/_Component_', module) 7 | .add('General', () => ( 8 | Sample component 9 | )); 10 | -------------------------------------------------------------------------------- /app/common/containers/layouts/Main/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import withStyles from 'withStyles'; 3 | 4 | import styles from './styles.scss'; 5 | 6 | const Main = ({ children }) => ( 7 |
8 | { children } 9 |
10 | ); 11 | export default withStyles(styles)(Main); 12 | -------------------------------------------------------------------------------- /app/common/helpers/url.js: -------------------------------------------------------------------------------- 1 | import Url from 'url'; 2 | import qs from 'qs'; 3 | 4 | export const createUrl = (endpoint, options) => { 5 | const url = Url.parse(endpoint, false); 6 | 7 | url.search = qs.stringify({ 8 | ...qs.parse(url.search), 9 | ...options, 10 | }); 11 | return Url.format(url); 12 | }; 13 | -------------------------------------------------------------------------------- /app/common/redux/ui/loading.js: -------------------------------------------------------------------------------- 1 | import { createAction, handleActions } from 'redux-actions'; 2 | 3 | export const showLoading = createAction('loading/SHOW'); 4 | export const hideLoading = createAction('loading/HIDE'); 5 | 6 | export default handleActions({ 7 | [showLoading]: () => true, 8 | [hideLoading]: () => false, 9 | }, false); 10 | -------------------------------------------------------------------------------- /app/common/components/Icon/icons.font.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | files: [ 4 | 'icons/*.svg', // glob style 5 | ], 6 | fontName: 'fontIcons', 7 | classPrefix: 'icon-', 8 | baseSelector: '.icon', 9 | fixedWidth: true, 10 | types: ['eot', 'woff', 'ttf', 'svg'], // this is the default 11 | cssTemplate: 'templates/css.hbs', 12 | }; 13 | -------------------------------------------------------------------------------- /app/common/containers/pages/NotFoundPage/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { compose } from 'recompose'; 3 | import { translate } from 'react-i18next'; 4 | 5 | const NotFoundPage = ({ t }) => ( 6 |
7 |

{t('Page Not Found')}

8 |
9 | ); 10 | 11 | export default compose( 12 | translate() 13 | )(NotFoundPage); 14 | -------------------------------------------------------------------------------- /app/common/components/Button/index.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | 4 | import Button from './index'; 5 | 6 | storiesOf('components/Button', module) 7 | .add('General', () => ( 8 | 9 | )) 10 | .add('Block', () => ( 11 | 12 | )); 13 | -------------------------------------------------------------------------------- /app/common/components/Button/styles.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .root { 4 | padding: 8px 12px; 5 | border-radius: 6px; 6 | background-color: $blue; 7 | color: white; 8 | min-width: 120px; 9 | cursor: pointer; 10 | display: inline-block; 11 | text-decoration: none; 12 | } 13 | 14 | .isBlock { 15 | width: 100%; 16 | display: block; 17 | } 18 | -------------------------------------------------------------------------------- /app/common/components/Form/index.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | 4 | import Form, { FormRow } from './index'; 5 | 6 | storiesOf('components/Form', module) 7 | .add('General', () => ( 8 |
9 | row 1 10 | row 2 11 |
12 | )); 13 | -------------------------------------------------------------------------------- /app/common/components/TextInput/index.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { action } from '@storybook/addon-actions'; 4 | 5 | import TextInput from './index'; 6 | 7 | storiesOf('components/TextInput', module) 8 | .add('General', () => ( 9 | 10 | )); 11 | -------------------------------------------------------------------------------- /app/common/containers/pages/MoviesListPage/styles.scss: -------------------------------------------------------------------------------- 1 | 2 | .root { 3 | overflow: hidden; 4 | } 5 | 6 | .list { 7 | margin-top: -16px; 8 | margin-left: -16px; 9 | } 10 | 11 | .item { 12 | margin-left: 16px; 13 | margin-top: 16px; 14 | display: inline-block; 15 | vertical-align: top; 16 | width: 300px; 17 | } 18 | 19 | .action { 20 | margin-top: 20px; 21 | } 22 | -------------------------------------------------------------------------------- /app/common/components/Form/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import withStyles from 'withStyles'; 3 | import { compose } from 'recompose'; 4 | import styles from './styles.scss'; 5 | 6 | const Form = ({ ...rest }) => ( 7 |
8 | ); 9 | 10 | export FormRow from './FormRow'; 11 | 12 | export default compose( 13 | withStyles(styles) 14 | )(Form); 15 | -------------------------------------------------------------------------------- /app/common/components/TextareaInput/index.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { action } from '@storybook/addon-actions'; 4 | 5 | import TextareaInput from './index'; 6 | 7 | storiesOf('components/TextareaInput', module) 8 | .add('General', () => ( 9 | 10 | )); 11 | -------------------------------------------------------------------------------- /app/common/components/Icon/icons/add.svg: -------------------------------------------------------------------------------- 1 | Прямоугольник 41Created with Avocode. -------------------------------------------------------------------------------- /app/common/locales/en.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: \n" 4 | "POT-Creation-Date: 2017-04-11 23:26+0200\n" 5 | "PO-Revision-Date: 2017-04-11 23:29+0200\n" 6 | "Last-Translator: \n" 7 | "Language-Team: \n" 8 | "Language: en\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Generator: Poedit 1.8.1\n" 13 | "X-Poedit-Basepath: .\n" 14 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 15 | -------------------------------------------------------------------------------- /app/common/components/Poster/index.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | 4 | import Poster from './index'; 5 | 6 | const posterUrl = 'https://ia.media-imdb.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_SY1000_CR0,0,704,1000_AL_.jpg'; 7 | 8 | storiesOf('components/Poster', module) 9 | .add('General', () => ( 10 | 11 | )); 12 | -------------------------------------------------------------------------------- /app/common/components/_Component_/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import withStyles from 'withStyles'; 4 | import { compose } from 'recompose'; 5 | import styles from './styles.scss'; 6 | 7 | const Component = ({ children }) => ( 8 |
9 | { children } 10 |
11 | ); 12 | 13 | Component.propTypes = { 14 | children: PropTypes.node, 15 | }; 16 | 17 | export default compose( 18 | withStyles(styles) 19 | )(Component); 20 | -------------------------------------------------------------------------------- /app/common/components/Poster/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import withStyles from 'withStyles'; 4 | import { compose } from 'recompose'; 5 | import styles from './styles.scss'; 6 | 7 | const Poster = ({ src, title }) => ( 8 |
9 | ); 10 | 11 | Poster.propTypes = { 12 | children: PropTypes.node, 13 | }; 14 | 15 | export default compose( 16 | withStyles(styles) 17 | )(Poster); 18 | -------------------------------------------------------------------------------- /app/common/components/Icon/icons/arrow-left-large.svg: -------------------------------------------------------------------------------- 1 | Прямоугольник 45Created with Avocode. -------------------------------------------------------------------------------- /app/common/locales/uk.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: i18next-conv\n" 4 | "POT-Creation-Date: 2017-04-11 23:28+0200\n" 5 | "PO-Revision-Date: 2017-04-11 23:28+0200\n" 6 | "Last-Translator: \n" 7 | "Language-Team: \n" 8 | "Language: uk\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" 13 | "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" 14 | "X-Generator: Poedit 1.8.1\n" 15 | -------------------------------------------------------------------------------- /app/common/components/Icon/icons/arrow-left.svg: -------------------------------------------------------------------------------- 1 | arrow_leftCreated with Avocode. -------------------------------------------------------------------------------- /app/common/components/Icon/icons/arrow-right.svg: -------------------------------------------------------------------------------- 1 | arrow_rightCreated with Avocode. -------------------------------------------------------------------------------- /app/common/components/TextInput/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import withStyles from 'withStyles'; 4 | import classnames from 'classnames'; 5 | import { compose } from 'recompose'; 6 | 7 | import styles from './styles.scss'; 8 | 9 | const TextInput = ({ error, ...rest }) => ( 10 | 11 | ); 12 | 13 | TextInput.propTypes = { 14 | error: PropTypes.bool, 15 | }; 16 | 17 | export default compose( 18 | withStyles(styles) 19 | )(TextInput); 20 | -------------------------------------------------------------------------------- /app/common/containers/pages/MoviesDetailsPage/styles.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | flex-direction: row; 4 | flex-wrap: nowrap; 5 | } 6 | 7 | .poster { 8 | flex: 0 0 auto; 9 | } 10 | 11 | .content { 12 | flex: 1 1 auto; 13 | padding: 20px; 14 | max-width: 450px; 15 | } 16 | 17 | .poster + .content { 18 | margin-left: 20px; 19 | } 20 | 21 | .title { 22 | font-size: 25px; 23 | font-weight: bold; 24 | } 25 | 26 | .info { 27 | p, 28 | ul { 29 | margin-top: 10px; 30 | } 31 | } 32 | 33 | .title + .info { 34 | margin-top: 30px; 35 | } 36 | -------------------------------------------------------------------------------- /app/common/helpers/tests/mount.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { configureStore } from '@/store'; 4 | import { Provider } from 'react-redux'; 5 | import createMemoryHistory from 'history/lib/createMemoryHistory'; 6 | import { mount } from 'enzyme'; 7 | import WithStylesContext from '@/WithStylesContext'; 8 | 9 | export default (component, ...args) => mount( 10 | 11 | 12 | {component} 13 | 14 | , 15 | ...args 16 | ); 17 | -------------------------------------------------------------------------------- /app/common/components/TextareaInput/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import withStyles from 'withStyles'; 4 | import classnames from 'classnames'; 5 | import { compose } from 'recompose'; 6 | import styles from './styles.scss'; 7 | 8 | const TextareaInput = ({ error, ...rest }) => ( 9 |