-
Notifications
You must be signed in to change notification settings - Fork 153
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
---|---|---|
|
@@ -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$', | ||
views.fellows_directory_senior, | ||
name='fellowships-directory-senior'), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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'), | ||
] |
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 { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
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 => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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`]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 = { | ||
|
@@ -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`)); | ||
|
@@ -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`)); | ||
|
@@ -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 }; |
There was a problem hiding this comment.
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