Skip to content

Commit

Permalink
Create CV components
Browse files Browse the repository at this point in the history
  • Loading branch information
omfj committed May 30, 2024
1 parent afe496d commit a64cb02
Show file tree
Hide file tree
Showing 31 changed files with 517 additions and 273 deletions.
File renamed without changes
26 changes: 26 additions & 0 deletions src/lib/components/Gradients.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<div class="gradient-1"></div>
<div class="gradient-2"></div>

<style>
.gradient-1 {
z-index: -1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: linear-gradient(160deg, #a2cffe 0%, rgba(255, 255, 255, 0) 25%);
}
.gradient-2 {
z-index: -1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: linear-gradient(200deg, #a2cffe 0%, rgba(255, 255, 255, 0) 55%);
}
</style>
143 changes: 143 additions & 0 deletions src/lib/components/cv/CV.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<script lang="ts">
import type { CV } from '$lib/data';
import Avatar from '$lib/assets/avatar.png?url';
import { Page, PageWrapper, Text, Metadata, Section, Table } from './internals';
type Props = {
cv: CV;
};
let { cv }: Props = $props();
let { metadata, education, workExperience, volunteerExperience, skills } = cv;
</script>

<PageWrapper>
<Page class="z-30" id="cv">
<div class="flex flex-col md:flex-row gap-10">
<div class="block">
<img src={Avatar} alt="Ole Magnus" class="h-36 max-w-36 flex rounded-full border shadow" />
</div>

<div>
<h1 class="text-3xl font-semibold mb-6">Ole Magnus Fon Johnsen</h1>

<Metadata.Root>
{#each metadata as { label, value, link }}
<Metadata.Item>
<Metadata.Label>{label}:</Metadata.Label>{' '}
{#if link}
<Metadata.Link href={link}>{value}</Metadata.Link>
{:else}
{value}
{/if}
</Metadata.Item>
{/each}
</Metadata.Root>
</div>
</div>

<Section.Root>
<Section.Title>About me</Section.Title>

<Text>
I am an outgoing and curious person who loves to learn. Ever since I was young, I have had a
great interest in everything related to computers and technology. When I am not studying, I
enjoy playing video games, or tennis with friends if the weather is nice.
</Text>
</Section.Root>

<Section.Root>
<Section.Title>Education</Section.Title>

<Table.Root>
{#each education as { year, title, institution }}
<Table.Item>
<Table.Label>{year}</Table.Label>
<Table.Content>
<Table.Description>
{title} at {institution}
</Table.Description>
</Table.Content>
</Table.Item>
{/each}
</Table.Root>
</Section.Root>

<Section.Root>
<Section.Title>Work experience</Section.Title>

<Table.Root>
{#each workExperience as { year, title, company, description }}
<Table.Item>
<Table.Label>{year}</Table.Label>
<Table.Content>
<Table.Title>
{title} at {company}
</Table.Title>
<Table.Description>{description}</Table.Description>
</Table.Content>
</Table.Item>
{/each}
</Table.Root>
</Section.Root>

<Section.Root>
<Section.Title>Volunteer experience</Section.Title>

<Table.Root>
{#each volunteerExperience as { year, title, company, description }}
<Table.Item>
<Table.Label>{year}</Table.Label>
<Table.Content>
<Table.Title>
{title} at {company}
</Table.Title>
<Table.Description>{description}</Table.Description>
</Table.Content>
</Table.Item>
{/each}
</Table.Root>
</Section.Root>

<Section.Root>
<Section.Title>Skills</Section.Title>

<Table.Root>
{#each skills as { title, description }}
<Table.Item>
<Table.Label>{title}</Table.Label>
<Table.Content>
<Table.Description>{description}</Table.Description>
</Table.Content>
</Table.Item>
{/each}
</Table.Root>
</Section.Root>

<Section.Root>
<Section.Title>Other</Section.Title>

<Text>See some of my other projects on my GitHub, @omfj. (https://www.github.com/omfj)</Text>
<Text>
I also have some certificates on Codecademy. (https://www.codecademy.com/profiles/omfj)
</Text>
</Section.Root>
</Page>
</PageWrapper>

<style>
@media print {
:global(body *) {
visibility: hidden;
}
:global(#cv, #cv *) {
visibility: visible;
}
:global(#cv) {
position: absolute;
left: 0;
top: 0;
width: 100%;
}
}
</style>
5 changes: 5 additions & 0 deletions src/lib/components/cv/internals/Download.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<button
onclick={() => window.print()}
class="text-center bg-white hover:bg-gray-100 z-50 w-fit mx-auto text-gray-700 text-sm h-8 flex items-center justify-center mt-6 hover:text-blue-500 shadow-inner rounded-xl px-4 transition-all"
>Download as PDF</button
>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
let { children, class: className, ...props }: Props = $props();
</script>

<div class={cn('flex flex-col gap-10 max-w-screen-a4 w-full h-a4 font-sans', className)} {...props}>
<div class={cn('flex flex-col gap-10 max-w-screen-a4 w-full font-sans', className)} {...props}>
{@render children()}
</div>
15 changes: 15 additions & 0 deletions src/lib/components/cv/internals/PageWrapper.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLDivElement> & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<div class={cn('my-10 rounded bg-white shadow mx-auto border p-10 md:p-20', className)} {...props}>
{@render children()}
</div>
15 changes: 15 additions & 0 deletions src/lib/components/cv/internals/Text.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLParagraphElement> & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<p class={cn('text-xs', className)} {...props}>
{@render children()}
</p>
8 changes: 8 additions & 0 deletions src/lib/components/cv/internals/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export { default as DownloadButton } from './Download.svelte';
export { default as Page } from './Page.svelte';
export { default as PageWrapper } from './PageWrapper.svelte';
export { default as Text } from './Text.svelte';

export * as Metadata from './metadata';
export * as Section from './section';
export * as Table from './table';
14 changes: 14 additions & 0 deletions src/lib/components/cv/internals/metadata/MetadataItem.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import type { HTMLLiAttributes } from 'svelte/elements';
type Props = HTMLLiAttributes & {
children: Snippet;
};
let { children, ...props }: Props = $props();
</script>

<li {...props}>
{@render children()}
</li>
13 changes: 13 additions & 0 deletions src/lib/components/cv/internals/metadata/MetadataLabel.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLSpanElement> & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<span class={cn('font-semibold', className)} {...props}>{@render children()}</span>
19 changes: 19 additions & 0 deletions src/lib/components/cv/internals/metadata/MetadataLink.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAnchorAttributes } from 'svelte/elements';
type Props = HTMLAnchorAttributes & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<a
target="_blank"
class={cn('underline hover:text-blue-500 transition-colors', className)}
{...props}
>
{@render children()}
</a>
15 changes: 15 additions & 0 deletions src/lib/components/cv/internals/metadata/MetadataRoot.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLUListElement> & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<ul class={cn('text-xs flex flex-wrap gap-2', className)} {...props}>
{@render children()}
</ul>
4 changes: 4 additions & 0 deletions src/lib/components/cv/internals/metadata/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default as Root } from './MetadataRoot.svelte';
export { default as Link } from './MetadataLink.svelte';
export { default as Item } from './MetadataItem.svelte';
export { default as Label } from './MetadataLabel.svelte';
15 changes: 15 additions & 0 deletions src/lib/components/cv/internals/section/SectionRoot.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLDivElement> & {
children: Snippet;
};
let { children, ...props }: Props = $props();
</script>

<div {...props}>
{@render children()}
</div>
15 changes: 15 additions & 0 deletions src/lib/components/cv/internals/section/SectionTitle.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLHeadingElement> & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<h2 class={cn('text-lg font-semibold mb-2', className)} {...props}>
{@render children()}
</h2>
2 changes: 2 additions & 0 deletions src/lib/components/cv/internals/section/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as Root } from './SectionRoot.svelte';
export { default as Title } from './SectionTitle.svelte';
15 changes: 15 additions & 0 deletions src/lib/components/cv/internals/table/TableContent.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLDivElement> & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<div class={cn('flex flex-col gap-1', className)} {...props}>
{@render children()}
</div>
14 changes: 14 additions & 0 deletions src/lib/components/cv/internals/table/TableDescription.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLParagraphElement> & {
children: Snippet;
};
let { children, ...props }: Props = $props();
</script>

<p {...props}>
{@render children()}
</p>
15 changes: 15 additions & 0 deletions src/lib/components/cv/internals/table/TableItem.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLLiAttributes } from 'svelte/elements';
type Props = HTMLLiAttributes & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<li class={cn('flex flex-col gap-1 md:flex-row md:gap-4', className)} {...props}>
{@render children()}
</li>
15 changes: 15 additions & 0 deletions src/lib/components/cv/internals/table/TableLabel.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/cn';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
type Props = HTMLAttributes<HTMLParagraphElement> & {
children: Snippet;
};
let { children, class: className, ...props }: Props = $props();
</script>

<p class={cn('max-w-[150px] w-full font-semibold', className)} {...props}>
{@render children()}
</p>
Loading

0 comments on commit a64cb02

Please sign in to comment.