Skip to content

Commit

Permalink
Better print friendly version
Browse files Browse the repository at this point in the history
Signed-off-by: Shauna Gordon <[email protected]>
ShaunaGordon committed Jan 12, 2025
1 parent 3a04cba commit 33d039c
Showing 7 changed files with 139 additions and 173 deletions.
2 changes: 1 addition & 1 deletion public/css/main.css
Original file line number Diff line number Diff line change
@@ -183,6 +183,6 @@ details {
margin: var(--gutter-ultra-wide) var(--gutter-wide);
}

.print-only {
.print {
display: none;
}
132 changes: 6 additions & 126 deletions public/css/print.css
Original file line number Diff line number Diff line change
@@ -1,137 +1,17 @@
@import url('./variables.css');

nav {
padding: 0;
}

h1, h2, h3 {
margin: 0;
margin-bottom: var(--gutter-narrow);
text-transform: uppercase;
font-weight: bold;
}

section {
header {
padding-top: var(--gutter-wide);
}
}

a {
font-weight: normal;
text-decoration: none;

&::after {
content: attr(href);
}
}

details {
height: fit-content;

&::details-content {
display: contents;
}

summary {
display: none;
}
}

.cardholder {
display: block;
}

.card {
/* padding: var(--gutter-narrow) var(--gutter-normal); */
padding: 0;
break-inside: avoid-page;

h3 {
letter-spacing: 0px;
}

&:not(.old) {
& + .old { /* Target the first .old card */
grid-column-start: 1;

&::before {
content: "";
}
}
}

.volunteer {
position: static;
top: initial;
right: initial;
}
}

.highlights {
margin-left: var(--gutter-normal);
padding: 0;

li {
padding: 0;
}
}

.no-print {
.screen {
display: none;
}

.print-only {
.print {
display: contents;
}

#top {
padding-bottom: var(--gutter-wide);
header {
display: block;
}

nav {
ul {
display: grid;
grid-template-columns: repeat(auto-fit, 33%);
justify-content: space-between;
align-items: baseline;
padding: 0;
margin: 0;

li {
text-align: center;
/* border: 1px solid red; */
}
}
}
}

#intro {
padding-bottom: var(--gutter-normal);
header {
p {
max-width: 100%;
opacity: 1;
margin: 0;
margin-bottom: var(--gutter-normal);
}
}
h3 {
margin-bottom: 0;
}

#projects {
.card {
&.old {
display: none;
}

details {
display: none;
}
}
}

#app {
margin: var(--gutter-normal);
p {
margin: 0;
}
20 changes: 13 additions & 7 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
<template>
<header-section v-if="resume.basics" :basics="resume.basics"></header-section>
<intro-section v-if="resume.basics" :data="resume.basics"></intro-section>
<div class="screen">
<header-section v-if="resume.basics" :basics="resume.basics"></header-section>
<intro-section v-if="resume.basics" :data="resume.basics"></intro-section>

<work-section v-if="resume.work" :work="resume.work" :basics="resume.basics"></work-section>
<work-section v-if="resume.work" :work="resume.work" :basics="resume.basics"></work-section>

<projects-section v-if="resume.projects" :projects="resume.projects"></projects-section>
<projects-section v-if="resume.projects" :projects="resume.projects"></projects-section>

<publications-section v-if="resume.publications" :publications="resume.publications"></publications-section>
<publications-section v-if="resume.publications" :publications="resume.publications"></publications-section>

<education-section v-if="resume.education" :schools="resume.education"></education-section>
<education-section v-if="resume.education" :schools="resume.education"></education-section>

<hire-me v-if="resume.basics" :basics="resume.basics"></hire-me>
<hire-me v-if="resume.basics" :basics="resume.basics"></hire-me>
</div>
<div class="print">
<print-friendly :resume="resume"></print-friendly>
</div>
</template>

<script setup>
@@ -19,6 +24,7 @@ import EducationSection from './components/sections/Education.vue';
import HeaderSection from './components/sections/Header.vue';
import HireMe from './components/sections/HireMe.vue';
import IntroSection from './components/sections/Intro.vue';
import PrintFriendly from './components/sections/PrintFriendly.vue';
import ProjectsSection from './components/sections/Projects.vue';
import PublicationsSection from './components/sections/Publications.vue';
import WorkSection from './components/sections/Experience.vue';
41 changes: 4 additions & 37 deletions src/components/sections/Header.vue
Original file line number Diff line number Diff line change
@@ -2,14 +2,14 @@
<section id="top">
<header>
<img class="avatar" :src="basics?.image" />
<h1 :title="basics?.pronouns.join('/')"><span">I'm </span>{{ basics?.name }}</h1>
<h1 :title="basics?.pronouns.join('/')">I'm {{ basics?.name }}</h1>
<h2>{{ basics?.label }}</h2>
</header>
<nav>
<ul>
<li v-for="(item, i) in basics?.profiles" :key="i" :class="networks[item.network.toLowerCase()].print ? '' : 'no-print'">
<a :href="item.url" target="_blank">
<i :class="iconClass(item.network.toLowerCase())"></i>{{ item.network }}
<i :class="getProfileIcon(item.network.toLowerCase())"></i>{{ item.network }}
</a>
</li>
</ul>
@@ -18,43 +18,10 @@
</template>

<script setup>
import { useIcons } from '../../mixins/icons';
import { useProfiles } from '../../mixins/profiles';
const { getFaBrandClass, getFaClass } = useIcons();
const { networks, getProfileIcon } = useProfiles();
const { basics } = defineProps(['basics']);
const networks = {
blog: {
brand: false,
icon: 'pencil-alt'
},
github: {
icon: 'github-alt',
brand: true
},
gitlab: {
icon: 'gitlab',
brand: true
},
// {
// link: 'https://goo.gl/PXLSWi',
// icon: 'file-alt',
// text: 'Resume'
// },
linkedin: {
icon: 'linkedin',
brand: true
},
"slide decks": {
icon: 'chalkboard-teacher',
brand: false
}
}
const iconClass = (network) => {
const icon = networks[network].brand ? getFaBrandClass(networks[network].icon) : getFaClass(networks[network].icon)
return `${icon} no-print`;
}
</script>
59 changes: 59 additions & 0 deletions src/components/sections/PrintFriendly.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<template>
<h1>{{ resume?.basics?.name }}</h1>
<ul>
<li>{{ resume?.basics?.email }}</li>
<li>{{ resume?.basics?.phone }}</li>
<li>{{ resume?.basics?.location.city }}, {{ resume?.basics?.location.region }}, {{ resume?.basics?.location.countryCode }}</li>
</ul>
<ul v-if="resume?.basics?.profiles.length > 0">
<li v-for="(profile, i) in resume?.basics?.profiles" :key="i" v-if="networks[profile?.network.toLowerCase()]?.print">
<i :class="getProfileIcon(profile?.network.toLowerCase())"></i>
{{ profile?.url }}
</li>
</ul>
<div v-if="resume?.basics?.summary" v-html="fromMarkdown(resume?.basics?.summary)"></div>
<h2>Experience</h2>
<div v-for="(job, i) in resume?.work" :key="i">
<h3>{{ job.name }}</h3>
<p>{{ job.entity }}</p>
<p>{{ toWordMonthFormat(job.startDate) }} - {{ toWordMonthFormat(job.endDate) || 'Current' }}</p>
<ul>
<li v-for="(item, i) in job.highlights" :key="i" v-html="fromInlineMarkdown(item)"></li>
</ul>
</div>
<h2>Projects</h2>
<div v-for="(project, i) in resume?.projects" :key="i">
<h3>{{ project.name }}</h3>
<p>{{ project.entity }}</p>
<p>{{ project.startDate }} - {{ project.endDate || 'Ongoing' }}</p>
<ul>
<li v-for="(item, i) in project.highlights" :key="i" v-html="fromInlineMarkdown(item)"></li>
</ul>
</div>
<h2>Education</h2>
<div v-for="(school, i) in resume?.education" :key="i">
<h3>{{ school.institution }}</h3>
<p>{{ school.studyType }}, {{ school.area }}</p>
<p>Graduated {{ school.honors || null }} {{ school.endDate }}</p>
</div>
</template>

<script setup>
import { onMounted } from 'vue';
const props = defineProps(['resume']);
import { useProfiles } from '../../mixins/profiles';
import { useMarkdown } from '../../mixins/markdown';
import { useDateUtils } from '../../mixins/dateUtils';
const { networks, getProfileIcon } = useProfiles();
const { fromMarkdown, fromInlineMarkdown } = useMarkdown();
const { toWordMonthFormat } = useDateUtils();
onMounted(() => {
console.log(props.resume)
})
</script>

<style scoped>
</style>
13 changes: 12 additions & 1 deletion src/mixins/dateUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
export const useDateUtils = () => {
const isCurrent = (date, cutoff = 5) => !date || Date.parse(date) >= Date.parse((new Date()).getFullYear() - cutoff);

return { isCurrent };
const toWordMonthFormat = (rawDate) => {
const date = Date.parse(rawDate);

const options = {
month: 'long',
year: 'long'
};

return date.toLocaleString('default', options);
}

return { isCurrent, toWordMonthFormat };
}
45 changes: 44 additions & 1 deletion src/mixins/profiles.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,50 @@
import { useIcons } from './icons';

const { getFaBrandClass, getFaClass } = useIcons();

export const useProfiles = () => {
const networks = {
blog: {
brand: false,
icon: 'pencil-alt',
print: true
},
github: {
icon: 'github-alt',
brand: true,
print: true
},
gitlab: {
icon: 'gitlab',
brand: true,
print: false
},
// {
// link: 'https://goo.gl/PXLSWi',
// icon: 'file-alt',
// text: 'Resume'
// },
linkedin: {
icon: 'linkedin',
brand: true,
print: true
},
"slide decks": {
icon: 'chalkboard-teacher',
brand: false,
print: false
}
};

const getProfile = (network, profiles) => {
return Object.values(profiles).find((profile) => profile.network.toLowerCase() == network.toLowerCase());
};

return { getProfile };
const getProfileIcon = (network) => {
const icon = networks[network].brand ? getFaBrandClass(networks[network].icon) : getFaClass(networks[network].icon)

return `${icon}`;
};

return { getProfile, getProfileIcon, networks };
}

0 comments on commit 33d039c

Please sign in to comment.