From ae4cf2526d6e501f6bd53bab5ef0f52d410e4744 Mon Sep 17 00:00:00 2001 From: Roberto Dip Date: Tue, 27 Jun 2017 12:27:29 -0300 Subject: [PATCH] Initial commit --- .gitignore | 22 + README.md | 57 + package.json | 20 + public/favicon.ico | Bin 0 -> 2749 bytes public/index.html | 40 + public/manifest.json | 15 + src/components/Container/Container.css | 11 + src/components/Container/Container.js | 12 + src/components/CopyOnClick/CopyOnClick.css | 4 + src/components/CopyOnClick/CopyOnClick.js | 48 + src/components/Forms/Button/Button.css | 14 + src/components/Forms/Button/Button.js | 10 + src/components/Forms/Input/Input.css | 31 + src/components/Forms/Input/Input.js | 15 + src/components/Header/Header.css | 13 + src/components/Header/Header.js | 12 + .../SignatureCreator/SignatureCreator.css | 23 + .../SignatureCreator/SignatureCreator.js | 40 + .../SignatureForm/SignatureForm.js | 18 + .../SignaturePreview/SignaturePreview.css | 28 + .../SignaturePreview/SignaturePreview.js | 22 + src/index.css | 31 + src/index.js | 9 + src/logo.png | Bin 0 -> 8841 bytes src/registerServiceWorker.js | 51 + src/scenes/Home/Home.css | 4 + src/scenes/Home/Home.js | 28 + yarn.lock | 6236 ++++++++++++++++++++ 28 files changed, 6814 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 package.json create mode 100644 public/favicon.ico create mode 100644 public/index.html create mode 100644 public/manifest.json create mode 100644 src/components/Container/Container.css create mode 100644 src/components/Container/Container.js create mode 100644 src/components/CopyOnClick/CopyOnClick.css create mode 100644 src/components/CopyOnClick/CopyOnClick.js create mode 100644 src/components/Forms/Button/Button.css create mode 100644 src/components/Forms/Button/Button.js create mode 100644 src/components/Forms/Input/Input.css create mode 100644 src/components/Forms/Input/Input.js create mode 100644 src/components/Header/Header.css create mode 100644 src/components/Header/Header.js create mode 100644 src/components/SignatureCreator/SignatureCreator.css create mode 100644 src/components/SignatureCreator/SignatureCreator.js create mode 100644 src/components/SignatureCreator/SignatureForm/SignatureForm.js create mode 100644 src/components/SignatureCreator/SignaturePreview/SignaturePreview.css create mode 100644 src/components/SignatureCreator/SignaturePreview/SignaturePreview.js create mode 100644 src/index.css create mode 100644 src/index.js create mode 100644 src/logo.png create mode 100644 src/registerServiceWorker.js create mode 100644 src/scenes/Home/Home.css create mode 100644 src/scenes/Home/Home.js create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b19cb8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +/node_modules + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local +.netlify + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ab326e --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Parse.ly signature composer + +This is a signature composer built for Parse.ly. +An online version is available [here](https://parsely-signature-composer.netlify.com/). + +## Requisites + +- Node.js v5 or superior + +## Getting started + +First, in order to clone the project you can run: + +```shell +$ git clone http://repo.or.cz/parsely-signature-composer.git +``` + +Then enter into the project directory and install all dependencies. + +```shell +$ cd parsely-signature-composer +$ npm install +``` + +That's it! now you can start playing with any of the available scripts + +## Available Scripts + +In the project directory, you can run: + +### `npm start` + +Runs the app in the development mode.
+Open [http://localhost:3000](http://localhost:3000) to view it in the browser. + +The page will reload if you make edits.
+You will also see any lint errors in the console. + +### `npm test` + +Launches the test runner in the interactive watch mode.
+See the section about [running tests](#running-tests) for more information. + +### `npm run build` + +Builds the app for production to the `build` folder.
+It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.
+Your app is ready to be deployed! + +See the section about [deployment](#deployment) for more information. + +## Deployment + +I'm using [Netlify](https://www.netlify.com/) to deploy the app, however the deployment +just consists of uploading the files under `build/` to a server. diff --git a/package.json b/package.json new file mode 100644 index 0000000..110d7fa --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "parsely-mail-signature", + "version": "1.0.0", + "private": true, + "dependencies": { + "clipboard": "^1.7.1", + "normalize.css": "^7.0.0", + "react": "^15.6.1", + "react-dom": "^15.6.1" + }, + "devDependencies": { + "react-scripts": "1.0.7" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fc289c8964f50d05fa7b9edb75f41dc41d4c2056 GIT binary patch literal 2749 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 BclrPT literal 0 HcwPel00001 diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..fcf8f5d --- /dev/null +++ b/public/index.html @@ -0,0 +1,40 @@ + + + + + + + + + + + Signature composer + + + +
+ + + diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..2e7ff70 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "Parse.ly signature composer", + "name": "Parse.ly signature composer", + "icons": [ + { + "src": "favicon.ico", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "./index.html", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/src/components/Container/Container.css b/src/components/Container/Container.css new file mode 100644 index 0000000..c4813e8 --- /dev/null +++ b/src/components/Container/Container.css @@ -0,0 +1,11 @@ +.Container { + max-width: 50rem; + margin: 0 auto; + padding: 0 2rem; +} + +@media(min-width: 60rem) { + .Container { + padding: 0; + } +} diff --git a/src/components/Container/Container.js b/src/components/Container/Container.js new file mode 100644 index 0000000..e9aaa5a --- /dev/null +++ b/src/components/Container/Container.js @@ -0,0 +1,12 @@ +import React from 'react'; +import './Container.css'; + +const Container = function({ children, className }) { + return ( +
+ {children} +
+ ); +} + +export default Container; diff --git a/src/components/CopyOnClick/CopyOnClick.css b/src/components/CopyOnClick/CopyOnClick.css new file mode 100644 index 0000000..f7caf54 --- /dev/null +++ b/src/components/CopyOnClick/CopyOnClick.css @@ -0,0 +1,4 @@ +.CopyOnClick-notification { + display: inline-block; + margin-left: 1rem; +} diff --git a/src/components/CopyOnClick/CopyOnClick.js b/src/components/CopyOnClick/CopyOnClick.js new file mode 100644 index 0000000..66464ad --- /dev/null +++ b/src/components/CopyOnClick/CopyOnClick.js @@ -0,0 +1,48 @@ +import React, { Component } from 'react'; +import Clipboard from 'clipboard'; +import './CopyOnClick.css'; + +class CopyOnClick extends Component { + state = { + active: false + } + + componentDidMount() { + const { target } = this.props; + + this.clipboard = new Clipboard(this.button, { + target: () => document.querySelector(target) + }); + } + + componentWillUnmount() { + this.clipboard.destroy(); + } + + showTooltip = () => { + this.setState({ active: true }); + setTimeout(this.hideTooltip, 1000); + } + + hideTooltip = () => { + this.setState({ active: false }); + } + + render() { + const { children } = this.props; + let notification = ''; + + if (this.state.active) { + notification = Copied!; + } + + return ( +
this.button = element} onClick={this.showTooltip}> + {children} + {notification} +
+ ); + } +} + +export default CopyOnClick; diff --git a/src/components/Forms/Button/Button.css b/src/components/Forms/Button/Button.css new file mode 100644 index 0000000..f5c1ddc --- /dev/null +++ b/src/components/Forms/Button/Button.css @@ -0,0 +1,14 @@ +.Button { + border: 2px solid #e2e2e2; + background-color: transparent; + color: #363d4e; + padding: 10px 50px; + transition: 0.33s; + cursor: pointer; + transition: transform .3s ease; +} + +.Button:hover { + border: 2px solid #5BA745; + color: #162338; +} diff --git a/src/components/Forms/Button/Button.js b/src/components/Forms/Button/Button.js new file mode 100644 index 0000000..f628184 --- /dev/null +++ b/src/components/Forms/Button/Button.js @@ -0,0 +1,10 @@ +import React from 'react'; +import './Button.css'; + +const Button = function({ text }) { + return ( + + ); +} + +export default Button; diff --git a/src/components/Forms/Input/Input.css b/src/components/Forms/Input/Input.css new file mode 100644 index 0000000..80c5b59 --- /dev/null +++ b/src/components/Forms/Input/Input.css @@ -0,0 +1,31 @@ +.Input-wrapper { + position: relative; + margin-bottom: 40px; +} + +.Input-label { + color: #9e9e9e; + position: absolute; + top: 0; + left: 0; + cursor: text; + pointer-events: none; + font-size: .8rem; +} + +.Input-input { + background-color: transparent; + border: none; + border-bottom: 1px solid #9e9e9e; + border-radius: 0; + outline: none; + height: 2.5rem; + width: 100%; + font-size: 1rem; + padding-top: 0.8rem; +} + +.Input-input:focus { + border-color: #5BA745; + box-shadow: 0 1px 0 0 #5BA745; +} diff --git a/src/components/Forms/Input/Input.js b/src/components/Forms/Input/Input.js new file mode 100644 index 0000000..d217d6e --- /dev/null +++ b/src/components/Forms/Input/Input.js @@ -0,0 +1,15 @@ +import React from 'react'; +import './Input.css'; + +const Input = function({ label, type, name, autoFocus, onChange }) { + let parsedName = name || label.toLowerCase(); + + return ( +
+ + +
+ ); +} + +export default Input; diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css new file mode 100644 index 0000000..dcfe1ca --- /dev/null +++ b/src/components/Header/Header.css @@ -0,0 +1,13 @@ +.Header-content { + height: 4rem; + line-height: 4rem; + margin: 2rem 0 2.5rem; + + border-bottom: 1px solid #d1d1d1; +} + +.Header-title { + margin: 0; + color: #2e2e2e; + text-transform: uppercase; +} diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js new file mode 100644 index 0000000..2f41d7a --- /dev/null +++ b/src/components/Header/Header.js @@ -0,0 +1,12 @@ +import React from 'react'; +import './Header.css' + +const Header = function() { + return ( +
+

Signature composer

+
+ ); +} + +export default Header; diff --git a/src/components/SignatureCreator/SignatureCreator.css b/src/components/SignatureCreator/SignatureCreator.css new file mode 100644 index 0000000..f91504c --- /dev/null +++ b/src/components/SignatureCreator/SignatureCreator.css @@ -0,0 +1,23 @@ +.SignatureCreator { + display: flex; + flex-wrap: wrap; + margin-top: 3.5rem; +} + +.SignatureCreator-form { + width: 100%; + margin-top: 3rem; +} + +@media(min-width: 60rem) { + .SignatureCreator { + flex-wrap: nowrap; + justify-content: space-between; + align-items: flex-start; + } + + .SignatureCreator-form { + width: 50%; + margin-top: 0; + } +} diff --git a/src/components/SignatureCreator/SignatureCreator.js b/src/components/SignatureCreator/SignatureCreator.js new file mode 100644 index 0000000..bd07f02 --- /dev/null +++ b/src/components/SignatureCreator/SignatureCreator.js @@ -0,0 +1,40 @@ +import React, { Component } from 'react'; +import SignaturePreview from './SignaturePreview/SignaturePreview'; +import SignatureForm from './SignatureForm/SignatureForm'; +import './SignatureCreator.css'; + +class SignatureCreator extends Component { + constructor(props) { + super(props); + + // Hard-coded initial state, hopefully some day... + this.state = { + name: 'Roberto Dip', + position: 'Front End Developer' + }; + } + + handleFormChange = (e) => { + const { name, value } = e.target; + + this.setState({...this.state, [name]: value }); + } + + handleFormSubmit = (e) => { + e.preventDefault(); + } + + render() { + return ( +
+ + +
+ ); + } +} + +export default SignatureCreator; diff --git a/src/components/SignatureCreator/SignatureForm/SignatureForm.js b/src/components/SignatureCreator/SignatureForm/SignatureForm.js new file mode 100644 index 0000000..42ec620 --- /dev/null +++ b/src/components/SignatureCreator/SignatureForm/SignatureForm.js @@ -0,0 +1,18 @@ +import React from 'react'; +import Input from '../../Forms/Input/Input'; +import Button from '../../Forms/Button/Button'; +import CopyOnClick from '../../CopyOnClick/CopyOnClick'; + +const SignatureForm = function({ onChange, onSubmit, className }) { + return ( +
+ + + +