Projects
This commit is contained in:
parent
a4620a399a
commit
63b6bccf94
|
@ -2,17 +2,6 @@ import type { MarkdownMetadata, MdsvexImport } from './types';
|
||||||
import { parseReadContent } from './utils';
|
import { parseReadContent } from './utils';
|
||||||
import { error } from '@sveltejs/kit';
|
import { error } from '@sveltejs/kit';
|
||||||
|
|
||||||
export interface Project extends MarkdownMetadata {
|
|
||||||
title: string;
|
|
||||||
excerpt: string;
|
|
||||||
slug: string;
|
|
||||||
image: string;
|
|
||||||
date: string;
|
|
||||||
pageTitle: string;
|
|
||||||
pageDescription: string;
|
|
||||||
keywords: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all the projects metadata
|
* Gets all the projects metadata
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,15 +5,18 @@ type Skill = {
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const skills: Skill[] = [
|
const skills: Skill[] = [
|
||||||
{title:'Langs/Frameworks', list: ['Svelte', 'SvelteKit', 'JavaScript/TypeScript', 'Python', 'C/C++']},
|
{title:'Langs', list: ['JavaScript/TypeScript', 'Python', 'a bit of C/C++', 'Bash', 'SQL', '...']},
|
||||||
{title:'Devops', list: ['Git', 'Terraform', 'Ansible', 'Docker', 'Docker Compose', 'K8s']},
|
{title:'Frontend', list: ['Svelte', 'SvelteKit']},
|
||||||
|
{title:'Devops', list: ['Git', 'Terraform', 'Ansible', 'Docker', 'Docker Compose', 'K8s', 'Grafana']},
|
||||||
|
{title:'CI/CD', list: ['GitHub Actions', 'Gitea Actors', 'Gitlab', 'SFTP', ]},
|
||||||
{title:'Linux', list: ['Debian', 'Ubuntu', 'Arch Linux', 'Alpine', 'Raspbian']},
|
{title:'Linux', list: ['Debian', 'Ubuntu', 'Arch Linux', 'Alpine', 'Raspbian']},
|
||||||
{title:'SysAdmin', list: ['Systemd', 'nginx', 'User acc management', 'basic networking tools, ...']},
|
{title:'SysAdmin', list: ['Systemd', 'nginx', 'User acc management', 'basic networking tools, ...']},
|
||||||
{title:'Databases', list: ['PostgreSQL', 'MariaDB', 'SQLite' ]},
|
{title:'Databases', list: ['PostgreSQL', 'MariaDB', 'SQLite' ]},
|
||||||
{title:'Cloud', list: ['AWS', 'Azure', 'DigitalOcean', 'Vercel', 'Hetzner Cloud']},
|
{title:'Cloud', list: ['AWS', 'Azure', 'Cloudflare', 'DigitalOcean', 'Vercel', 'Hetzner Cloud']},
|
||||||
{title:'IoT', list: ['Raspberry Pi', 'Arduino', 'ESP32', 'ESP8266', '...sensors', 'MQTT', 'LoRa', 'BLE', 'NFC', 'WiFi', ]},
|
{title:'IoT', list: ['Raspberry Pi', 'Arduino', 'ESP32', 'ESP8266', '...sensors', 'MQTT', 'LoRa', 'BLE', 'NFC', 'WiFi', ]},
|
||||||
|
{title:'other tools', list: ['HC Vault / AWS Secrets Manager', 'AWS Lambda']},
|
||||||
{title:'Languages', list: ['English', 'Czech', 'French', 'German']},
|
{title:'Languages', list: ['English', 'Czech', 'French', 'German']},
|
||||||
{title:'other', list: ['Figma', 'UI/UX', 'Wireframing', 'Prototyping', 'Adobe InDesign, Illustrator, Inkscape, ...',]}
|
{title:'design', list: ['Figma', 'UI/UX', 'Wireframing', 'Prototyping', 'Adobe InDesign, Illustrator, Inkscape, ...',]}
|
||||||
];
|
];
|
||||||
|
|
||||||
export default skills;
|
export default skills;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { listProjects } from '$content/projects';
|
import { listProjects } from '$content/projects';
|
||||||
import type { LayoutServerLoad } from './$types';
|
import type { LayoutServerLoad } from './$types';
|
||||||
|
|
||||||
export const load: LayoutServerLoad = () => {
|
export const load = () => {
|
||||||
return {
|
return {
|
||||||
projects: listProjects()
|
projects: listProjects()
|
||||||
};
|
};
|
|
@ -1,11 +1,23 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
|
import PostPreview from '$lib/components/blog/PostPreview.svelte';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="projects-layout">
|
<div class="space-y-8">
|
||||||
{data.projects}
|
<header class="flex flex-col justify-center items-center">
|
||||||
|
<h1 class="h1 m-4">Projects</h1>
|
||||||
|
</header>
|
||||||
|
<div
|
||||||
|
class="grid m-auto max-w-7xl w-full gap-6 grid-cols-none justify-center md:grid-cols-2 lg:grid-cols-3"
|
||||||
|
>
|
||||||
|
{#each data.projects as post}
|
||||||
|
<div class="flex justify-center min-w-[20rem] max-w-sm">
|
||||||
|
<PostPreview {post} type="blog" isMostRecent />
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { listProjects } from '$content/projects';
|
||||||
|
import { error } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
function shuffle<T>(array: T[]) {
|
||||||
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[array[i], array[j]] = [array[j], array[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function load({ params }) {
|
||||||
|
const posts = listProjects();
|
||||||
|
const currentPost = posts.find((post) => post.slug == params.slug);
|
||||||
|
|
||||||
|
if (!currentPost) {
|
||||||
|
throw error(404, `Unable to find blog post "${params.slug}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffle(posts);
|
||||||
|
|
||||||
|
return {
|
||||||
|
featuredPosts: posts
|
||||||
|
.filter((post) => post.slug != params.slug)
|
||||||
|
.filter((p) => p.tags?.some((t) => currentPost.tags?.includes(t)))
|
||||||
|
.slice(0, 3)
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ProjectsContentLayout from '$lib/components/projects/projects-content-layout.svelte';
|
import ProjectsContentLayout from '$lib/components/projects/ProjectsContentLayout.svelte';
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { removeTrailingSlash } from '$lib/utils/helpers';
|
import { removeTrailingSlash } from '$lib/utils/helpers';
|
||||||
import type { RequestHandler } from './$types';
|
|
||||||
import { listBlogPosts } from '$content/blog';
|
import { listBlogPosts } from '$content/blog';
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
@ -16,10 +15,10 @@ const sitemap = (pages: string[]) => `<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
</urlset>
|
</urlset>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const GET: RequestHandler = async () => {
|
export const GET = async () => {
|
||||||
const staticPages = Object.keys(
|
const staticPages = Object.keys(
|
||||||
// For other static pages. Except content pages - changelogs, guides, blog posts, guides etc.
|
// For other static pages. Except content pages - changelogs, guides, blog posts, guides etc.
|
||||||
import.meta.glob('/src/routes/**/!(_)*.{svelte,md}'),
|
import.meta.glob('/src/routes/**/!(_)*.{svelte,md,svx}')
|
||||||
)
|
)
|
||||||
.filter((page) => {
|
.filter((page) => {
|
||||||
const filters = [
|
const filters = [
|
||||||
|
@ -28,14 +27,10 @@ export const GET: RequestHandler = async () => {
|
||||||
'404',
|
'404',
|
||||||
'slug]',
|
'slug]',
|
||||||
'title]',
|
'title]',
|
||||||
'src/routes/docs/introduction/getting-started',
|
|
||||||
'extension-activation',
|
|
||||||
'unsubscribe',
|
'unsubscribe',
|
||||||
'subscribe',
|
'subscribe',
|
||||||
'stay-connected',
|
|
||||||
'extension-uninstall',
|
|
||||||
'+error',
|
'+error',
|
||||||
'+layout',
|
'+layout'
|
||||||
];
|
];
|
||||||
return !filters.find((filter) => page.includes(filter));
|
return !filters.find((filter) => page.includes(filter));
|
||||||
})
|
})
|
||||||
|
@ -49,18 +44,13 @@ export const GET: RequestHandler = async () => {
|
||||||
.replace('/+page', '');
|
.replace('/+page', '');
|
||||||
});
|
});
|
||||||
|
|
||||||
const blogPosts = listBlogPosts().map(
|
const blogPosts = listBlogPosts().map((post) => `https://www.mattmor.in/blog/${post.slug}`);
|
||||||
(post) => `https://www.gitpod.io/blog/${post.slug}`,
|
const renderedSitemap = sitemap([...staticPages, ...blogPosts]);
|
||||||
);
|
|
||||||
const renderedSitemap = sitemap([
|
|
||||||
...staticPages,
|
|
||||||
...blogPosts,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return new Response(renderedSitemap, {
|
return new Response(renderedSitemap, {
|
||||||
headers: {
|
headers: {
|
||||||
'Cache-Control': 'max-age=0, s-maxage=3600',
|
'Cache-Control': 'max-age=0, s-maxage=3600',
|
||||||
'Content-Type': 'application/xml',
|
'Content-Type': 'application/xml'
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue