Merge pull request #78 from bartvdbraak/feat/layout-changes
Layout changes
BIN
src/lib/assets/ticketdashboard.png
Normal file
After Width: | Height: | Size: 661 KiB |
|
@ -1 +0,0 @@
|
|||
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>
|
Before Width: | Height: | Size: 963 B |
BIN
src/lib/assets/videowall-logo.png
Normal file
After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 696 KiB After Width: | Height: | Size: 696 KiB |
Before Width: | Height: | Size: 272 KiB After Width: | Height: | Size: 272 KiB |
|
@ -2,6 +2,7 @@
|
|||
import { AppBar, LightSwitch, ProgressBar, drawerStore } from '@skeletonlabs/skeleton';
|
||||
import GitHub from './icons/GitHub.svelte';
|
||||
import Hamburger from './icons/Hamburger.svelte';
|
||||
import LinkedIn from './icons/LinkedIn.svelte';
|
||||
|
||||
export let progress: number;
|
||||
|
||||
|
@ -12,20 +13,26 @@
|
|||
|
||||
<AppBar>
|
||||
<svelte:fragment slot="lead">
|
||||
<button class="md:hidden btn btn-sm mr-4" on:click={drawerOpen}>
|
||||
<button aria-label="Toggle navigation menu" class="md:hidden btn btn-sm mr-4" on:click={drawerOpen}>
|
||||
<span>
|
||||
<Hamburger />
|
||||
</span>
|
||||
</button>
|
||||
<img src="./icon.svg" alt="Logo" srcset="" class="pr-2" />
|
||||
<code class="code">hellob.art</code>
|
||||
<h2 class="code">hellob.art</h2>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="trail">
|
||||
<a
|
||||
href="https://linkedin.com/in/bartvdbraak"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="btn-icon btn-icon-sm hover:variant-soft-primary"><LinkedIn /><span class="sr-only">LinkedIn Profile of Bart van der Braak</span></a
|
||||
>
|
||||
<a
|
||||
href="https://github.com/bartvdbraak"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="btn-icon variant-primary"><GitHub /></a
|
||||
class="btn-icon btn-icon-sm hover:variant-soft-primary"><GitHub /><span class="sr-only">GitHub Profile of Bart van der Braak</span></a
|
||||
>
|
||||
<LightSwitch />
|
||||
</svelte:fragment>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<nav class="list-nav p-3">
|
||||
<ul>
|
||||
{#each routes as route}
|
||||
<li>
|
||||
<li class="pb-2">
|
||||
<a class="{classesActive(route.url)}" href={route.url} on:click={drawerClose}>{route.label}</a>
|
||||
</li>
|
||||
{/each}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<a class="card bg-initial card-hover overflow-hidden" href={link}>
|
||||
<header>
|
||||
<img src={headerImage} class="bg-black/50 w-full aspect-[21/9] object-cover" alt="Post" />
|
||||
<img src={headerImage} class="bg-black/50 w-full aspect-[21/9] object-cover object-top" alt="Post" />
|
||||
</header>
|
||||
<div class="p-4 space-y-4">
|
||||
<h6 class="h6">{headerSubTitle}</h6>
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { browser } from '$app/environment';
|
||||
import * as THREE from 'three';
|
||||
|
||||
let camera: THREE.PerspectiveCamera,
|
||||
scene: THREE.Scene,
|
||||
renderer: THREE.WebGLRenderer,
|
||||
cube: THREE.Mesh<THREE.BoxGeometry, THREE.MeshBasicMaterial>;
|
||||
|
||||
const renderContainerId = 'render';
|
||||
|
||||
const toolsData = [
|
||||
{ name: 'Git', info: 'Short note about Git and its usage.' },
|
||||
{ name: 'DBeaver', info: 'Short note about DBeaver and its usage.' },
|
||||
{ name: 'Notion', info: 'Short note about Notion and its usage.' },
|
||||
{ name: 'Insomnia', info: 'Short note about Insomnia and its usage.' },
|
||||
{ name: 'Cyberduck', info: 'Short note about Cyberduck and its usage.' },
|
||||
{ name: 'Mullvad VPN', info: 'Short note about Mullvad VPN and its usage.' },
|
||||
{ name: 'Maccy', info: 'Short note about Maccy and its usage.' }
|
||||
];
|
||||
|
||||
onMount(() => {
|
||||
init();
|
||||
addTools();
|
||||
animate();
|
||||
});
|
||||
|
||||
const init = () => {
|
||||
scene = new THREE.Scene();
|
||||
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
const renderContainer = document.getElementById(renderContainerId);
|
||||
if (renderContainer) {
|
||||
renderContainer.appendChild(renderer.domElement);
|
||||
}
|
||||
|
||||
camera.position.z = 5;
|
||||
};
|
||||
|
||||
const addTool = (name: string, x: number, y: number, z: number) => {
|
||||
const geometry = new THREE.BoxGeometry();
|
||||
const material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
|
||||
cube = new THREE.Mesh(geometry, material);
|
||||
cube.position.set(x, y, z);
|
||||
scene.add(cube);
|
||||
|
||||
cube.userData.name = name;
|
||||
cube.userData.info = toolsData.find((tool) => tool.name === name)?.info || '';
|
||||
|
||||
cube.addEventListener('click', () => {
|
||||
alert(`${cube.userData.name}: ${cube.userData.info}`);
|
||||
});
|
||||
};
|
||||
|
||||
const addTools = () => {
|
||||
addTool('Git', -2, 0, 0);
|
||||
addTool('DBeaver', 0, 0, 0);
|
||||
addTool('Notion', 2, 0, 0);
|
||||
addTool('Insomnia', -2, 2, 0);
|
||||
addTool('Cyberduck', 0, 2, 0);
|
||||
addTool('Mullvad VPN', 2, 2, 0);
|
||||
addTool('Maccy', 0, 4, 0);
|
||||
};
|
||||
|
||||
const render = () => {
|
||||
renderer.clear();
|
||||
renderer.render(scene, camera);
|
||||
};
|
||||
|
||||
const isMeshType = (object?: THREE.Object3D): object is THREE.Mesh => {
|
||||
return object?.type === 'Mesh';
|
||||
};
|
||||
|
||||
const animate = () => {
|
||||
if (!browser) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestAnimationFrame(animate);
|
||||
|
||||
scene.traverse((object: THREE.Object3D) => {
|
||||
if (isMeshType(object) && object.isMesh) {
|
||||
object.rotation.x += 0.005;
|
||||
object.rotation.y += 0.005;
|
||||
}
|
||||
});
|
||||
|
||||
render();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#render {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<section id="render" />
|
1
src/lib/components/icons/LinkedIn.svelte
Normal file
|
@ -0,0 +1 @@
|
|||
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zM349.3 793.7H230.6V411.9h118.7v381.8zm-59.3-434a68.8 68.8 0 1 1 68.8-68.8c-.1 38-30.9 68.8-68.8 68.8zm503.7 434H675.1V608c0-44.3-.8-101.2-61.7-101.2-61.7 0-71.2 48.2-71.2 98v188.9H423.7V411.9h113.8v52.2h1.6c15.8-30 54.5-61.7 112.3-61.7 120.2 0 142.3 79.1 142.3 181.9v209.4z"></path></svg>
|
After Width: | Height: | Size: 555 B |
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import '../theme.postcss';
|
||||
import '@skeletonlabs/skeleton/themes/theme-crimson.css';
|
||||
import '@skeletonlabs/skeleton/styles/skeleton.css';
|
||||
import '../app.postcss';
|
||||
import { AppShell, Drawer } from '@skeletonlabs/skeleton';
|
||||
|
@ -31,7 +31,7 @@
|
|||
{ url: '/', label: 'Home' },
|
||||
{ url: '/projects', label: 'Projects' },
|
||||
{ url: '/tools', label: 'Tools' },
|
||||
{ url: '/blog', label: 'Blog' }
|
||||
// { url: '/blog', label: 'Blog' }
|
||||
];
|
||||
|
||||
let progress = 0;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
<svelte:head>
|
||||
<title>hellob.art — home</title>
|
||||
<meta name="description" content="Meet Bart, a passionate DevOps engineer from Zaandam, Netherlands. With expertise in Azure, Kubernetes, and automation, he loves solving challenges through code. Discover his journey, interests in cats and whiskey, and how to connect with him for exciting collaborations.">
|
||||
</svelte:head>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 text-left">
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<script>
|
||||
import videowallImage from '$lib/assets/videowall-irl.jpeg';
|
||||
import tripleLogo from '$lib/assets/triple-logo.png';
|
||||
import zaantjeImage from '$lib/assets/zaantje-3d.png';
|
||||
import videowallImage from '$lib/assets/videowall.jpeg';
|
||||
import videowallLogo from '$lib/assets/videowall-logo.png';
|
||||
import ticketDashboardImage from '$lib/assets/ticketdashboard.png';
|
||||
import ticketDashboardLogo from '$lib/assets/triple-logo.png';
|
||||
import zaantjeImage from '$lib/assets/zaantje.png';
|
||||
import zaantjeLogo from '$lib/assets/zaantje-logo.png';
|
||||
import ProjectCard from '$lib/components/ProjectCard.svelte';
|
||||
|
||||
|
@ -10,16 +12,28 @@
|
|||
id: 1,
|
||||
link: '#',
|
||||
headerImage: videowallImage,
|
||||
headerSubTitle: 'Internal Project',
|
||||
headerSubTitle: 'Private Project',
|
||||
title: 'Videowall',
|
||||
description: `An internal application to control an impressive 6x5 monitor setup with a user-friendly
|
||||
frontend built on Next.js and a powerful backend developed in Golang.`,
|
||||
logo: tripleLogo,
|
||||
frontend built with React and Next.js utilizing a powerful backend developed in Golang.`,
|
||||
logo: videowallLogo,
|
||||
contributors: [],
|
||||
date: '2021'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
link: '#',
|
||||
headerImage: ticketDashboardImage,
|
||||
headerSubTitle: 'Private Project',
|
||||
title: 'Ticket Dashboard',
|
||||
description: `Web app that consolidates tickets from various sources into one view for easy navigation, filters, and search for efficient
|
||||
ticket management. Developed with Next.js for frontend and Golang for backend.`,
|
||||
logo: ticketDashboardLogo,
|
||||
contributors: [],
|
||||
date: '2020'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
link: 'https://zaantje.com',
|
||||
headerImage: zaantjeImage,
|
||||
headerSubTitle: 'Personal Project',
|
||||
|
@ -35,10 +49,20 @@
|
|||
|
||||
<svelte:head>
|
||||
<title>hellob.art — projects</title>
|
||||
<meta name="description" content="Explore a diverse collection of web applications and virtual tours in the portfolio of a passionate DevOps engineer. Discover innovative projects in React, Golang, Next.js, and more.">
|
||||
</svelte:head>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 text-left">
|
||||
<h2 class="text-3xl font-bold mb-8">My Projects</h2>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-8">
|
||||
Here, you'll find a curated collection of projects that I've either created or contributed to as
|
||||
a passionate DevOps engineer and developer. This portfolio encompasses a diverse range of
|
||||
endeavors, including both public and private projects. With a mix of open-source contributions
|
||||
and private collaborations from my corporate endeavors, this showcase represents my dedication
|
||||
to pushing the boundaries of innovation in various domains.
|
||||
</p>
|
||||
|
||||
<div class="w-full text-token grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{#each projects as project}
|
||||
<ProjectCard
|
||||
|
|
|
@ -3,53 +3,109 @@
|
|||
import { Canvas } from '@threlte/core';
|
||||
import { T } from '@threlte/core';
|
||||
import { ContactShadows, Float, Grid, OrbitControls } from '@threlte/extras';
|
||||
import Github from './Github.svelte';
|
||||
import TerraformFlat from './TerraformFlat.svelte';
|
||||
import Kubernetes from './Kubernetes.svelte';
|
||||
import Github from './models/Github.svelte';
|
||||
import TerraformFlat from './models/TerraformFlat.svelte';
|
||||
import Kubernetes from './models/Kubernetes.svelte';
|
||||
import Warp from './models/Warp.svelte';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>hellob.art — tools</title>
|
||||
<meta name="description" content="Explore essential DevOps tools like Kubernetes, Terraform, Warp, and version control platforms GitHub, Azure DevOps, and GitLab.">
|
||||
</svelte:head>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 text-left">
|
||||
<h2 class="text-3xl font-bold mb-8">Tools</h2>
|
||||
|
||||
<Canvas>
|
||||
<T.PerspectiveCamera makeDefault position={[-10, 10, 30]} fov={15}>
|
||||
<OrbitControls
|
||||
autoRotate
|
||||
enableZoom={false}
|
||||
enableDamping
|
||||
autoRotateSpeed={0.2}
|
||||
target.y={3}
|
||||
/>
|
||||
</T.PerspectiveCamera>
|
||||
<h2 class="text-2xl font-bold mb-8">Kubernetes</h2>
|
||||
|
||||
<T.DirectionalLight intensity={0.5} position.x={5} position.y={10} />
|
||||
<T.AmbientLight intensity={0.2} />
|
||||
<p class="text-lg leading-relaxed mb-8">
|
||||
Kubernetes is an indispensable part of my daily routine, providing powerful container
|
||||
orchestration capabilities for seamless application deployment and scaling. I enhance my
|
||||
Kubernetes workflows with essential tools like k9s for cluster interactions, ArgoCD for
|
||||
GitOps-based continuous delivery, Kustomize for configuration customization, and AKS (Azure
|
||||
Kubernetes Service) for managed solutions. This combination streamlines my tasks and ensures
|
||||
efficient, reliable application management.
|
||||
</p>
|
||||
|
||||
<Grid
|
||||
<h2 class="text-2xl font-bold mb-8">Terraform</h2>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-8">
|
||||
Terraform plays a central role in my DevOps toolkit, empowering me to manage and provision
|
||||
infrastructure efficiently as code. It saves valuable time and effort while maintaining
|
||||
consistency across deployments, preventing configuration drift in dynamic cloud environments.
|
||||
The reproductibility that Terraform offers is a game-changer, enabling easy and reliable
|
||||
environment recreation for testing and development. Seamless integration with Azure DevOps
|
||||
allows for streamlined CI/CD pipelines, instilling confidence in continuously delivering
|
||||
infrastructure changes. Embracing Terraform has simplified my daily tasks and enhanced the
|
||||
overall robustness and stability of our cloud infrastructure.
|
||||
</p>
|
||||
|
||||
<div class="max-h-80">
|
||||
<Canvas>
|
||||
<T.PerspectiveCamera makeDefault position={[-10, 15, 20]} fov={10}>
|
||||
<OrbitControls
|
||||
autoRotate
|
||||
enableZoom={false}
|
||||
enableDamping
|
||||
autoRotateSpeed={0.2}
|
||||
target.y={3}
|
||||
/>
|
||||
</T.PerspectiveCamera>
|
||||
|
||||
<T.DirectionalLight intensity={0.5} position.x={5} position.y={3} />
|
||||
<T.AmbientLight intensity={0.2} />
|
||||
|
||||
<!-- <Grid
|
||||
position.y={-0.001}
|
||||
cellColor="#ffffff"
|
||||
sectionColor="#ffffff"
|
||||
sectionThickness={0}
|
||||
fadeDistance={40}
|
||||
cellSize={2}
|
||||
/>
|
||||
/> -->
|
||||
|
||||
<ContactShadows scale={10} blur={2} far={2.5} opacity={0.5} />
|
||||
<ContactShadows scale={10} blur={2} far={2.5} opacity={0.5} />
|
||||
|
||||
<Float floatIntensity={1} floatingRange={[0, 1]}>
|
||||
<Github position.y={0.4} position.z={-0.75} scale={50} />
|
||||
</Float>
|
||||
<Float floatIntensity={1} floatingRange={[0, 1]}>
|
||||
<Github position.y={0} position.z={-0.75} scale={50} />
|
||||
</Float>
|
||||
|
||||
<Float floatIntensity={1} floatingRange={[0, 1]}>
|
||||
<TerraformFlat position.y={0.4} position.z={-4} scale={10} />
|
||||
</Float>
|
||||
<Float floatIntensity={1} floatingRange={[0, 1]}>
|
||||
<TerraformFlat position.y={0} position.z={-8} position.x={-5} scale={10} />
|
||||
</Float>
|
||||
|
||||
<Float floatIntensity={1} floatingRange={[0, 1]}>
|
||||
<Kubernetes position.y={0.4} position.z={-2} position.x={-3} scale={100} />
|
||||
</Float>
|
||||
</Canvas>
|
||||
<Float floatIntensity={1} floatingRange={[0, 1]}>
|
||||
<Kubernetes position.y={0} position.z={-2} position.x={-5} scale={100} />
|
||||
</Float>
|
||||
|
||||
<Float floatIntensity={1} floatingRange={[0, 1]}>
|
||||
<Warp position.y={0} position.z={-1} position.x={6} scale={8} />
|
||||
</Float>
|
||||
</Canvas>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl font-bold mb-8">Warp</h2>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-8">
|
||||
Warp, the high-performance terminal built in Rust, is an essential tool I rely on daily for
|
||||
development and operations. Its full-text editor for commands, visual grouping of outputs into
|
||||
blocks, and enhanced shortcuts have significantly boosted my productivity and made CLI
|
||||
interactions more intuitive. With its impressive speed, multiplatform support, and seamless
|
||||
integration into existing shells, Warp excels in handling complex tasks, making it indispensable
|
||||
for efficient and responsive terminal operations.
|
||||
</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mb-8">GitHub, Azure DevOps and Gitlab</h2>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-8">
|
||||
In my daily work, essential platforms like GitHub, Azure DevOps, and GitLab play a crucial role.
|
||||
For public and personal projects, GitHub provides robust version control and collaboration
|
||||
tools. Azure DevOps, on the other hand, is my preferred choice for private and corporate
|
||||
projects, thanks to seamless integration with Azure services and powerful CI/CD capabilities,
|
||||
optimizing application development and deployment. Additionally, I leverage GitLab for specific
|
||||
projects, benefiting from its strong version control features and CI/CD pipelines. Together,
|
||||
these platforms empower efficient collaboration, project management, and development processes,
|
||||
catering to a wide range of contexts.
|
||||
</p>
|
||||
</main>
|
||||
|
|
|
@ -22,12 +22,12 @@ Command: npx @threlte/gltf@1.0.0-next.13 ./static/models/kubernetes.glb --transf
|
|||
<T.Mesh
|
||||
geometry={gltf.nodes.Curve.geometry}
|
||||
material={gltf.materials['SVGMat.006']}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0.9]}
|
||||
/>
|
||||
<T.Mesh
|
||||
geometry={gltf.nodes.Curve001.geometry}
|
||||
material={gltf.materials['SVGMat.007']}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0.9]}
|
||||
/>
|
||||
{:catch error}
|
||||
<slot name="error" {error} />
|
29
src/routes/tools/models/Warp.svelte
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
Auto-generated by: https://github.com/threlte/threlte/tree/main/packages/gltf
|
||||
Command: npx @threlte/gltf@1.0.0-next.13 ./static/models/warp.glb --transform
|
||||
-->
|
||||
|
||||
<script>
|
||||
import { Group } from 'three'
|
||||
import { T, forwardEventHandlers } from '@threlte/core'
|
||||
import { useGltf } from '@threlte/extras'
|
||||
|
||||
export const ref = new Group()
|
||||
|
||||
const gltf = useGltf('/models/warp-transformed.glb', { useDraco: true })
|
||||
|
||||
const component = forwardEventHandlers()
|
||||
</script>
|
||||
|
||||
<T is={ref} dispose={false} {...$$restProps} bind:this={$component}>
|
||||
{#await gltf}
|
||||
<slot name="fallback" />
|
||||
{:then gltf}
|
||||
<T.Mesh geometry={gltf.nodes.Warp.geometry} material={gltf.materials.SVGMat} rotation={[Math.PI / 2, 0, 0.3]} />
|
||||
<T.Mesh geometry={gltf.nodes.Warp001.geometry} material={gltf.materials.Gradient} rotation={[Math.PI / 2, 0, 0.3]} />
|
||||
{:catch error}
|
||||
<slot name="error" {error} />
|
||||
{/await}
|
||||
|
||||
<slot {ref} />
|
||||
</T>
|