feat(contact): move contact information to header
- List location with city and country - Linkify phone number - Render decorative Feather icons - Use Node.js 14 with Intl.DisplayNames support
This commit is contained in:
parent
cdea9ecf9f
commit
1c5b4cb7c5
|
@ -12,7 +12,7 @@ jobs:
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 12
|
node-version: 14
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
10
index.js
10
index.js
|
@ -17,6 +17,12 @@ fs.readdirSync(partialsDir)
|
||||||
Handlebars.registerPartial(path.basename(filename, extname), template),
|
Handlebars.registerPartial(path.basename(filename, extname), template),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Handlebars.registerHelper('formatCountry', countryCode =>
|
||||||
|
Intl.DisplayNames
|
||||||
|
? new Intl.DisplayNames(['en'], { type: 'region' }).of(countryCode)
|
||||||
|
: countryCode,
|
||||||
|
)
|
||||||
|
|
||||||
Handlebars.registerHelper('formatDate', dateString =>
|
Handlebars.registerHelper('formatDate', dateString =>
|
||||||
new Date(dateString).toLocaleDateString('en', {
|
new Date(dateString).toLocaleDateString('en', {
|
||||||
month: 'short',
|
month: 'short',
|
||||||
|
@ -24,6 +30,10 @@ Handlebars.registerHelper('formatDate', dateString =>
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Handlebars.registerHelper('formatPhone', phone =>
|
||||||
|
phone.replace(/[^\d|+]+/g, ''),
|
||||||
|
)
|
||||||
|
|
||||||
Handlebars.registerHelper('formatURL', url =>
|
Handlebars.registerHelper('formatURL', url =>
|
||||||
url.replace(/^(https?:|)\/\//, '').replace(/\/$/, ''),
|
url.replace(/^(https?:|)\/\//, '').replace(/\/$/, ''),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
<section id="contact">
|
|
||||||
<h3>Contact</h3>
|
|
||||||
<div class="grid-list">
|
|
||||||
{{#email}}
|
|
||||||
<div>
|
|
||||||
<h4>Email</h4>
|
|
||||||
<a href="mailto:{{.}}">{{.}}</a>
|
|
||||||
</div>
|
|
||||||
{{/email}}
|
|
||||||
{{#phone}}
|
|
||||||
<div>
|
|
||||||
<h4>Phone</h4>
|
|
||||||
{{.}}
|
|
||||||
</div>
|
|
||||||
{{/phone}}
|
|
||||||
{{#url}}
|
|
||||||
<div>
|
|
||||||
<h4>Website</h4>
|
|
||||||
<a href="{{.}}">{{formatURL .}}</a>
|
|
||||||
</div>
|
|
||||||
{{/url}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
|
@ -1,8 +1,38 @@
|
||||||
<header class="masthead">
|
<header class="masthead">
|
||||||
{{#name}}
|
<div>
|
||||||
<h1>{{.}}</h1>
|
{{#name}}
|
||||||
{{/name}}
|
<h1>{{.}}</h1>
|
||||||
{{#label}}
|
{{/name}}
|
||||||
<h2>{{.}}</h2>
|
{{#label}}
|
||||||
{{/label}}
|
<h2>{{.}}</h2>
|
||||||
|
{{/label}}
|
||||||
|
</div>
|
||||||
|
<ul class="icon-list">
|
||||||
|
{{#location}}
|
||||||
|
{{#if city}}
|
||||||
|
<li>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle></svg>
|
||||||
|
{{city}}{{#countryCode}}, {{formatCountry .}}{{/countryCode}}
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{/location}}
|
||||||
|
{{#email}}
|
||||||
|
<li>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
|
||||||
|
<a href="mailto:{{.}}">{{.}}</a>
|
||||||
|
</li>
|
||||||
|
{{/email}}
|
||||||
|
{{#phone}}
|
||||||
|
<li>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg>
|
||||||
|
<a href="tel:{{formatPhone .}}">{{.}}</a>
|
||||||
|
</li>
|
||||||
|
{{/phone}}
|
||||||
|
{{#url}}
|
||||||
|
<li>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
||||||
|
<a href="{{.}}">{{formatURL .}}</a>
|
||||||
|
</li>
|
||||||
|
{{/url}}
|
||||||
|
</ul>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
<body>
|
<body>
|
||||||
{{#resume.basics}}
|
{{#resume.basics}}
|
||||||
{{> header}}
|
{{> header}}
|
||||||
{{> contact}}
|
|
||||||
{{> about}}
|
{{> about}}
|
||||||
{{> profiles}}
|
{{> profiles}}
|
||||||
{{/resume.basics}}
|
{{/resume.basics}}
|
||||||
|
|
18
style.css
18
style.css
|
@ -57,7 +57,7 @@ ul {
|
||||||
}
|
}
|
||||||
|
|
||||||
li + li {
|
li + li {
|
||||||
margin-top: 0.2em;
|
margin-top: 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
li::marker {
|
li::marker {
|
||||||
|
@ -130,6 +130,16 @@ cite::before {
|
||||||
content: '— ';
|
content: '— ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
fill: none;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
stroke: currentColor;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: round;
|
||||||
|
stroke-width: 2;
|
||||||
|
vertical-align: -0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
.masthead {
|
.masthead {
|
||||||
background: var(--mutedColor);
|
background: var(--mutedColor);
|
||||||
display: inherit;
|
display: inherit;
|
||||||
|
@ -137,7 +147,6 @@ cite::before {
|
||||||
grid-column: full;
|
grid-column: full;
|
||||||
grid-template-columns: inherit;
|
grid-template-columns: inherit;
|
||||||
padding: 4em 0;
|
padding: 4em 0;
|
||||||
row-gap: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.masthead > *,
|
.masthead > *,
|
||||||
|
@ -155,6 +164,11 @@ blockquote > * + * {
|
||||||
gap: 1.5em;
|
gap: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.grid-list {
|
.grid-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
|
|
|
@ -73,7 +73,7 @@ ul {
|
||||||
}
|
}
|
||||||
|
|
||||||
li + li {
|
li + li {
|
||||||
margin-top: 0.2em;
|
margin-top: 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
li::marker {
|
li::marker {
|
||||||
|
@ -146,6 +146,16 @@ cite::before {
|
||||||
content: '— ';
|
content: '— ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
fill: none;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
stroke: currentColor;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: round;
|
||||||
|
stroke-width: 2;
|
||||||
|
vertical-align: -0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
.masthead {
|
.masthead {
|
||||||
background: var(--mutedColor);
|
background: var(--mutedColor);
|
||||||
display: inherit;
|
display: inherit;
|
||||||
|
@ -153,7 +163,6 @@ cite::before {
|
||||||
grid-column: full;
|
grid-column: full;
|
||||||
grid-template-columns: inherit;
|
grid-template-columns: inherit;
|
||||||
padding: 4em 0;
|
padding: 4em 0;
|
||||||
row-gap: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.masthead > *,
|
.masthead > *,
|
||||||
|
@ -171,6 +180,11 @@ blockquote > * + * {
|
||||||
gap: 1.5em;
|
gap: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.grid-list {
|
.grid-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
|
@ -230,26 +244,29 @@ blockquote > * + * {
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="masthead">
|
<header class="masthead">
|
||||||
<h1>Richard Hendriks</h1>
|
<div>
|
||||||
<h2>Programmer</h2>
|
<h1>Richard Hendriks</h1>
|
||||||
</header>
|
<h2>Programmer</h2>
|
||||||
<section id="contact">
|
|
||||||
<h3>Contact</h3>
|
|
||||||
<div class="grid-list">
|
|
||||||
<div>
|
|
||||||
<h4>Email</h4>
|
|
||||||
<a href="mailto:richard.hendriks@mail.com">richard.hendriks@mail.com</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h4>Phone</h4>
|
|
||||||
(912) 555-4321
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h4>Website</h4>
|
|
||||||
<a href="http://richardhendricks.example.com">richardhendricks.example.com</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<ul class="icon-list">
|
||||||
|
<li>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle></svg>
|
||||||
|
San Francisco, United States
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
|
||||||
|
<a href="mailto:richard.hendriks@mail.com">richard.hendriks@mail.com</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg>
|
||||||
|
<a href="tel:9125554321">(912) 555-4321</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
||||||
|
<a href="http://richardhendricks.example.com">richardhendricks.example.com</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</header>
|
||||||
<section id="about">
|
<section id="about">
|
||||||
<h3>About</h3>
|
<h3>About</h3>
|
||||||
<article>
|
<article>
|
||||||
|
|
|
@ -12,6 +12,7 @@ test('renders a resume', t => {
|
||||||
test('renders valid HTML', t => {
|
test('renders valid HTML', t => {
|
||||||
const htmlvalidate = new HtmlValidate({
|
const htmlvalidate = new HtmlValidate({
|
||||||
extends: ['html-validate:recommended'],
|
extends: ['html-validate:recommended'],
|
||||||
|
rules: { 'svg-focusable': 'off' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
Loading…
Reference in New Issue