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

2025 content update #192

Merged
merged 49 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
609bbfa
fix: not found text for typeahead
joshuagraber Jan 13, 2025
04e44e7
fix: linting rules broken in many files
joshuagraber Jan 13, 2025
f3ca1f7
refactor: workflow job names
joshuagraber Jan 13, 2025
7a0ed76
finish removing data view
josh-chamberlain Dec 25, 2024
06abfc7
remove PDAP logo
josh-chamberlain Dec 26, 2024
6dbad8b
reduce nav links
josh-chamberlain Jan 8, 2025
16d756d
remove main scroll
josh-chamberlain Jan 8, 2025
928afdc
rm search form request button
josh-chamberlain Jan 8, 2025
cf3b769
index context
josh-chamberlain Jan 8, 2025
164a58a
update img paths
josh-chamberlain Jan 8, 2025
bda63da
index language
josh-chamberlain Jan 8, 2025
03de344
about tweaks
josh-chamberlain Jan 8, 2025
77db065
index content
josh-chamberlain Jan 12, 2025
7bd5aa0
newsletter to about
josh-chamberlain Jan 13, 2025
8913ed2
about content
josh-chamberlain Jan 13, 2025
3ea907b
rm community and data views
josh-chamberlain Jan 13, 2025
08dd31c
funding model
josh-chamberlain Jan 13, 2025
48d3881
donate content
josh-chamberlain Jan 13, 2025
6dea6a1
linting
josh-chamberlain Jan 13, 2025
46b8a52
button and CTA cleanup
josh-chamberlain Jan 13, 2025
0574ac2
button destinations
josh-chamberlain Jan 14, 2025
39ac3bc
data alias
josh-chamberlain Jan 14, 2025
853730f
basic metrics
josh-chamberlain Jan 15, 2025
7123b8e
ignore 51 states
josh-chamberlain Jan 15, 2025
e44f1fa
add source count
josh-chamberlain Jan 15, 2025
7a23627
recent requests and fallback
josh-chamberlain Jan 16, 2025
f8e0f4e
recent requests cleanup
josh-chamberlain Jan 16, 2025
ce2e0e1
add plausible
josh-chamberlain Jan 16, 2025
b003686
add caching to requests
josh-chamberlain Jan 17, 2025
abd04b0
clean up comments
josh-chamberlain Jan 17, 2025
8185047
add recent sources
josh-chamberlain Jan 17, 2025
9592b38
recently added sources
josh-chamberlain Jan 17, 2025
50d4c97
clean up programs
josh-chamberlain Jan 17, 2025
acce8c0
Merge pull request #205 from Police-Data-Accessibility-Project/feat/u…
maxachis Jan 18, 2025
78f6365
update nav links
josh-chamberlain Jan 21, 2025
2ee6b70
about refactor
josh-chamberlain Jan 21, 2025
22295ce
issues and timeline
josh-chamberlain Jan 21, 2025
549ad6a
remove resolved in dev issues
josh-chamberlain Jan 21, 2025
6c2cc05
section borders
josh-chamberlain Jan 21, 2025
0ad6541
icons and docs
josh-chamberlain Jan 22, 2025
ceff4b2
newsletter button padding
josh-chamberlain Jan 22, 2025
15b8366
Merge branch '2025-content-update' of https://github.com/Police-Data-…
josh-chamberlain Jan 22, 2025
94f0b53
linting
josh-chamberlain Jan 22, 2025
a02c6fd
remove unused vars
josh-chamberlain Jan 22, 2025
1a88a94
move contact
josh-chamberlain Jan 22, 2025
9f3e7e5
adjust footer links
josh-chamberlain Jan 22, 2025
580184a
minor language update
josh-chamberlain Jan 23, 2025
140acd9
lint
josh-chamberlain Jan 23, 2025
01496fe
update donate
josh-chamberlain Jan 23, 2025
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
3 changes: 1 addition & 2 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
* @josh-chamberlain
* @joshuagraber

* @joshuagraber
8 changes: 4 additions & 4 deletions .github/workflows/pull.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:

jobs:
setup:
name: Setup client
name: Setup
runs-on: ubuntu-latest
steps:
- name: Cancel previous
Expand All @@ -28,7 +28,7 @@ jobs:
key: node-modules-${{ hashFiles('package-lock.json') }}

lint:
name: Lint client
name: Lint
needs: setup
runs-on: ubuntu-latest
steps:
Expand All @@ -48,7 +48,7 @@ jobs:
run: npm run lint

test:
name: Test client
name: Test
needs: setup
runs-on: ubuntu-latest
steps:
Expand All @@ -69,7 +69,7 @@ jobs:
run: npm run test:ci

build:
name: Build client
name: Build
needs: setup
runs-on: ubuntu-latest
steps:
Expand Down
143 changes: 113 additions & 30 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,31 +1,114 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" type="image/x-icon" href="/assets/favicon.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Public+Sans:[email protected]&display=swap"
rel="stylesheet"
/>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css"
rel="stylesheet"
type="text/css"
/>
<title>Police Data Accessibility Project</title>
</head>
<body>
<noscript>
<strong
>We're sorry but this website doesn't work properly without JavaScript
enabled. Please enable it to continue.</strong
>
</noscript>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>PDAP</title>
<link rel="icon" type="image/x-icon" href="./node_modules/pdap-design-system/public/images/favicon.png">
<meta
name="description"
content="Explore our database to see what kind of data is published about any police system in the United States. Find misconduct, budgets, and more."
/>
<meta
name="keywords"
content="police data, public records, open data, police transparency, police oversight"
/>
<meta content="width=device-width, initial-scale=1" name="viewport" />
<!-- schema.org -->
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NGO",
"name": "Police Data Access Point",
"alternateName": "PDAP",
"description": "A web app for helping people find and use public data about police systems.",
"url": "https://pdap.io",
"sameAs": [
"https://www.guidestar.org/profile/85-4207132",
"https://www.linkedin.com/company/pdap/",
"https://github.com/Police-Data-Accessibility-Project"
],
"foundingDate": "2021",
"areaServed": "United States",
"purpose": "Access to public records and promoting transparency in policing.",
"contactPoint": [
{
"@type": "ContactPoint",
"email": "[email protected]",
"contactType": "General Contact"
}
],
"knowsAbout": [
"public records",
"transparency",
"police",
"court",
"jail",
"legal system",
"scraping",
"FOIA"
]
}
</script>
<!-- plausible.io -->
<script defer data-domain="pdap.io" src="https://plausible.io/js/script.tagged-events.js"></script>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css"
rel="stylesheet"
type="text/css"
/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Public+Sans:[email protected]&display=swap" rel="stylesheet">
<link
href="https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,400;0,600;0,900;1,400;1,600;1,900&display=swap"
rel="stylesheet"
/>
<!-- [if lt IE 9]><script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js" type="text/javascript"></script><![endif] -->
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-REKS6B95BL"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-REKS6B95BL');
</script>
<!-- Google ads tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=AW-11016541790"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'AW-11016541790');
</script>
<!-- Event snippet for newsletter signup conversion page
In your html page, add the snippet and call gtag_report_conversion when someone clicks on the chosen link or button. -->
<script>
function gtag_report_conversion(url) {
var callback = function () {
if (typeof url != 'undefined') {
window.location = url;
}
};
gtag('event', 'conversion', {
send_to: 'AW-11016541790/BTkiCN2cyoEYEN6sjIUp',
event_callback: callback,
});
return false;
}
</script>
<link
href="node_modules/pdap-design-system/system/images/favicon.png"
rel="shortcut icon"
type="image/x-icon"
/>
<link href="node_modules/pdap-design-system/system/images/webclip.gif" rel="apple-touch-icon" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dev": "vite",
"build": "NODE_ENV=production vite build",
"serve": "vite preview --port 8888",
"lint": "eslint src --ext .js .",
"lint": "eslint src --ext .vue .",
"lint:fix": "npm run lint -- --fix",
"test": "vitest --dom --run",
"test:ci": "npm run test -- --silent",
Expand Down
7 changes: 5 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import { ErrorBoundary, Footer, Header, Spinner } from 'pdap-design-system';
import AuthWrapper from './components/AuthWrapper.vue';
import acronym from 'pdap-design-system/images/acronym.svg';
import lockup from 'pdap-design-system/images/lockup.svg';

import { NAV_LINKS, FOOTER_LINKS } from '@/util/constants';
import { provide, ref } from 'vue';
Expand All @@ -36,7 +35,11 @@ const routeKey = ref(null);

onBeforeRouteUpdate((to, from) => {
// preserves static key for data source by ID route so that component transition overrides top-level route
if ([to.path, from.path].every((path) => path.includes('data-source') && !path.includes('create'))) {
if (
[to.path, from.path].every(
(path) => path.includes('data-source') && !path.includes('create')
)
) {
routeKey.value = 'data-source-by-id';
} else {
routeKey.value = to.path;
Expand Down
3 changes: 3 additions & 0 deletions src/api/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,8 @@ export const ENDPOINTS = {
ID: {
UPDATE_PASSWORD: 'update-password'
}
},
METRICS: {
METRICS: 'metrics'
}
};
47 changes: 46 additions & 1 deletion src/api/data-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export async function getDataRequest(id) {
cached &&
isCachedResponseValid({
cacheTime: cached.timestamp,
// Cache for 5 minutes
// Cache for 3 minutes
intervalBeforeInvalidation: 1000 * 60 * 3
})
) {
Expand Down Expand Up @@ -92,3 +92,48 @@ export async function createRequest(data) {
requestsStore.clearCache();
return response.data;
}

export async function getRecentRequests() {
const requestsStore = useDataRequestsStore();

const cached = requestsStore.getDataRequestFromCache('recent-requests');

if (
cached &&
isCachedResponseValid({
cacheTime: cached.timestamp,
// Cache for 3 minutes
intervalBeforeInvalidation: 1000 * 60 * 3,
})
) {
return cached.data;
}

const params = {
sort_by: 'date_created',
sort_order: 'DESC',
// requested_columns: 'id,title', // Was not working, see data-sources-app/issues/581
// request_statuses: 'Intake', // Used for testing, should be 'Ready to start'
// limit: 3, // Not supported, see data-sources-app/issues/579
};

const response = await axios.get(REQUESTS_BASE, {
headers: HEADERS_BASIC,
params,
});

const recentRequests = response.data.data
.slice(0, 3)
.map((item) => ({
id: item.id,
title: item.title,
status: item.request_status,
locationDisplayName:
item.locations?.[0]?.display_name || 'Unknown location',
route: `/data-request/${item.id}`,
}));

requestsStore.setDataRequestToCache('recent-requests', recentRequests);

return recentRequests;
}
47 changes: 47 additions & 0 deletions src/api/data-sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,50 @@ export async function getDataSource(id) {

return response;
}

export async function getRecentSources() {
const dataSourceStore = useDataSourceStore();
const cached = dataSourceStore.getDataSourceFromCache('recent-sources');

if (
cached &&
isCachedResponseValid({
cacheTime: cached.timestamp,
// Cache for 3 minutes
intervalBeforeInvalidation: 1000 * 60 * 3,
})
) {
return cached.data;
}

const params = {
sort_by: 'created_at',
sort_order: 'DESC',
// requested_columns: 'id,name,created_at,source_url', // Was not working, see data-sources-app/issues/581
approval_status: 'approved',
};

try {
const response = await axios.get(DATA_SOURCES_BASE, {
headers: HEADERS_BASIC,
params,
});

const recentSources = response.data.data
.slice(0, 3)
.map((item) => ({
id: item.id,
name: item.name,
createdAt: item.created_at,
sourceUrl: item.source_url,
route: `/data-source/${item.id}`,
}));

dataSourceStore.setDataSourceToCache('recent-sources', recentSources);

return recentSources;
} catch (error) {
console.error('Error fetching recent sources:', error.response?.data || error.message);
throw error;
}
}
17 changes: 17 additions & 0 deletions src/api/metrics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import axios from 'axios';

const METRICS_BASE = `${import.meta.env.VITE_API_URL}/metrics`;
const HEADERS = {
'Content-Type': 'application/json'
};
const HEADERS_BASIC = {
...HEADERS,
authorization: `Basic ${import.meta.env.VITE_API_KEY}`
};

export async function getMetrics() {
const response = await axios.get(`${METRICS_BASE}`, {
headers: HEADERS_BASIC
});
return response.data;
}
Loading
Loading