Skip to content

Commit ee885d6

Browse files
committed
Adds ConsenSys @ Medium section to Blockchain community's Learn page
1 parent e9b6b12 commit ee885d6

File tree

14 files changed

+449
-38
lines changed

14 files changed

+449
-38
lines changed

.exchange-rates.cache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"disclaimer":"Usage subject to terms: https://openexchangerates.org/terms","license":"https://openexchangerates.org/license","timestamp":1510430426,"base":"USD","rates":{"AED":3.673018,"AFN":68.5905,"ALL":114.268015,"AMD":485.835,"ANG":1.783866,"AOA":165.9225,"ARS":17.49,"AUD":1.305262,"AWG":1.786752,"AZN":1.6985,"BAM":1.676693,"BBD":2,"BDT":83.148415,"BGN":1.67641,"BHD":0.377032,"BIF":1760,"BMD":1,"BND":1.357824,"BOB":6.909874,"BRL":3.27715,"BSD":1,"BTC":0.000158230047,"BTN":65.009917,"BWP":10.60399,"BYN":1.98819,"BZD":2.005603,"CAD":1.268115,"CDF":1579,"CHF":0.99603,"CLF":0.02347,"CLP":631.5,"CNH":6.661808,"CNY":6.64125,"COP":3008,"CRC":568.23,"CUC":1,"CUP":25.5,"CVE":94.95,"CZK":21.9065,"DJF":178.97,"DKK":6.379455,"DOP":47.92,"DZD":115.078,"EGP":17.6505,"ERN":15.336062,"ETB":27.275,"EUR":0.857192,"FJD":2.0568,"FKP":0.75816,"GBP":0.75816,"GEL":2.561854,"GGP":0.75816,"GHS":4.43036,"GIP":0.75816,"GMD":47.26,"GNF":9013.35,"GTQ":7.32654,"GYD":208.292635,"HKD":7.80107,"HNL":23.591593,"HRK":6.4643,"HTG":63.169196,"HUF":267.154,"IDR":13524.113381,"ILS":3.549105,"IMP":0.75816,"INR":65.368,"IQD":1164.45,"IRR":34668.946723,"ISK":103.613694,"JEP":0.75816,"JMD":126.058505,"JOD":0.709001,"JPY":113.525,"KES":103.602489,"KGS":69.119478,"KHR":4025.25,"KMF":422.25,"KPW":900,"KRW":1121.1,"KWD":0.302532,"KYD":0.831547,"KZT":332.157791,"LAK":8307.85,"LBP":1512.7,"LKR":153.291485,"LRD":122.988952,"LSL":14.335761,"LYD":1.365714,"MAD":9.479031,"MDL":17.601594,"MGA":3152.15,"MKD":52.786,"MMK":1352.15,"MNT":2451.70248,"MOP":8.01931,"MRO":354.39,"MUR":34.400227,"MVR":15.390067,"MWK":722.69,"MXN":19.1046,"MYR":4.191994,"MZN":60.994761,"NAD":14.365,"NGN":359.215,"NIO":30.684016,"NOK":8.13405,"NPR":104.024834,"NZD":1.4431,"OMR":0.385115,"PAB":1,"PEN":3.2425,"PGK":3.197794,"PHP":51.13782,"PKR":104.82,"PLN":3.6236,"PYG":5640.75,"QAR":3.8115,"RON":3.982002,"RSD":101.59,"RUB":59.135,"RWF":852.62,"SAR":3.750225,"SBD":7.802011,"SCR":13.988,"SDG":6.662214,"SEK":8.35636,"SGD":1.3605,"SHP":0.75816,"SLL":7643.328121,"SOS":577.205,"SRD":7.448,"SSP":130.2634,"STD":20725.000286,"SVC":8.731481,"SYP":514.98999,"SZL":14.331779,"THB":33.043,"TJS":8.790913,"TMT":3.50998,"TND":2.500007,"TOP":2.254482,"TRY":3.86361,"TTD":6.715426,"TWD":30.171,"TZS":2252.2,"UAH":26.451281,"UGX":3634.1,"USD":1,"UYU":29.133845,"UZS":8080,"VEF":9.984033,"VND":22714.053308,"VUV":106.093334,"WST":2.547073,"XAF":562.280992,"XAG":0.05917511,"XAU":0.00078379,"XCD":2.70255,"XDR":0.712515,"XOF":562.280992,"XPD":0.00100377,"XPF":102.290196,"XPT":0.00107614,"YER":250.25,"ZAR":14.37934,"ZMW":9.914463,"ZWL":322.355011}}
1+
{"disclaimer":"Usage subject to terms: https://openexchangerates.org/terms","license":"https://openexchangerates.org/license","timestamp":1510495225,"base":"USD","rates":{"AED":3.673018,"AFN":68.5905,"ALL":114.268015,"AMD":485.835,"ANG":1.783866,"AOA":165.9225,"ARS":17.4665,"AUD":1.305262,"AWG":1.786752,"AZN":1.6985,"BAM":1.676693,"BBD":2,"BDT":83.148415,"BGN":1.67641,"BHD":0.376856,"BIF":1748.9,"BMD":1,"BND":1.357847,"BOB":6.909874,"BRL":3.27715,"BSD":1,"BTC":0.00016224277,"BTN":65.009917,"BWP":10.60399,"BYN":1.98819,"BZD":2.005603,"CAD":1.268665,"CDF":1579,"CHF":0.99606,"CLF":0.02347,"CLP":630.025,"CNH":6.661808,"CNY":6.64125,"COP":3003.75,"CRC":568.23,"CUC":1,"CUP":25.5,"CVE":94.95,"CZK":21.9065,"DJF":178.97,"DKK":6.379455,"DOP":47.92,"DZD":115.078,"EGP":17.6505,"ERN":15.336062,"ETB":27.017895,"EUR":0.85728,"FJD":2.0568,"FKP":0.75818,"GBP":0.75818,"GEL":2.532272,"GGP":0.75818,"GHS":4.43036,"GIP":0.75818,"GMD":47.26,"GNF":9013.35,"GTQ":7.32654,"GYD":208.292635,"HKD":7.80107,"HNL":23.591593,"HRK":6.4643,"HTG":63.169196,"HUF":267.154,"IDR":13515.620071,"ILS":3.55041,"IMP":0.75818,"INR":65.368,"IQD":1164.45,"IRR":34668.946723,"ISK":103.613694,"JEP":0.75818,"JMD":126.058505,"JOD":0.709001,"JPY":113.525,"KES":103.602489,"KGS":69.119478,"KHR":4025.25,"KMF":422.1,"KPW":900,"KRW":1121.1,"KWD":0.302532,"KYD":0.831547,"KZT":332.157791,"LAK":8307.85,"LBP":1512.7,"LKR":153.291485,"LRD":122.988952,"LSL":14.335761,"LYD":1.365714,"MAD":9.479031,"MDL":17.601594,"MGA":3152.15,"MKD":52.786,"MMK":1352.15,"MNT":2451.70248,"MOP":8.01931,"MRO":354.39,"MUR":34.325,"MVR":15.390067,"MWK":722.69,"MXN":19.1046,"MYR":4.191994,"MZN":60.994761,"NAD":14.335761,"NGN":359.215,"NIO":30.684016,"NOK":8.13405,"NPR":104.024834,"NZD":1.4431,"OMR":0.385115,"PAB":1,"PEN":3.235348,"PGK":3.197794,"PHP":51.13782,"PKR":104.82,"PLN":3.6268,"PYG":5640.75,"QAR":3.8115,"RON":3.982002,"RSD":101.59,"RUB":59.135,"RWF":852.62,"SAR":3.750225,"SBD":7.802011,"SCR":13.438825,"SDG":6.662214,"SEK":8.35636,"SGD":1.3605,"SHP":0.75818,"SLL":7643.328121,"SOS":577.205,"SRD":7.448,"SSP":130.2634,"STD":20725.000286,"SVC":8.731481,"SYP":514.98999,"SZL":14.331779,"THB":33.0425,"TJS":8.790913,"TMT":3.50998,"TND":2.500007,"TOP":2.254482,"TRY":3.86361,"TTD":6.715426,"TWD":30.171,"TZS":2231.735079,"UAH":26.451281,"UGX":3634.1,"USD":1,"UYU":29.133845,"UZS":8050,"VEF":9.9842,"VND":22714.053308,"VUV":106.093334,"WST":2.547073,"XAF":562.338817,"XAG":0.05917511,"XAU":0.00078379,"XCD":2.70255,"XDR":0.712515,"XOF":562.338817,"XPD":0.00100377,"XPF":102.300716,"XPT":0.00107614,"YER":250.25,"ZAR":14.37934,"ZMW":9.843587,"ZWL":322.355011}}

src/server/server.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import atob from 'atob';
33
import bodyParser from 'body-parser';
44
import cookieParser from 'cookie-parser';
55
import express from 'express';
6+
import fetch from 'isomorphic-fetch';
67
import helmet from 'helmet';
78
import logger from 'utils/logger';
89
import loggerMiddleware from 'morgan';
@@ -103,6 +104,14 @@ app.use('/community-app-assets/api/xml2json', (req, res) => {
103104
xmlToJson(req.body.xml).then(json => res.json(json));
104105
});
105106

107+
/* Proxy endpoint for GET requests (to fetch data from resources prohibiting
108+
* cross-origin requests). */
109+
app.use('/community-app-assets/api/proxy-get', (req, res) => {
110+
fetch(req.query.url)
111+
.then(x => x.text())
112+
.then(x => res.send(x));
113+
});
114+
106115
/* Returns currency exchange rates, cached at the server-side (thus drastically
107116
* reducing amount of calls to openexchangerates.com). */
108117
app.use('/community-app-assets/api/exchange-rates', (req, res) => {

src/shared/actions/rss.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Actions for management of data loaded from RSS feeds.
3+
*/
4+
5+
import fetch from 'isomorphic-fetch';
6+
import { toJson } from 'utils/xml2json';
7+
import { createActions } from 'redux-actions';
8+
9+
/**
10+
* Payload creator for the action that drops data loaded from the specified
11+
* RSS feed. Also cancels any pending loading of data for that feed.
12+
* @param {String} feed Internal name of the feed.
13+
* @return {String}
14+
*/
15+
function drop(feed) {
16+
return feed;
17+
}
18+
19+
/**
20+
* Payload creator for the actions that drops all data loaded from RSS feeds.
21+
*/
22+
function dropAll() {}
23+
24+
/**
25+
* Payload creator for the action that initializes data loading for the
26+
* specified feed.
27+
* @param {String} feed Internal name of the feed.
28+
* @param {String} uuid UUID of the loading operations.
29+
* @return {Object} Action payload.
30+
*/
31+
function getInit(feed, uuid) {
32+
return { feed, uuid };
33+
}
34+
35+
/**
36+
* Payload creator for the action that actually loads data for the specified
37+
* RSS feed.
38+
* @param {String} feed Internal name of the feed.
39+
* @param {String} uuid UUID of the loading operation.
40+
* @param {String} url URL of the RSS feed.
41+
* @return {Object} Action payload.
42+
*/
43+
async function getDone(feed, uuid, url) {
44+
let res = await fetch(url);
45+
if (!res.ok) throw new Error(res.statusText);
46+
res = await res.text();
47+
res = await toJson(res);
48+
return { feed, uuid, data: res.rss.channel };
49+
}
50+
51+
export default createActions({
52+
RSS: {
53+
DROP: drop,
54+
DROP_ALL: dropAll,
55+
GET_INIT: getInit,
56+
GET_DONE: getDone,
57+
},
58+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Renders a single article card.
3+
*/
4+
5+
import PT from 'prop-types';
6+
import React from 'react';
7+
8+
import './style.scss';
9+
10+
export default function Card({ fullWidth, item }) {
11+
return (
12+
<div styleName={fullWidth ? 'full-width-container' : 'container'}>
13+
<h3>
14+
<a
15+
href={item.link}
16+
rel="noopener noreferrer"
17+
target="_blank"
18+
>{item.title}</a></h3>
19+
<div
20+
/* eslint-disable react/no-danger */
21+
dangerouslySetInnerHTML={{ __html: item['content:encoded'] }}
22+
/* eslint-enable react/no-danger */
23+
/>
24+
<a
25+
href={item.link}
26+
styleName="readMore"
27+
target="_blank"
28+
rel="noopener noreferrer"
29+
>Read More...</a>
30+
<div styleName="mask" />
31+
</div>
32+
);
33+
}
34+
35+
Card.defaultProps = {
36+
fullWidth: false,
37+
};
38+
39+
Card.propTypes = {
40+
fullWidth: PT.bool,
41+
item: {
42+
'content:encoded': PT.string.isRequired,
43+
link: PT.string.isRequired,
44+
title: PT.string.isRequired,
45+
}.isRequired,
46+
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
@import '../../../themes/mixins';
2+
3+
@mixin container {
4+
@include body-text;
5+
6+
height: 480px;
7+
margin-bottom: 48px;
8+
overflow: hidden;
9+
position: relative;
10+
width: 48%;
11+
12+
@include xxs-to-sm {
13+
padding: 0 24px;
14+
width: 100%;
15+
}
16+
17+
a {
18+
@include link;
19+
20+
text-decoration: underline;
21+
}
22+
23+
h3 {
24+
@include h3;
25+
}
26+
27+
h4 {
28+
@include h4;
29+
}
30+
31+
iframe {
32+
height: 280px;
33+
width: 100%;
34+
}
35+
36+
img {
37+
width: 100%;
38+
}
39+
}
40+
41+
.container {
42+
@include container;
43+
}
44+
45+
.full-width-container {
46+
@include container;
47+
48+
width: 100%;
49+
height: 720px;
50+
}
51+
52+
.mask {
53+
background: linear-gradient(180deg, transparent, rgba(255, 255, 255, 0.5) 50%, white 80%);
54+
bottom: 0;
55+
height: 128px;
56+
left: 0;
57+
position: absolute;
58+
right: 0;
59+
}
60+
61+
.readMore {
62+
bottom: 0;
63+
position: absolute;
64+
z-index: 2;
65+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Renders the section with content from ConsenSys blog at Medium.
3+
*/
4+
5+
import PT from 'prop-types';
6+
import React from 'react';
7+
import Section from 'components/tc-communities/Section';
8+
9+
import Card from './Card';
10+
import style from './style.scss';
11+
12+
13+
export default function ConsenSysAtMedium({ consenSysRss }) {
14+
const cards = consenSysRss.data.item
15+
.filter(item => Boolean(item.category))
16+
.slice(0, 3)
17+
.map((item, index) => (
18+
<Card fullWidth={!index} item={item} />
19+
));
20+
21+
return (
22+
<Section
23+
theme={{
24+
content: style.content,
25+
}}
26+
title="ConsenSys @ Medium"
27+
>
28+
{cards}
29+
</Section>
30+
);
31+
}
32+
33+
ConsenSysAtMedium.propTypes = {
34+
consenSysRss: PT.shape({
35+
data: PT.shape({
36+
item: PT.arrayOf(PT.object).isRequired,
37+
}).isRequired,
38+
}).isRequired,
39+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.content {
2+
flex-wrap: wrap;
3+
}

src/shared/components/tc-communities/communities/blockchain/Learn/index.jsx

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
/* eslint-disable max-len */
88

9+
import PT from 'prop-types';
910
import React from 'react';
1011
import JoinCommunity from 'containers/tc-communities/JoinCommunity';
1112
import Section from 'components/tc-communities/Section';
@@ -17,9 +18,12 @@ import ArticleCard from 'components/tc-communities/ArticleCard2';
1718
import LinksCard from 'components/tc-communities/LinksCard';
1819
import Text from 'components/tc-communities/Text';
1920

21+
import ConsenSysAtMedium from './ConsenSysAtMedium';
2022
import style from './style.scss';
2123

22-
export default function Learn() {
24+
export default function Learn({
25+
consenSysRss,
26+
}) {
2327
return (
2428
<main>
2529

@@ -85,36 +89,6 @@ export default function Learn() {
8589
</p>
8690
</Text>
8791
</AccordionItem>
88-
<AccordionItem title="Managing your Certifications">
89-
<Text>
90-
<p>
91-
Nam dapibus nisl vitae elit fringilla rutrum. Aenean sollicitudin, erat a elementum rutrum, neque sem pretium metus, quis mollis nisl nunc et massa. Vestibulum sed metus in lorem tristique ullamcorper id vitae erat. Nulla mollis sapien sollicitudin lacinia lacinia. Vivamus facilisis dolor et massa placerat, at vestibulum nisl egestas. Nullam rhoncus lacus non odio luctus, eu condimentum mauris ultrices. Praesent blandit, augue a posuere aliquam, arcu tortor feugiat turpis,
92-
</p>
93-
<p>
94-
Nam dapibus nisl vitae elit fringilla rutrum. Aenean sollicitudin, erat a elementum rutrum, neque sem pretium metus, quis mollis nisl nunc et massa. Vestibulum sed metus in lorem tristique ullamcorper id vitae erat. Nulla mollis sapien sollicitudin lacinia lacinia. Vivamus facilisis dolor et massa placerat, at vestibulum nisl egestas. Nullam rhoncus lacus non odio luctus, eu condimentum mauris ultrices. Praesent blandit, augue a posuere aliquam, arcu tortor feugiat turpis,
95-
</p>
96-
</Text>
97-
</AccordionItem>
98-
<AccordionItem title="Managing your Badges">
99-
<Text>
100-
<p>
101-
Nam dapibus nisl vitae elit fringilla rutrum. Aenean sollicitudin, erat a elementum rutrum, neque sem pretium metus, quis mollis nisl nunc et massa. Vestibulum sed metus in lorem tristique ullamcorper id vitae erat. Nulla mollis sapien sollicitudin lacinia lacinia. Vivamus facilisis dolor et massa placerat, at vestibulum nisl egestas. Nullam rhoncus lacus non odio luctus, eu condimentum mauris ultrices. Praesent blandit, augue a posuere aliquam, arcu tortor feugiat turpis,
102-
</p>
103-
<p>
104-
Nam dapibus nisl vitae elit fringilla rutrum. Aenean sollicitudin, erat a elementum rutrum, neque sem pretium metus, quis mollis nisl nunc et massa. Vestibulum sed metus in lorem tristique ullamcorper id vitae erat. Nulla mollis sapien sollicitudin lacinia lacinia. Vivamus facilisis dolor et massa placerat, at vestibulum nisl egestas. Nullam rhoncus lacus non odio luctus, eu condimentum mauris ultrices. Praesent blandit, augue a posuere aliquam, arcu tortor feugiat turpis,
105-
</p>
106-
</Text>
107-
</AccordionItem>
108-
<AccordionItem title="Updating your Profile">
109-
<Text>
110-
<p>
111-
Nam dapibus nisl vitae elit fringilla rutrum. Aenean sollicitudin, erat a elementum rutrum, neque sem pretium metus, quis mollis nisl nunc et massa. Vestibulum sed metus in lorem tristique ullamcorper id vitae erat. Nulla mollis sapien sollicitudin lacinia lacinia. Vivamus facilisis dolor et massa placerat, at vestibulum nisl egestas. Nullam rhoncus lacus non odio luctus, eu condimentum mauris ultrices. Praesent blandit, augue a posuere aliquam, arcu tortor feugiat turpis,
112-
</p>
113-
<p>
114-
Nam dapibus nisl vitae elit fringilla rutrum. Aenean sollicitudin, erat a elementum rutrum, neque sem pretium metus, quis mollis nisl nunc et massa. Vestibulum sed metus in lorem tristique ullamcorper id vitae erat. Nulla mollis sapien sollicitudin lacinia lacinia. Vivamus facilisis dolor et massa placerat, at vestibulum nisl egestas. Nullam rhoncus lacus non odio luctus, eu condimentum mauris ultrices. Praesent blandit, augue a posuere aliquam, arcu tortor feugiat turpis,
115-
</p>
116-
</Text>
117-
</AccordionItem>
11892
</Accordion>
11993
</Section>
12094
<Section
@@ -127,15 +101,15 @@ export default function Learn() {
127101
<div styleName="historyOfBlockchainVideoWrapper">
128102
<iframe
129103
styleName="historyOfBlockchainVideo"
130-
src="https://www.youtube.com/embed/TDGq4aeevgY"
131-
title="Vitalik Buterin explains Ethereum"
104+
src="https://www.youtube.com/embed/j23HnORQXvs"
105+
title="Ethereum: the World Computer"
132106
/>
133107
</div>
134108
<div styleName="historyOfBlockchainVideoWrapper">
135109
<iframe
136110
styleName="historyOfBlockchainVideo"
137-
src="https://www.youtube.com/embed/j23HnORQXvs"
138-
title="Ethereum: the World Computer"
111+
src="https://www.youtube.com/embed/TDGq4aeevgY"
112+
title="Vitalik Buterin explains Ethereum"
139113
/>
140114
</div>
141115
<ArticleCard
@@ -250,6 +224,12 @@ export default function Learn() {
250224
</ArticleCard>
251225
</Section>
252226

227+
{
228+
consenSysRss && consenSysRss.data ? (
229+
<ConsenSysAtMedium consenSysRss={consenSysRss} />
230+
) : null
231+
}
232+
253233
<Section
254234
title="More Resources"
255235
theme={{
@@ -307,3 +287,11 @@ export default function Learn() {
307287
</main>
308288
);
309289
}
290+
291+
Learn.defaultProps = {
292+
consenSysRss: null,
293+
};
294+
295+
Learn.propTypes = {
296+
consenSysRss: PT.shape(),
297+
};

src/shared/components/tc-communities/communities/blockchain/Learn/style.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
}
2929

3030
.bannerContainer {
31-
height: 252px;
31+
height: 470px;
3232

3333
@include xxs-to-xs {
3434
height: 300px;
@@ -106,6 +106,10 @@
106106
position: absolute;
107107
width: 100%;
108108
height: 100%;
109+
110+
@include xxs-to-sm {
111+
padding: 0 18px;
112+
}
109113
}
110114

111115
.historyOfBlockchainVideoWrapper {

0 commit comments

Comments
 (0)