Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fellowships directory pages #1046

Merged
merged 4 commits into from
Feb 13, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion network-api/networkapi/fellows/templates/fellows_directory.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
{% extends "fellowships-base.html" %}

{% block template_id %}fellows-directory{% endblock %}

{% block body %}
fellows directory
<div class="row">
<div class="col-md-12 col-lg-9">
<div class="mb-4">
<h1 class="h1-white">Fellows Directory</h1>
</div>
</div>
</div>

<div id="fellows-directory-featured-fellows"></div>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends "fellowships-base.html" %}

{% block template_id %}fellows-directory-{{type|slugify}}{% endblock %}

{% block body %}
<div id="fellowship-breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item small-gray">
<a href="{% url 'fellowships-directory' %}" class="small-gray">Directory</a>
</li>
<li class="breadcrumb-item small-gray active text-capitalize">
{{ type }} Fellows
</li>
</ol>
</div>

<div class="row">
<div class="col-12">
<div class="mb-4">
<h1 class="h1-white text-capitalize">{{ type }} Fellows</h1>
</div>
</div>
</div>

<div id="fellows-directory-fellows-by-type" data-type="{{type}}">
</div>
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ <h4 class="h4-headingcontract-black">Engaging Title for Funders</h4>
</div>
</div>

<div class="row mb-5">
<div class="mb-5">
<div id="featured-fellow-support-page" class="featured-fellow"></div>
</div>

{% endblock %}
2 changes: 0 additions & 2 deletions network-api/networkapi/fellows/templates/fellows_type.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ <h4 class="h2-headings-white">Eligibility Criteria</h4>
<div class="col-md-4">img</div>
</div>

<div class="row mb-5">
{% block featured_fellow %}
{% endblock %}
</div>

<div class="row py-5 px-md-2">
<div class="col-md-2">img</div>
Expand Down
19 changes: 17 additions & 2 deletions network-api/networkapi/fellows/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,26 @@

urlpatterns = [
url(r'^$', views.fellows_home, name='fellowships-home'),
url(r'^science/$', views.fellows_science, name='fellowships-science'),
url(r'^open-web/$', views.fellows_openweb, name='fellowships-open-web'),
url(r'^directory/$',
views.fellows_directory,
name='fellowships-directory'),
url(r'^directory/senior$',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we're doing things pretty statically, but I think it's worth it to make this DRYer. Check out named groups

views.fellows_directory_senior,
name='fellowships-directory-senior'),
Copy link
Contributor

@alanmoo alanmoo Feb 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this called "senior"?

url(r'^directory/science$',
views.fellows_directory_science,
name='fellowships-directory-science'),
url(r'^directory/open-web$',
views.fellows_directory_open_web,
name='fellowships-directory-open-web'),
url(r'^directory/tech-policy$',
views.fellows_directory_tech_policy,
name='fellowships-directory-tech-policy'),
url(r'^directory/media$',
views.fellows_directory_senior,
name='fellowships-directory-media'),
url(r'^support/$', views.fellows_support, name='fellowships-support'),
url(r'^science/$', views.fellows_science, name='fellowships-science'),
url(r'^open-web/$', views.fellows_openweb, name='fellowships-open-web'),
url(r'^apply/$', views.fellows_apply, name='fellowships-apply'),
]
42 changes: 36 additions & 6 deletions network-api/networkapi/fellows/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,50 @@ def fellows_home(request):
return render(request, 'fellows_home.html')


def fellows_science(request):
return render(request, 'fellows_science.html')


def fellows_openweb(request):
return render(request, 'fellows_openweb.html')


def fellows_directory(request):
return render(request, 'fellows_directory.html')


def fellows_support(request):
return render(request, 'fellows_support.html')
def fellows_directory_senior(request):
context = {'type': 'senior'}

return render(request, 'fellows_directory_type.html', context)

def fellows_science(request):
return render(request, 'fellows_science.html')

def fellows_directory_science(request):
context = {'type': 'science'}

def fellows_openweb(request):
return render(request, 'fellows_openweb.html')
return render(request, 'fellows_directory_type.html', context)


def fellows_directory_open_web(request):
context = {'type': 'open web'}

return render(request, 'fellows_directory_type.html', context)


def fellows_directory_tech_policy(request):
context = {'type': 'tech policy'}

return render(request, 'fellows_directory_type.html', context)


def fellows_directory_media(request):
context = {'type': 'media'}

return render(request, 'fellows_directory_type.html', context)


def fellows_support(request):
return render(request, 'fellows_support.html')


def fellows_apply(request):
Expand Down
2 changes: 1 addition & 1 deletion network-api/networkapi/templates/fellowships-base.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
<div class="col">
<div id="multipage-nav" class="d-flex flex-row align-items-center">
<div><a href="{% url 'fellowships-home' %}" class="{% fellowship_active_nav request 'fellowships-home fellowships-science fellowships-open-web' %}">Fellowships</a></div>
<div><a href="{% url 'fellowships-directory' %}" class="{% fellowship_active_nav request 'fellowships-directory' %}">Directory</a></div>
<div><a href="{% url 'fellowships-directory' %}" class="{% fellowship_active_nav request 'fellowships-directory fellowships-directory-senior fellowships-directory-science fellowships-directory-open-web fellowships-directory-tech-policy fellowships-directory-media' %}">Directory</a></div>
<div><a href="{% url 'fellowships-support' %}" class="{% fellowship_active_nav request 'fellowships-support' %}">Support the Program</a></div>
<div><a href="{% url 'fellowships-apply' %}" class="{% fellowship_active_nav request 'fellowships-apply' %}">Apply to be a Fellow</a></div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion source/js/components/multipage-nav/multipage-nav.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#multipage-nav-mobile {
background: #f2f2f2;
background: $off-white;

.multipage-nav {
div:first-child {
Expand Down
20 changes: 17 additions & 3 deletions source/js/components/people/person.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ export default class Person extends React.Component {
<a className="cta-link" href={this.props.metadata.links.interview}>Read Interview</a>
</div>
}
{this.props.metadata.fellow_directory_link &&
{this.props.metadata.custom_link &&
<div>
<a href={this.props.metadata.fellow_directory_link.link} className="cta-link">See all {this.props.metadata.fellow_directory_link.type} fellows</a>
<a href={this.props.metadata.custom_link.link} className="cta-link">{this.props.metadata.custom_link.text}</a>
</div>
}
</div>
Expand Down Expand Up @@ -114,7 +114,21 @@ export default class Person extends React.Component {
</div>
}
<div className="person-social-links mt-3">
{socialLinks}
<div className="row flex-column-reverse flex-md-row justify-content-between">
{socialLinks.length > 0 &&
<div className="col-12 col-md my-1 my-0">{socialLinks}</div>
}
{this.props.metadata.links.interview &&
<div className="col-12 col-md my-1 my-0">
<a className="cta-link" href={this.props.metadata.links.interview}>Read Interview</a>
</div>
}
{this.props.metadata.custom_link &&
<div className="col-12 col-md my-1 my-0 text-md-right">
<a href={this.props.metadata.custom_link.link} className="cta-link">{this.props.metadata.custom_link.text}</a>
</div>
}
</div>
</div>
</div>
</div>
Expand Down
156 changes: 152 additions & 4 deletions source/js/fellowships.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,146 @@ import ReactDOM from 'react-dom';

import Person from './components/people/person.jsx';

let pulseApiDomain = ``;

function getFellows(params, callback) {
Object.assign(params, {'profile_type': `fellow`});

let queryString = Object.entries(params).map(pair => pair.map(encodeURIComponent).join(`=`)).join(`&`);
let req = new XMLHttpRequest();

req.addEventListener(`load`, () => {
callback.call(this, JSON.parse(req.response));
});

req.open(`GET`, `https://${pulseApiDomain}/api/pulse/profiles/?${queryString}`);
req.send();
}

function renderFellowCard(fellow) {
Copy link
Contributor

@alanmoo alanmoo Feb 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put a comment in describing what this is doing (vs, say, the existing person.jsx component)?

let links = {};

if ( fellow.twitter ) {
links.twitter = fellow.twitter;
}

if ( fellow.linkedin ) {
links.linkedIn = fellow.linkedin;
}

let metadata = {
'internet_health_issues': fellow.issues,
links: links,
name: fellow.custom_name,
role: `${fellow.program_type}${fellow.program_year ? `, ${fellow.program_year}` : ``}`,
image: fellow.thumbnail,
affiliations: [ fellow.affiliation ],
'custom_link': { text: `See work`, link: `/fellowships/directory` }
};

return <Person metadata={metadata} key={fellow.custom_name} />;
}

function groupFellowsByAttr(attribute, fellows) {
if (!attribute) {
return false;
}

let fellowsGroup = {};

fellows.forEach(fellow => {
let attr = fellow[attribute];

if (!attr) {
return;
}

if (!fellowsGroup[attr]) {
fellowsGroup[attr] = [fellow];
} else {
fellowsGroup[attr].push(fellow);
}
});

return fellowsGroup;
}

function renderFellowsOnDirectoryPage() {
let getTypeSlug = function(type) {
return type.toLowerCase().replace(`fellow`,``).trim().replace(/\s/g, `-`);
};

let renderFilterOption = function(option) {
return <button
className="btn btn-link text-capitalize"
key={option}
onClick={(event) => { window.scrollTo(0, document.getElementById(event.target.dataset.targetId).offsetTop); }}
data-target-id={`fellowships-directory-${getTypeSlug(option)}`}
>
{`${option}${option === `senior` ? ` Fellow` :``}`}
</button>;
};

getFellows({'program_year': `2017`}, fellows => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this a const at the top of the file so it stands out more when we want to change it

let fellowsByType = groupFellowsByAttr(`program_type`, fellows);
const ORDER = [ `senior`, `science`, `open web`, `tech policy`, `media`];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe bring this to the top while you're at it?


// render filter bar
let filterBar = <div className="row">
<div className="col-12">
<div id="fellowships-directory-filter" className="d-flex flex-wrap p-2">
<div className="d-inline-block mr-2"><strong>Areas:</strong></div>
{ ORDER.map(renderFilterOption) }
</div>
</div>
</div>;

// render program type sections
let sections = Object.keys(fellowsByType).sort((a, b) => {
return ORDER.indexOf(a.replace(`fellow`,``).trim()) - ORDER.indexOf(b.replace(`fellow`,``).trim());
}).map(type => {
return <div className="row my-4" key={type} id={`fellowships-directory-${getTypeSlug(type)}`}>
<div className="col-12">
<h3 className="h3-black text-capitalize">{type}s</h3>
<div className="row">
{fellowsByType[type].map(renderFellowCard)}
</div>
</div>
<div className="col-12 text-center mt-3 mb-5">
<a href={`/fellowships/directory/${getTypeSlug(type)}`} className="btn btn-ghost">See all {type}s</a>
</div>
</div>;
});

ReactDOM.render(<div>{filterBar}<div className="featured-fellow">{sections}</div></div>, document.getElementById(`fellows-directory-featured-fellows`));
});
}

function renderFellowsOnDirectoryByTypePage() {
let type = document.getElementById(`fellows-directory-fellows-by-type`).dataset.type;

getFellows({'program_type': `${type} fellow`}, fellows => {
let fellowsByYear = groupFellowsByAttr(`program_year`, fellows);

let sections = Object.keys(fellowsByYear).sort().reverse().map(year => {
return <div className="row mb-5" key={year}>
<div className="col-12">
<div className="mb-4">
<h2 className="h2-typeaccents-gray">{year}</h2>
</div>
</div>
{fellowsByYear[year].map(renderFellowCard)}
</div>;
});

ReactDOM.render(<div className="featured-fellow">{sections}</div>, document.getElementById(`fellows-directory-fellows-by-type`));
});
}

// Embed various Fellowships pages related React components
function injectReactComponents() {
function injectReactComponents(pulseApiURL) {
pulseApiDomain = pulseApiURL;

// Science Fellowship
if (document.getElementById(`featured-science-fellow`)) {
let metadata = {
Expand All @@ -19,7 +157,7 @@ function injectReactComponents() {
image: `https://images.pexels.com/photos/264206/pexels-photo-264206.jpeg?w=500`,
quote: `Quote quote quote quote quote quote quote quote quote quote quote quote.`,
affiliations: [`Stanford University Professor; YouthLAB founder`],
'fellow_directory_link': { type: `science`, link: `/fellowships/directory` }
'custom_link': { text: `See all science fellows`, link: `/fellowships/directory` }
};

ReactDOM.render(<Person metadata={metadata} />, document.getElementById(`featured-science-fellow`));
Expand All @@ -37,7 +175,7 @@ function injectReactComponents() {
image: `https://images.pexels.com/photos/802112/pexels-photo-802112.jpeg?w=500`,
quote: `Quote quote quote quote quote quote quote quote quote quote quote quote.`,
affiliations: [`Stanford University Professor; YouthLAB founder`],
'fellow_directory_link': { type: `science`, link: `/fellowships/directory` }
'custom_link': { text: `See all science fellows`, link: `/fellowships/directory` }
};

ReactDOM.render(<Person metadata={metadata} />, document.getElementById(`featured-open-web-fellow`));
Expand All @@ -55,11 +193,21 @@ function injectReactComponents() {
image: `https://static.pexels.com/photos/416138/pexels-photo-416138.jpeg?w=500`,
quote: `Quote quote quote quote quote quote quote quote quote quote quote quote.`,
affiliations: [ `Stanford University Professor; YouthLAB founder`],
'fellow_directory_link': { type: `science`, link: `/fellowships/directory` }
'custom_link': { text: `See all science fellows`, link: `/fellowships/directory` }
};

ReactDOM.render(<Person metadata={metadata} />, document.getElementById(`featured-fellow-support-page`));
}

// Fellows on Fellows Directory page
if (document.querySelectorAll(`#fellows-directory-featured-fellows`)) {
renderFellowsOnDirectoryPage();
}

// Fellows on individual Directory page (e.g., science directory, open web directory)
if (document.getElementById(`fellows-directory-fellows-by-type`)) {
renderFellowsOnDirectoryByTypePage();
}
}

export default { injectReactComponents };
Loading