diff --git a/package.json b/package.json index d854e24..9410fb4 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,62 @@ { - "name": "email-renderer", - "version": "1.0.0", - "description": "", - "main": "src/index.js", - "repository": { - "type": "git", - "url": "git+ssh://git@gitlab.com/elyby/email-renderer.git" - }, - "keywords": [], - "author": "SleepWalker ", - "license": "Apache-2.0", - "bugs": { - "url": "https://gitlab.com/elyby/email-renderer/issues" - }, - "homepage": "https://gitlab.com/elyby/email-renderer#README", - "scripts": { - "start": "webpack-dev-server --mode=development --progress --colors", - "lint": "eslint ./src", - "i18n:collect": "./scripts/i18n-collect/index.js", - "i18n:pull": "node scripts/i18n-crowdin/index.js pull", - "i18n:push": "node scripts/i18n-crowdin/index.js push", - "build": "rm -rf dist/ && webpack --mode=production --progress --colors" - }, - "dependencies": { - "react": "^16.8.4", - "react-dom": "^16.8.4", - "react-intl": "^2.0.0" - }, - "devDependencies": { - "@babel/core": "^7.3.4", - "@babel/plugin-proposal-class-properties": "^7.3.4", - "@babel/plugin-proposal-export-default-from": "^7.2.0", - "@babel/preset-env": "^7.3.4", - "@babel/preset-react": "^7.0.0", - "babel-eslint": "^6.0.0", - "babel-loader": "^8.0.5", - "babel-preset-react-hot": "^1.0.5", - "eslint": "^3.1.1", - "eslint-plugin-react": "^6.0.0", - "extended-translations-loader": "file:webpack-utils/extended-translations-loader", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "i18n-collect": "file:scripts/i18n-collect", - "i18n-crowdin": "file:scripts/i18n-crowdin", - "intl-json-loader": "file:./webpack-utils/intl-json-loader", - "json-loader": "^0.5.7", - "prop-types": "^15.7.2", - "text2png-loader": "file:./webpack-utils/text2png-loader", - "webpack": "^4.29.6", - "webpack-cli": "^3.3.0", - "webpack-dev-server": "^3.2.1" - }, - "engines": { - "node": ">=7.6.0" - } + "name": "email-renderer", + "version": "1.0.0", + "description": "", + "main": "src/index.js", + "repository": { + "type": "git", + "url": "git+ssh://git@gitlab.com/elyby/email-renderer.git" + }, + "keywords": [], + "author": "SleepWalker ", + "license": "Apache-2.0", + "bugs": { + "url": "https://gitlab.com/elyby/email-renderer/issues" + }, + "homepage": "https://gitlab.com/elyby/email-renderer#README", + "scripts": { + "start": "webpack-dev-server --mode=development --progress --colors", + "lint": "eslint ./src", + "i18n:collect": "./scripts/i18n-collect/index.js", + "i18n:pull": "node scripts/i18n-crowdin/index.js pull", + "i18n:push": "node scripts/i18n-crowdin/index.js push", + "build": "rm -rf dist/ && webpack --mode=production --progress --colors" + }, + "dependencies": { + "react": "^16.8.4", + "react-dom": "^16.8.4", + "react-intl": "^2.0.0" + }, + "devDependencies": { + "@babel/core": "^7.3.4", + "@babel/plugin-proposal-class-properties": "^7.3.4", + "@babel/plugin-proposal-export-default-from": "^7.2.0", + "@babel/preset-env": "^7.3.4", + "@babel/preset-react": "^7.0.0", + "@babel/preset-typescript": "^7.3.3", + "@types/react": "^16.8.17", + "@types/react-intl": "^2.3.17", + "@types/webpack-env": "^1.13.9", + "babel-eslint": "^6.0.0", + "babel-loader": "^8.0.5", + "babel-preset-react-hot": "^1.0.5", + "eslint": "^3.1.1", + "eslint-plugin-react": "^6.0.0", + "extended-translations-loader": "file:webpack-utils/extended-translations-loader", + "file-loader": "^3.0.1", + "html-webpack-plugin": "^3.2.0", + "i18n-collect": "file:scripts/i18n-collect", + "i18n-crowdin": "file:scripts/i18n-crowdin", + "intl-json-loader": "file:./webpack-utils/intl-json-loader", + "json-loader": "^0.5.7", + "text2png-loader": "file:./webpack-utils/text2png-loader", + "typescript": "^3.4.5", + "webpack": "^4.29.6", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-cli": "^3.3.0", + "webpack-dev-server": "^3.2.1" + }, + "engines": { + "node": ">=8.0" + } } diff --git a/src/App.js b/src/App.tsx similarity index 56% rename from src/App.js rename to src/App.tsx index cbbd358..04af477 100644 --- a/src/App.js +++ b/src/App.tsx @@ -1,15 +1,19 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - +import React, { FunctionComponent } from 'react'; import { IntlProvider, addLocaleData } from 'react-intl'; -import { SUPPORTED_LANGUAGES, DEFAULT_LANGUAGE } from './params'; +import { SUPPORTED_LANGUAGES, DEFAULT_LANGUAGE } from 'params'; -import BaseLayout from 'components/BaseLayout'; +import { BaseLayout } from 'components'; -export default function App({type, payload = {}}) { - let { locale } = payload; +export interface Params { + type: string; + payload: { + locale: string; + [key: string]: any; + }; +} +const App: FunctionComponent = ({ type, payload: { locale, ...params } }) => { if (!locale || SUPPORTED_LANGUAGES.indexOf(locale) === -1) { locale = DEFAULT_LANGUAGE; } @@ -21,17 +25,13 @@ export default function App({type, payload = {}}) { const { default: Email } = require(`emails/${type}/index`); return ( + // @ts-ignore have no idea why - + ); -} - -App.propTypes = { - type: PropTypes.string.isRequired, - payload: PropTypes.shape({ - locale: PropTypes.string, - }), }; + +export default App; diff --git a/src/components/BaseLayout.js b/src/components/BaseLayout.tsx similarity index 69% rename from src/components/BaseLayout.js rename to src/components/BaseLayout.tsx index ac660da..9273d32 100644 --- a/src/components/BaseLayout.js +++ b/src/components/BaseLayout.tsx @@ -1,10 +1,10 @@ -import React from 'react'; +import React, { FunctionComponent } from 'react'; import styles from './styles'; import { Table } from 'components/table'; -export default function BaseLayout(props) { +const BaseLayout: FunctionComponent = ({ children }) => { return ( @@ -12,7 +12,7 @@ export default function BaseLayout(props) {  
- {props.children} + {children}   @@ -20,4 +20,6 @@ export default function BaseLayout(props) {
); -} +}; + +export default BaseLayout; diff --git a/src/components/Html.js b/src/components/Html.tsx similarity index 68% rename from src/components/Html.js rename to src/components/Html.tsx index c347e40..7b69691 100644 --- a/src/components/Html.js +++ b/src/components/Html.tsx @@ -1,6 +1,6 @@ -import React from 'react'; +import React, { FunctionComponent } from 'react'; -export default function Html(props) { +const Html: FunctionComponent = ({ children }) => { return ( @@ -10,8 +10,10 @@ export default function Html(props) { - {props.children} + {children} ); -} +}; + +export default Html; diff --git a/src/components/blocks/code/Code.js b/src/components/blocks/code/Code.tsx similarity index 67% rename from src/components/blocks/code/Code.js rename to src/components/blocks/code/Code.tsx index 46fc548..e377540 100644 --- a/src/components/blocks/code/Code.js +++ b/src/components/blocks/code/Code.tsx @@ -1,15 +1,21 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { FunctionComponent, ReactElement } from 'react'; import { FormattedMessage as Message } from 'react-intl'; -import { colors, green } from 'components/ui/colors'; +import { Colors } from 'components/ui/colors'; import { Button, Input } from 'components/ui'; import styles from './styles'; import messages from './messages.intl.json'; -export default function Code({code, link, label, color = green}) { +interface Props { + code: string; + link: string; + label: ReactElement; + color?: Colors; +} + +const Code: FunctionComponent = ({ code, link, label, color = 'green' }) => { return (
@@ -28,11 +34,6 @@ export default function Code({code, link, label, color = green}) {
); -} - -Code.propTypes = { - code: PropTypes.string.isRequired, - link: PropTypes.string.isRequired, - label: PropTypes.node.isRequired, - color: PropTypes.oneOf(Object.values(colors)) }; + +export default Code; diff --git a/src/components/blocks/code/styles.js b/src/components/blocks/code/styles.js deleted file mode 100644 index 7ffc652..0000000 --- a/src/components/blocks/code/styles.js +++ /dev/null @@ -1,21 +0,0 @@ -export default { - codeWrapper: { - paddingTop: '20px', - textAlign: 'center' - }, - confirmEmailButton: { - paddingLeft: '50px', - paddingRight: '50px' - }, - or: { - fontSize: '12px', - paddingTop: '5px' - }, - codeLabel: { - paddingTop: '1px', - fontSize: '16px' - }, - code: { - paddingTop: '5px' - } -}; diff --git a/src/components/blocks/code/styles.ts b/src/components/blocks/code/styles.ts new file mode 100644 index 0000000..580d1de --- /dev/null +++ b/src/components/blocks/code/styles.ts @@ -0,0 +1,25 @@ +import { CSSProperties } from 'react'; + +const styles: { [key: string]: CSSProperties } = { + codeWrapper: { + paddingTop: '20px', + textAlign: 'center', + }, + confirmEmailButton: { + paddingLeft: '50px', + paddingRight: '50px', + }, + or: { + fontSize: '12px', + paddingTop: '5px', + }, + codeLabel: { + paddingTop: '1px', + fontSize: '16px', + }, + code: { + paddingTop: '5px', + }, +}; + +export default styles; diff --git a/src/components/blocks/index.js b/src/components/blocks/index.js deleted file mode 100644 index 261c22b..0000000 --- a/src/components/blocks/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import Code from './code/Code'; - -export { - Code -}; diff --git a/src/components/blocks/index.ts b/src/components/blocks/index.ts new file mode 100644 index 0000000..e747675 --- /dev/null +++ b/src/components/blocks/index.ts @@ -0,0 +1 @@ +export { default as Code } from './code/Code'; diff --git a/src/components/index.js b/src/components/index.js deleted file mode 100644 index 34c5e1c..0000000 --- a/src/components/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import Html from './Html'; - -export { - Html -}; diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..61edafb --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1,2 @@ +export { default as HTML } from './Html'; +export { default as BaseLayout } from './BaseLayout'; diff --git a/src/components/layout/content/Content.js b/src/components/layout/content/Content.js deleted file mode 100644 index ee9e55d..0000000 --- a/src/components/layout/content/Content.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; - -import styles from './styles'; - -export default function Content(props) { - return ( -
- {props.children} -
- ); -} diff --git a/src/components/layout/content/Content.tsx b/src/components/layout/content/Content.tsx new file mode 100644 index 0000000..b37835b --- /dev/null +++ b/src/components/layout/content/Content.tsx @@ -0,0 +1,13 @@ +import React, { FunctionComponent } from 'react'; + +import styles from './styles'; + +const Content: FunctionComponent = ({ children }) => { + return ( +
+ {children} +
+ ); +}; + +export default Content; diff --git a/src/components/layout/content/styles.js b/src/components/layout/content/styles.ts similarity index 100% rename from src/components/layout/content/styles.js rename to src/components/layout/content/styles.ts diff --git a/src/components/layout/footer/Footer.js b/src/components/layout/footer/Footer.tsx similarity index 100% rename from src/components/layout/footer/Footer.js rename to src/components/layout/footer/Footer.tsx diff --git a/src/components/layout/footer/styles.js b/src/components/layout/footer/styles.js deleted file mode 100644 index 632fd85..0000000 --- a/src/components/layout/footer/styles.js +++ /dev/null @@ -1,24 +0,0 @@ -import {green} from 'components/ui/colors'; - -export default { - footer: { - borderTop: `10px solid ${green.color}`, - background: '#DDD8CE', - height: '135px' - }, - footerText: { - verticalAlign: 'middle', - paddingLeft: '30px', - fontSize: '13px', - color: '#7A7A7A' - }, - footerLink: { - color: '#7A7A7A', - textDecoration: 'none', - borderBottom: '1px dashed #7A7A7A' - }, - footerLogo: { - padding: '0 30px', - textAlign: 'center' - } -}; diff --git a/src/components/layout/footer/styles.ts b/src/components/layout/footer/styles.ts new file mode 100644 index 0000000..3936132 --- /dev/null +++ b/src/components/layout/footer/styles.ts @@ -0,0 +1,27 @@ +import { green } from 'components/ui/colors'; +import { CSSProperties } from 'react'; + +const styles: { [key: string]: CSSProperties } = { + footer: { + borderTop: `10px solid ${green.base}`, + background: '#DDD8CE', + height: '135px', + }, + footerText: { + verticalAlign: 'middle', + paddingLeft: '30px', + fontSize: '13px', + color: '#7A7A7A', + }, + footerLink: { + color: '#7A7A7A', + textDecoration: 'none', + borderBottom: '1px dashed #7A7A7A', + }, + footerLogo: { + padding: '0 30px', + textAlign: 'center', + }, +}; + +export default styles; diff --git a/src/components/layout/header/Header.js b/src/components/layout/header/Header.tsx similarity index 72% rename from src/components/layout/header/Header.js rename to src/components/layout/header/Header.tsx index cff82e3..bebb59c 100644 --- a/src/components/layout/header/Header.js +++ b/src/components/layout/header/Header.tsx @@ -1,5 +1,4 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { FunctionComponent, ReactElement } from 'react'; import { FormattedMessage as Message } from 'react-intl'; import { Table } from 'components/table'; @@ -7,7 +6,12 @@ import { Table } from 'components/table'; import styles from './styles'; import messages from './messages.intl.json'; -export default function Userbar({username, title}) { +interface Props { + username: string; + title: ReactElement; +} + +const Userbar: FunctionComponent = ({ username, title }) => { return ( @@ -21,9 +25,6 @@ export default function Userbar({username, title}) {
); -} - -Userbar.propTypes = { - username: PropTypes.string, - title: PropTypes.node }; + +export default Userbar; diff --git a/src/components/layout/header/styles.js b/src/components/layout/header/styles.js deleted file mode 100644 index 05eb370..0000000 --- a/src/components/layout/header/styles.js +++ /dev/null @@ -1,16 +0,0 @@ -import background from './background.jpg'; - -export default { - headerImage: { - height: '200px', - backgroundImage: `url(${background})` - }, - headerTextContainer: { - color: '#fff', - textAlign: 'center', - verticalAlign: 'middle' - }, - welcomeUsername: { - fontSize: '20px' - }, -}; diff --git a/src/components/layout/header/styles.ts b/src/components/layout/header/styles.ts new file mode 100644 index 0000000..f69439c --- /dev/null +++ b/src/components/layout/header/styles.ts @@ -0,0 +1,19 @@ +import background from './background.jpg'; +import { CSSProperties } from 'react'; + +const styles: { [key: string]: CSSProperties } = { + headerImage: { + height: '200px', + backgroundImage: `url(${background})`, + }, + headerTextContainer: { + color: '#fff', + textAlign: 'center', + verticalAlign: 'middle', + }, + welcomeUsername: { + fontSize: '20px', + }, +}; + +export default styles; diff --git a/src/components/layout/index.js b/src/components/layout/index.js deleted file mode 100644 index 0a6a8a9..0000000 --- a/src/components/layout/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import Userbar from './userbar/Userbar'; -import Header from './header/Header'; -import Content from './content/Content'; -import Footer from './footer/Footer'; - -export { - Userbar, - Header, - Content, - Footer -}; diff --git a/src/components/layout/index.ts b/src/components/layout/index.ts new file mode 100644 index 0000000..4f03a37 --- /dev/null +++ b/src/components/layout/index.ts @@ -0,0 +1,4 @@ +export { default as Userbar } from './userbar/Userbar'; +export { default as Header } from './header/Header'; +export { default as Content } from './content/Content'; +export { default as Footer } from './footer/Footer'; diff --git a/src/components/layout/userbar/Userbar.js b/src/components/layout/userbar/Userbar.tsx similarity index 59% rename from src/components/layout/userbar/Userbar.js rename to src/components/layout/userbar/Userbar.tsx index 84d6a75..8e274dd 100644 --- a/src/components/layout/userbar/Userbar.js +++ b/src/components/layout/userbar/Userbar.tsx @@ -1,26 +1,24 @@ -import React from 'react'; +import React, { FunctionComponent } from 'react'; import { Table } from 'components/table'; import styles from './styles'; import logoImage from './logo.png'; -export default function Userbar() { +const Userbar: FunctionComponent = () => { return (
- {/* TODO: здесь нужно динамически сформировать название, т.к. может быть Ёly.by */} - Ely.by + Ely.by  
); -} +}; + +export default Userbar; diff --git a/src/components/layout/userbar/styles.js b/src/components/layout/userbar/styles.js deleted file mode 100644 index 1358250..0000000 --- a/src/components/layout/userbar/styles.js +++ /dev/null @@ -1,21 +0,0 @@ -import {green} from 'components/ui/colors'; - -export default { - userbar: { - background: green.color, - height: '50px' - }, - marginColumn: { - width: '20px' - }, - logoColumn: { - width: '1%', - verticalAlign: 'middle', - background: green.dark - }, - logo: { - padding: '0 13px', - display: 'block', - lineHeight: '50px' - } -}; diff --git a/src/components/layout/userbar/styles.ts b/src/components/layout/userbar/styles.ts new file mode 100644 index 0000000..f5f92da --- /dev/null +++ b/src/components/layout/userbar/styles.ts @@ -0,0 +1,25 @@ +import { green } from 'components/ui/colors'; + +export default { + userbar: { + background: green.base, + height: '50px', + }, + marginColumn: { + width: '20px', + }, + logoColumn: { + width: '1%', + verticalAlign: 'middle', + background: green.dark, + }, + logo: { + padding: '0 13px', + display: 'block', + lineHeight: '50px', + }, + logoImage: { + width: '65px', + verticalAlign: 'middle', + }, +}; diff --git a/src/components/styles.js b/src/components/styles.ts similarity index 75% rename from src/components/styles.js rename to src/components/styles.ts index 4656a38..8cd2d52 100644 --- a/src/components/styles.js +++ b/src/components/styles.ts @@ -3,9 +3,9 @@ export default { backgroundColor: '#EBE8E1', width: '100%', fontFamily: 'Roboto, Arial, sans-serif', - color: '#444' + color: '#444', }, container: { - width: '600px' - } + width: '600px', + }, }; diff --git a/src/components/table/Table.js b/src/components/table/Table.js deleted file mode 100644 index 2f73564..0000000 --- a/src/components/table/Table.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; - -import styles from './styles'; - -export default function Table(props) { - return ( - - - {props.children} - -
- ); -} diff --git a/src/components/table/Table.tsx b/src/components/table/Table.tsx new file mode 100644 index 0000000..4fe8081 --- /dev/null +++ b/src/components/table/Table.tsx @@ -0,0 +1,22 @@ +import React, { CSSProperties, FunctionComponent } from 'react'; + +import styles from './styles'; + +interface Props { + style?: CSSProperties; +} + +const Table: FunctionComponent = ({ children, style }) => { + return ( + + + {children} + +
+ ); +}; + +export default Table; diff --git a/src/components/table/index.js b/src/components/table/index.js deleted file mode 100644 index 0e9b375..0000000 --- a/src/components/table/index.js +++ /dev/null @@ -1 +0,0 @@ -export Table from './Table'; diff --git a/src/components/table/index.ts b/src/components/table/index.ts new file mode 100644 index 0000000..56abcd1 --- /dev/null +++ b/src/components/table/index.ts @@ -0,0 +1 @@ +export { default as Table } from './Table'; diff --git a/src/components/table/styles.js b/src/components/table/styles.js deleted file mode 100644 index 0835a2c..0000000 --- a/src/components/table/styles.js +++ /dev/null @@ -1,8 +0,0 @@ -export default { - table: { - borderCollapse: 'collapse', - msoTableLspace: '0pt', - msoTableRspace: '0pt', - width: '100%' - } -}; diff --git a/src/components/table/styles.ts b/src/components/table/styles.ts new file mode 100644 index 0000000..fd275e3 --- /dev/null +++ b/src/components/table/styles.ts @@ -0,0 +1,13 @@ +import { CSSProperties } from 'react'; + +const styles: { [key: string]: CSSProperties } = { + table: { + borderCollapse: 'collapse', + // @ts-ignore + msoTableLspace: '0pt', + msoTableRspace: '0pt', + width: '100%' + }, +}; + +export default styles; diff --git a/src/components/ui/button/Button.js b/src/components/ui/button/Button.js deleted file mode 100644 index 765c865..0000000 --- a/src/components/ui/button/Button.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; - -import styles from './styles'; - -import { colors, green } from 'components/ui/colors'; - -export default class Button extends Component { - - static propTypes = { - label: PropTypes.node.isRequired, - color: PropTypes.oneOf(Object.values(colors)) - }; - - static defaultProps = { - color: green - }; - - render() { - const {props} = this; - const {color, label} = props; - - return ( -
- {label} -
- ); - } - -} diff --git a/src/components/ui/button/Button.tsx b/src/components/ui/button/Button.tsx new file mode 100644 index 0000000..13d37ef --- /dev/null +++ b/src/components/ui/button/Button.tsx @@ -0,0 +1,26 @@ +import React, { CSSProperties, FunctionComponent, ReactElement } from 'react'; + +import { Colors, green } from 'components/ui/colors'; + +import styles from './styles'; + +interface Props { + label: ReactElement; + style?: CSSProperties; + color?: Colors; +} + +const Button: FunctionComponent = ({ label, style, color = 'green' }) => { + + return ( +
+ {label} +
+ ); +}; + +export default Button; diff --git a/src/components/ui/button/index.js b/src/components/ui/button/index.js deleted file mode 100644 index 75b7ff0..0000000 --- a/src/components/ui/button/index.js +++ /dev/null @@ -1 +0,0 @@ -export Button from './Button'; diff --git a/src/components/ui/button/index.ts b/src/components/ui/button/index.ts new file mode 100644 index 0000000..efe8c80 --- /dev/null +++ b/src/components/ui/button/index.ts @@ -0,0 +1 @@ +export { default } from './Button'; diff --git a/src/components/ui/button/styles.js b/src/components/ui/button/styles.js deleted file mode 100644 index 1bd5c87..0000000 --- a/src/components/ui/button/styles.js +++ /dev/null @@ -1,25 +0,0 @@ -import { colors } from 'components/ui/colors'; - -/** - * @param {Color} color - * @return {{backgroundColor: *}} - */ -function generateColor(color) { - return { - backgroundColor: color.color - }; -} - -const styles = { - button: { - padding: '0 13px', - lineHeight: '50px', - display: 'inline-block' - } -}; - -Object.values(colors).forEach((color) => { - styles[color] = generateColor(color); -}); - -export default styles; diff --git a/src/components/ui/button/styles.ts b/src/components/ui/button/styles.ts new file mode 100644 index 0000000..530f6f6 --- /dev/null +++ b/src/components/ui/button/styles.ts @@ -0,0 +1,27 @@ +import { Color, Colors, colors } from 'components/ui/colors'; +import { CSSProperties } from 'react'; + +function generateColor({ base }: Color): CSSProperties { + return { + backgroundColor: base, + }; +} + +type Styles = { + [key: string]: CSSProperties; +} + +const styles: Styles = { + button: { + padding: '0 13px', + lineHeight: '50px', + display: 'inline-block', + }, +}; + +Object.keys(colors).forEach((colorName) => { + // TS has error when trying to recognize keys types, so we cast it manually + styles[colorName] = generateColor(colors[colorName as any as Colors]); +}); + +export default styles; diff --git a/src/components/ui/colors.js b/src/components/ui/colors.js deleted file mode 100644 index b330803..0000000 --- a/src/components/ui/colors.js +++ /dev/null @@ -1,48 +0,0 @@ -export class Color { - - constructor(name, base, light, dark) { - this._name = name; - this._base = base; - this._light = light; - this._dark = dark; - } - - get name() { - return this._name; - } - - get color() { - return this._base; - } - - get light() { - return this._light; - } - - get dark() { - return this._dark; - } - - toString() { - return this.name; - } - -} - -export const green = new Color('green', '#207e5c', '#379070', '#1a6449'); -export const blue = new Color('blue', '#5b9aa9', '#71a6b2', '#568297'); -export const darkBlue = new Color('darkBlue', '#28555b', '#3e6164', '#233d49'); -export const violet = new Color('violet', '#6b5b8c', '#816795', '#66437a'); -export const lightViolet = new Color('lightViolet', '#8b5d79', '#a16982', '#864567'); -export const orange = new Color('orange', '#dd8650', '#f39259', '#d86e3e'); -export const red = new Color('red', '#e66c69', '#e15457', '#fc7872'); - -export const colors = { - green, - blue, - darkBlue, - violet, - lightViolet, - orange, - red -}; diff --git a/src/components/ui/colors.ts b/src/components/ui/colors.ts new file mode 100644 index 0000000..c0f0c37 --- /dev/null +++ b/src/components/ui/colors.ts @@ -0,0 +1,63 @@ +export type Colors = + | 'green' + | 'blue' + | 'darkBlue' + | 'violet' + | 'lightViolet' + | 'orange' + | 'red' + ; + +export interface Color { + base: string; + light: string; + dark: string; +} + +export const green: Color = { + base: '#207e5c', + light: '#379070', + dark: '#1a6449', +}; +export const blue: Color = { + base: '#5b9aa9', + light: '#71a6b2', + dark: '#568297', +}; +export const darkBlue: Color = { + base: '#28555b', + light: '#3e6164', + dark: '#233d49', +}; +export const violet: Color = { + base: '#6b5b8c', + light: '#816795', + dark: '#66437a', +}; +export const lightViolet: Color = { + base: '#8b5d79', + light: '#a16982', + dark: '#864567', +}; +export const orange: Color = { + base: '#dd8650', + light: '#f39259', + dark: '#d86e3e', +}; +export const red: Color = { + base: '#e66c69', + light: '#e15457', + dark: '#fc7872', +}; + +type ColorsMap = { [key in Colors]: Color }; + +export const colors: ColorsMap = { + green, + blue, + darkBlue, + violet, + lightViolet, + orange, + red, +}; diff --git a/src/components/ui/index.js b/src/components/ui/index.ts similarity index 100% rename from src/components/ui/index.js rename to src/components/ui/index.ts diff --git a/src/components/ui/input/Input.js b/src/components/ui/input/Input.js deleted file mode 100644 index 027cf24..0000000 --- a/src/components/ui/input/Input.js +++ /dev/null @@ -1,32 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; - -import { colors, green } from 'components/ui/colors'; - -import styles from './styles'; - -export default class Input extends Component { - static propTypes = { - value: PropTypes.string.isRequired, - color: PropTypes.oneOf(Object.values(colors)), - }; - - static defaultProps = { - color: green, - }; - - render() { - const {props} = this; - const {value, color, style} = props; - - return ( -
- {value} -
- ); - } -} diff --git a/src/components/ui/input/Input.tsx b/src/components/ui/input/Input.tsx new file mode 100644 index 0000000..5ae485a --- /dev/null +++ b/src/components/ui/input/Input.tsx @@ -0,0 +1,25 @@ +import React, { CSSProperties, FunctionComponent } from 'react'; + +import { Colors } from 'components/ui/colors'; + +import styles from './styles'; + +interface Props { + value: string; + color?: Colors; + style?: CSSProperties; +} + +const Input: FunctionComponent = ({ value, style, color = 'green' }) => { + return ( +
+ {value} +
+ ); +}; + +export default Input; diff --git a/src/components/ui/input/index.js b/src/components/ui/input/index.js deleted file mode 100644 index 3069022..0000000 --- a/src/components/ui/input/index.js +++ /dev/null @@ -1 +0,0 @@ -export Input from './Input'; diff --git a/src/components/ui/input/index.ts b/src/components/ui/input/index.ts new file mode 100644 index 0000000..a2e6049 --- /dev/null +++ b/src/components/ui/input/index.ts @@ -0,0 +1 @@ +export { default } from './Input'; diff --git a/src/components/ui/input/styles.js b/src/components/ui/input/styles.js deleted file mode 100644 index f5a24bd..0000000 --- a/src/components/ui/input/styles.js +++ /dev/null @@ -1,30 +0,0 @@ -import { colors } from 'components/ui/colors'; - -/** - * @param {Color} color - * @return {{backgroundColor: *}} - */ -function generateColor(color) { - return { - borderColor: color.color, - color: color.dark - }; -} - -const styles = { - input: { - backgroundColor: '#fff', - padding: '0 30px', - lineHeight: '50px', - fontSize: '18px', - display: 'inline-block', - border: '3px solid transparent', - color: '#444' - } -}; - -Object.values(colors).forEach((color) => { - styles[color] = generateColor(color); -}); - -export default styles; diff --git a/src/components/ui/input/styles.ts b/src/components/ui/input/styles.ts new file mode 100644 index 0000000..df5e636 --- /dev/null +++ b/src/components/ui/input/styles.ts @@ -0,0 +1,28 @@ +import { CSSProperties } from 'react'; +import { Color, Colors, colors } from 'components/ui/colors'; + +const styles: { [key: string]: CSSProperties } = { + input: { + backgroundColor: '#fff', + padding: '0 30px', + lineHeight: '50px', + fontSize: '18px', + display: 'inline-block', + border: '3px solid transparent', + color: '#444', + }, +}; + +function generateColor({ base, dark }: Color): CSSProperties { + return { + borderColor: base, + color: dark, + }; +} + +Object.keys(colors).forEach((color) => { + // TS has error when trying to recognize keys types, so we cast it manually + styles[color] = generateColor(colors[color as any as Colors]); +}); + +export default styles; diff --git a/src/devTools/DevApp.js b/src/devTools/DevApp.js deleted file mode 100644 index 315c9d3..0000000 --- a/src/devTools/DevApp.js +++ /dev/null @@ -1,94 +0,0 @@ -import React, { Component } from 'react'; - -import App from 'App'; - -import List from './List'; - -import { DEFAULT_LANGUAGE, SUPPORTED_LANGUAGES } from 'params'; - -const AVAILABLE_EMAILS = require.context('emails', true, /index\.js$/).keys().map((path) => path.split('/')[1]); - -export default class DevApp extends Component { - state = { - locale: DEFAULT_LANGUAGE, - type: AVAILABLE_EMAILS[0], - fixture: 'default', - isMinimized: false, - }; - - componentWillMount() { - try { - const lastState = JSON.parse(localStorage.getItem('emailRendererState')); - lastState && this.setState(lastState); - } catch (err) {/* no state was saved */} - } - - componentWillUpdate(nextProps, nextState) { - localStorage.setItem('emailRendererState', JSON.stringify(nextState)); - } - - render() { - const {locale, type, isMinimized} = this.state; - let {fixture} = this.state; - - let fixturesAvailable = {}; - try { - fixturesAvailable = require(`emails/${type}/fixtures`).default; - } catch (err) {/* no fixtures available */} - - if (!fixturesAvailable[fixture]) { - fixture = 'default'; - } - - const payload = { - locale, - ...(fixturesAvailable[fixture] || {}) - }; - - return ( -
-
- [ - {isMinimized ? '+' : '-'} - ] - -
- - - - - -
-
- - -
- ); - } - - onLocaleChange = (locale) => this.setState({locale}); - onTypeChange = (type) => this.setState({type}); - onFixtureChange = (fixture) => this.setState({fixture}); - onMinimizeToggle = (event) => { - event.preventDefault(); - - this.setState({ - isMinimized: !this.state.isMinimized - }); - } -} diff --git a/src/devTools/DevApp.tsx b/src/devTools/DevApp.tsx new file mode 100644 index 0000000..2ec0091 --- /dev/null +++ b/src/devTools/DevApp.tsx @@ -0,0 +1,109 @@ +import React, { BaseSyntheticEvent, FunctionComponent, useCallback, useEffect, useMemo, useState } from 'react'; + +import { DEFAULT_LANGUAGE, SUPPORTED_LANGUAGES } from 'params'; + +import App from 'App'; + +import List from './List'; + +const AVAILABLE_TEMPLATES = require.context('emails', true, /index\.[jt]s$/).keys().map((path) => path.split('/')[1]); + +interface LocalStorageState { + locale: string; + template: string; + fixture: string; + isMinimized: boolean; +} + +const DevApp: FunctionComponent = () => { + const [ locale, setLocale ] = useState(DEFAULT_LANGUAGE); + const [ template, setTemplate ] = useState(AVAILABLE_TEMPLATES[0]); + const [ fixture, setFixture ] = useState('default'); + const [ isMinimized, setIsMinimized ] = useState(false); + + // Load stored state from local storage on the first run + useEffect(() => { + let state: LocalStorageState; + try { + state = JSON.parse(localStorage.getItem('emailRendererState') || ''); + if (!state) { + return; + } + } catch (err) { + return; + } + + setLocale(state.locale); + setTemplate(state.template); + setFixture(state.fixture); + setIsMinimized(state.isMinimized); + }, []); + + // Store current state to the local storage when any param is changed + useEffect(() => { + const state: LocalStorageState = { locale, template, fixture, isMinimized }; + localStorage.setItem('emailRendererState', JSON.stringify(state)); + }, [locale, template, fixture, isMinimized]); + + const availableFixtures = useMemo(() => { + try { + return require(`emails/${template}/fixtures`).default; + } catch (err) { + return {}; + } + }, [template]); + + const payload = useMemo(() => ({ + locale, + ...(availableFixtures[fixture] || availableFixtures['default'] || {}), + }), [locale, availableFixtures, fixture]); + + const onMinimizeClick = useCallback((event: BaseSyntheticEvent) => { + event.preventDefault(); + setIsMinimized(!isMinimized); + }, [isMinimized, setIsMinimized]); + + return ( +
+
+ [ + {isMinimized ? '+' : '-'} + ] + +
+ + + + + +
+
+ + +
+ ); +}; + +export default DevApp; diff --git a/src/devTools/List.js b/src/devTools/List.js deleted file mode 100644 index 8f8c081..0000000 --- a/src/devTools/List.js +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -export default function List({label, items, active, onChange}) { - return ( - - ); -} - -List.propTypes = { - label: PropTypes.string.isRequired, - items: PropTypes.arrayOf(PropTypes.string).isRequired, - active: PropTypes.string, - onChange: PropTypes.func -}; diff --git a/src/devTools/List.tsx b/src/devTools/List.tsx new file mode 100644 index 0000000..4be2447 --- /dev/null +++ b/src/devTools/List.tsx @@ -0,0 +1,34 @@ +import React, { FunctionComponent } from 'react'; + +interface Props { + label: string; + items: ReadonlyArray; + active: string; + onChange: (item: string) => any; +} + +const List: FunctionComponent = ({ label, items, active, onChange = () => {} }) => { + return ( + + ); +}; + +export default List; diff --git a/src/devTools/index.js b/src/devTools/index.js deleted file mode 100644 index 605753e..0000000 --- a/src/devTools/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import DevApp from './DevApp'; - -export default DevApp; diff --git a/src/devTools/index.ts b/src/devTools/index.ts new file mode 100644 index 0000000..52e1665 --- /dev/null +++ b/src/devTools/index.ts @@ -0,0 +1 @@ +export { default } from './DevApp'; diff --git a/src/emails/forgotPassword/ForgotPassword.js b/src/emails/forgotPassword/ForgotPassword.tsx similarity index 79% rename from src/emails/forgotPassword/ForgotPassword.js rename to src/emails/forgotPassword/ForgotPassword.tsx index e4532e8..a1fd748 100644 --- a/src/emails/forgotPassword/ForgotPassword.js +++ b/src/emails/forgotPassword/ForgotPassword.tsx @@ -1,16 +1,20 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { FunctionComponent } from 'react'; import { FormattedMessage as Message, FormattedHTMLMessage as HTMLMessage } from 'react-intl'; import { Userbar, Header, Content, Footer } from 'components/layout'; import { Table } from 'components/table'; import { Code } from 'components/blocks'; -import { lightViolet } from 'components/ui/colors'; import styles from './styles'; import messages from './messages.intl.json'; -export default function ForgotPassword({username, link, code}) { +interface Props { + username: string; + link: string; + code: string; +} + +const ForgotPassword: FunctionComponent = ({ username, link, code }) => { return (
@@ -30,7 +34,7 @@ export default function ForgotPassword({username, link, code}) { - } /> @@ -41,10 +45,6 @@ export default function ForgotPassword({username, link, code}) {
); -} - -ForgotPassword.propTypes = { - username: PropTypes.string, - link: PropTypes.string, - code: PropTypes.string }; + +export default ForgotPassword; diff --git a/src/emails/forgotPassword/fixtures.js b/src/emails/forgotPassword/fixtures.ts similarity index 96% rename from src/emails/forgotPassword/fixtures.js rename to src/emails/forgotPassword/fixtures.ts index 9bb0338..746f034 100644 --- a/src/emails/forgotPassword/fixtures.js +++ b/src/emails/forgotPassword/fixtures.ts @@ -2,6 +2,6 @@ export default { default: { username: 'ErickSkrauch', code: 'I7SP06BUTLLM8MA03O', - link: 'https://account.ely.by/activation/I7SP06BUTLLM8MA03O' + link: 'https://account.ely.by/activation/I7SP06BUTLLM8MA03O', }, }; diff --git a/src/emails/forgotPassword/index.js b/src/emails/forgotPassword/index.js deleted file mode 100644 index e89ea7c..0000000 --- a/src/emails/forgotPassword/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import ForgotPassword from './ForgotPassword'; - -export default ForgotPassword; diff --git a/src/emails/forgotPassword/index.ts b/src/emails/forgotPassword/index.ts new file mode 100644 index 0000000..f7e2960 --- /dev/null +++ b/src/emails/forgotPassword/index.ts @@ -0,0 +1 @@ +export { default } from './ForgotPassword'; diff --git a/src/emails/forgotPassword/styles.js b/src/emails/forgotPassword/styles.ts similarity index 64% rename from src/emails/forgotPassword/styles.js rename to src/emails/forgotPassword/styles.ts index 5351cda..f30cfce 100644 --- a/src/emails/forgotPassword/styles.js +++ b/src/emails/forgotPassword/styles.ts @@ -1,10 +1,9 @@ export default { contentCenterCell: { - textAlign: 'center' + textAlign: 'center', }, - paragraph: { fontSize: '16px', - lineHeight: '125%' + lineHeight: '125%', }, }; diff --git a/src/emails/register/Register.js b/src/emails/register/Register.tsx similarity index 84% rename from src/emails/register/Register.js rename to src/emails/register/Register.tsx index a6100f1..a79bdd3 100644 --- a/src/emails/register/Register.js +++ b/src/emails/register/Register.tsx @@ -1,10 +1,8 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { FunctionComponent } from 'react'; import { FormattedMessage as Message, FormattedHTMLMessage as HTMLMessage } from 'react-intl'; import { Userbar, Header, Content, Footer } from 'components/layout'; import { Table } from 'components/table'; -import { blue } from 'components/ui/colors'; import { Code } from 'components/blocks'; import styles from './styles'; @@ -14,7 +12,13 @@ import violetManImage from './images/violetMan.png'; import orangeManImage from './images/orangeMan.png'; import darkBlueManImage from './images/darkBlueMan.png'; -export default function Register({username, link, code}) { +interface Props { + username: string; + link: string; + code: string; +} + +const Register: FunctionComponent = ({ username, link, code }) => { return (
@@ -34,7 +38,7 @@ export default function Register({username, link, code}) { - } /> @@ -42,7 +46,7 @@ export default function Register({username, link, code}) { @@ -52,10 +56,7 @@ export default function Register({username, link, code}) {
- + @@ -75,10 +76,7 @@ export default function Register({username, link, code}) {
- + @@ -98,10 +96,7 @@ export default function Register({username, link, code}) {
- + @@ -122,10 +117,6 @@ export default function Register({username, link, code}) {