diff --git a/public/index.html b/public/index.html index 9a8ef8f..5d57a79 100644 --- a/public/index.html +++ b/public/index.html @@ -8,7 +8,7 @@ content="width=device-width, initial-scale=1, shrink-to-fit=no" /> - React App + Яндекс.Почта diff --git a/src/app/app.css b/src/app/app.css index 1c4d511..69bbb16 100644 --- a/src/app/app.css +++ b/src/app/app.css @@ -1,27 +1,29 @@ -.app { - text-align: center; +@font-face { + font-family: YandexSansBold; + src: url(fonts/YandexSansDisplay-Bold.ttf); } -.app-header { - display: flex; - min-height: 100vh; - flex-direction: column; - align-items: center; - justify-content: center; - background-color: #282c34; - color: #fff; - font-size: calc(10px + 2vmin); +@font-face { + font-family: YandexSansThin; + src: url(/src/app/fonts/YandexSansDisplay-Thin.ttf); } -.app-link { - color: #61dafb; +@font-face { + font-family: HelveticaNeue; + src: url(/src/app/fonts/HelveticaNeueCyr-Medium.otf); } -@keyframes app-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } +@font-face { + font-family: HelveticaNeueLight; + src: url(/src/app/fonts/HelveticaNeueCyr-Light.otf); +} + +body { + position: relative; + + min-width: 750px; + max-width: 1600px; + padding: 0; + margin: 0 auto; + background: #e5eaf0; } diff --git a/src/app/app.jsx b/src/app/app.jsx index f759eed..9574d3e 100644 --- a/src/app/app.jsx +++ b/src/app/app.jsx @@ -1,24 +1,17 @@ import React, { Component } from 'react'; import './app.css'; +import { Header } from './structure/header/header'; +import { Menu } from './structure/menu/menu'; +import { MainContent } from './structure/main-content/mainContent'; export class App extends Component { render() { return (
-
-

- Edit src/app/app.jsx and save to reload. -

- - Learn React - -
+
+ +
); } diff --git a/src/app/fonts/HelveticaNeueCyr-Light.otf b/src/app/fonts/HelveticaNeueCyr-Light.otf new file mode 100755 index 0000000..7ced49a Binary files /dev/null and b/src/app/fonts/HelveticaNeueCyr-Light.otf differ diff --git a/src/app/fonts/HelveticaNeueCyr-Medium.otf b/src/app/fonts/HelveticaNeueCyr-Medium.otf new file mode 100755 index 0000000..a2cde16 Binary files /dev/null and b/src/app/fonts/HelveticaNeueCyr-Medium.otf differ diff --git a/src/app/fonts/YandexSansDisplay-Bold.ttf b/src/app/fonts/YandexSansDisplay-Bold.ttf new file mode 100755 index 0000000..d901f4b Binary files /dev/null and b/src/app/fonts/YandexSansDisplay-Bold.ttf differ diff --git a/src/app/fonts/YandexSansDisplay-Thin.ttf b/src/app/fonts/YandexSansDisplay-Thin.ttf new file mode 100755 index 0000000..3b8e196 Binary files /dev/null and b/src/app/fonts/YandexSansDisplay-Thin.ttf differ diff --git a/src/app/structure/header/header.css b/src/app/structure/header/header.css new file mode 100644 index 0000000..edc064c --- /dev/null +++ b/src/app/structure/header/header.css @@ -0,0 +1,35 @@ +/*Start SearchInput*/ + +.header { + margin-top: 7px; + margin-bottom: 18px; + margin-left: 22px; +} + +.header__lines, +.header__main-logo { + margin: 0; + float: left; +} + +.header__lines { + margin-top: 12px; +} + +.header__line { + width: 20px; + height: 3px; + margin-top: 4px; + background-color: #000000; +} + +.header__main-logo { + margin-top: 7px; + margin-left: 11px; +} + +.clearfix:after { + display: table; + clear: both; + content: ''; +} diff --git a/src/app/structure/header/header.jsx b/src/app/structure/header/header.jsx new file mode 100644 index 0000000..6267f69 --- /dev/null +++ b/src/app/structure/header/header.jsx @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; + +import './header.css'; +import logo from './images/logo.png'; +import { SearchInput } from './searchInput/searchInput'; + +export class Header extends Component { + render() { + return ( +
+
+
+
+
+
+
+ logo +
+ +
+ ); + } +} diff --git a/src/app/structure/header/images/logo.png b/src/app/structure/header/images/logo.png new file mode 100644 index 0000000..e79b98c Binary files /dev/null and b/src/app/structure/header/images/logo.png differ diff --git a/src/app/structure/header/images/reset.png b/src/app/structure/header/images/reset.png new file mode 100644 index 0000000..ab907a0 Binary files /dev/null and b/src/app/structure/header/images/reset.png differ diff --git a/src/app/structure/header/searchInput/searchInput.css b/src/app/structure/header/searchInput/searchInput.css new file mode 100644 index 0000000..9904a40 --- /dev/null +++ b/src/app/structure/header/searchInput/searchInput.css @@ -0,0 +1,32 @@ +.header__search { + width: 37%; + height: 32px; + margin-top: 11px; + margin-left: 114px; + background: #f2f5f8; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2); + float: left; +} + +.header__input { + display: inline-block; + width: calc(100% - 50px); + height: 26px; + margin-left: 16px; + + border: none; + background: none; + outline: none; + vertical-align: center; +} + +.header__button { + width: 12px; + height: 12px; + padding: 0; + margin: 10px; + + border: none; + background: #f2f5f8; + float: right; +} diff --git a/src/app/structure/header/searchInput/searchInput.jsx b/src/app/structure/header/searchInput/searchInput.jsx new file mode 100644 index 0000000..abee1a7 --- /dev/null +++ b/src/app/structure/header/searchInput/searchInput.jsx @@ -0,0 +1,31 @@ +import React from 'react'; + +import './searchInput.css'; +import reset from '../images/reset.png'; + +export class SearchInput extends React.Component { + constructor(props) { + super(props); + this.inputVal = ''; + } + + resetForm = () => { + this.inputVal.value = ''; + }; + + render() { + return ( +
+ (this.inputVal = el)} + placeholder="Поиск" + className="header__input" + /> + +
+ ); + } +} diff --git a/src/app/structure/main-content/all-functions/Button/Button.css b/src/app/structure/main-content/all-functions/Button/Button.css new file mode 100644 index 0000000..e082e9f --- /dev/null +++ b/src/app/structure/main-content/all-functions/Button/Button.css @@ -0,0 +1,13 @@ +.main-block__ref-func { + border: none; + background: none; + color: #cccccc; + font-family: "'HelveticaNeue'", sans-serif; + font-size: 13px; + font-weight: 500; + text-decoration: none; +} + +.main-block__ref-func:hover { + border-bottom: 2px solid #cccccc; +} diff --git a/src/app/structure/main-content/all-functions/Button/Button.jsx b/src/app/structure/main-content/all-functions/Button/Button.jsx new file mode 100644 index 0000000..95f48f5 --- /dev/null +++ b/src/app/structure/main-content/all-functions/Button/Button.jsx @@ -0,0 +1,25 @@ +import React, { Component } from 'react'; + +import './Button.css'; + +export class Button extends Component { + constructor(props) { + super(props); + this.action = this.props.action.bind(this); + } + + render() { + return ( + + ); + } +} diff --git a/src/app/structure/main-content/all-functions/allFunctions.css b/src/app/structure/main-content/all-functions/allFunctions.css new file mode 100644 index 0000000..b785a7f --- /dev/null +++ b/src/app/structure/main-content/all-functions/allFunctions.css @@ -0,0 +1,37 @@ +.clearfix:after { + display: table; + clear: both; + content: ''; +} + +.check { + width: 16px; + height: 16px; + margin: 12px; + + border: 1px solid rgba(0, 0, 0, 0.15); + background-color: #ffffff; + border-radius: 3px; + float: left; +} + +.hidden-check { + display: none; +} + +.main-block__mail-functions { + height: 40px; + + border-bottom: 2px solid rgba(0, 0, 0, 0.15); +} + +.main-block__all-function { + padding-top: 6px; + margin: 0; +} + +.main-block__func { + display: inline-block; + margin-left: 20px; + list-style: none; +} diff --git a/src/app/structure/main-content/all-functions/allFunctions.jsx b/src/app/structure/main-content/all-functions/allFunctions.jsx new file mode 100644 index 0000000..dcbdc94 --- /dev/null +++ b/src/app/structure/main-content/all-functions/allFunctions.jsx @@ -0,0 +1,72 @@ +import React, { Component } from 'react'; + +import './allFunctions.css'; +import { Button } from './Button/Button'; + +export class AllFunctions extends Component { + constructor(props) { + super(props); + this.newMailOnClick = this.props.newMailOnClick.bind(this); + this.deleteLetter = this.props.deleteLetter.bind(this); + this.selectAll = this.props.selectAll.bind(this); + } + + doNothing = () => {}; + + render() { + return ( +
+ { + if (!this.props.isLetterOpened) this.selectAll(); + }} + /> + +
+ ); + } +} diff --git a/src/app/structure/main-content/footer/footer.css b/src/app/structure/main-content/footer/footer.css new file mode 100644 index 0000000..2a868f3 --- /dev/null +++ b/src/app/structure/main-content/footer/footer.css @@ -0,0 +1,20 @@ +.footer { + position: absolute; + bottom: 0; + left: 0; + + width: 100%; + height: 26px; + padding-top: 5px; + + border-top: 2px solid rgba(140, 140, 140, 0.45); + background-color: white; + color: #9b9b9b; + font-family: "'HelveticaNeue'", sans-serif; + font-size: 0.7em; +} + +.footer__texts { + margin-right: 20px; + float: right; +} diff --git a/src/app/structure/main-content/footer/footer.jsx b/src/app/structure/main-content/footer/footer.jsx new file mode 100644 index 0000000..9e317a3 --- /dev/null +++ b/src/app/structure/main-content/footer/footer.jsx @@ -0,0 +1,18 @@ +import React, { Component } from 'react'; + +import './footer.css'; +import { FooterText } from './footerText/footerText'; + +export class Footer extends Component { + render() { + return ( + + ); + } +} diff --git a/src/app/structure/main-content/footer/footerText/footerText.css b/src/app/structure/main-content/footer/footerText/footerText.css new file mode 100644 index 0000000..f9d6c77 --- /dev/null +++ b/src/app/structure/main-content/footer/footerText/footerText.css @@ -0,0 +1,5 @@ +.footer__ref { + margin-right: 10px; + color: #9b9b9b; + text-decoration: none; +} diff --git a/src/app/structure/main-content/footer/footerText/footerText.jsx b/src/app/structure/main-content/footer/footerText/footerText.jsx new file mode 100644 index 0000000..2513a08 --- /dev/null +++ b/src/app/structure/main-content/footer/footerText/footerText.jsx @@ -0,0 +1,13 @@ +import React, { Component } from 'react'; + +import './footerText.css'; + +export class FooterText extends Component { + render() { + return ( + + {this.props.text} + + ); + } +} diff --git a/src/app/structure/main-content/letters/letter-page/img/reset.png b/src/app/structure/main-content/letters/letter-page/img/reset.png new file mode 100644 index 0000000..ab907a0 Binary files /dev/null and b/src/app/structure/main-content/letters/letter-page/img/reset.png differ diff --git a/src/app/structure/main-content/letters/letter-page/letterPage.css b/src/app/structure/main-content/letters/letter-page/letterPage.css new file mode 100644 index 0000000..95ebd5e --- /dev/null +++ b/src/app/structure/main-content/letters/letter-page/letterPage.css @@ -0,0 +1,25 @@ +.main-block__letter-content { + position: absolute; + top: 42px; + + overflow: scroll; + width: 100%; + height: calc(100% - 70px); + padding: 0; + background: #ffffff; + color: #000000; + float: left; + font-family: "'HelveticaNeue'", sans-serif; + font-size: 0.8em; + font-weight: 700; +} + +.main-block__paragraph { + padding: 10px; + margin-top: 10px; +} + +.close { + padding: 15px; + float: right; +} diff --git a/src/app/structure/main-content/letters/letter-page/letterPage.jsx b/src/app/structure/main-content/letters/letter-page/letterPage.jsx new file mode 100644 index 0000000..829d0cc --- /dev/null +++ b/src/app/structure/main-content/letters/letter-page/letterPage.jsx @@ -0,0 +1,28 @@ +import React, { Component } from 'react'; + +import './letterPage.css'; +import reset from './img/reset.png'; + +export class LetterPage extends Component { + constructor(props) { + super(props); + this.closeLetter = this.props.closeLetter.bind(this); + } + + render() { + return ( +
+ reset { + this.closeLetter(); + }} + /> +

{this.props.text}

+
+ ); + } +} diff --git a/src/app/structure/main-content/letters/letters-list/letter/icons/ebay.png b/src/app/structure/main-content/letters/letters-list/letter/icons/ebay.png new file mode 100644 index 0000000..c9edef4 Binary files /dev/null and b/src/app/structure/main-content/letters/letters-list/letter/icons/ebay.png differ diff --git a/src/app/structure/main-content/letters/letters-list/letter/icons/facebook.png b/src/app/structure/main-content/letters/letters-list/letter/icons/facebook.png new file mode 100644 index 0000000..2d7290c Binary files /dev/null and b/src/app/structure/main-content/letters/letters-list/letter/icons/facebook.png differ diff --git a/src/app/structure/main-content/letters/letters-list/letter/icons/live.png b/src/app/structure/main-content/letters/letters-list/letter/icons/live.png new file mode 100644 index 0000000..19f8a27 Binary files /dev/null and b/src/app/structure/main-content/letters/letters-list/letter/icons/live.png differ diff --git a/src/app/structure/main-content/letters/letters-list/letter/icons/reddit.png b/src/app/structure/main-content/letters/letters-list/letter/icons/reddit.png new file mode 100644 index 0000000..a297ce9 Binary files /dev/null and b/src/app/structure/main-content/letters/letters-list/letter/icons/reddit.png differ diff --git a/src/app/structure/main-content/letters/letters-list/letter/icons/twitter.png b/src/app/structure/main-content/letters/letters-list/letter/icons/twitter.png new file mode 100644 index 0000000..41e07c1 Binary files /dev/null and b/src/app/structure/main-content/letters/letters-list/letter/icons/twitter.png differ diff --git a/src/app/structure/main-content/letters/letters-list/letter/icons/yandex.png b/src/app/structure/main-content/letters/letters-list/letter/icons/yandex.png new file mode 100644 index 0000000..df4059c Binary files /dev/null and b/src/app/structure/main-content/letters/letters-list/letter/icons/yandex.png differ diff --git a/src/app/structure/main-content/letters/letters-list/letter/icons/youtube.png b/src/app/structure/main-content/letters/letters-list/letter/icons/youtube.png new file mode 100644 index 0000000..f06f858 Binary files /dev/null and b/src/app/structure/main-content/letters/letters-list/letter/icons/youtube.png differ diff --git a/src/app/structure/main-content/letters/letters-list/letter/letter.css b/src/app/structure/main-content/letters/letters-list/letter/letter.css new file mode 100644 index 0000000..eee2846 --- /dev/null +++ b/src/app/structure/main-content/letters/letters-list/letter/letter.css @@ -0,0 +1,78 @@ +.check { + width: 16px; + height: 16px; + margin: 12px; + + border: 1px solid rgba(0, 0, 0, 0.15); + background-color: #ffffff; + border-radius: 3px; + float: left; +} + +.main-block__topic { + overflow: hidden; + width: 30%; + min-width: 30px; + height: 18px; + margin-top: 11px; + margin-left: 2%; + color: #000000; + float: left; + font-family: "'HelveticaNeue'", sans-serif; + font-size: 0.8em; +} + +.main-block__letter { + height: 40px; + + border-bottom: 2px solid #e2e2e2; + list-style: none; +} + +.main-block__img { + height: 30px; + margin-top: 5px; + margin-left: 2%; + float: left; + text-align: center; +} + +.main-block__mail-from { + overflow: hidden; + width: 29%; + height: 18px; + margin: 10px; + float: left; + font-family: "'HelveticaNeue'", sans-serif; + font-size: 0.8em; +} + +.main-block__mail-not-read { + width: 10px; + height: 10px; + margin-top: 15px; + margin-left: 10px; + background: #6287bd; + border-radius: 50%; + float: left; +} + +.hidden { + visibility: hidden; +} + +.bold-text { + font-weight: 700; +} + +.main-block__date { + overflow: hidden; + width: 6%; + height: 15px; + margin-top: 12px; + margin-right: 2%; + color: #9b9b9b; + float: right; + font-family: "'HelveticaNeue'", sans-serif; + font-size: 11px; +} diff --git a/src/app/structure/main-content/letters/letters-list/letter/letter.jsx b/src/app/structure/main-content/letters/letters-list/letter/letter.jsx new file mode 100644 index 0000000..4cfbc41 --- /dev/null +++ b/src/app/structure/main-content/letters/letters-list/letter/letter.jsx @@ -0,0 +1,53 @@ +import React, { Component } from 'react'; + +import './letter.css'; +import logo1 from './icons/ebay.png'; +import logo2 from './icons/yandex.png'; +import logo3 from './icons/live.png'; +import logo4 from './icons/facebook.png'; +import logo5 from './icons/twitter.png'; +import logo6 from './icons/reddit.png'; +import logo7 from './icons/youtube.png'; + +export class Letter extends Component { + constructor(props) { + super(props); + this.onCheckboxChange = this.props.onCheckboxChange.bind(this); + this.openLetter = this.props.openLetter.bind(this); + this.firms = { + ebay: logo1, + yandex: logo2, + live: logo3, + facebook: logo4, + twitter: logo5, + reddit: logo6, + youtube: logo7 + }; + } + + render() { + return ( +
  • +
    + this.onCheckboxChange(this.props.id)} + checked={this.props.isChecked} + /> +
    this.openLetter(this.props.text)}> +
    + {this.props.author} +
    + {this.props.author} +
    + {this.props.topic} + +
    +
    +
  • + ); + } +} diff --git a/src/app/structure/main-content/letters/letters-list/letterList.jsx b/src/app/structure/main-content/letters/letters-list/letterList.jsx new file mode 100644 index 0000000..8342e4e --- /dev/null +++ b/src/app/structure/main-content/letters/letters-list/letterList.jsx @@ -0,0 +1,29 @@ +import React, { Component } from 'react'; + +import './lettersList.css'; +import { Letter } from './letter/letter'; + +export class LetterList extends Component { + render() { + return ( + + ); + } +} diff --git a/src/app/structure/main-content/letters/letters-list/lettersList.css b/src/app/structure/main-content/letters/letters-list/lettersList.css new file mode 100644 index 0000000..fd91245 --- /dev/null +++ b/src/app/structure/main-content/letters/letters-list/lettersList.css @@ -0,0 +1,45 @@ +.main-block__all-letters { + overflow: scroll; + height: calc(100vh - 14px); + padding: 0; + margin: 0; +} + +.animation-insert { + animation: inserting 0.5s linear; +} + +.all-letter-down { + animation: down 0.6s linear; +} + +.animation-delete { + animation: deleting 0.6s linear; +} + +@keyframes inserting { + 0% { + transform: scale(0.5); + } + 100% { + transform: scale(1); + } +} + +@keyframes down { + 0% { + transform: translateY(-40px); + } + 100% { + opacity: 1; + } +} + +@keyframes deleting { + 0% { + transform: scale(1); + } + 100% { + transform: scale(0.5); + } +} diff --git a/src/app/structure/main-content/letters/letters.css b/src/app/structure/main-content/letters/letters.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/structure/main-content/letters/letters.jsx b/src/app/structure/main-content/letters/letters.jsx new file mode 100644 index 0000000..eb1002e --- /dev/null +++ b/src/app/structure/main-content/letters/letters.jsx @@ -0,0 +1,20 @@ +import React, { Component } from 'react'; + +import './letters.css'; +import { LetterPage } from './letter-page/letterPage'; +import { LetterList } from './letters-list/letterList'; + +export class Letters extends Component { + render() { + return this.props.isLetterOpened ? ( + + ) : ( + + ); + } +} diff --git a/src/app/structure/main-content/mainContent.css b/src/app/structure/main-content/mainContent.css new file mode 100644 index 0000000..909b74c --- /dev/null +++ b/src/app/structure/main-content/mainContent.css @@ -0,0 +1,14 @@ +.main-block { + position: relative; + + width: calc(100% - 230px); + min-width: 515px; + min-height: 300px; + padding: 0; + margin: 0 20px 14px 22px; + + background-color: #ffffff; + border-radius: 3px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.34); + float: right; +} diff --git a/src/app/structure/main-content/mainContent.jsx b/src/app/structure/main-content/mainContent.jsx new file mode 100644 index 0000000..8e68e7d --- /dev/null +++ b/src/app/structure/main-content/mainContent.jsx @@ -0,0 +1,134 @@ +import React, { Component } from 'react'; + +import './mainContent.css'; +import { Letters } from './letters/letters'; +import { AllFunctions } from './all-functions/allFunctions'; +import { generateNewLetter, randomInt } from './scripts/generator'; +import { Footer } from './footer/footer'; + +const LETTERS_ON_PAGE = 30; + +export class MainContent extends Component { + constructor(props) { + super(props); + this.state = { + isLetterOpened: false, + openedLetterText: null, + letters: [], + isAllChecked: false, + checkedLetters: {} + }; + + this.onCheckboxChange = this.onCheckboxChange.bind(this); + this.selectAll = this.selectAll.bind(this); + this.newMail = this.newMail.bind(this); + this.deleteLetter = this.deleteLetter.bind(this); + this.getRandomLetter = this.getRandomLetter.bind(this); + this.openLetter = this.openLetter.bind(this); + this.closeLetter = this.closeLetter.bind(this); + + setTimeout(this.getRandomLetter, 100); + } + + onCheckboxChange(id) { + this.setState(prevState => { + const newCheckedLetters = prevState.checkedLetters; + newCheckedLetters[id] = !newCheckedLetters[id]; + return { + isAllChecked: false, + checkedLetters: newCheckedLetters + }; + }); + } + + getRandomLetter() { + const t = randomInt(10, 300000) + 300000; + this.newMail(); + setTimeout(this.getRandomLetter, t); + } + + selectAll() { + this.setState(prevState => { + const newCheckedLetters = prevState.checkedLetters; + prevState.letters.forEach(letter => { + if (letter.isVisible) { + newCheckedLetters[letter.key] = !prevState.isAllChecked; + } + }); + return { + isAllChecked: !prevState.isAllChecked, + checkedLetters: newCheckedLetters + }; + }); + } + + newMail() { + const newLetter = generateNewLetter(); + this.setState(prevState => { + const newCheckedLetters = prevState.checkedLetters; + const newLetters = prevState.letters; + newCheckedLetters[newLetter.id] = false; + for (let i = newLetters.length - 1; i >= LETTERS_ON_PAGE - 1; i--) { + newLetters[i].isVisible = false; + newLetters[i].isChecked = false; + newCheckedLetters[newLetters[i].key] = false; + } + return { + letters: [newLetter, ...newLetters], + checkedLetters: newCheckedLetters, + isAllChecked: false + }; + }); + } + + deleteLetter() { + this.setState(prevState => { + const newLetters = prevState.letters.filter(letter => !prevState.checkedLetters[letter.key]); + for (let i = 0; i < Math.min(newLetters.length, LETTERS_ON_PAGE); i++) { + newLetters[i].isVisible = true; + } + return { + letters: newLetters, + isAllChecked: false + }; + }); + } + + openLetter(text) { + this.setState({ + isLetterOpened: true, + openedLetterText: text + }); + } + + closeLetter() { + this.setState({ + isLetterOpened: false, + openedLetterText: null + }); + } + + render() { + return ( +
    + + +
    +
    + ); + } +} diff --git a/src/app/structure/main-content/scripts/generator.js b/src/app/structure/main-content/scripts/generator.js new file mode 100644 index 0000000..a90f2bb --- /dev/null +++ b/src/app/structure/main-content/scripts/generator.js @@ -0,0 +1,119 @@ +const companies = ['ebay', 'facebook', 'live', 'yandex', 'live', 'reddit', 'twitter', 'youtube']; +const topics = [ + 'Внимание!', + 'Добро пожаловать!', + 'Обновление', + 'Получите приз!', + 'Восстановление аккаунта', + 'Ищем сотрудников', + 'Спасибо за отзыв' +]; +const hello = ['Здравствуйте!', 'Добрый день!', 'Привет!', 'Приветствую!', 'Салют!']; +const word1 = ['Я', 'Меня зовут', 'Это']; +const firstName = ['Виталий', 'Андрей', 'Владимир', 'Алексей', 'Артём', 'Антон']; +const secondName = [ + 'Соболев', + 'Чиркин', + 'Борисов', + 'Орехов', + 'Гаврилов', + 'Иванов', + 'Сергеев', + 'Онегин' +]; +const phrase1 = [ + 'Так вышло, что', + 'Нам стало известно, что', + 'Сообщаем вам, что', + 'Как вы могли заметить,', + 'С сегоднящнего дня' +]; +const nouns1 = ['эксперт', 'редактор', 'программист', 'рабочий']; +const verbs = [ + 'взломал', + 'проверил', + 'удалил', + 'исправил', + 'закрыл', + 'заметил', + 'пометил', + 'пересмотрел', + 'передал' +]; +const nouns2 = ['счет', 'аккаунт', 'пароль', 'кабинет']; +const adjectives = [ + 'идеальный', + 'прямой', + 'обратный', + 'наш', + 'постоянный', + 'великолепный', + 'исключительный', + 'личный', + 'ваш' +]; + +let counter = 0; + +export function randomInt(min, max) { + return Math.floor((max - min) * Math.random() + min); +} + +function randFromList(list) { + return list[randomInt(0, list.length)]; +} + +const randomDate = () => { + const m = randomInt(1, 12); + let day = randomInt(1, 30); + if (m === 2) day = Math.min(28, day); + const month = [ + 'янв', + 'фев', + 'мар', + 'апр', + 'май', + 'июн', + 'июл', + 'авг', + 'сен', + 'окт', + 'ноя', + 'дек' + ]; + return `${String(day)} ${String(month[m - 1])}`; +}; + +const generateText = sender => { + const textContent = [ + `${randFromList(hello)} ${randFromList(word1)} ${randFromList(firstName)} ${randFromList( + secondName + )}, глава компании ${sender.toUpperCase()}.` + ]; + textContent.push( + `${randFromList(phrase1)} ${randFromList(adjectives)} ${randFromList(nouns1)} ${randFromList( + verbs + )} ${randFromList(adjectives)} ${randFromList(nouns2)}.` + ); + return textContent; +}; + +export const generateNewLetter = () => { + counter++; + const id = counter; + const author = randFromList(companies); + const text = generateText(author); + const topic = randFromList(topics); + const date = randomDate(); + + return { + key: `id${id}`, + id: `id${id}`, + text, + author, + topic, + date, + isChecked: false, + isVisible: true + }; +}; diff --git a/src/app/structure/menu/menu.css b/src/app/structure/menu/menu.css new file mode 100644 index 0000000..bafed00 --- /dev/null +++ b/src/app/structure/menu/menu.css @@ -0,0 +1,53 @@ +.menu { + width: 147px; + max-width: 170px; + margin-left: 22px; + float: left; +} + +.menu__to-write { + width: 147px; + height: 32px; + + border: none; + background-color: #6287bd; + border-radius: 3px; + color: #ffffff; + font-family: "'HelveticaNeue'", sans-serif; + font-size: 12px; +} + +.menu__to-write:hover { + box-shadow: 2px 2px rgba(0, 0, 0, 0.6); +} + +.menu__bar { + padding: 0; +} + +.menu__action { + width: 147px; + height: 22px; + margin-top: 2px; + border-radius: 3px; + list-style: none; +} + +.menu__text-ref { + display: block; + padding-left: 10px; + color: #555555; + font-family: "'HelveticaNeue'", sans-serif; + font-size: 11px; + font-weight: 500; + line-height: 22px; + text-decoration: none; +} + +.menu__action:hover { + background-color: #cdd6e4; +} + +.menu__text-ref:hover { + font-weight: 700; +} diff --git a/src/app/structure/menu/menu.jsx b/src/app/structure/menu/menu.jsx new file mode 100644 index 0000000..7cc0737 --- /dev/null +++ b/src/app/structure/menu/menu.jsx @@ -0,0 +1,35 @@ +import React, { Component } from 'react'; + +import './menu.css'; + +const actions = [ + { title: 'Входящие', fragment: 'inbox' }, + { title: 'Отправленные', fragment: 'sent' }, + { title: 'Удалённые', fragment: 'deleted' }, + { title: 'Спам', fragment: 'spam' }, + { title: 'Черновики', fragment: 'drafts' }, + { title: 'Создать папку', fragment: 'createdir' } +]; + +export class Menu extends Component { + render() { + return ( +
    + + +
    + ); + } +}