Skip to content
This repository has been archived by the owner on Nov 8, 2018. It is now read-only.

Commit

Permalink
Merge pull request #197 from redbadger/multiday-events
Browse files Browse the repository at this point in the history
Multiday events
  • Loading branch information
AndrewBestbier authored Jul 25, 2016
2 parents 1f4a6bb + a65d40b commit 18bd6c9
Show file tree
Hide file tree
Showing 27 changed files with 898 additions and 443 deletions.
1 change: 0 additions & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ test:
- npm run lint
- npm run security:check
- npm run test:server
- npm run test:client -- --browsers PhantomJS
- export APP_HOST=`ifconfig eth0 | grep -oP 'inet addr:\K\S+'` && COMPOSE_FILE=docker-compose-test.yml docker-compose up -d
- npm run test:e2e

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
"security:check": "./node_modules/.bin/nsp check",
"start": "node build/server",
"test": "npm run test:server && npm run security:check",
"test-full": "npm run test:server && npm run test:client && npm run security:check && npm run lint && npm run test:e2e",
"test:client": "karma start spec/karma.config.js",
"test-full": "npm run test:server && npm run security:check && npm run lint && npm run test:e2e",
"test:e2e": "wdio spec/wdio.config.js",
"test:server": "mocha --compilers js:babel-core/register --require spec/mocha-helper.js --recursive --reporter spec $(find src -name *spec.js)"
},
Expand Down Expand Up @@ -76,6 +75,7 @@
"chai": "^3.5.0",
"css-loader": "^0.23.1",
"css-modules-require-hook": "^2.1.0",
"enzyme": "^2.4.1",
"eslint": "^2.12.0",
"eslint-config-airbnb": "^9.0.1",
"eslint-plugin-import": "^1.8.1",
Expand Down
9 changes: 8 additions & 1 deletion spec/fixtures/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,20 @@ export const defaultEvent = {
url: 'http://www.frontendlondon.co.uk/'
},
],
datetime: {
startDateTime: {
iso: '2016-06-25T11:00:00+0000',
date: '25',
month: '06',
monthSym: 'Jun',
year: '2016',
},
endDateTime: {
iso: '2016-06-28T11:00:00+0000',
date: '28',
month: '06',
monthSym: 'Jun',
year: '2016',
},
body: [
{
type: 'paragraph',
Expand Down
11 changes: 9 additions & 2 deletions src/server/api/controllers/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ const allEventFields = `
title
url
}
datetime {
startDateTime {
iso
date
month
monthSym
year
}
endDateTime {
iso
date
month
Expand Down Expand Up @@ -77,7 +84,7 @@ export default class EventsController {
.then((response) => response.json())
.then((events) => {
res.send({ list: events.data.allEvents.sort((a, b) =>
new Date(b.datetime.iso) - new Date(a.datetime.iso)
new Date(b.startDateTime.iso) - new Date(a.startDateTime.iso)
) });
})
.catch((err) => {
Expand Down
51 changes: 30 additions & 21 deletions src/shared/components/date-bubble/index.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
// Displays date bubble

import React, { Component } from 'react';
import React, { PropTypes } from 'react';
import styles from './style.css';

export default class DateBubble extends Component {
static propTypes = {
date: React.PropTypes.string,
month: React.PropTypes.string,
year: React.PropTypes.string,
};

render() {
function displayDateContent(startDateTime, endDateTime) {
if (endDateTime) {
return (
<div className={styles.dateBubble}>
<div className={styles.date}>
{this.props.date}
</div>
<div className={styles.month}>
{this.props.month}
</div>
<div className={styles.year}>
{this.props.year}
</div>
</div>
);
`${startDateTime.date} ${startDateTime.monthSym} ${startDateTime.year} - `
+ `${endDateTime.date} ${endDateTime.monthSym} ${endDateTime.year}`);
}
return (
`${startDateTime.date} ${startDateTime.monthSym} ${startDateTime.year}`);
}

const DateBubble = ({
startDateTime,
endDateTime,
}) => (
<div className={styles.dateBubble}>
{displayDateContent(startDateTime, endDateTime)}
</div>
);


const dateShape = {
date: PropTypes.string.isRequired,
monthSym: PropTypes.string.isRequired,
year: PropTypes.string.isRequired,
};

DateBubble.propTypes = {
startDateTime: PropTypes.shape(dateShape).isRequired,
endDateTime: PropTypes.shape(dateShape),
};

export default DateBubble;
33 changes: 8 additions & 25 deletions src/shared/components/date-bubble/style.css
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
@value mobile from "../variables/breakpoints.css";
@value red from "../variables/colors.css";

.dateBubble {
background: #be1414;
display: inline-block;
font-size: 0.8em;
color: #fff;
font-size: 0.9em;
font-weight: bold;
color: red;
text-align: center;
text-transform: uppercase;
min-width: 3em;
margin-bottom: 1em;
padding: 0.3em 0;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
Expand All @@ -18,27 +17,11 @@
}

.date {
font-size: 2em;
font-size: 0.9em;
line-height: 1.2em;
}

.month {
}

.year {
}

@media mobile {
.dateBubble {
padding: 0.3em;
}

.date, .month, .year {
display: inline-block;
margin: 0 2px;
}

.date {
font-size: 1em;
}
.date, .month, .year {
display: inline-block;
margin: 0 2px;
}
76 changes: 40 additions & 36 deletions src/shared/components/event-links-list/index.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,51 @@
// Displays list of links related to the event

import React, { Component } from 'react';
import React, { PropTypes } from 'react';

import classNames from 'classnames';
import layout from '../utils/layout.css';
import icons from '../icons/style.css';
import styles from './style.css';

export default class EventLinksList extends Component {
static propTypes = {
linkList: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
listType: React.PropTypes.oneOf(['external', 'internal']).isRequired,
};
const EventLinksList = ({
linkList,
listType,
}) => {
if (linkList.length === 0) return (<noscript />);
return (
<div className={classNames({
[styles.eventLinkList]: true,
[layout.cf]: true,
})}>
{
linkList.map(eventLink => (
<a
className={styles.fullDetailsLink}
href={eventLink.url}
key={eventLink.url}
target={listType === 'external' ? '_blank' : null}
>
<span>{eventLink.title}</span>
<span className={classNames({
[icons.sketchExternalLink]: listType === 'external',
[icons.sketchArrowRight]: listType === 'internal',
[styles.externalLinkIcon]: true,
})}
/>
</a>
))
}
</div>
);
};

render() {
if (this.props.linkList.length === 0) return null;

const { listType } = this.props;
EventLinksList.propTypes = {
linkList: PropTypes.arrayOf(PropTypes.shape({
url: PropTypes.string,
title: PropTypes.string,
})).isRequired,
listType: React.PropTypes.oneOf(['external', 'internal']).isRequired,
};

return (
<div className={classNames({
[styles.eventLinkList]: true,
[layout.cf]: true,
})}>
{
this.props.linkList.map(eventLink => (
<a
className={styles.fullDetailsLink}
href={eventLink.url}
key={eventLink.url}
target={listType === 'external' ? '_blank' : null}
>
<span>{eventLink.title}</span>
<span className={classNames({
[icons.sketchExternalLink]: listType === 'external',
[icons.sketchArrowRight]: listType === 'internal',
[styles.externalLinkIcon]: true,
})}
/>
</a>
))
}
</div>
);
}
}
export default EventLinksList;
46 changes: 46 additions & 0 deletions src/shared/components/event-meta/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { PropTypes } from 'react';
import styles from './style.css';

import TagsList from '../tags-list';
import EventLinksList from '../event-links-list';

const EventMeta = ({
internalLinks,
externalLinks,
tags,
}) => {
if (internalLinks.length > 0 && externalLinks.length > 0) {
return (<div>
{
externalLinks || internalLinks ?
<div className={styles.eventLinks}>
<EventLinksList
linkList={externalLinks}
listType="external" />
<EventLinksList
linkList={internalLinks}
listType="internal" />
</div>
: <noscript />
}
{
tags
? <TagsList
tags={tags}
tagsLinkPath="about-us/events" />
: <noscript />
}
</div>
);
}

return (<noscript />);
};

EventMeta.propTypes = {
internalLinks: EventLinksList.propTypes.linkList,
externalLinks: EventLinksList.propTypes.linkList,
tags: PropTypes.arrayOf(PropTypes.string),
};

export default EventMeta;
16 changes: 16 additions & 0 deletions src/shared/components/event-meta/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import EventMeta from './index.js';
import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';
import { defaultEvent } from '../../../../spec/fixtures/events.js';

describe('EventMeta component', () => {
it('renders successfully with default props', () => {
const wrapper = shallow(<EventMeta
internalLinks={defaultEvent.internalLinks}
externalLinks={defaultEvent.externalLinks}
tags={defaultEvent.tags}
/>);
expect(wrapper.find('div').length).to.equal(2);
});
});
4 changes: 4 additions & 0 deletions src/shared/components/event-meta/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.eventLinks {
composes: cf from "../../components/utils/layout.css";
margin-bottom: 1em;
}
35 changes: 35 additions & 0 deletions src/shared/components/event-title/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { PropTypes } from 'react';
import classNames from 'classnames';
import icons from '../icons/style.css';
import styles from './style.css';
import { h2 } from '../typography/style.css';

const EventTitle = ({
eventTitle,
eventHref,
}) => (
<a className={styles.eventTitleLink}
href={eventHref}>
<h2 className={classNames({
[styles.eventTitle]: true,
[h2]: true,
})}>
<span>
{eventTitle}
</span>
<span className={classNames(
{
[styles.arrow]: true,
[icons.sketchArrowRight]: true,
})}
/>
</h2>
</a>
);

EventTitle.propTypes = {
eventTitle: PropTypes.string.isRequired,
eventHref: PropTypes.string.isRequired,
};

export default EventTitle;
14 changes: 14 additions & 0 deletions src/shared/components/event-title/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import EventTitle from './index.js';
import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';

describe('EventTitle component', () => {
it('renders successfully with default props', () => {
const wrapper = shallow(<EventTitle
eventTitle={'Event title'}
eventHref={'https://www.red-badger.com'}
/>);
expect(wrapper.find('h2').length).to.equal(1);
});
});
Loading

0 comments on commit 18bd6c9

Please sign in to comment.