Skip to content

Commit e9b1249

Browse files
committed
Import and open source project
1 parent eaf471c commit e9b1249

16 files changed

+537
-16
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
### README
22

3-
Example page patterns showcasing [Checkr Embeds](https://docs.checkr.com/embeds).
3+
A minimal application which showcases how typical product user experiences can incorporate [Checkr Embeds](https://docs.checkr.com/embeds).
4+
5+
[checkr-embed-patterns.herokuapp.com](https://checkr-embed-patterns.herokuapp.com/)
6+
7+
### Developing
8+
9+
* Run `yarn install` to install dependencies.
10+
* Run `yarn dev` to start it at [http://localhost:5000](http://localhost:5000).

app.js

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
var express = require('express');
2-
var app = express();
1+
import express from 'express';
2+
import path from 'path';
3+
import {fakeData, pageHelp} from './utils.js'
34

4-
// set the view engine to ejs
5-
app.set('view engine', 'ejs');
5+
const port = process.env.PORT || 5000;
6+
const app = express();
7+
const __dirname = path.resolve();
68

7-
// use res.render to load up an ejs view file
9+
app.set('view engine', 'ejs');
10+
app.set('views', './views');
11+
app.use(express.static('public'))
812

9-
// index page
1013
app.get('/', function(req, res) {
11-
res.render('pages/index');
14+
res.render('index', pageHelp('index'));
1215
});
1316

14-
// about page
15-
app.get('/about', function(req, res) {
16-
res.render('pages/about');
17+
app.get('/patterns/:slug', function(req, res) {
18+
res.render(`${req.params.slug}`, {...fakeData(), ...pageHelp(req.params.slug)});
1719
});
1820

19-
app.listen(8080);
20-
console.log('Server is listening on port 8080');
21+
app.listen(port);
22+
console.log(`Started at http://localhost:${port}`);
23+

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
"description": "",
55
"main": "app.js",
66
"scripts": {
7-
"dev": "nodemon app.js"
7+
"dev": "nodemon app.js",
8+
"start": "node app.js"
89
},
9-
"keywords": [],
10-
"author": "",
10+
"type": "module",
11+
"keywords": [
12+
"checkr"
13+
],
14+
"author": "Checkr",
1115
"license": "",
1216
"dependencies": {
17+
"@faker-js/faker": "^6.0.0-alpha.6",
1318
"ejs": "^3.1.6",
1419
"express": "^4.17.2"
1520
},

public/code.png

413 Bytes
Loading

public/favicon.ico

15 KB
Binary file not shown.

public/logo.png

14.9 KB
Loading

public/styles.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
:root {
2+
--light-gray: #f4f4f4;
3+
--green: #85bf3e;
4+
--white: #ffffff;
5+
}
6+
7+
body {
8+
background-color: var(--light-gray);
9+
padding-bottom: 5rem;
10+
}
11+
12+
.bg-dark, .btn, .btn:hover {
13+
background-color: var(--green) !important;
14+
color: var(--white);
15+
}
16+
17+
.checkr-dialog-content {
18+
width: 600px
19+
}
20+
21+
.logo {
22+
height: 35px;
23+
margin: 0 20px 0 25px;
24+
}

utils.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { faker } from '@faker-js/faker';
2+
3+
function fakeData () {
4+
return {
5+
candidates: Array(20).fill().map((item, i) => {
6+
return {
7+
address: `${faker.address.streetAddress()}, ${faker.address.state()} - ${faker.address.zipCode()}`,
8+
currentPosition: `${faker.name.jobTitle()} at ${faker.company.companyName()}`,
9+
email: faker.internet.email(),
10+
id: i,
11+
name: faker.name.findName(),
12+
notes: faker.lorem.paragraph(),
13+
lastUpdated: faker.date.past(),
14+
phone: faker.phone.phoneNumber(),
15+
step: faker.helpers.randomize(["interviewing", "offer made", "pending screening"])
16+
}
17+
}),
18+
funnelData: [
19+
["Applicants", 12000],
20+
["Pre-screened", 4000],
21+
["Interviewed", 2500],
22+
["Hired", 1500]
23+
]
24+
}
25+
}
26+
27+
const help = {
28+
'candidate-profile-actions': 'This shows an example candidate profile page with an actions dropdown which uses both Checkr Embeds via modals.',
29+
'candidate-pipeline': 'This shows Checkr Embeds within tabs in an example candidate listing page.',
30+
'full-page': 'This shows an example background check page for a candidate which uses both Checkr Embeds inline.',
31+
'index': 'When viewing a pattern, this section will describe more about it.'
32+
}
33+
34+
function pageHelp(slug) {
35+
return {pageHelp: help[slug] };
36+
}
37+
38+
export {fakeData, pageHelp}

views/actions-dropdown.ejs

Whitespace-only changes.

views/candidate-pipeline.ejs

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<%- include('./partials/head'); %>
5+
</head>
6+
<body>
7+
<%- include('./partials/navbar'); %>
8+
9+
<div class="container-fluid">
10+
<div class="my-5">
11+
<h2>Candidate Pipeline</h2>
12+
<h5>Position: Software Engineer</h3>
13+
</div>
14+
15+
<div class="row">
16+
<div class="col-12 mb-5">
17+
<div class="d-flex justify-content-center">
18+
<div id="funnel"></div>
19+
</div>
20+
</div>
21+
</div>
22+
23+
<div class="row">
24+
<div class="col-12">
25+
<div class="accordion accordion-flush" id="accordion-candidates">
26+
<% candidates.forEach(candidate => { %>
27+
<div class="accordion-item">
28+
<div class="accordion-header">
29+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#candidate-detail-<%= candidate.id %>">
30+
<span class="w-25"><%= candidate.name %></span>
31+
<span class="w-25"><span class="badge bg-secondary"><%= candidate.step %></span></span>
32+
<span class="w-25 small text-muted text-truncate"><%= candidate.notes %></span>
33+
<span class="text-muted small w-25 text-end"><span class="me-3"><%= candidate.lastUpdated.toLocaleDateString('en-US') %></span></span>
34+
</button>
35+
</div>
36+
<div id="candidate-detail-<%= candidate.id %>" class="accordion-collapse collapse" data-bs-parent="#accordion-candidates">
37+
<div class="accordion-body">
38+
<ul class="nav nav-tabs">
39+
<li class="nav-item">
40+
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#candidate-tab-content-<%= candidate.id %>-info" type="button">Basic Information</button>
41+
</li>
42+
<li class="nav-item">
43+
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#candidate-tab-content-<%= candidate.id %>-activity" type="button">Activity</button>
44+
</li>
45+
</ul>
46+
<div class="tab-content">
47+
<div class="tab-pane active p-3" id="candidate-tab-content-<%= candidate.id %>-info">
48+
<dl>
49+
<dt>Email</dt>
50+
<dd><%= candidate.email %></dd>
51+
<dt>Phone</dd>
52+
<dd><%= candidate.phone %></dt>
53+
<dt>Current Position</dt>
54+
<dd><%= candidate.currentPosition %></dd>
55+
<dt>Address</dt>
56+
<dd><%= candidate.address %></dd>
57+
<dt>Notes</dt>
58+
<dd><%= candidate.notes %></dd>
59+
</dl>
60+
</div>
61+
<div class="tab-pane p-3" id="candidate-tab-content-<%= candidate.id %>-activity">
62+
<div class="card mb-4">
63+
<div class="card-header">
64+
Screening - <%= candidate.lastUpdated.toLocaleDateString('en-US') %>
65+
</div>
66+
<div class="card-body">
67+
<p class="card-text"><%= candidate.notes %></p>
68+
</div>
69+
</div>
70+
<div class="card mb-4">
71+
<div class="card-header">
72+
Interview - <%= candidate.lastUpdated.toLocaleDateString('en-US') %>
73+
</div>
74+
<div class="card-body">
75+
<p class="card-text"><%= candidate.notes %></p>
76+
</div>
77+
</div>
78+
79+
<div class="card">
80+
<div class="card-header">Background checks</div>
81+
<div class="card-body">
82+
<button type="button" data-checkr-candidate-email="<%= candidate.email %>" data-checkr-embed="new-invitation" class="btn btn-sm">New Background Check</button>
83+
<div class="card-text mt-3">
84+
<div data-checkr-candidate-email="<%= candidate.email %>" data-checkr-embed="reports-overview"></div>
85+
</div>
86+
</div>
87+
</div>
88+
</div>
89+
</div>
90+
</div>
91+
</div>
92+
</div>
93+
<% }) %>
94+
</div>
95+
</div>
96+
</div>
97+
</div>
98+
99+
<script type="module">
100+
const styles = {
101+
'.btn-primary': {
102+
background: '#527a00',
103+
},
104+
'.header': {
105+
'font-size': '150%',
106+
'font-weight': 'normal',
107+
color: '#527a00',
108+
},
109+
'.form-label': {
110+
'font-weight': 'bold',
111+
},
112+
'.form-control': {
113+
padding: '0.5rem',
114+
},
115+
'.link': {
116+
'text-decoration': 'none'
117+
},
118+
};
119+
120+
const props = {
121+
externalCandidateId: 'WEB-SDK-DEMO-001',
122+
sessionTokenPath: '/session-token-path',
123+
fakeMode: true,
124+
styles
125+
}
126+
127+
document.querySelectorAll("[data-checkr-embed='new-invitation']").forEach(button => {
128+
button.addEventListener('click', event => {
129+
const newInvitationEmbed = new Checkr.Embeds.NewInvitation({...props, ...{defaultEmail: button.dataset.checkrCandidateEmail}});
130+
newInvitationEmbed.modal();
131+
embed.modal();
132+
});
133+
});
134+
135+
document.querySelectorAll("[data-checkr-embed='reports-overview']").forEach(section => {
136+
const reportsOverviewEmbed = new Checkr.Embeds.ReportsOverview({...props, ...{defaultEmail: section.dataset.checkrCandidateEmail}});
137+
reportsOverviewEmbed.render(section);
138+
});
139+
</script>
140+
141+
<script>
142+
const chart = new D3Funnel('#funnel');
143+
chart.draw(<%- JSON.stringify(funnelData) %>, {});
144+
</script>
145+
146+
</body>
147+
</html>

0 commit comments

Comments
 (0)