diff --git a/admin-panel/package.json b/admin-panel/package.json index 5fbeba9..d40efcb 100644 --- a/admin-panel/package.json +++ b/admin-panel/package.json @@ -8,6 +8,7 @@ "history": "^4.7.2", "immutable": "^3.8.2", "logger": "^0.0.1", + "prop-types": "^15.6.0", "react": "^16.2.0", "react-dom": "^16.2.0", "react-redux": "^5.0.6", diff --git a/admin-panel/src/components/common/Button.css b/admin-panel/src/components/common/Button.css new file mode 100644 index 0000000..a45ed71 --- /dev/null +++ b/admin-panel/src/components/common/Button.css @@ -0,0 +1,21 @@ +.button { + padding: 5px 15px; + color: #fff; + background-color: #108ee9; + border-color: #108ee9; + outline: 0; + border-radius: 4px; + cursor: pointer; + border: 0; + font-size: 14px; +} + +.button:hover { + background-color: #49a9ee; + border-color: #49a9ee; +} + +.button:active { + background-color: #0e77ca; + border-color: #0e77ca; +} diff --git a/admin-panel/src/components/common/Button.jsx b/admin-panel/src/components/common/Button.jsx new file mode 100644 index 0000000..6ed225c --- /dev/null +++ b/admin-panel/src/components/common/Button.jsx @@ -0,0 +1,28 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import './Button.css'; + +export default function Button({ children, className, ...rest }) { + return ( + + ); +} + +Button.propTypes = { + children: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.object, + ]), + className: PropTypes.string, +}; + +Button.defaultProps = { + children: null, + className: '', +}; diff --git a/admin-panel/src/components/common/InputField.css b/admin-panel/src/components/common/InputField.css new file mode 100644 index 0000000..2cdbb0c --- /dev/null +++ b/admin-panel/src/components/common/InputField.css @@ -0,0 +1,24 @@ +.input-field__label { + font-weight: bold; +} + +.input-field__input { + padding: 5px; + border-radius: 4px; + border: 1px solid #d9d9d9; +} + +.input-field__input:hover { + border-color: #49a9ee; +} + +.input-field__input:focus { + outline: 0; + box-shadow: 0 0 0 2px rgba(16,142,233,.2); +} + +.input-field__error { + display: block; + color: #FF0000; + font-size: 0.85em; +} \ No newline at end of file diff --git a/admin-panel/src/components/common/InputField.jsx b/admin-panel/src/components/common/InputField.jsx new file mode 100644 index 0000000..8fd388a --- /dev/null +++ b/admin-panel/src/components/common/InputField.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import './InputField.css'; + +export default function renderField(props) { + const { + input, + label, + meta: { touched, error }, + className, + ...rest + } = props; + + return ( +
+ {label && + + {label} + + } +
+ + {touched && + error && + + {error} + + } +
+ ); +} + +renderField.propTypes = { + input: PropTypes.shape({}).isRequired, + meta: PropTypes.shape({}).isRequired, + label: PropTypes.string, + className: PropTypes.string, +}; + +renderField.defaultProps = { + label: '', + className: '', +}; diff --git a/admin-panel/src/components/routes/AddUserForm.jsx b/admin-panel/src/components/routes/AddUserForm.jsx new file mode 100644 index 0000000..1170a9e --- /dev/null +++ b/admin-panel/src/components/routes/AddUserForm.jsx @@ -0,0 +1,115 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Field, reduxForm } from 'redux-form'; +import Button from '../common/Button'; +import InputField from '../common/InputField'; +import { + required, + minLength, + maxLength, + allowedChars, + invalidEmail, +} from '../../helpers/reduxForm/fieldLevelValidation'; + +const firstAndFirstNameValidation = [required, allowedChars, minLength(3), maxLength(100)]; +const emailValidation = [required, invalidEmail, maxLength(100)]; +const passwordValidation = [required, minLength(8), maxLength(100)]; + +class AddUserForm extends React.Component { + static propTypes = { + handleSubmit: PropTypes.func.isRequired, + reset: PropTypes.func.isRequired, + submitting: PropTypes.bool.isRequired, + pristine: PropTypes.bool.isRequired, + error: PropTypes.string, + }; + + static defaultProps = { + error: '', + }; + + submit = () => { }; + + render() { + const { + handleSubmit, + error, + pristine, + reset, + submitting, + } = this.props; + + return ( +
+ + + + +
+ { + error && + + {error} + + } +
+ + +
+
+ + + ); + } +} + +export default reduxForm({ + form: 'AddUserForm', +})(AddUserForm); diff --git a/admin-panel/src/components/routes/Admin.js b/admin-panel/src/components/routes/Admin.js deleted file mode 100644 index 952248e..0000000 --- a/admin-panel/src/components/routes/Admin.js +++ /dev/null @@ -1,17 +0,0 @@ -import React, { Component } from 'react' - -class Admin extends Component { - static propTypes = { - - }; - - render() { - return ( -
-

Admin Page

-
- ) - } -} - -export default Admin \ No newline at end of file diff --git a/admin-panel/src/components/routes/Admin.jsx b/admin-panel/src/components/routes/Admin.jsx new file mode 100644 index 0000000..dbe83f1 --- /dev/null +++ b/admin-panel/src/components/routes/Admin.jsx @@ -0,0 +1,22 @@ +import React, { Component } from 'react'; +import AddUserForm from './AddUserForm'; + +class Admin extends Component { + static propTypes = { + + }; + + state = {}; + + render() { + return ( +
+

Admin Page

+

Create user

+ +
+ ); + } +} + +export default Admin; diff --git a/admin-panel/src/config.js b/admin-panel/src/config.js index 65bba00..0fe00c9 100644 --- a/admin-panel/src/config.js +++ b/admin-panel/src/config.js @@ -1,14 +1,14 @@ import firebase from 'firebase' -export const appName = 'advreact-04-12' +export const appName = 'advreact-386f6' const config = { - apiKey: "AIzaSyCmDWlgYIhtEr1pWjgKYds3iXKWBl9wbjE", + apiKey: "AIzaSyDSPRtistNZnrnNMJXCra5uS9Ugpken3F0", authDomain: `${appName}.firebaseapp.com`, databaseURL: `https://${appName}.firebaseio.com`, projectId: appName, storageBucket: "", - messagingSenderId: "95255462276" + messagingSenderId: "648901552269" } -firebase.initializeApp(config) \ No newline at end of file +firebase.initializeApp(config) diff --git a/admin-panel/src/helpers/reduxForm/fieldLevelValidation.js b/admin-panel/src/helpers/reduxForm/fieldLevelValidation.js new file mode 100644 index 0000000..e2797c4 --- /dev/null +++ b/admin-panel/src/helpers/reduxForm/fieldLevelValidation.js @@ -0,0 +1,19 @@ +export const required = value => ( + value ? undefined : 'Required' +); + +export const minLength = min => value => ( + value && value.length < min ? `Must be ${min} character or more` : undefined +); + +export const maxLength = max => value => ( + value && value.length > max ? `Must be ${max} character or less` : undefined +); + +export const allowedChars = value => ( + value && !/^[А-ЯA-Z]+$/i.test(value) ? 'Only letters are allowed' : undefined +); + +export const invalidEmail = value => ( + value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value) ? 'Invalid email address' : undefined +); diff --git a/admin-panel/src/index.css b/admin-panel/src/index.css new file mode 100644 index 0000000..c86bc01 --- /dev/null +++ b/admin-panel/src/index.css @@ -0,0 +1,10 @@ +body { + margin: 0; + padding: 0; + font-family: sans-serif; +} + +.common-margins { + margin-right: 5px; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/admin-panel/src/index.js b/admin-panel/src/index.js index ad60938..8b5e116 100644 --- a/admin-panel/src/index.js +++ b/admin-panel/src/index.js @@ -2,5 +2,6 @@ import React from 'react' import ReactDOM from 'react-dom' import './config' import Root from './Root' +import './index.css'; ReactDOM.render(, document.getElementById('root'))