Skip to content

Instantly share code, notes, and snippets.

@LasaleFamine
Created July 22, 2017 18:45
Show Gist options
  • Select an option

  • Save LasaleFamine/110c4da7a48ff881b62467c141ba33cd to your computer and use it in GitHub Desktop.

Select an option

Save LasaleFamine/110c4da7a48ff881b62467c141ba33cd to your computer and use it in GitHub Desktop.
UnkApp
<div id="app">
</div>
const API = {
getNews(id) {
return fetch(`https://jsonplaceholder.typicode.com/posts/${id}`)
.then(res => res.json())
.catch(err => console.log(err))
}
}
const Logo = ({screenType}) => (
<div className={`HeaderLogo ${screenType}`}>
<img src="http://www.ynap.com/wp-content/themes/yoox/img/logo-ynap.svg"></img>
</div>
)
const Header = () => {
return (
<div className="HeaderWrapper">
<Logo screenType="ForSmallScreen" />
<div className="HeaderImage"></div>
<Logo screenType="ForWideScreen" />
</div>
)
}
const Intro = () => {
return (
<div className="MainBox">
<p>YOOX NET-A-PORTER GROUP is the <strong>world’s leading online luxury fashion retailer</strong>. The Group is a Global company with Anglo-Italian roots, the result of a game-changing merger, which in October 2015 brought together YOOX GROUP and THE NET-A-PORTER GROUP, two companies that have <strong>revolutionized the luxury fashion industry</strong> since their birth in 2000.
</p>
</div>
)
}
const BadButtonsGroup = ({quantity, selected, handleChange}) => {
const buttons = Array(quantity).fill().map((_, i) => {
const actualIndex = i + 1;
return (
<button
className={actualIndex === selected ? 'ButtonSelected' : ''}
onClick={handleChange} data-index={actualIndex}>{actualIndex}</button>
)
});
return (
<div className="BadButtonsGroupWrapper">
{buttons}
</div>
)
}
const NewsBody = ({post, quantity}) => {
const postBody = post.body || '';
const capitalizeFirst = text => text.charAt(0).toUpperCase() + text.slice(1);
const body = Array(quantity).fill().map((_, i) => <p>{capitalizeFirst(postBody)}</p>);
return (
<div className="NewsContent">
<div className="NewsTitle">
<h1>{post.title}</h1>
</div>
<div className="NewsBody">{body}</div>
</div>
)
}
const News = ({data, selected, handleChangeNews}) => {
return (
<div className="NewsBox">
<BadButtonsGroup quantity={5} selected={selected} handleChange={handleChangeNews} />
<NewsBody post={data} quantity={5} />
</div>
)
}
const NewsletterForm = ({handleSubmit}) => {
return (
<form className="NewsletterInputWrapper" onSubmit={handleSubmit}>
<input name="email" placeholder="work@ynap.com" type="email" required/>
<button type="submit">Subscribe</button>
</form>
)
}
const NewsletterSubscribed = () => {
return (
<span>You were successfully subscribed to our newsletter. Thank you!</span>
)
}
const Newsletter = ({subscribed, handleSubmit}) => {
const body = subscribed ?
<NewsletterSubscribed /> :
<NewsletterForm handleSubmit={handleSubmit} />;
return (
<div className="NewsletterBox">
<div><h1>Newsletter</h1></div>
<div>{body}</div>
</div>
)
}
const Footer = () => {
return (
<footer>
<p>COPYRIGHT © 2000-2017 YOOX NET-A-PORTER GROUP</p>
</footer>
)
}
class YooxApp extends React.Component {
constructor() {
super()
/* The state should be Redux... */
this.state = {
currentPost: 1,
post: {},
subscribed: false
};
this.loadNews(this.state.currentPost);
}
loadNews(id) {
API.getNews(id)
.then(res => res && this.setState({post: Object.assign({}, res), currentPost: res.id}));
}
subscribeNewsletter(email) {
this.setState({subscribed: true});
}
handleChangeNews(e) {
const id = e.target.dataset.index;
this.loadNews(id);
}
handleSubmit(e) {
e.preventDefault();
// Another check should be done here.
const email = event.target.email.value;
this.subscribeNewsletter(email);
}
render() {
return (
<div className="MainWrapper">
<Header />
<Intro />
<News
data={this.state.post}
selected={this.state.currentPost}
handleChangeNews={this.handleChangeNews.bind(this)} />
<Newsletter
subscribed={this.state.subscribed}
handleSubmit={this.handleSubmit.bind(this)} />
<Footer />
</div>
);
}
}
ReactDOM.render(<YooxApp />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
@use postcss-nested;
@use cssnext;
@use lost;
/* === Vars === */
:root {
--fontFamilyBody : 'Open Sans', sans-serif;
--margin: 20px;
--padding: 20px;
--lineHeight: 1.4rem;
--lineHeightHeading: 1.8rem;
/* Colors */
--fontColor: #333;
--fontLightColor: #FFF;
--bgColor: #666666;
--plainBgColor: #F2F2F2;
--contentBgColor: #FFF;
--darkBgColor: #333;
--borderColor: #ABABAB;
--mainGradient: linear-gradient(to bottom right, #FFF 0%, #ccc 100%);
--selectedGradient: linear-gradient(to bottom right, #ccc 0%, #FFF 100%);
/* wrapper width */
--wrapperWidth: 64rem;
/* Sizes */
--fontSizeSmall: 10px;
--fontSize: 14px;
--fontSizeH1: 24px;
}
/* === Mediaqueries === */
@custom-media --wide-screen320 (min-width: 20.0625rem); /* > 320px */
@custom-media --wide-screen412 (min-width: 25.75rem); /* > 412px */
@custom-media --wide-screen640 (min-width: 40rem); /* > 640px */
@custom-media --wide-screen750 (min-width: 46.875rem); /* > 750px */
@custom-media --wide-screen768 (min-width: 48rem); /* > 768px */
@custom-media --wide-screen824 (min-width: 51.5rem); /* > 824px */
@custom-media --wider-screen (min-width: 64rem); /* > 1024px */
@lost flexbox;
/* === Reset == */
*,
*:before,
*:after {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
background-color: var(--bgColor);
}
p {
margin: 0;
}
img {
max-width: 100%;
}
button:focus,
input:focus {
outline: none;
}
/* === Main styles == */
p {
font-size: var(--fontSize);
margin-bottom: var(--margin);
}
p:last-child {
margin-bottom: 0;
}
span {
font-size: var(--fontSize);
}
button {
cursor: pointer;
font-family: var(--fontFamilyBody);
font-size: var(--fontSize);
}
input {
border: 1px solid var(--borderColor);
padding: 10px;
}
input::placeholder {
padding-left: 0px;
font-size: var(--fontSize);
}
/* Heading */
h1,
h2,
h3 {
font-weight: 500;
line-height: var(--lineHeightHeading);
margin-top: 0;
}
h1 {
font-size: var(--fontSizeH1);
margin-bottom: var(--margin);
}
/* Transitions */
section, h1, li, img, div, p {
transition: width 1s ease-in-out, left 1.5s ease-in-out;
}
div {
transition: background-image 0.3s ease-in-out, left 0.3s ease-in-out;
}
/* Main */
.MainWrapper {
lost-center: var(--wrapperWidth);
lost-utility: clearfix;
font-family: var(--fontFamilyBody);
line-height: var(--lineHeight);
color: var(--fontColor);
background-color: var(--contentBgColor);
}
.HeaderWrapper {
& {
width: 100%;
}
& div {
lost-column: 1;
width: 100%;
}
& .HeaderLogo {
padding: var(--padding);
}
& .HeaderLogo.ForSmallScreen {
visibility: visible;
display: block;
}
& .HeaderLogo.ForWideScreen {
visibility: hidden;
display: none;
}
& .HeaderImage {
background-size: contain;
background: url('https://media.yoox.biz/ytos/resources/FEDTEST/images/man-yellow-jacket/man-yellow-jacket-320w.jpg') no-repeat;
height: 152px;
}
}
.MainBox {
padding-top: var(--padding);
padding-left: var(--padding);
padding-right: var(--padding);
}
.NewsBox {
& {
margin-top: var(--margin);
padding: var(--padding);
background-color: var(--plainBgColor);
width: 100%;
}
& h1 {
text-transform: uppercase;
}
& .NewsContent {
padding-top: var(--padding);
}
& .NewsContent span {
margin-bottom: var(--margin);
}
}
.BadButtonsGroupWrapper {
& button {
border: 1px solid var(--borderColor);
width: 27px;
height: 27px;
margin-right: 14px;
background-image: var(--mainGradient);
}
& button:focus,
& button.ButtonSelected {
background-image: var(--selectedGradient);
}
}
.NewsletterBox {
& {
padding: var(--padding);
width: 100%;
}
& h1 {
text-transform: uppercase;
}
& .NewsletterInputWrapper {
display: flex;
}
& .NewsletterInputWrapper,
& .NewsletterInputWrapper input {
width: 100%;
height: 30px;
}
& .NewsletterInputWrapper button {
border: 1px solid var(--borderColor);
width: 100px;
background-image: var(--mainGradient);
height: 30px;
}
& .NewsletterInputWrapper button:focus {
background-image: var(--selectedGradient);
}
}
footer {
& {
width: 100%;
background-color: var(--darkBgColor);
padding: var(--padding);
text-align: center;
}
& p {
font-size: var(--fontSizeSmall);
color: var(--fontLightColor);
}
}
@media (--wide-screen320) {
.HeaderWrapper {
& .HeaderImage {
background: url('https://media.yoox.biz/ytos/resources/FEDTEST/images/man-yellow-jacket/man-yellow-jacket-412w.jpg') no-repeat;
height: 195px;
}
}
}
@media (--wide-screen412) {
.HeaderWrapper .HeaderImage {
background: url('https://media.yoox.biz/ytos/resources/FEDTEST/images/man-yellow-jacket/man-yellow-jacket-640w.jpg') no-repeat;
height: 303px;
}
}
@media (--wide-screen640) {
.HeaderWrapper .HeaderImage {
background: url('https://media.yoox.biz/ytos/resources/FEDTEST/images/man-yellow-jacket/man-yellow-jacket-750w.jpg') no-repeat;
height: 355px;
}
}
@media (--wide-screen750) {
.HeaderWrapper .HeaderImage {
background: url('https://media.yoox.biz/ytos/resources/FEDTEST/images/man-yellow-jacket/man-yellow-jacket-768w.jpg') no-repeat;
height: 364px;
}
}
@media (--wide-screen768) {
.HeaderWrapper .HeaderImage {
background: url('https://media.yoox.biz/ytos/resources/FEDTEST/images/man-yellow-jacket/man-yellow-jacket-824w.jpg') no-repeat;
height: 390px;
}
}
@media (--wide-screen824) {
.HeaderWrapper .HeaderImage {
background: url('https://media.yoox.biz/ytos/resources/FEDTEST/images/man-yellow-jacket/man-yellow-jacket-1024w.jpg') no-repeat;
height: 485px;
}
}
@media (--wider-screen) {
.HeaderWrapper {
& .HeaderLogo.ForSmallScreen {
visibility: hidden;
display: none;
}
& .HeaderLogo.ForWideScreen {
visibility: visible;
display: block;
}
}
.MainBox {
padding: 0 var(--padding);
}
.NewsBox .NewsContent .NewsTitle,
.NewsletterBox div:first-child {
lost-column: 1/3;
}
.NewsletterBox div:last-child {
lost-column: 2/3;
}
.NewsletterBox > * {
lost-column: 1/2;
}
.NewsBox .NewsContent .NewsBody {
columns: 2 10em;
}
.NewsletterBox h1 {
margin-bottom: 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment