commit
f9b68c52be
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: How I've built my website
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-02-28T16:00:55.791Z
|
||||
thumbnail: /images/uploads/DSC01202.jpg
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Custom Redox keyboard assembly
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-04-10T15:16:54.820Z
|
||||
thumbnail: /images/uploads/img_20200301_171735.jpg
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Transition to Colemak keyboard layout
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-05-11T05:38:18.797Z
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Samsung Galaxy Buds+ Review
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-06-07T22:58:18.797Z # TODO executable line for generating date
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: I've made an RSS feed
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-06-15T15:48:18.797Z # TODO executable line for generating date
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: WebAssembly briefing
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-08-05T15:38:18.797Z # TODO executable line for generating date
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: How to deal with technical debt
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-11-08T15:57:18.797Z
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: I've moved my site to Netlify
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-11-20T20:35:05.230Z
|
||||
tags:
|
||||
@ -38,4 +40,4 @@ I haven't found a big decider feature in any of these so I just went with the on
|
||||
I was able to **configure whole deployment** of my website **in 8 minutes**.
|
||||
The instructions where so clear and simple that I've also **transfered my DNS nameserver** too. I didn't have to search in 10 different services and documentations. I've just went with the flow. Didn't had to change a single line of code. I've just removed the `amplify` folder and I don't want to see any of the AWS docs ever again.
|
||||
|
||||
It got me so pumped that I've immediately logged in to the CMS (finally) through my own domain and written this article.
|
||||
It got me so pumped that I've immediately logged in to the CMS (finally) through my own domain and written this article.
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Guide on error handling
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-12-09T14:44:11.948Z
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Logging recommendations
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2020-12-18T14:39:53.533Z
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Podcast episode about Agile development
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2021-02-16T09:09:57.102Z
|
||||
tags:
|
||||
@ -14,4 +16,4 @@ I have to admit, it was a wonderful experience and I've enjoyed it. I'd like to
|
||||
|
||||
The episode was **recorded in Slovak** language. You can **listen to the podcast episode here**:
|
||||
|
||||
<iframe src="https://open.spotify.com/embed-podcast/episode/0NE6Gakn6wUP6oj7Rq4viR" width="100%" height="232" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>
|
||||
<iframe src="https://open.spotify.com/embed-podcast/episode/0NE6Gakn6wUP6oj7Rq4viR" width="100%" height="232" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Introduction to JavaScript Application testing
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2021-05-07T14:44:57.102Z # update date accordingly
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: How we handle the rapid growth of the project team
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2021-12-16T11:02:10.123Z
|
||||
tags:
|
||||
@ -8,4 +10,4 @@ tags:
|
||||
- Interviews
|
||||
- Management
|
||||
---
|
||||
I've been interviewed by my friend [@zubkka](https://www.instagram.com/zubkka/) about my current position at _The Expert_ team as an Engineering Manager. We have talked about my journey at [sudolabs](https://sudolabs.com) but also about my early years and how I've got into programming. Please, [go check out the interview](https://sudolabs.com/blog/how-we-handle-the-rapid-growth-of-the-project-team) and let me know what you think. Happy reading!
|
||||
I've been interviewed by my friend [@zubkka](https://www.instagram.com/zubkka/) about my current position at _The Expert_ team as an Engineering Manager. We have talked about my journey at [sudolabs](https://sudolabs.com) but also about my early years and how I've got into programming. Please, [go check out the interview](https://sudolabs.com/blog/how-we-handle-the-rapid-growth-of-the-project-team) and let me know what you think. Happy reading!
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: First Weekly
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-02-06T17:13:02.611Z
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "I've started streaming - Weekly #06-2022 "
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-02-13T19:39:33.578Z
|
||||
tags:
|
||||
@ -42,4 +44,4 @@ My next pick will be a [podcast *Lifespan* hosted by Dr. David Sinclair](https:/
|
||||
|
||||
In our management course, we've been learning about different **person typologies**. That helped me to understand how I should treat other people and how to communicate better with them.
|
||||
|
||||
That's it for this week. Thank you very much!
|
||||
That's it for this week. Thank you very much!
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Laptop battery got fat - Weekly #07-2022"
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-02-20T17:50:56.214Z
|
||||
tags:
|
||||
@ -37,4 +39,4 @@ I have to also mention, that I've changed my theme to light [NeoSolarized](https
|
||||
|
||||
Github is now able to parse [mermaid diagrams](https://github.com/mermaid-js/mermaid#readme). You can [check out the announcement](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/). It looks like I could be able to do that on my blog as well. I will put this into my to-do list and perhaps code it sometime during my stream ;)
|
||||
|
||||
[State of JS](https://2021.stateofjs.com/en-US/) results for 2021 has been presented this week. I am very excited about the satisfaction rate of [@svelte/kit](https://github.com/sveltejs/kit).
|
||||
[State of JS](https://2021.stateofjs.com/en-US/) results for 2021 has been presented this week. I am very excited about the satisfaction rate of [@svelte/kit](https://github.com/sveltejs/kit).
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Error handling with Either<Type>
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-02-28T11:30:54.195Z
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Second attempt @ Weekly #08-2022"
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-02-28T11:49:53.914Z
|
||||
tags:
|
||||
@ -28,4 +30,4 @@ I was very surprised that the mermaid is directly dependent on the browser to be
|
||||
|
||||
I haven't finished it, yet. So **prepare for a new article** where I will present the solution. I will stream it on [my twitch](https://www.twitch.tv/michalvankodev) so if you're interested, **please follow me there**.
|
||||
|
||||
Let's keep it short. Thank you!
|
||||
Let's keep it short. Thank you!
|
||||
|
18
_posts/blog/2022-03-15-devbreak-1-state-of-js-2021.md
Normal file
18
_posts/blog/2022-03-15-devbreak-1-state-of-js-2021.md
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "DevBreak #1 State of JS 2021 review with Lukáš Orgován"
|
||||
segments:
|
||||
- broadcasts
|
||||
published: true
|
||||
date: 2022-03-15T20:22:21.191Z
|
||||
tags:
|
||||
- DevBreak
|
||||
---
|
||||
The first episode of the [DevBreak talk show](/broadcasts/tags/DevBreak).
|
||||
I've invited my close friend and a tech lead [Lukáš Orgován](https://www.linkedin.com/in/lukasorgovan/) to talk about the opinions on the results of the [State of JS 2021 survey](https://2021.stateofjs.com/en-us/).
|
||||
|
||||
This episode aired on the 15th of March 2022 and is in the Slovak language.
|
||||
|
||||
<div class="video-embed">
|
||||
<iframe src="https://player.twitch.tv/?video=1427225407&parent=localhost&parent=michalvanko.dev" frameborder="0" allowfullscreen="true" scrolling="no" height="100%" width="100%" class="embed"></iframe>
|
||||
</div>
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Coming from DevBreak - Weekly #11-2022"
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-03-19T21:22:35.128Z
|
||||
tags:
|
||||
@ -24,4 +26,4 @@ During the vacation time, I've stumbled upon a [great article about markdown by
|
||||
|
||||
The next one is a simpler tutorial on [Hosting a React App with OpenFaaS](https://www.openfaas.com/blog/react-app/). I am an advocate for open-source software and I am glad to see [OpenFaaS](https://www.openfaas.com) being still developed and trying to be more accessible for typical use-cases.
|
||||
|
||||
Be ready for the next one, Thank you!
|
||||
Be ready for the next one, Thank you!
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Happy Easter - Weekly #15-2022"
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-04-17T08:05:05.489Z
|
||||
tags:
|
||||
|
@ -0,0 +1,17 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "DevBreak #2 Stories and impressions from Hack Kosice 2022"
|
||||
segments:
|
||||
- broadcasts
|
||||
published: true
|
||||
date: 2022-04-26T20:22:21.191Z
|
||||
tags:
|
||||
- DevBreak
|
||||
---
|
||||
|
||||
At the last possible moment, I have been able to invite **Daniela, Samuel, and Filip** over to talk about stories and their impressions of the _Hack Kosice 2022_ event that took place last weekend.
|
||||
This episode aired on the 26th of April 2022 and is in the Slovak language.
|
||||
|
||||
<div class="video-embed">
|
||||
<iframe src="https://player.twitch.tv/?video=1468441353&parent=localhost&parent=michalvanko.dev" frameborder="0" allowfullscreen="true" scrolling="no" height="100%" width="100%" class="embed"></iframe>
|
||||
</div>
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Treasure hunt - Weekly #18-2022'
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-05-07T08:35:51.818Z
|
||||
tags:
|
||||
|
17
_posts/blog/2022-06-09-devbreak-3-full-stack-development.md
Normal file
17
_posts/blog/2022-06-09-devbreak-3-full-stack-development.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "DevBreak #3 Full-stack development with Dominik Štefan"
|
||||
segments:
|
||||
- broadcasts
|
||||
published: true
|
||||
date: 2022-06-09T20:22:21.191Z
|
||||
tags:
|
||||
- DevBreak
|
||||
---
|
||||
|
||||
My friend and former colleague [Dominik Štefan](https://www.linkedin.com/in/dominik-%C5%A1tefan-167266180/) came by to talk about his experience working on full-stack web application development. We talked about many different topics but most importantly we had a lot of fun.
|
||||
This episode aired on the 9th of June 2022 and is in the Slovak language.
|
||||
|
||||
<div class="video-embed">
|
||||
<iframe src="https://player.twitch.tv/?video=1503339615&parent=localhost&parent=michalvanko.dev" frameborder="0" allowfullscreen="true" scrolling="no" height="100%" width="100%" class="embed"></iframe>
|
||||
</div>
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Our attempt at Rusty game jam - Weekly #25-2022"
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-06-26T20:02:47.419Z
|
||||
tags:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Lovely London Trip
|
||||
segments:
|
||||
- blog
|
||||
published: true
|
||||
date: 2022-11-27T19:49:09.204Z
|
||||
tags:
|
||||
@ -40,4 +42,4 @@ And next time we will take a laptop with us so we can watch movies or when we ac
|
||||
|
||||
Credits for all pictures go to my wife [Marika](https://www.instagram.com/marika_vnk/). She says Hi!
|
||||
|
||||
![Me and my wife on the Queens walk](/images/uploads/image2.jpeg "Me and my wife on the Queens walk")
|
||||
![Me and my wife on the Queens walk](/images/uploads/image2.jpeg "Me and my wife on the Queens walk")
|
||||
|
17
_posts/blog/2023-01-21-devbreak-4-state-of-js-2022.md
Normal file
17
_posts/blog/2023-01-21-devbreak-4-state-of-js-2022.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "DevBreak #4 State of JS 2022 review with Filip Seman"
|
||||
segments:
|
||||
- broadcasts
|
||||
published: true
|
||||
date: 2023-01-21T20:22:21.191Z
|
||||
tags:
|
||||
- DevBreak
|
||||
---
|
||||
After another year, the results of the [State of JS](https://2022.stateofjs.com/en-us/) survey have been published.
|
||||
I've invited my #1 fan and friend [Filip Seman](https://www.linkedin.com/in/xseman/).
|
||||
This episode aired on the 21st of January 2023 and is in the Slovak language.
|
||||
|
||||
<div class="video-embed">
|
||||
<iframe src="https://player.twitch.tv/?video=1715138585&parent=localhost&parent=michalvanko.dev" frameborder="0" allowfullscreen="true" scrolling="no" height="100%" width="100%" class="embed"></iframe>
|
||||
</div>
|
@ -0,0 +1,16 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "DevBreak #5 Joys and concerns of Engineering manager with Pavol Dudrík"
|
||||
segments:
|
||||
- broadcasts
|
||||
published: true
|
||||
date: 2023-02-04T20:22:21.191Z
|
||||
tags:
|
||||
- DevBreak
|
||||
---
|
||||
In this episode, I've invited my friend [Pavol Dudrík](https://www.linkedin.com/in/pavol-dudr%C3%ADk-043100168/) to talk about what motivates us and makes us happy about the work of the Engineering manager. This job combines two views, and the transition from engineer to manager is often full of pitfalls. We want to share our experience and dispel misconceptions often associated with managerial positions in IT.
|
||||
This episode aired on the 4th of February 2023 and is in the Slovak language.
|
||||
|
||||
<div class="video-embed">
|
||||
<iframe src="https://player.twitch.tv/?video=1728904048&parent=localhost&parent=michalvanko.dev" frameborder="0" allowfullscreen="true" scrolling="no" height="100%" width="100%" class="embed"></iframe>
|
||||
</div>
|
@ -1,6 +1,10 @@
|
||||
---
|
||||
layout: blog
|
||||
title: dev - Ide to ? copy
|
||||
segments:
|
||||
- blog
|
||||
- broadcasts
|
||||
- cookbook
|
||||
published: true
|
||||
date: 2020-01-09T17:24:13.481Z
|
||||
thumbnail: /images/uploads/screenshot.gif
|
||||
|
@ -1,6 +1,10 @@
|
||||
---
|
||||
layout: blog
|
||||
title: dev - Ide to ?
|
||||
segments:
|
||||
- blog
|
||||
- broadcasts
|
||||
- cookbook
|
||||
published: true
|
||||
date: 2019-08-09T17:24:13.481Z
|
||||
thumbnail: /images/uploads/screenshot.gif
|
||||
|
@ -1,6 +1,10 @@
|
||||
---
|
||||
layout: blog
|
||||
title: dev - Anothert one
|
||||
segments:
|
||||
- blog
|
||||
- broadcasts
|
||||
- cookbook
|
||||
published: true
|
||||
date: 2019-11-03T11:01:32.621Z
|
||||
thumbnail: /images/uploads/responzio.png
|
||||
|
@ -1,6 +1,10 @@
|
||||
---
|
||||
layout: blog
|
||||
title: New Title
|
||||
segments:
|
||||
- blog
|
||||
- broadcasts
|
||||
- cookbook
|
||||
published: true
|
||||
date: 2020-05-11T05:38:18.797Z # TODO executable line for generating date
|
||||
tags:
|
||||
|
@ -1,29 +0,0 @@
|
||||
|
||||
<section id="personal">
|
||||
<h3>Personal Information</h3>
|
||||
<p>I was born on 26th of May in Košice, Slovakia and I still live here.</p>
|
||||
<h4>Hobbies:</h4>
|
||||
<p>
|
||||
I enjoy playing basketball with my friends. I also like to play other team sports like football and hockey.
|
||||
I also play squash and table tennis. Once I've won a competition in squash at my university.
|
||||
During summer I love water skiing and swimming in a nearby lake.
|
||||
<br />
|
||||
I am very passionate about music. I've also tried some software for composing music but I am not really hooked into that yet.
|
||||
From time to time I enjoy playing board games with my friends.
|
||||
</p>
|
||||
<h4>Interests:</h4>
|
||||
<p>
|
||||
I like to explore new technologies and I'm passionate about <em>Open Source movement</em>,
|
||||
<em>Internet of Things</em> applications and <em>Linux desktop evolution</em>.
|
||||
<br />
|
||||
I am interested in modern software architecture and <em>reactive programming</em>.
|
||||
<br />
|
||||
I've attended various <strong>tech conferences and hackathons</strong>. I like them for all of the fascinating ideas that might be invented.
|
||||
<br />
|
||||
I've given presentations on various topics related to <em>web development</em>. You can <a href='#presentations'>take a look at some of them here</a>.
|
||||
<br />
|
||||
I enjoy <strong>teaching and explaining</strong> how various technologies and techniques work to my colleagues for their better understanding.
|
||||
<br />
|
||||
I take advantage of <strong>test driven development</strong>.
|
||||
</p>
|
||||
</section><!--/personal-->
|
38
src/lib/articleContent/articleContent.ts
Normal file
38
src/lib/articleContent/articleContent.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { error } from '@sveltejs/kit'
|
||||
import fm from 'front-matter'
|
||||
import { readFile } from 'fs'
|
||||
import { parseField } from '$lib/markdown/parse-markdown'
|
||||
import { promisify } from 'util'
|
||||
|
||||
export interface ArticleAttributes {
|
||||
slug: string
|
||||
layout: string
|
||||
segments: string[]
|
||||
title: string
|
||||
published: boolean
|
||||
date: string
|
||||
thumbnail: string
|
||||
tags: string[]
|
||||
body: string
|
||||
}
|
||||
|
||||
export async function getArticleContent(slug: string) {
|
||||
let postSource: string
|
||||
try {
|
||||
postSource = await promisify(readFile)(`_posts/blog/${slug}.md`, 'utf-8')
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
if (e.code === 'ENOENT') {
|
||||
throw error(404, 'Post not found \n' + e.toString())
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
const parsedPost = fm<ArticleAttributes>(postSource)
|
||||
|
||||
const post = parseField<ArticleAttributes>('body')({
|
||||
...parsedPost.attributes,
|
||||
body: parsedPost.body,
|
||||
})
|
||||
return post
|
||||
}
|
@ -8,24 +8,13 @@ import {
|
||||
filterAndCount,
|
||||
type PaginationQuery,
|
||||
} from '$lib/pagination/pagination'
|
||||
import type { ArticleAttributes } from './articleContent'
|
||||
|
||||
export interface ArticlePreviewAttributes extends ArticleAttributes {
|
||||
preview: string
|
||||
}
|
||||
|
||||
const { NODE_ENV } = process.env
|
||||
|
||||
export interface PostAttributes {
|
||||
layout: string
|
||||
title: string
|
||||
published: boolean
|
||||
date: string
|
||||
thumbnail: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
export interface PostContent extends PostAttributes {
|
||||
preview: string
|
||||
slug: string
|
||||
published: boolean
|
||||
}
|
||||
|
||||
export async function getBlogListing(paginationQuery: PaginationQuery) {
|
||||
const files = await promisify(readdir)(`_posts/blog/`, 'utf-8')
|
||||
const filteredFiles = filterDevelopmentFiles(files)
|
||||
@ -36,7 +25,7 @@ export async function getBlogListing(paginationQuery: PaginationQuery) {
|
||||
`_posts/blog/${file}`,
|
||||
'utf-8'
|
||||
)
|
||||
const parsedAttributes = fm<PostAttributes>(fileContent)
|
||||
const parsedAttributes = fm<ArticleAttributes>(fileContent)
|
||||
|
||||
const lineOfTextRegExp = /^(?:\w|\[).+/gm
|
||||
const lines = parsedAttributes.body
|
||||
@ -53,7 +42,7 @@ export async function getBlogListing(paginationQuery: PaginationQuery) {
|
||||
})
|
||||
)
|
||||
const filteredContents = pipe(
|
||||
sortBy<PostContent>(prop('date')),
|
||||
sortBy<ArticlePreviewAttributes>(prop('date')),
|
||||
(items) => reverse(items),
|
||||
filter<(typeof contents)[0]>((article) => article.published),
|
||||
filterAndCount(paginationQuery)
|
11
src/lib/articleContent/onMountScripts.ts
Normal file
11
src/lib/articleContent/onMountScripts.ts
Normal file
@ -0,0 +1,11 @@
|
||||
declare global {
|
||||
interface Window {
|
||||
onMountScripts?: Array<() => void>
|
||||
}
|
||||
}
|
||||
export function runOnMountScripts() {
|
||||
window.onMountScripts?.forEach((fn) => {
|
||||
fn()
|
||||
})
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { format } from 'date-fns'
|
||||
import type { PostContent } from 'src/routes/blog/content'
|
||||
import type { ArticlePreviewAttributes } from '$lib/articleContent/articleContentListing'
|
||||
import SvgIcon from './SvgIcon.svelte'
|
||||
import {
|
||||
boldClass,
|
||||
@ -22,7 +22,7 @@
|
||||
licenceText,
|
||||
} from './Footer.css'
|
||||
|
||||
export let latestPosts: PostContent[]
|
||||
export let latestPosts: ArticlePreviewAttributes[]
|
||||
</script>
|
||||
|
||||
<footer class="site-footer navigation-theme {siteFooterClass}">
|
||||
@ -61,7 +61,7 @@
|
||||
<ul class={listUlClass}>
|
||||
{#each latestPosts as post}
|
||||
<li class={listLiClass}>
|
||||
<a rel="prefetch" href="/blog/{post.slug}">
|
||||
<a rel="prefetch" href="/{post.segments[0]}/{post.slug}">
|
||||
<span>{post.title}</span>
|
||||
<time class="date {dateClass}" datetime={post.date}>
|
||||
- {format(new Date(post.date), 'do MMM, yyyy')}
|
@ -12,40 +12,48 @@
|
||||
portfolioPageNavigationLinksClass,
|
||||
selectedClass,
|
||||
} from './Nav.css'
|
||||
import { page } from "$app/stores"
|
||||
import { page } from '$app/stores'
|
||||
|
||||
$: segment = $page.url.pathname
|
||||
|
||||
let links = [
|
||||
{
|
||||
label: 'Introduction',
|
||||
url: '/',
|
||||
},
|
||||
{
|
||||
label: 'Blog',
|
||||
url: '/blog',
|
||||
},
|
||||
{
|
||||
label: 'Broadcasts',
|
||||
url: '/broadcasts',
|
||||
},
|
||||
// {
|
||||
// label: "Dev's Cookery",
|
||||
// url: '/cookery',
|
||||
// },
|
||||
{
|
||||
label: 'Portfolio',
|
||||
url: '/portfolio',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<nav class={navigationClass}>
|
||||
<section class={navigationContentClass}>
|
||||
<ul class={navigationLinksClass}>
|
||||
<li>
|
||||
<a class={classNames({ [selectedClass]: segment === '/' })} href="/">
|
||||
Introduction
|
||||
</a>
|
||||
</li>
|
||||
<!-- for the blog link, we're using rel=prefetch so that Sapper prefetches
|
||||
the blog data when we hover over the link or tap it on a touchscreen -->
|
||||
<li>
|
||||
<a
|
||||
rel="prefetch"
|
||||
class={classNames({ [selectedClass]: segment.startsWith('/blog') })}
|
||||
href="/blog"
|
||||
>
|
||||
Blog
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class={classNames({
|
||||
[selectedClass]: segment.startsWith('/portfolio'),
|
||||
})}
|
||||
href="/portfolio"
|
||||
>
|
||||
Portfolio
|
||||
</a>
|
||||
</li>
|
||||
{#each links as link}
|
||||
<li>
|
||||
<a
|
||||
rel="prefetch"
|
||||
class={classNames({ [selectedClass]: segment === link.url })}
|
||||
href={link.url}
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<aside class="logo-section {logoSectionClass}">
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import svgSprite from '../svg/build/icons-sprite.svg'
|
||||
import svgSprite from '../../svg/build/icons-sprite.svg'
|
||||
export let className: string
|
||||
export let name: string
|
||||
</script>
|
@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
interface ArticleDetails {
|
||||
title: string
|
||||
slug: string
|
||||
preview: string
|
||||
}
|
||||
export let segment: string
|
||||
export let article: ArticleDetails
|
||||
</script>
|
||||
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<a rel="prefetch" href={`/${segment}/${article.slug}`}>{article.title}</a>
|
||||
</h2>
|
||||
</header>
|
||||
{@html article.preview}
|
||||
</article>
|
@ -2,26 +2,27 @@
|
||||
import { horizontalBorderTopClass } from '$lib/styles/scoops.css'
|
||||
|
||||
import { format } from 'date-fns'
|
||||
import type { PostContent } from '../../routes/blog/content'
|
||||
import type { ArticleContent } from '$lib/content/articleContentListing'
|
||||
import {
|
||||
footerClass,
|
||||
publishedClass,
|
||||
publishedLabelClass,
|
||||
tagsListClass,
|
||||
tagsListLiClass,
|
||||
} from './ArticleFooter.css'
|
||||
} from './ArticlePreviewFooter.css'
|
||||
|
||||
export let post: PostContent
|
||||
export let segment: string
|
||||
export let article: ArticleContent
|
||||
</script>
|
||||
|
||||
<footer class="{footerClass} {horizontalBorderTopClass}">
|
||||
<div class="article-tags">
|
||||
{#if post.tags.length > 0}
|
||||
{#if article.tags.length > 0}
|
||||
<span class="lighten">Tags:</span>
|
||||
<ul class={tagsListClass}>
|
||||
{#each post.tags as tag}
|
||||
{#each article.tags as tag}
|
||||
<li class={tagsListLiClass}>
|
||||
<a href="/blog/tags/{tag}">{tag}</a>
|
||||
<a href="/{segment}/tags/{tag}">{tag}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
@ -29,8 +30,8 @@
|
||||
</div>
|
||||
<div class="created-at">
|
||||
<span class={publishedLabelClass}>Published on</span>
|
||||
<time datetime={post.date} class={publishedClass}>
|
||||
{format(new Date(post.date), "do MMMM',' y")}
|
||||
<time datetime={article.date} class={publishedClass}>
|
||||
{format(new Date(article.date), "do MMMM',' y")}
|
||||
</time>
|
||||
</div>
|
||||
</footer>
|
@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
import ArticleFooter from '$lib/components/articles/ArticlePreviewFooter/ArticlePreviewFooter.svelte'
|
||||
import Paginator from '$lib/components/paginator/Paginator.svelte'
|
||||
import { postListClass } from './ArticlePreviewList.css'
|
||||
import ArticlePreviewCard from '$lib/components/articles/ArticlePreviewCard/ArticlePreviewCard.svelte'
|
||||
import type { PaginationResult } from '$lib/pagination/pagination'
|
||||
import type { ArticleContent } from '$lib/content/articleContentListing'
|
||||
|
||||
export let page: number
|
||||
export let pageSize: number
|
||||
export let filters: Record<string, string>
|
||||
export let posts: PaginationResult<ArticleContent>
|
||||
export let segment: string
|
||||
</script>
|
||||
|
||||
<header>
|
||||
<Paginator
|
||||
{segment}
|
||||
{page}
|
||||
{pageSize}
|
||||
{filters}
|
||||
totalCount={posts.totalCount}
|
||||
/>
|
||||
</header>
|
||||
<ul class="post-list {postListClass}">
|
||||
{#each posts.items as article (article.slug)}
|
||||
<li>
|
||||
<ArticlePreviewCard {article} {segment} />
|
||||
<ArticleFooter {article} {segment} />
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<footer>
|
||||
<Paginator
|
||||
{segment}
|
||||
{page}
|
||||
{pageSize}
|
||||
{filters}
|
||||
totalCount={posts.totalCount}
|
||||
/>
|
||||
</footer>
|
@ -10,12 +10,11 @@
|
||||
|
||||
export const Divider = 'divider'
|
||||
|
||||
export let href: string
|
||||
export let segment: string
|
||||
export let page: number
|
||||
export let pageSize: number
|
||||
export let totalCount: number
|
||||
export let filters: Record<string, string>
|
||||
let paginatorPages: (number | typeof Divider)[]
|
||||
|
||||
$: paginatorPages = getPaginatorPages({ page, pageSize, totalCount })
|
||||
</script>
|
||||
@ -23,7 +22,7 @@
|
||||
<ul class={listClass}>
|
||||
{#if page !== 1}
|
||||
<li class="{listItemClass} ">
|
||||
<a class={pageLinkClass} href={createHref(href, filters, page - 1)}
|
||||
<a class={pageLinkClass} href={createHref(segment, filters, page - 1)}
|
||||
><</a
|
||||
>
|
||||
</li>
|
||||
@ -35,7 +34,7 @@
|
||||
<li class="{listItemClass} {activePage}">{pageNumber}</li>
|
||||
{:else}
|
||||
<li class="{listItemClass} ">
|
||||
<a class={pageLinkClass} href={createHref(href, filters, pageNumber)}
|
||||
<a class={pageLinkClass} href={createHref(segment, filters, pageNumber)}
|
||||
>{pageNumber}</a
|
||||
>
|
||||
</li>
|
||||
@ -43,7 +42,7 @@
|
||||
{/each}
|
||||
{#if page !== paginatorPages.length}
|
||||
<li class="{listItemClass} ">
|
||||
<a class={pageLinkClass} href={createHref(href, filters, page + 1)}
|
||||
<a class={pageLinkClass} href={createHref(segment, filters, page + 1)}
|
||||
>></a
|
||||
>
|
||||
</li>
|
@ -11,11 +11,13 @@ export function getPaginatorPages({
|
||||
page: number
|
||||
pageSize: number
|
||||
totalCount: number
|
||||
}) {
|
||||
}): (number | typeof Divider)[] {
|
||||
const maxLinksLength = 7
|
||||
const linksAroundActive = 2
|
||||
const totalPages = Math.ceil(totalCount / pageSize)
|
||||
const daco = range(1, totalPages + 1).reduce((acc, link) => {
|
||||
const shownPages = range(1, totalPages + 1).reduce<
|
||||
(number | typeof Divider)[]
|
||||
>((acc, link) => {
|
||||
const isFirst = link === 1
|
||||
const isLast = link === totalPages
|
||||
const isPageOnStart = page <= 3 && link < maxLinksLength
|
||||
@ -36,7 +38,7 @@ export function getPaginatorPages({
|
||||
return [...acc, link]
|
||||
}, [])
|
||||
|
||||
return daco
|
||||
return shownPages
|
||||
}
|
||||
|
||||
export function createHref(
|
@ -1,9 +1,9 @@
|
||||
import { splitEvery } from 'ramda'
|
||||
import { init, splitEvery } from 'ramda'
|
||||
|
||||
export function parseParams(params: string) {
|
||||
const splittedParams = params.split('/')
|
||||
let splittedParams = params.split('/')
|
||||
if (splittedParams.length % 2 !== 0) {
|
||||
return []
|
||||
splittedParams = init(splittedParams)
|
||||
}
|
||||
const splits = splitEvery(2, splittedParams)
|
||||
return Object.fromEntries(splits)
|
||||
|
@ -17,7 +17,10 @@ export function dropAndTake<Item>({ offset = 0, limit = Infinity }) {
|
||||
) => Item[]
|
||||
}
|
||||
|
||||
export function filterByPropContains<Item>(filters: Record<string, string>) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function filterByPropContains<Item extends Record<string, any>>(
|
||||
filters: Record<string, string>
|
||||
) {
|
||||
return function (items: Item[]) {
|
||||
return items.filter((item) => {
|
||||
return Object.entries(filters).every(([fieldName, value]) =>
|
||||
@ -27,7 +30,8 @@ export function filterByPropContains<Item>(filters: Record<string, string>) {
|
||||
}
|
||||
}
|
||||
|
||||
export function filterAndCount<Item>({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function filterAndCount<Item extends Record<string, any>>({
|
||||
filters,
|
||||
...dropTakeParams
|
||||
}: PaginationQuery) {
|
||||
|
@ -19,3 +19,9 @@ globalStyle(`${contentClass} img:only-child`, {
|
||||
display: 'block',
|
||||
margin: '0 auto',
|
||||
})
|
||||
|
||||
globalStyle(`${contentClass} .video-embed`, {
|
||||
margin: '0 auto',
|
||||
maxWidth: vars.width.image,
|
||||
aspectRatio: vars.aspectRatio.monitor,
|
||||
})
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type { LayoutData } from "./$types"
|
||||
import Nav from '../components/Nav.svelte'
|
||||
import Footer from '../components/Footer.svelte'
|
||||
import type { LayoutData } from './$types'
|
||||
import Nav from '$lib/components/Nav.svelte'
|
||||
import Footer from '$lib/components/Footer.svelte'
|
||||
import 'modern-normalize/modern-normalize.css'
|
||||
import '$lib/styles/global.css'
|
||||
import { mainContentClass } from './layout.css'
|
||||
|
@ -2,7 +2,7 @@ import type { LayoutLoad } from './$types'
|
||||
export const prerender = true
|
||||
|
||||
export const load = (async ({ fetch }) => {
|
||||
const blogPostsResponse = await fetch(`/blog/articles/pageSize/5.json`)
|
||||
const blogPostsResponse = await fetch(`/articles/pageSize/5.json`)
|
||||
const blogPostsContent = await blogPostsResponse.json()
|
||||
|
||||
return {
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
parseParams,
|
||||
} from '$lib/pagination/dropTakeParams'
|
||||
import { json } from '@sveltejs/kit'
|
||||
import { getBlogListing } from '../../content'
|
||||
import { getBlogListing } from '$lib/articleContent/articleContentListing'
|
||||
import type { RequestHandler } from './$types'
|
||||
|
||||
export const prerender = true
|
@ -1,12 +1,10 @@
|
||||
<script lang="ts">
|
||||
import ArticleFooter from '../../../components/blog/ArticleFooter.svelte'
|
||||
import Paginator from '../../../components/paginator/Paginator.svelte'
|
||||
import { postListClass, seeAllClass } from './page.css'
|
||||
import type { PageData } from './$types'
|
||||
import ArticlePreviewList from '$lib/components/articles/ArticlePreviewList/ArticlePreviewList.svelte'
|
||||
import { seeAllClass } from '$lib/components/articles/ArticlePreviewList/ArticlePreviewList.css'
|
||||
|
||||
export let data: PageData
|
||||
let { posts, filters, page, pageSize } = data
|
||||
$: ({ posts, filters, page, pageSize } = data)
|
||||
$: ({ posts, filters } = data)
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@ -30,36 +28,5 @@
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
<header>
|
||||
<Paginator
|
||||
href="blog"
|
||||
{page}
|
||||
{pageSize}
|
||||
{filters}
|
||||
totalCount={posts.totalCount}
|
||||
/>
|
||||
</header>
|
||||
<ul class="post-list {postListClass}">
|
||||
{#each posts.items as post (post.slug)}
|
||||
<li>
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<a rel="prefetch" href="/blog/{post.slug}">{post.title}</a>
|
||||
</h2>
|
||||
</header>
|
||||
{@html post.preview}
|
||||
</article>
|
||||
<ArticleFooter {post} />
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<footer>
|
||||
<Paginator
|
||||
href="blog"
|
||||
{page}
|
||||
{pageSize}
|
||||
{filters}
|
||||
totalCount={posts.totalCount}
|
||||
/>
|
||||
</footer>
|
||||
|
||||
<ArticlePreviewList {...data} segment="blog" />
|
||||
|
@ -1,16 +1,15 @@
|
||||
import { parseParams } from '$lib/pagination/dropTakeParams'
|
||||
import type { PageLoad } from './$types'
|
||||
import type { PostContent } from './../content'
|
||||
import type { ArticlePreviewAttributes } from '$lib/articleContent/articleContentListing'
|
||||
import type { PaginationResult } from '$lib/pagination/pagination'
|
||||
|
||||
export const load = (async ({ fetch, params }) => {
|
||||
const { page = 1, pageSize = 7, ...filters } = parseParams(params.params)
|
||||
const articleResponse = await fetch(
|
||||
`/blog/articles/${params.params ? params.params : 'index'}.json`
|
||||
`/articles/segments/blog${params.params ? `/${params.params}` : ''}.json`
|
||||
).then((r) => r.json())
|
||||
|
||||
return {
|
||||
posts: articleResponse.posts as PaginationResult<PostContent>,
|
||||
posts: articleResponse.posts as PaginationResult<ArticlePreviewAttributes >,
|
||||
page: Number(page),
|
||||
pageSize,
|
||||
filters,
|
||||
|
@ -1,35 +1,9 @@
|
||||
import { readFile } from 'fs'
|
||||
import { promisify } from 'util'
|
||||
import fm from 'front-matter'
|
||||
import { parseField } from '../../../markdown/parse-markdown'
|
||||
import { error, json } from '@sveltejs/kit'
|
||||
import type { PostAttributes } from '../content'
|
||||
import type { PageServerLoad } from './$types'
|
||||
import { getArticleContent } from '$lib/articleContent/articleContent'
|
||||
|
||||
export const prerender = true
|
||||
|
||||
export interface SinglePost {
|
||||
body: string
|
||||
}
|
||||
|
||||
export const load = (async ({ params: { slug } }) => {
|
||||
let postSource: string
|
||||
try {
|
||||
postSource = await promisify(readFile)(`_posts/blog/${slug}.md`, 'utf-8')
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
if (e.code === 'ENOENT') {
|
||||
throw error(404, 'Post not found \n' + e.toString())
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
const parsedPost = fm<PostAttributes>(postSource)
|
||||
|
||||
const post = parseField<SinglePost>('body')({
|
||||
...parsedPost.attributes,
|
||||
body: parsedPost.body,
|
||||
})
|
||||
|
||||
const post = await getArticleContent(slug);
|
||||
return post
|
||||
}) satisfies PageServerLoad
|
||||
|
@ -1,9 +1,15 @@
|
||||
<script lang="ts">
|
||||
import ArticleFooter from '../../../components/blog/ArticleFooter.svelte'
|
||||
import ArticleFooter from '$lib/components/articles/ArticlePreviewFooter/ArticlePreviewFooter.svelte'
|
||||
import type { PageData } from './$types'
|
||||
import { contentClass } from './page.css'
|
||||
import { contentClass } from '$lib/styles/article/article.css'
|
||||
import { onMount } from 'svelte'
|
||||
import { runOnMountScripts } from '$lib/articleContent/onMountScripts'
|
||||
|
||||
export let data: PageData
|
||||
|
||||
onMount(() => {
|
||||
runOnMountScripts()
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@ -12,7 +18,7 @@
|
||||
|
||||
<h1>{data.title}</h1>
|
||||
|
||||
<div class="content {contentClass}">
|
||||
<article class="content {contentClass}">
|
||||
{@html data.body}
|
||||
</div>
|
||||
<ArticleFooter post={data} />
|
||||
</article>
|
||||
<ArticleFooter article={data} segment="blog" />
|
||||
|
30
src/routes/broadcasts/[...params]/+page.svelte
Normal file
30
src/routes/broadcasts/[...params]/+page.svelte
Normal file
@ -0,0 +1,30 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from './$types'
|
||||
import ArticlePreviewList from '$lib/components/articles/ArticlePreviewList/ArticlePreviewList.svelte'
|
||||
import { seeAllClass } from '$lib/components/articles/ArticlePreviewList/ArticlePreviewList.css'
|
||||
|
||||
export let data: PageData
|
||||
$: ({ posts, filters } = data)
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Broadcasts @michalvankodev</title>
|
||||
</svelte:head>
|
||||
|
||||
{#if posts.items.length === 0}
|
||||
<p class="no-posts">You've found void in the space.</p>
|
||||
{:else}
|
||||
<h1>
|
||||
{#if filters.tags}
|
||||
<em>{filters.tags}</em>
|
||||
{/if}
|
||||
Broadcasts
|
||||
</h1>
|
||||
{#if filters.tags}
|
||||
<div class={seeAllClass}>
|
||||
<a href="/broadcasts">See all broadcasts</a>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<ArticlePreviewList {...data} segment="broadcasts" />
|
18
src/routes/broadcasts/[...params]/+page.ts
Normal file
18
src/routes/broadcasts/[...params]/+page.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { parseParams } from '$lib/pagination/dropTakeParams'
|
||||
import type { PageLoad } from './$types'
|
||||
import type { ArticlePreviewAttributes } from '$lib/articleContent/articleContentListing'
|
||||
import type { PaginationResult } from '$lib/pagination/pagination'
|
||||
|
||||
export const load = (async ({ fetch, params }) => {
|
||||
const { page = 1, pageSize = 7, ...filters } = parseParams(params.params)
|
||||
const articleResponse = await fetch(
|
||||
`/articles/segments/broadcasts${params.params ? `/${params.params}` : ''}.json`
|
||||
).then((r) => r.json())
|
||||
|
||||
return {
|
||||
posts: articleResponse.posts as PaginationResult<ArticlePreviewAttributes>,
|
||||
page: Number(page),
|
||||
pageSize,
|
||||
filters,
|
||||
}
|
||||
}) satisfies PageLoad
|
9
src/routes/broadcasts/[slug=blogPage]/+page.server.ts
Normal file
9
src/routes/broadcasts/[slug=blogPage]/+page.server.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import type { PageServerLoad } from './$types'
|
||||
import { getArticleContent } from '$lib/articleContent/articleContent'
|
||||
|
||||
export const prerender = true
|
||||
|
||||
export const load = (async ({ params: { slug } }) => {
|
||||
const post = await getArticleContent(slug);
|
||||
return post
|
||||
}) satisfies PageServerLoad
|
24
src/routes/broadcasts/[slug=blogPage]/+page.svelte
Normal file
24
src/routes/broadcasts/[slug=blogPage]/+page.svelte
Normal file
@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import ArticleFooter from '$lib/components/articles/ArticlePreviewFooter/ArticlePreviewFooter.svelte'
|
||||
import type { PageData } from './$types'
|
||||
import { contentClass } from '$lib/styles/article/article.css'
|
||||
import { onMount } from 'svelte'
|
||||
import { runOnMountScripts } from '$lib/articleContent/onMountScripts'
|
||||
|
||||
export let data: PageData
|
||||
|
||||
onMount(() => {
|
||||
runOnMountScripts()
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{data.title}</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>{data.title}</h1>
|
||||
|
||||
<article class="content {contentClass}">
|
||||
{@html data.body}
|
||||
</article>
|
||||
<ArticleFooter article={data} segment="broadcasts" />
|
@ -1,5 +1,5 @@
|
||||
import { getBlogListing } from '$lib/articleContent/articleContentListing'
|
||||
import { Feed } from 'feed'
|
||||
import { getBlogListing } from './blog/content'
|
||||
|
||||
export async function getFeed() {
|
||||
const feed = new Feed({
|
||||
|
@ -3,7 +3,7 @@ import { promisify } from 'util'
|
||||
import fm from 'front-matter'
|
||||
// TODO Switch marked for unified
|
||||
import marked from 'marked'
|
||||
import { parseField } from '../../markdown/parse-markdown'
|
||||
import { parseField } from '$lib/markdown/parse-markdown'
|
||||
import type { PageServerLoad } from './$types'
|
||||
|
||||
export const prerender = true
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Work from '../../components/portfolio/work.svelte'
|
||||
import Project from '../../components/portfolio/project.svelte'
|
||||
import Presentation from '../../components/portfolio/presentation.svelte'
|
||||
import Work from './components/work.svelte'
|
||||
import Project from './components/project.svelte'
|
||||
import Presentation from './components/presentation.svelte'
|
||||
import type { PageData } from './$types'
|
||||
|
||||
import { listClass, listItemClass, nameTagClass } from './page.css'
|
||||
|
39
src/routes/portfolio/components/personal.svelte
Normal file
39
src/routes/portfolio/components/personal.svelte
Normal file
@ -0,0 +1,39 @@
|
||||
<section id="personal">
|
||||
<h3>Personal Information</h3>
|
||||
<p>I was born on 26th of May in Košice, Slovakia and I still live here.</p>
|
||||
<h4>Hobbies:</h4>
|
||||
<p>
|
||||
I enjoy playing basketball with my friends. I also like to play other team
|
||||
sports like football and hockey. I also play squash and table tennis. Once
|
||||
I've won a competition in squash at my university. During summer I love
|
||||
water skiing and swimming in a nearby lake.
|
||||
<br />
|
||||
I am very passionate about music. I've also tried some software for composing
|
||||
music but I am not really hooked into that yet. From time to time I enjoy playing
|
||||
board games with my friends.
|
||||
</p>
|
||||
<h4>Interests:</h4>
|
||||
<p>
|
||||
I like to explore new technologies and I'm passionate about <em
|
||||
>Open Source movement</em
|
||||
>,
|
||||
<em>Internet of Things</em> applications and
|
||||
<em>Linux desktop evolution</em>.
|
||||
<br />
|
||||
I am interested in modern software architecture and
|
||||
<em>reactive programming</em>.
|
||||
<br />
|
||||
I've attended various <strong>tech conferences and hackathons</strong>. I
|
||||
like them for all of the fascinating ideas that might be invented.
|
||||
<br />
|
||||
I've given presentations on various topics related to
|
||||
<em>web development</em>. You can
|
||||
<a href="#presentations">take a look at some of them here</a>.
|
||||
<br />
|
||||
I enjoy <strong>teaching and explaining</strong> how various technologies
|
||||
and techniques work to my colleagues for their better understanding.
|
||||
<br />
|
||||
I take advantage of <strong>test driven development</strong>.
|
||||
</p>
|
||||
</section>
|
||||
<!--/personal-->
|
@ -19,6 +19,15 @@ collections:
|
||||
fields: # The fields for each document, usually in front matter
|
||||
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'blog' }
|
||||
- { label: 'Title', name: 'title', widget: 'string' }
|
||||
- label: 'Segments'
|
||||
name: 'segments'
|
||||
widget: 'select'
|
||||
multiple: true
|
||||
options:
|
||||
- { label: 'Blog', value: 'blog' }
|
||||
- { label: 'Broadcasts', value: 'broadcasts' }
|
||||
- { label: 'Cookbook', value: 'cookbook' }
|
||||
default: ['blog']
|
||||
- {
|
||||
label: 'Published',
|
||||
name: 'published',
|
||||
|
Loading…
Reference in New Issue
Block a user