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

Refactor sharing tag component #1162

Merged
merged 11 commits into from
Jul 19, 2017
Binary file modified public/data/agencies-by-state.json.gz
Binary file not shown.
1 change: 1 addition & 0 deletions public/data/agencies-names-by-state.json

Large diffs are not rendered by default.

3,400 changes: 0 additions & 3,400 deletions public/swagger/swagger.json

This file was deleted.

22 changes: 21 additions & 1 deletion scripts/agencies/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,31 @@ const KEY = process.env.API_KEY
const url = `${API}/agencies?fields=agency_name,ori,primary_county,agency_type_name,icpsr_lat,icpsr_lng,months_reported,nibrs_months_reported,past_10_years_reported,state_abbr,submitting_name&per_page=25000&api_key=${KEY}`

// const agencies = require('./agencies.json')
const outFile = path.join(__dirname, '../../public/data/agencies-by-state.json')
const outDir = path.join(__dirname, '../../public/data/')

console.log('updating agencies data from api')
http
.get(url)
.then(res => res.data)
.then(agencies => {
const names = agencies.results
.map(agency => ({
key: agency.ori,
value: agency.agency_name,
}))
.reduce((accum, next) => {
return Object.assign({}, accum, {
[next.key]: next.value,
})
}, {})

const outFile = path.join(outDir, 'agencies-names-by-state.json')
fs.writeFile(outFile, JSON.stringify(names), err => {
if (err) throw err
})

return agencies
})
.then(agencies => {
const usStates = {}
agencies.results.forEach(agency => {
Expand Down Expand Up @@ -55,6 +74,7 @@ http
}
})

const outFile = path.join(outDir, 'agencies-by-state.json')
fs.writeFile(outFile, JSON.stringify(usStates), err => {
if (err) throw err

Expand Down
32 changes: 18 additions & 14 deletions src/components/About.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react'
import Helmet from 'react-helmet'
import { Link } from 'react-router'

import SharingTags from './SharingTags'
import Term from './Term'
import UsaMap from './UsaMap'

Expand Down Expand Up @@ -64,6 +65,7 @@ const agenciesParticiaptionDownloadUrl =
const About = ({ dispatch }) =>
<div>
<Helmet title="CDE :: About" />
<SharingTags title="About" />
<section className="bg-white">
<div className="px2 py7 container mx-auto">
<h1 className="mt0 mb4 pb1 fs-28 sm-fs-40 border-bottom border-blue-light">
Expand All @@ -73,17 +75,17 @@ const About = ({ dispatch }) =>
<div className="md-col md-col-9 md-pr7 fs-16 sm-fs-20 serif">
<p className="mb2 md-m0">
The Crime Data Explorer is part of the FBI’s broader effort to
modernize the reporting of national crime data.
It allows you to{' '}
modernize the reporting of national crime data. It allows you to{' '}
<a href="explorer/violent-crime" className="underline">
view trends
</a>,{' '}
<a href="/downloads-and-docs" className="underline">
download bulk data
</a>, and access
the <a href="/api" className="underline">Crime Data API</a> for
reported crime at the
national, state, and agency levels.
</a>, and access the{' '}
<a href="/api" className="underline">
Crime Data API
</a>{' '}
for reported crime at the national, state, and agency levels.
</p>
</div>
<div className="md-col md-col-3">
Expand Down Expand Up @@ -134,7 +136,9 @@ const About = ({ dispatch }) =>
<div className="bold monospace">
{`${d.count} State${d.count !== 1 ? 's' : ''}`}
</div>
<div>{d.text}</div>
<div>
{d.text}
</div>
</div>
</div>,
)}
Expand Down Expand Up @@ -183,12 +187,9 @@ const About = ({ dispatch }) =>
This data includes the number of offenses that were reported on a
state or agency level. It captures the most serious offense
involved in crime incidents according to the{' '}
<Term id="hierarchy rule">
hierarchy rule
</Term>
{' '}
and supplemental details depending on the offense. For example,
victim and offender data are collected only for murder offenses.
<Term id="hierarchy rule">hierarchy rule</Term> and supplemental
details depending on the offense. For example, victim and offender
data are collected only for murder offenses.
</p>
<div className="mb-tiny bold">
Incident-based (NIBRS) data
Expand All @@ -207,7 +208,10 @@ const About = ({ dispatch }) =>
</p>
<p>
The Crime Data Explorer makes this data available through the{' '}
<a href="/api" className="underline">API</a> and{' '}
<a href="/api" className="underline">
API
</a>{' '}
and{' '}
<a href="/downloads-and-docs" className="underline">
bulk downloads
</a>.
Expand Down
2 changes: 2 additions & 0 deletions src/components/DownloadsAndDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Helmet from 'react-helmet'

import DownloadBulkNibrs from './DownloadBulkNibrs'
import DownloadDataBtn from './DownloadDataBtn'
import SharingTags from './SharingTags'
import Term from './Term'
import otherDatasets from '../../content/datasets.yml'
import markdown from '../util/md'
Expand All @@ -19,6 +20,7 @@ const nibrsTerm = (
const DownloadsAndDocs = () =>
<section className="bg-white">
<Helmet title="CDE :: Downloads & Documentation" />
<SharingTags title="Downloads & Documentation" />
<div className="px2 py7 container mx-auto">
<h1 className={`mt0 mb4 pb1 fs-28 sm-fs-40 ${border}`}>
Downloads & Documentation
Expand Down
18 changes: 14 additions & 4 deletions src/components/Explorer.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import startCase from 'lodash.startcase'
import PropTypes from 'prop-types'
import React from 'react'
import Helmet from 'react-helmet'
Expand All @@ -7,6 +8,7 @@ import AgencyChartContainer from '../containers/AgencyChartContainer'
import ExplorerHeaderContainer from '../containers/ExplorerHeaderContainer'
import NibrsContainer from '../containers/NibrsContainer'
import NotFound from './NotFound'
import SharingTags from './SharingTags'
import SidebarContainer from '../containers/SidebarContainer'
import SparklineContainer from '../containers/SparklineContainer'
import TrendContainer from '../containers/TrendContainer'
Expand All @@ -15,7 +17,9 @@ import { updateApp } from '../actions/composite'
import { showTerm } from '../actions/glossary'
import { hideSidebar, showSidebar } from '../actions/sidebar'
import offenses from '../util/offenses'
import { getAgency } from '../util/agencies'
import { getPlaceInfo } from '../util/place'
import { sentenceCase } from '../util/text'

import lookup from '../util/usa'

Expand Down Expand Up @@ -69,10 +73,11 @@ class Explorer extends React.Component {

render() {
const { appState, dispatch, params } = this.props
const { filters } = appState
const { agencies, filters } = appState
const { crime } = params
const { place, placeType } = getPlaceInfo(params)
const isAgency = placeType === 'agency'
const agency = placeType === 'agency' && getAgency(agencies, place)
const placeDisplay = agency ? agency.agency_name : startCase(place)

// ensure app state place matches url params place
if (filters.place && filters.place !== place) return null
Expand All @@ -85,6 +90,11 @@ class Explorer extends React.Component {
return (
<div className="site-wrapper">
<Helmet title="CDE :: Explorer" />
<SharingTags
title={`${sentenceCase(crime)} reported ${placeType === 'agency'
? 'by the'
: 'in'} ${placeDisplay}`}
/>
<div className="sticky top-0">
<div className="inline-block p1 bg-red-bright rounded-br md-hide lg-hide">
<button
Expand All @@ -108,8 +118,8 @@ class Explorer extends React.Component {
<div className="site-content" id="explorer">
<div className="container-main mx-auto px2 md-py3 lg-px3">
<ExplorerHeaderContainer />
{isAgency && <SparklineContainer />}
{isAgency ? <AgencyChartContainer /> : <TrendContainer />}
{agency && <SparklineContainer />}
{agency ? <AgencyChartContainer /> : <TrendContainer />}
<NibrsContainer />
<AboutTheData
crime={crime}
Expand Down
48 changes: 24 additions & 24 deletions src/components/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import Helmet from 'react-helmet'
import { Link } from 'react-router'

import LocationSelect from './LocationSelect'
import SharingTags from './SharingTags'
import UsaMap from './UsaMap'
import { updateApp } from '../actions/composite'
import { updateFilters } from '../actions/filters'
import { oriToState } from '../util/agencies'
import { crimeTypes } from '../util/offenses'
import { slugify } from '../util/text'
import stateLookup from '../util/usa'
import dataPreview from '../../content/preview.yml'
Expand Down Expand Up @@ -41,6 +43,7 @@ const Home = ({ appState, dispatch, router }) => {
return (
<div>
<Helmet title="CDE :: Home" />
<SharingTags />
<section className="px2 bg-blue-white">
<div className="py7 container mx-auto relative">
<h1 className="mt0 mb4 pb1 fs-28 sm-fs-40 border-bottom border-blue-light">
Expand All @@ -54,13 +57,11 @@ const Home = ({ appState, dispatch, router }) => {
</Link>,{' '}
<Link to="/downloads-and-docs" className="underline">
download bulk datasets
</Link>, and access
the{' '}
</Link>, and access the{' '}
<a href="/api" className="underline">
Crime Data API
</a>{' '}
for reported crime at the national, state, and
agency levels.
for reported crime at the national, state, and agency levels.
</p>
</div>
</section>
Expand All @@ -87,26 +88,22 @@ const Home = ({ appState, dispatch, router }) => {
onChange={selectCrime}
defaultValue={crime || ''}
>
<option value="" disabled>Crime Type</option>
<option value="" disabled>
Crime Type
</option>
<optgroup label="Violent Crime">
<option value="violent-crime">
All Violent Crime
</option>
<option value="homicide">Homicide</option>
<option value="rape">Rape</option>
<option value="robbery">Robbery</option>
<option value="aggravated-assault">Aggravated Assault</option>
{crimeTypes.violentCrime.map((o, i) =>
<option key={i} value={o.id || slugify(o)}>
{o.text || o}
</option>,
)}
</optgroup>
<optgroup label="Property Crime">
<option value="property-crime">
All Property Crime
</option>
<option value="arson">Arson</option>
<option value="burglary">Burglary</option>
<option value="larceny">Larceny Theft</option>
<option value="motor-vehicle-theft">
Motor Vehicle Theft
</option>
{crimeTypes.propertyCrime.map((o, i) =>
<option key={i} value={o.id || slugify(o)}>
{o.text || o}
</option>,
)}
</optgroup>
</select>
</div>
Expand Down Expand Up @@ -150,7 +147,9 @@ const Home = ({ appState, dispatch, router }) => {
<div className="mb1 pb-tiny bold border-bottom border-blue-light">
{d.title}
</div>
<p className="mb2">{d.description}</p>
<p className="mb2">
{d.description}
</p>
</div>
</div>,
)}
Expand All @@ -171,8 +170,9 @@ const Home = ({ appState, dispatch, router }) => {
Open data
</h2>
<p className="p0 md-col-9 fs-16 sm-fs-20 serif">
The data is voluntarily submitted by as many as 18,000 law enforcement agencies
across the country that participate in the FBI’s{' '}
The data is voluntarily submitted by as many as 18,000 law
enforcement agencies across the country that participate in the
FBI’s{' '}
<a href="https://ucr.fbi.gov/" className="underline">
Uniform Crime Reporting (UCR) Program
</a>. This is an open data project to improve the nation’s crime
Expand Down
62 changes: 19 additions & 43 deletions src/components/SharingTags.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,30 @@
import startCase from 'lodash.startcase'
import PropTypes from 'prop-types'
import React from 'react'
import Helmet from 'react-helmet'
import { connect } from 'react-redux'

import offenses from '../util/offenses'
import { getAgency } from '../util/agencies'
import { getPlaceInfo } from '../util/place'
import usa from '../util/usa'
const SharingTags = ({ description, image, title }) =>
<div>
<Helmet>
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />

const SharingTags = ({ agency, crime, place, since, until }) => {
const placeDisplay = agency ? agency.agency_name : startCase(place)
const title = `${startCase(
crime,
)} offenses reported by ${placeDisplay}, ${since}–${until}`
return (
<div>
<Helmet>
<meta property="og:title" content={title} />

<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@fbi" />
</Helmet>
</div>
)
}
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@fbi" />
</Helmet>
</div>

SharingTags.propTypes = {
agency: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
crime: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
place: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
since: PropTypes.number,
until: PropTypes.number,
description: PropTypes.string,
image: PropTypes.string,
title: PropTypes.string,
}

const mapStateToProps = ({ agencies, filters }) => {
const { crime, since, until } = filters
const { place, placeType } = getPlaceInfo(filters)
const isAgency = placeType === 'agency'
const agency = isAgency && getAgency(agencies, place)
const isKnownCrime = crime && offenses.includes(crime)
const isKnownPlace = place && usa(place)

return {
agency,
crime: isKnownCrime ? crime : false,
place: isKnownPlace ? place : false,
since,
until,
}
SharingTags.defaultProps = {
description:
'The Crime Data Explorer publishes nationwide crime data collected by the FBI in an open and accessible format.',
image: 'https://crime-data-explorer.fr.cloud.gov/img/cde-logo.png',
title: 'FBI Crime Data Explorer',
}

export default connect(mapStateToProps)(SharingTags)
export default SharingTags
2 changes: 0 additions & 2 deletions src/containers/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import Feedback from '../components/Feedback'
import Footer from '../components/Footer'
import Glossary from '../components/Glossary'
import Header from '../components/Header'
import SharingTags from '../components/SharingTags'
import SkipContent from '../components/SkipContent'
import * as feedbackActions from '../actions/feedback'
import * as glossaryActions from '../actions/glossary'
Expand All @@ -35,7 +34,6 @@ const App = ({ actions, appState, children, dispatch, location }) =>
onClose={actions.hideFeedback}
/>
<Analytics />
<SharingTags />
</div>

App.propTypes = {
Expand Down
Loading