diff --git a/public/index.html b/public/index.html index 9a8ef8f..4f4d4b1 100644 --- a/public/index.html +++ b/public/index.html @@ -2,16 +2,15 @@ - + - React App + Яндекс.Почта -
diff --git a/public/ya-mail-favicon.png b/public/ya-mail-favicon.png new file mode 100644 index 0000000..555ec0b Binary files /dev/null and b/public/ya-mail-favicon.png differ diff --git a/src/app/app.css b/src/app/app.css index 1c4d511..6638e73 100644 --- a/src/app/app.css +++ b/src/app/app.css @@ -1,27 +1,98 @@ -.app { - text-align: center; +@font-face { + font-family: YandexSansBold; + font-weight: 700; + 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("../fonts/YandexSansDisplay-Thin.ttf"); } -.app-link { - color: #61dafb; +@font-face { + font-family: HelveticaNeueLight; + src: url("../fonts/HelveticaNeueCyr-Light.otf"); } -@keyframes app-logo-spin { - from { - transform: rotate(0deg); +@font-face { + font-family: HelveticaNeue; + src: url("../fonts/HelveticaNeueCyr-Medium.otf"); +} + +.page { + position: relative; + min-width: 800px; + padding-right: 20px; + min-height: 100%; +} + +ul{ + list-style-type: none; +} + +a, a:active, a:visited, a:hover { + color: unset; + text-decoration: none; + position: unset !important; +} + +.page_inline{ + display: inline; + text-decoration-color: red; +} + +.page_text-overflow_hide{ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.page_visibility_hide{ + visibility: hidden; +} + +.page_checkbox{ + width: 16px; + height: 16px; +} + +.create_animation{ + animation: add 1s forwards; +} + +.delete_animation{ + animation: remove 1s forwards; +} + +@keyframes add{ + 0%{ + height: 0; + opacity: 0; + } + + 50%{ + height: 500px; + opacity: 0.5; } - to { - transform: rotate(360deg); + + 100%{ + opacity: 1; + } +} + +@keyframes remove{ + 0%{ + height: 22px; + opacity: 1; + } + + 50%{ + height: 500px; + opacity: 0.5; + } + + 100%{ + height: 0px; + opacity: 0; } } diff --git a/src/app/app.jsx b/src/app/app.jsx index f759eed..0d1703d 100644 --- a/src/app/app.jsx +++ b/src/app/app.jsx @@ -2,23 +2,158 @@ import React, { Component } from 'react'; import './app.css'; +import { Header } from './header/header'; +import { YaSideBar } from './ya-sidebar/ya-sidebar'; +import { YaMail } from './ya-mail/ya-mail'; + export class App extends Component { + constructor(props) { + super(props); + this.createMessage = this.createMessage.bind(this); + this.buildMessage = this.buildMessage.bind(this); + this.deleteSelected = this.deleteSelected.bind(this); + this.selectCheckBox = this.selectCheckBox.bind(this); + this.selectAll = this.selectAll.bind(this); + this.newMailTime = this.newMailTime.bind(this); + this.setNextRand = this.setNextRand.bind(this); + + this.authors = ['Антон', 'Саша', 'Алексей']; + this.subject = ['Путешествие', 'Стажировка', 'Виза']; + this.text = [ + 'Когда планируема дата вашего приезда ?', + 'Где вы собираетесь оставаться ?', + 'Ты опоздал с дедлайном' + ]; + this.dates = ['1 янв', '2 фев', '3 март', '4 апр', '5 авг']; + + this.minTime = 10; + this.maxTime = 1000 * 60 * 10 - this.minTime; + + this.state = { + messageList: [], + allSelected: false + }; + } + + componentDidMount() { + this.newMailTime(); + } + + newMailTime() { + this.createMessage(); + this.setNextRand(); + } + + setNextRand() { + setTimeout(this.newMailTime, Math.random() * this.maxTime + this.minTime); + } + + buildMessage() { + const id = new Date().getTime(); + const messageText = this.text[Math.floor(Math.random() * this.text.length)]; + const messageAuthor = this.authors[Math.floor(Math.random() * this.authors.length)]; + const messageSubject = this.subject[Math.floor(Math.random() * this.subject.length)]; + const messageDate = this.dates[Math.floor(Math.random() * this.dates.length)]; + return { + id, + messageAuthor, + messageSubject, + messageDate, + messageText, + selected: false, + addAnimation: true, + deleteAnimation: false + }; + } + + createMessage() { + this.setState(prevState => { + const newMessageList = prevState.messageList; + if (prevState.messageList.length >= 30) { + return { + messageList: newMessageList + }; + } + const newMessage = this.buildMessage(); + const curId = newMessage.id; + setTimeout(() => { + this.setState(prevSt => { + return prevSt.messageList.map(message => { + if (message.id === curId) { + const updMessage = message; + updMessage.addAnimation = false; + return updMessage; + } + return message; + }); + }); + }, 1500); + newMessageList.unshift(newMessage); + return { + messageList: newMessageList + }; + }); + } + + deleteSelected() { + this.setState(prevState => { + return { + messageList: prevState.messageList.map(message => { + if (message.selected) { + const updMessage = message; + updMessage.deleteAnimation = true; + return updMessage; + } + return message; + }), + allSelected: false + }; + }); + setTimeout(() => { + this.setState(prevState => { + return { + messageList: prevState.messageList.filter(message => !message.selected) + }; + }); + }, 1500); + } + + selectAll() { + this.setState(prevState => { + const newMessageList = prevState.messageList; + for (let i = 0; i < newMessageList.length; i++) { + newMessageList[i].selected = !newMessageList[i].selected; + } + + return { + messageList: newMessageList, + allSelected: !prevState.allSelected + }; + }); + } + + selectCheckBox(messageIndex) { + this.setState(prevState => { + const newMessageList = prevState.messageList; + newMessageList[messageIndex].selected = !newMessageList[messageIndex].selected; + return { + messagesList: newMessageList + }; + }); + } + render() { return ( -
-
-

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

- - Learn React - -
+
+
+ +
); } diff --git a/src/app/header/header.css b/src/app/header/header.css new file mode 100644 index 0000000..9ea0534 --- /dev/null +++ b/src/app/header/header.css @@ -0,0 +1,8 @@ +.page__header { + display: inline-block; + width: 100%; + height: 31px; + position: relative; + margin-top: 13px; + margin-bottom: 13px; +} diff --git a/src/app/header/header.jsx b/src/app/header/header.jsx new file mode 100644 index 0000000..75f58d5 --- /dev/null +++ b/src/app/header/header.jsx @@ -0,0 +1,21 @@ +import React, { Component } from 'react'; + +import './header.css'; + +import Menu from './menu/menu'; +import YaMailLogo from './ya-mail-logo/ya-mail-logo'; +import SearchBar from './search-bar/search-bar'; +import MessageCreator from './message-creator/message-creator'; + +export class Header extends Component { + render() { + return ( +
+ + + + +
+ ); + } +} diff --git a/src/app/header/menu/menu.css b/src/app/header/menu/menu.css new file mode 100644 index 0000000..3d32103 --- /dev/null +++ b/src/app/header/menu/menu.css @@ -0,0 +1,9 @@ +.page__ya-menu-logo{ + margin-left: 22px; +} + +.page__sidebar-menu{ + position: relative; + vertical-align: bottom; + bottom: 3px; +} diff --git a/src/app/header/menu/menu.jsx b/src/app/header/menu/menu.jsx new file mode 100644 index 0000000..0d45afc --- /dev/null +++ b/src/app/header/menu/menu.jsx @@ -0,0 +1,17 @@ +import React from 'react'; + +import './menu.css'; + +import SidebarMenu from '../../../images/sidebar-menu.png'; + +function Menu() { + return ( +
+ + menu + +
+ ); +} + +export default Menu; diff --git a/src/app/header/message-creator/message-creator.css b/src/app/header/message-creator/message-creator.css new file mode 100644 index 0000000..50e6d31 --- /dev/null +++ b/src/app/header/message-creator/message-creator.css @@ -0,0 +1,7 @@ +.page__message-creator { + display: inline-block; + position: relative; + left: 18%; + opacity: 0.5; + cursor: pointer; +} diff --git a/src/app/header/message-creator/message-creator.jsx b/src/app/header/message-creator/message-creator.jsx new file mode 100644 index 0000000..efa4c75 --- /dev/null +++ b/src/app/header/message-creator/message-creator.jsx @@ -0,0 +1,15 @@ +import React from 'react'; + +import './message-creator.css'; + +class MessageCreator extends React.Component { + render() { + return ( + + ); + } +} + +export default MessageCreator; diff --git a/src/app/header/search-bar/search-bar.css b/src/app/header/search-bar/search-bar.css new file mode 100644 index 0000000..29bc76c --- /dev/null +++ b/src/app/header/search-bar/search-bar.css @@ -0,0 +1,18 @@ +.page__ya-search{ + display: inline-block; + position: relative; + min-width: 301px; + width: 38%; + height: 32px; + left: 18%; + opacity: 0.5; + padding-left: 16px; + font-family: YandexSanThin, sans-serif; + font-size: 15px; + font-weight: normal; + font-style: normal; + font-stretch: normal; + letter-spacing: normal; + line-height: 2.13; + color: #000000; +} diff --git a/src/app/header/search-bar/search-bar.jsx b/src/app/header/search-bar/search-bar.jsx new file mode 100644 index 0000000..7758caf --- /dev/null +++ b/src/app/header/search-bar/search-bar.jsx @@ -0,0 +1,9 @@ +import React from 'react'; + +import './search-bar.css'; + +function SearchBar() { + return ; +} + +export default SearchBar; diff --git a/src/app/header/ya-mail-logo/ya-mail-logo.css b/src/app/header/ya-mail-logo/ya-mail-logo.css new file mode 100644 index 0000000..c19dee4 --- /dev/null +++ b/src/app/header/ya-mail-logo/ya-mail-logo.css @@ -0,0 +1,5 @@ +.page__ya-mail-logo{ + display: inline-block; + position: relative; + vertical-align: bottom; +} diff --git a/src/app/header/ya-mail-logo/ya-mail-logo.jsx b/src/app/header/ya-mail-logo/ya-mail-logo.jsx new file mode 100644 index 0000000..de22360 --- /dev/null +++ b/src/app/header/ya-mail-logo/ya-mail-logo.jsx @@ -0,0 +1,15 @@ +import React from 'react'; + +import './ya-mail-logo.css'; + +import MailLogo from '../../../images/ya-mail-logo.png'; + +function YaMailLogo() { + return ( + + + + ); +} + +export default YaMailLogo; diff --git a/src/app/ya-mail/content-messages/content-messages.css b/src/app/ya-mail/content-messages/content-messages.css new file mode 100644 index 0000000..c79897b --- /dev/null +++ b/src/app/ya-mail/content-messages/content-messages.css @@ -0,0 +1,16 @@ +.ya-mail__content-messages{ + width: 100%; + min-height: 456px; + height: fit-content; + border-top: solid 1px #e2e2e2; + border-bottom: solid 1px #e2e2e2; +} + +.content-messages__message-list{ + margin: 0; + padding: 0; +} + +#message-select1{ + display: none; +} diff --git a/src/app/ya-mail/content-messages/content-messages.jsx b/src/app/ya-mail/content-messages/content-messages.jsx new file mode 100644 index 0000000..23a35ac --- /dev/null +++ b/src/app/ya-mail/content-messages/content-messages.jsx @@ -0,0 +1,61 @@ +import React, { Component } from 'react'; + +import './content-messages.css'; + +import { MessageText } from './message-text/message-text'; +import { Message } from './message/message'; + +export class ContentMessages extends Component { + constructor(props) { + super(props); + this.openMessage = this.openMessage.bind(this); + this.closeMessage = this.closeMessage.bind(this); + + this.state = { + openedMessageText: this.props.openedMessageText, + messageIsOpen: false + }; + } + + closeMessage() { + this.setState({ + messageIsOpen: false + }); + } + + openMessage(message) { + this.setState({ + messageIsOpen: true, + openedMessageText: message.messageText + }); + } + + render() { + const hidenClass = this.state.messageIsOpen ? ' page_visibility_hide' : ''; + return ( +
+
+ + +
+ +
+ ); + } +} diff --git a/src/app/ya-mail/content-messages/message-text/message-text.css b/src/app/ya-mail/content-messages/message-text/message-text.css new file mode 100644 index 0000000..c29c071 --- /dev/null +++ b/src/app/ya-mail/content-messages/message-text/message-text.css @@ -0,0 +1,43 @@ +.content-messages__message-text{ + box-sizing: border-box; + width: 100%; + min-height: 455px; + position: absolute; + top: 0; + background-color: white; + font-family: sans-serif; + font-size: 14px; + padding: 20px 0 20px 20px; + display: none; + font-weight: 300; + z-index: 1; +} + +.message-text__round{ + position: relative; + float: right; + border-radius: 50%; + shape-outside:circle(); +} + +.message-text__exit { + position: absolute; + top: 0; + right: 0; + margin: 10px; + width: 15px; + height: 15px; + font-family: HelveticaNeueLight, sans-serif; + font-weight: 100; + text-align: center; + line-height: 15px; + vertical-align: middle; +} + +.message-text__exit:hover { + background-color: #cdd6e4; +} + +#message-select1:checked + .content-messages__message-text{ + display: block; +} diff --git a/src/app/ya-mail/content-messages/message-text/message-text.jsx b/src/app/ya-mail/content-messages/message-text/message-text.jsx new file mode 100644 index 0000000..fbb51b8 --- /dev/null +++ b/src/app/ya-mail/content-messages/message-text/message-text.jsx @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; + +import './message-text.css'; + +import Round from '../../../../images/round.png'; + +export class MessageText extends Component { + render() { + return ( +
+ + round +
{this.props.openedMessageText}
+
+ ) + } +} diff --git a/src/app/ya-mail/content-messages/message/message.css b/src/app/ya-mail/content-messages/message/message.css new file mode 100644 index 0000000..421d793 --- /dev/null +++ b/src/app/ya-mail/content-messages/message/message.css @@ -0,0 +1,69 @@ +.content-messages__message{ + position: relative; + height: 37px; + line-height: 37px; + font: 13px HelveticaNeue; + color: #000000; + border-bottom: solid 1px #e2e2e2; + vertical-align: middle; +} + +.content-messages__message:hover{ + background-color: #cdd6e4; +} + +.message_unread{ + font-weight: bold; +} + +.message__message-select{ + margin: 0; + margin-left: 20px; +} + +.message-open{ + position: unset; +} + +.message__elem{ + display: inline-block; + height: 37px; + line-height: 37px; + vertical-align: middle; +} + +.message__author-avatar{ + width: 30px; + height: 30px; + margin-left: 10px; + margin-right: 10px; + border-radius: 15px; +} + +.message__author-name{ + width: 150px; +} + +.message__mark-as-read-tick{ + width: 10px; + height: 10px; + margin-left: 69px; + margin-right: 15px; + background-color: #6287bd; + border-radius: 10px; +} + +.message__message-subject{ + width: 75%; +} + +.message__message-receive-time{ + position: relative; + margin-right: 20px; + float: right; + width: fit-content; + max-width: 60px; + text-align: right; + color: #9b9b9b; + font-weight: normal; +} diff --git a/src/app/ya-mail/content-messages/message/message.jsx b/src/app/ya-mail/content-messages/message/message.jsx new file mode 100644 index 0000000..06506df --- /dev/null +++ b/src/app/ya-mail/content-messages/message/message.jsx @@ -0,0 +1,47 @@ +import React, { Component } from 'react'; + +import './message.css'; + +import MessageLogo from '../../../../images/ya-message-logo.svg'; + +export class Message extends Component { + render() { + const addAnimation = this.props.message.addAnimation ? ' create_animation' : ''; + const deleteAnimation = this.props.message.deleteAnimation ? ' delete_animation' : ''; + return ( +
  • + this.props.selectCheckBox(this.props.messageIndex)} + /> +
  • + ); + } +} diff --git a/src/app/ya-mail/content-top-bar/content-top-bar.css b/src/app/ya-mail/content-top-bar/content-top-bar.css new file mode 100644 index 0000000..2229896 --- /dev/null +++ b/src/app/ya-mail/content-top-bar/content-top-bar.css @@ -0,0 +1,39 @@ +.ya-mail__content-top-bar{ + position: relative; + padding: 0; + width: 100%; + height: 37px; + line-height: 37px; + font-family: HelveticaNeue, sans-serif; + font-size: 13px; + font-weight: 500; + vertical-align: middle; + color: #cccccc; +} + +.content-top-bar__top-content-list{ + cursor: pointer; + padding: 0; + width: 100%; + height: 100%; + margin: auto; +} + +.ya-mail__select-all{ + display: inline-block; + height: 100%; + width: 30px; +} + +.ya-mail__select-all-check{ + margin: 0; + height: 100%; +} + +.content-top-bar__action{ + position: relative; + display: inline-block; + width: fit-content; + max-width: 85px; + padding-left: 20px; +} diff --git a/src/app/ya-mail/content-top-bar/content-top-bar.jsx b/src/app/ya-mail/content-top-bar/content-top-bar.jsx new file mode 100644 index 0000000..a0d0da2 --- /dev/null +++ b/src/app/ya-mail/content-top-bar/content-top-bar.jsx @@ -0,0 +1,36 @@ +import React, { Component } from 'react'; + +import './content-top-bar.css'; + +export class ContentTopBar extends Component { + render() { + return ( +
    + +
    + ); + } +} diff --git a/src/app/ya-mail/footer-content/footer-content.css b/src/app/ya-mail/footer-content/footer-content.css new file mode 100644 index 0000000..4ff1ec7 --- /dev/null +++ b/src/app/ya-mail/footer-content/footer-content.css @@ -0,0 +1,21 @@ +.page__footer-content{ + position: relative; + width: 100%; + height: 30px; +} + +footer{ + text-align: right; + font-size: 11px; + font-family: HelveticaNeueLight; + color: #9b9b9b; +} + +.footer-content__copyright, .footer-content__link{ + display: inline-block; + vertical-align: middle; + max-width: 150px; + width: fit-content; + margin-right: 20px; + line-height: 30px; +} diff --git a/src/app/ya-mail/footer-content/footer-content.jsx b/src/app/ya-mail/footer-content/footer-content.jsx new file mode 100644 index 0000000..9233ab3 --- /dev/null +++ b/src/app/ya-mail/footer-content/footer-content.jsx @@ -0,0 +1,25 @@ +import React, { Component } from 'react'; + +import './footer-content.css'; + +export class FooterContent extends Component { + render() { + return ( +
    + +
    + ); + } +} diff --git a/src/app/ya-mail/ya-mail.css b/src/app/ya-mail/ya-mail.css new file mode 100644 index 0000000..4a30fff --- /dev/null +++ b/src/app/ya-mail/ya-mail.css @@ -0,0 +1,9 @@ +.page__ya-mail{ + position: relative; + overflow: hidden; + min-width: 589; + min-height: 530px; + background-color: #ffffff; + border-radius: 3px; + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.34); +} diff --git a/src/app/ya-mail/ya-mail.jsx b/src/app/ya-mail/ya-mail.jsx new file mode 100644 index 0000000..89894d3 --- /dev/null +++ b/src/app/ya-mail/ya-mail.jsx @@ -0,0 +1,26 @@ +import React, { Component } from 'react'; + +import './ya-mail.css'; + +import { ContentTopBar } from './content-top-bar/content-top-bar'; +import { FooterContent } from './footer-content/footer-content'; +import { ContentMessages } from './content-messages/content-messages'; + +export class YaMail extends Component { + render() { + return ( +
    + + + +
    + ); + } +} diff --git a/src/app/ya-sidebar/ya-sidebar.css b/src/app/ya-sidebar/ya-sidebar.css new file mode 100644 index 0000000..52c2cf3 --- /dev/null +++ b/src/app/ya-sidebar/ya-sidebar.css @@ -0,0 +1,45 @@ +.page__ya-sidebar{ + position: relative; + float: left; + width: 200px; + vertical-align: top; + font-family: HelveticaNeue, sans-serif; + font-size: 11px; + font-weight: 500px; + color: #707070; +} + +.ya-sidebar__nav-sidebar{ + margin-left: 22px; + margin-top: 0px; + padding: 0px; +} + +.ya-sidebar__action{ + width: 137px; + height: 22px; + margin-left: 0px; + padding-left: 10px; + text-align: left; + vertical-align: middle; + line-height: 22px; +} + +.ya-sidebar__action:hover{ + background-color: #cdd6e4; +} + +.ya-sidebar__compose-message{ + width: 147px; + height: 32px; + background-color: #6287bd; + border-radius: 3px; + margin-bottom: 8px; + font-family: HelveticaNeue, sans-serif; + font-size: 12px; + font-weight: 500; + color: #ffffff; + text-align: center; + vertical-align: middle; + line-height: 32px; +} diff --git a/src/app/ya-sidebar/ya-sidebar.jsx b/src/app/ya-sidebar/ya-sidebar.jsx new file mode 100644 index 0000000..0ad7262 --- /dev/null +++ b/src/app/ya-sidebar/ya-sidebar.jsx @@ -0,0 +1,35 @@ +import React, { Component } from 'react'; + +import './ya-sidebar.css'; + +export class YaSideBar extends Component { + render() { + return ( +
    + +
    + ); + } +} diff --git a/src/fonts/HelveticaNeueCyr-Light.otf b/src/fonts/HelveticaNeueCyr-Light.otf new file mode 100644 index 0000000..7ced49a Binary files /dev/null and b/src/fonts/HelveticaNeueCyr-Light.otf differ diff --git a/src/fonts/HelveticaNeueCyr-Medium.otf b/src/fonts/HelveticaNeueCyr-Medium.otf new file mode 100644 index 0000000..a2cde16 Binary files /dev/null and b/src/fonts/HelveticaNeueCyr-Medium.otf differ diff --git a/src/fonts/YandexSansDisplay-Bold.ttf b/src/fonts/YandexSansDisplay-Bold.ttf new file mode 100644 index 0000000..d901f4b Binary files /dev/null and b/src/fonts/YandexSansDisplay-Bold.ttf differ diff --git a/src/fonts/YandexSansDisplay-Thin.ttf b/src/fonts/YandexSansDisplay-Thin.ttf new file mode 100644 index 0000000..3b8e196 Binary files /dev/null and b/src/fonts/YandexSansDisplay-Thin.ttf differ diff --git a/src/images/round.png b/src/images/round.png new file mode 100644 index 0000000..e6d9d23 Binary files /dev/null and b/src/images/round.png differ diff --git a/src/images/sidebar-menu.png b/src/images/sidebar-menu.png new file mode 100644 index 0000000..b5abb28 Binary files /dev/null and b/src/images/sidebar-menu.png differ diff --git a/src/images/ya-mail-logo.png b/src/images/ya-mail-logo.png new file mode 100644 index 0000000..fcb4c91 Binary files /dev/null and b/src/images/ya-mail-logo.png differ diff --git a/src/images/ya-message-logo.svg b/src/images/ya-message-logo.svg new file mode 100644 index 0000000..04faa81 --- /dev/null +++ b/src/images/ya-message-logo.svg @@ -0,0 +1,15 @@ + + + + ya-default + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/src/index.css b/src/index.css index 2b6e525..e397124 100644 --- a/src/index.css +++ b/src/index.css @@ -1,6 +1,9 @@ +html, body { + height: 100%; padding: 0; margin: 0; + background-color: #e5eaf0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased;