<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/deammer/pen/NxmEbe?depth=everything&order=popularity&page=2&q=react&show_forks=false" />
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css'><link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css'>
<style class="cp-pen-styles">@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,600);
*, *:before, *:after {
box-sizing: border-box;
}
body {
background: #eee;
font-family: "Open Sans", Arial, sans-serif;
font-size: 14px;
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 {
margin-top: 50px;
}
#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%, #009fc4), color-stop(100%, #0c7ead));
background-image: -moz-linear-gradient(bottom right, #009fc4, #0c7ead);
background-image: -webkit-linear-gradient(bottom right, #009fc4, #0c7ead);
background-image: linear-gradient(to top left, #009fc4, #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 {
color: #009fc4;
}
.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: #009fc4;
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%;
}
</style></head><body>
<div class="wrapper">
<div id="inbox"></div>
<div class="footer">Built with React and powered by ES6.</div>
</div>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='//cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.min.js'></script><script src='https://code.jquery.com/jquery-2.2.4.min.js'></script>
<script >'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
/* App */
var App = function (_React$Component) {
_inherits(App, _React$Component);
function App(args) {
_classCallCheck(this, App);
// Assign unique IDs to the emails
var _this = _possibleConstructorReturn(this, _React$Component.call(this, args));
var emails = _this.props.emails;
var id = 0;
for (var _iterator = emails, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {if (window.CP.shouldStopExecution(1)){break;}
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
var email = _ref;
email.id = id++;
}
window.CP.exitedLoop(1);
_this.state = {
selectedEmailId: 0,
currentSection: 'inbox',
emails: emails
};
return _this;
}
App.prototype.openEmail = function openEmail(id) {
var emails = this.state.emails;
var index = emails.findIndex(function (x) {
return x.id === id;
});
emails[index].read = 'true';
this.setState({
selectedEmailId: id,
emails: emails
});
};
App.prototype.deleteMessage = function deleteMessage(id) {
// Mark the message as 'deleted'
var emails = this.state.emails;
var index = emails.findIndex(function (x) {
return x.id === id;
});
emails[index].tag = 'deleted';
// Select the next message in the list
var selectedEmailId = '';
for (var _iterator2 = emails, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {if (window.CP.shouldStopExecution(2)){break;}
var _ref2;
if (_isArray2) {
if (_i2 >= _iterator2.length) break;
_ref2 = _iterator2[_i2++];
} else {
_i2 = _iterator2.next();
if (_i2.done) break;
_ref2 = _i2.value;
}
var email = _ref2;
if (email.tag === this.state.currentSection) {
selectedEmailId = email.id;
break;
}
}
window.CP.exitedLoop(2);
this.setState({
emails: emails,
selectedEmailId: selectedEmailId
});
};
App.prototype.setSidebarSection = function setSidebarSection(section) {
var selectedEmailId = this.state.selectedEmailId;
if (section !== this.state.currentSection) {
selectedEmailId = '';
}
this.setState({
currentSection: section,
selectedEmailId: selectedEmailId
});
};
App.prototype.render = function render() {
var _this2 = this;
var currentEmail = this.state.emails.find(function (x) {
return x.id === _this2.state.selectedEmailId;
});
return React.createElement(
'div',
null,
React.createElement(Sidebar, {
emails: this.props.emails,
setSidebarSection: function setSidebarSection(section) {
_this2.setSidebarSection(section);
} }),
React.createElement(
'div',
{ className: 'inbox-container' },
React.createElement(EmailList, {
emails: this.state.emails.filter(function (x) {
return x.tag === _this2.state.currentSection;
}),
onEmailSelected: function onEmailSelected(id) {
_this2.openEmail(id);
},
selectedEmailId: this.state.selectedEmailId,
currentSection: this.state.currentSection }),
React.createElement(EmailDetails, {
email: currentEmail,
onDelete: function onDelete(id) {
_this2.deleteMessage(id);
} })
)
);
};
return App;
}(React.Component);
/* Sidebar */
var Sidebar = function Sidebar(_ref3) {
var emails = _ref3.emails;
var setSidebarSection = _ref3.setSidebarSection;
var unreadCount = emails.reduce(function (previous, msg) {
if (msg.read !== "true") {
return previous + 1;
} else {
return previous;
}
}.bind(undefined), 0);
var deletedCount = emails.reduce(function (previous, msg) {
if (msg.tag === "deleted") {
return previous + 1;
} else {
return previous;
}
}.bind(undefined), 0);
return React.createElement(
'div',
{ id: 'sidebar' },
React.createElement(
'div',
{ className: 'sidebar__compose' },
React.createElement(
'a',
{ href: '#', className: 'btn compose' },
'Compose ',
React.createElement('span', { className: 'fa fa-pencil' })
)
),
React.createElement(
'ul',
{ className: 'sidebar__inboxes' },
React.createElement(
'li',
{ onClick: function onClick() {
setSidebarSection('inbox');
} },
React.createElement(
'a',
null,
React.createElement('span', { className: 'fa fa-inbox' }),
' Inbox',
React.createElement(
'span',
{ className: 'item-count' },
unreadCount
)
)
),
React.createElement(
'li',
{ onClick: function onClick() {
setSidebarSection('sent');
} },
React.createElement(
'a',
null,
React.createElement('span', { className: 'fa fa-paper-plane' }),
' Sent',
React.createElement(
'span',
{ className: 'item-count' },
'0'
)
)
),
React.createElement(
'li',
{ onClick: function onClick() {
setSidebarSection('drafts');
} },
React.createElement(
'a',
null,
React.createElement('span', { className: 'fa fa-pencil-square-o' }),
' Drafts',
React.createElement(
'span',
{ className: 'item-count' },
'0'
)
)
),
React.createElement(
'li',
{ onClick: function onClick() {
setSidebarSection('deleted');
} },
React.createElement(
'a',
null,
React.createElement('span', { className: 'fa fa-trash-o' }),
' Trash',
React.createElement(
'span',
{ className: 'item-count' },
deletedCount
)
)
)
)
);
};
/* Email classes */
var EmailListItem = function EmailListItem(_ref4) {
var email = _ref4.email;
var onEmailClicked = _ref4.onEmailClicked;
var selected = _ref4.selected;
var classes = "email-item";
if (selected) {
classes += " selected";
}
return React.createElement(
'div',
{ onClick: function onClick() {
onEmailClicked(email.id);
}, className: classes },
React.createElement('div', { className: 'email-item__unread-dot', 'data-read': email.read }),
React.createElement(
'div',
{ className: 'email-item__subject truncate' },
email.subject
),
React.createElement(
'div',
{ className: 'email-item__details' },
React.createElement(
'span',
{ className: 'email-item__from truncate' },
email.from
),
React.createElement(
'span',
{ className: 'email-item__time truncate' },
getPrettyDate(email.time)
)
)
);
};
var EmailDetails = function EmailDetails(_ref5) {
var email = _ref5.email;
var onDelete = _ref5.onDelete;
if (!email) {
return React.createElement('div', { className: 'email-content empty' });
}
var date = getPrettyDate(email.time) + ' · ' + getPrettyTime(email.time);
var getDeleteButton = function getDeleteButton() {
if (email.tag !== 'deleted') {
return React.createElement('span', { onClick: function onClick() {
onDelete(email.id);
}, className: 'delete-btn fa fa-trash-o' });
}
return undefined;
};
return React.createElement(
'div',
{ className: 'email-content' },
React.createElement(
'div',
{ className: 'email-content__header' },
React.createElement(
'h3',
{ className: 'email-content__subject' },
email.subject
),
getDeleteButton(),
React.createElement(
'div',
{ className: 'email-content__time' },
date
),
React.createElement(
'div',
{ className: 'email-content__from' },
email.from
)
),
React.createElement(
'div',
{ className: 'email-content__message' },
email.message
)
);
};
/* EmailList contains a list of Email components */
var EmailList = function EmailList(_ref6) {
var emails = _ref6.emails;
var onEmailSelected = _ref6.onEmailSelected;
var selectedEmailId = _ref6.selectedEmailId;
if (emails.length === 0) {
return React.createElement(
'div',
{ className: 'email-list empty' },
'Nothing to see here, great job!'
);
}
return React.createElement(
'div',
{ className: 'email-list' },
emails.map(function (email) {
return React.createElement(EmailListItem, {
onEmailClicked: function 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 success(result) {
React.render(React.createElement(App, { emails: result }), document.getElementById('inbox'));
}
});
// Helper methods
var getPrettyDate = function getPrettyDate(date) {
date = date.split(' ')[0];
var newDate = date.split('-');
var month = months[0];
return month + ' ' + newDate[2] + ', ' + newDate[0];
};
// Remove the seconds from the time
var getPrettyTime = function getPrettyTime(date) {
var time = date.split(' ')[1].split(':');
return time[0] + ':' + time[1];
};
//# sourceURL=pen.js
</script>
</body></html>