<div class="wrapper"> <div id="inbox"></div> </div> <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.min.js"></script> @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,600); *, *:before, *:after { box-sizing: border-box; } body { /* background: #216476;; */ background: url(https://images.unsplash.com/photo-1476820865390-c52aeebb9891?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80); background-size: cover; background-repeat: no-repeat; font-family: "Open Sans", Arial, sans-serif; font-size: 16px; line-height: 150%; } .truncate { display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%; } .disclaimer { margin: 0 auto 50px; text-align: center; width: 400px; } .btn { border: none; cursor: pointer; display: block; font-family: "Open Sans", Arial, sans-serif; font-size: 16px; outline: none; padding: 15px; transition: all .1s linear; } .wrapper { box-shadow: 0 4px 20px rgba(51, 51, 51, 0.2); margin: 50px auto; overflow: auto; width: 1024px; } .wrapper .inbox-container { float: left; height: 500px; width: calc(100% - 200px); } #sidebar { background: #34393d; float: left; height: 500px; width: 200px; } #sidebar .sidebar__inboxes { padding-left: 0; margin-top: 10px; } #sidebar .sidebar__inboxes .item-count { background: #34393d; border-radius: 5px; float: right; padding: 2px 8px; margin: -2px -8px; } #sidebar .sidebar__inboxes li a { color: #fff; cursor: pointer; display: block; margin-bottom: 10px; padding: 15px; text-decoration: none; transition: background .1s linear; width: 100%; } #sidebar .sidebar__inboxes li a:hover { background: #404549; } #sidebar .sidebar__inboxes .fa { margin-right: 10px; } #sidebar .btn.compose { color: #fff; padding: 30px 15px; text-align: center; text-decoration: none; transition: all .1s linear; width: 100%; background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjEuMCIgeTE9IjEuMCIgeDI9IjAuMCIgeTI9IjAuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwOWZjNCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzBjN2VhZCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=='); background-size: 100%; background-image: -webkit-gradient(linear, 100% 100%, 0% 0%, color-stop(0%, #216476), color-stop(100%, #0c7ead)); background-image: -moz-linear-gradient(bottom right, #216476, #0c7ead); background-image: -webkit-linear-gradient(bottom right, #216476, #0c7ead); background-image: linear-gradient(to top left, #216476, #0c7ead); } #sidebar .btn.compose:hover { background-size: 150%; } #sidebar .btn.compose:hover .fa { -webkit-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } #sidebar .btn.compose .fa { margin-left: 10px; transition: all .1s linear; } .email-list { background: #f5f5f5; float: left; height: 500px; max-height: 100%; overflow-y: auto; width: 35%; } .email-list.empty { color: #aaa; padding-top: 200px; text-align: center; } .email-list .email-item { background: #fff; border-bottom: 1px solid #eee; cursor: pointer; padding: 10px 15px; position: relative; } .email-list .email-item.selected { background-color: aliceblue; color: #216476; } .email-list .email-item__subject { margin-bottom: 8px; } .email-list .email-item__details { font-size: 12px; opacity: .5; text-transform: uppercase; } .email-list .email-item__unread-dot { height: 100%; right: 10px; position: absolute; top: 10px; } .email-list .email-item__unread-dot[data-read="false"]:before { background: #216476; border-radius: 50%; content: ''; display: block; height: 6px; width: 6px; } .email-list .email-item__time { float: right; text-align: right; width: 40%; } .email-list .email-item__from.truncate { width: 60%; } .email-list .email-item:hover:not(.selected) { background: #fafafa; } .email-content { background: #fff; border-left: 1px solid #ddd; float: left; height: 500px; position: relative; width: 65%; } .email-content__header { background: #f5f5f5; border-bottom: 1px solid #eee; padding: 10px 15px; } .email-content__subject { font-size: 18px; margin: 10px 0; } .email-content__details { font-size: 12px; opacity: .5; text-transform: uppercase; } .email-content__time { color: #878787; float: right; } .email-content__from { color: #878787; } .email-content__message { padding: 20px 15px 15px; } .email-content .delete-btn { cursor: pointer; margin: -5px; padding: 5px; position: absolute; right: 20px; top: 24px; transition: color .1s linear; } .email-content .delete-btn:hover { color: #E23E57; } .footer { background: #f5f5f5; border-top: 1px solid #ddd; color: #999; clear: both; font-size: 14px; padding: 10px; text-align: center; width: 100%; } ul.sidebar__inboxes { list-style-type: none; } .fa { font-size: large; } var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; /* App */ class App extends React.Component { constructor(args) { super(args); // Assign unique IDs to the emails const emails = this.props.emails; let id = 0; for (const email of emails) { email.id = id++; } this.state = { selectedEmailId: 0, currentSection: 'inbox', emails }; } openEmail(id) { const emails = this.state.emails; const index = emails.findIndex(x => x.id === id); emails[index].read = 'true'; this.setState({ selectedEmailId: id, emails }); } deleteMessage(id) { // Mark the message as 'deleted' const emails = this.state.emails; const index = emails.findIndex(x => x.id === id); emails[index].tag = 'deleted'; // Select the next message in the list let selectedEmailId = ''; for (const email of emails) { if (email.tag === this.state.currentSection) { selectedEmailId = email.id; break; } } this.setState({ emails, selectedEmailId }); } setSidebarSection(section) { let selectedEmailId = this.state.selectedEmailId; if (section !== this.state.currentSection) { selectedEmailId = ''; } this.setState({ currentSection: section, selectedEmailId }); } render() { const currentEmail = this.state.emails.find(x => x.id === this.state.selectedEmailId); return /*#__PURE__*/( React.createElement("div", null, /*#__PURE__*/ React.createElement(Sidebar, { emails: this.props.emails, setSidebarSection: section => {this.setSidebarSection(section);} }), /*#__PURE__*/ React.createElement("div", { className: "inbox-container" }, /*#__PURE__*/ React.createElement(EmailList, { emails: this.state.emails.filter(x => x.tag === this.state.currentSection), onEmailSelected: id => {this.openEmail(id);}, selectedEmailId: this.state.selectedEmailId, currentSection: this.state.currentSection }), /*#__PURE__*/ React.createElement(EmailDetails, { email: currentEmail, onDelete: id => {this.deleteMessage(id);} })))); }} /* Sidebar */ const Sidebar = ({ emails, setSidebarSection }) => { var unreadCount = emails.reduce( function (previous, msg) { if (msg.read !== "true") { return previous + 1; } else { return previous; } }.bind(this), 0); var deletedCount = emails.reduce( function (previous, msg) { if (msg.tag === "deleted") { return previous + 1; } else { return previous; } }.bind(this), 0); return /*#__PURE__*/( React.createElement("div", { id: "sidebar" }, /*#__PURE__*/ React.createElement("div", { className: "sidebar__compose" }, /*#__PURE__*/ React.createElement("a", { href: "#", className: "btn compose" }, "Compose ", /*#__PURE__*/ React.createElement("span", { className: "fa fa-pencil" }))), /*#__PURE__*/ React.createElement("ul", { className: "sidebar__inboxes" }, /*#__PURE__*/ React.createElement("li", { onClick: () => {setSidebarSection('inbox');} }, /*#__PURE__*/React.createElement("a", null, /*#__PURE__*/ React.createElement("span", { className: "fa fa-inbox" }), " Inbox", /*#__PURE__*/ React.createElement("span", { className: "item-count" }, unreadCount))), /*#__PURE__*/ React.createElement("li", { onClick: () => {setSidebarSection('sent');} }, /*#__PURE__*/React.createElement("a", null, /*#__PURE__*/ React.createElement("span", { className: "fa fa-paper-plane" }), " Sent", /*#__PURE__*/ React.createElement("span", { className: "item-count" }, "0"))), /*#__PURE__*/ React.createElement("li", { onClick: () => {setSidebarSection('drafts');} }, /*#__PURE__*/React.createElement("a", null, /*#__PURE__*/ React.createElement("span", { className: "fa fa-pencil-square-o" }), " Drafts", /*#__PURE__*/ React.createElement("span", { className: "item-count" }, "0"))), /*#__PURE__*/ React.createElement("li", { onClick: () => {setSidebarSection('deleted');} }, /*#__PURE__*/React.createElement("a", null, /*#__PURE__*/ React.createElement("span", { className: "fa fa-trash-o" }), " Trash", /*#__PURE__*/ React.createElement("span", { className: "item-count" }, deletedCount)))))); }; /* Email classes */ const EmailListItem = ({ email, onEmailClicked, selected }) => { let classes = "email-item"; if (selected) { classes += " selected"; } return /*#__PURE__*/( React.createElement("div", { onClick: () => {onEmailClicked(email.id);}, className: classes }, /*#__PURE__*/ React.createElement("div", { className: "email-item__unread-dot", "data-read": email.read }), /*#__PURE__*/ React.createElement("div", { className: "email-item__subject truncate" }, email.subject), /*#__PURE__*/ React.createElement("div", { className: "email-item__details" }, /*#__PURE__*/ React.createElement("span", { className: "email-item__from truncate" }, email.from), /*#__PURE__*/ React.createElement("span", { className: "email-item__time truncate" }, getPrettyDate(email.time))))); }; const EmailDetails = ({ email, onDelete }) => { if (!email) { return /*#__PURE__*/( React.createElement("div", { className: "email-content empty" })); } const date = `${getPrettyDate(email.time)} · ${getPrettyTime(email.time)}`; const getDeleteButton = () => { if (email.tag !== 'deleted') { return /*#__PURE__*/React.createElement("span", { onClick: () => {onDelete(email.id);}, className: "delete-btn fa fa-trash-o" }); } return undefined; }; return /*#__PURE__*/( React.createElement("div", { className: "email-content" }, /*#__PURE__*/ React.createElement("div", { className: "email-content__header" }, /*#__PURE__*/ React.createElement("h3", { className: "email-content__subject" }, email.subject), getDeleteButton(), /*#__PURE__*/ React.createElement("div", { className: "email-content__time" }, date), /*#__PURE__*/ React.createElement("div", { className: "email-content__from" }, email.from)), /*#__PURE__*/ React.createElement("div", { className: "email-content__message" }, email.message))); }; /* EmailList contains a list of Email components */ const EmailList = ({ emails, onEmailSelected, selectedEmailId }) => { if (emails.length === 0) { return /*#__PURE__*/( React.createElement("div", { className: "email-list empty" }, "Nothing to see here, great job!")); } return /*#__PURE__*/( React.createElement("div", { className: "email-list" }, emails.map(email => { return /*#__PURE__*/( React.createElement(EmailListItem, { onEmailClicked: id => {onEmailSelected(id);}, email: email, selected: selectedEmailId === email.id })); }))); }; // Render $.ajax({ url: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/311743/dummy-emails.json', type: 'GET', success: function (result) { React.render( /*#__PURE__*/React.createElement(App, { emails: result }), document.getElementById('inbox')); } }); // Helper methods const getPrettyDate = date => { date = date.split(' ')[0]; const newDate = date.split('-'); const month = months[0]; return `${month} ${newDate[2]}, ${newDate[0]}`; }; // Remove the seconds from the time const getPrettyTime = date => { const time = date.split(' ')[1].split(':'); return `${time[0]}:${time[1]}`; }; Навигация по записям React | Multi Tab Component on class