Compare commits

...

10 Commits

Author SHA1 Message Date
7b9c9e8971 Update Dockerfile
All checks were successful
Build and Deploy / Deploy (push) Successful in 2m7s
2023-11-28 16:32:17 +01:00
2ff922cab5 Update Dockerfile
Some checks failed
Build and Deploy / Deploy (push) Failing after 1m22s
2023-11-28 16:30:04 +01:00
dc23b5248b Update ci.yml
Some checks failed
Build and Deploy / Deploy (push) Failing after 1m15s
2023-11-28 16:27:29 +01:00
9ccb8a24f7 Update Dockerfile
Some checks failed
Build and Deploy / Deploy (push) Failing after 1m19s
2023-11-28 16:21:42 +01:00
49eb33e83a Added working directory
Some checks failed
Build and Deploy / Deploy (push) Has been cancelled
2023-11-28 16:19:40 +01:00
2f86fc30c3 Added workflow
Some checks failed
Build and Deploy / Deploy (push) Failing after 13s
2023-11-28 16:17:24 +01:00
92878dd50a First release 2023-11-28 16:15:51 +01:00
1883dcb8bb Changed order of skills 2023-11-21 21:33:13 +01:00
25f68630c8 Changed NuxtLink to a 2023-11-21 21:28:56 +01:00
8dd3994ed4 Added boilerplate 2023-11-21 21:23:16 +01:00
19 changed files with 1187 additions and 182 deletions

38
.gitea/workflows/ci.yml Normal file
View File

@@ -0,0 +1,38 @@
name: Build and Deploy
on: [push]
jobs:
Deploy:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
steps:
- uses: actions/checkout@v3
- name: Use Nodejs
uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install
working-directory: ./website
- run: npm run build
working-directory: ./website
- uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
with:
registry: gitea.xeovalyte.dev
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
- run: docker buildx build -t gitea.xeovalyte.dev/xeovalyte/portfolio:latest --load --platform=linux/amd64 .
- run: docker push gitea.xeovalyte.dev/xeovalyte/portfolio:latest
- run: docker buildx build -t gitea.xeovalyte.dev/xeovalyte/portfolio:latest-arm --load --platform=linux/arm64 .
- run: docker push gitea.xeovalyte.dev/xeovalyte/portfolio:latest-arm

9
Dockerfile Normal file
View File

@@ -0,0 +1,9 @@
FROM node:18
WORKDIR /usr/src/app
COPY website/.output .
EXPOSE 3000
CMD [ "node", "server/index.mjs" ]

10
shell.nix Normal file
View File

@@ -0,0 +1,10 @@
let
pkgs = import <nixpkgs> { };
in
pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_18
nodePackages.pnpm
nodePackages.typescript-language-server
];
}

6
website/app.config.ts Normal file
View File

@@ -0,0 +1,6 @@
export default defineAppConfig({
umami: {
host: 'https://umami.xeovalyte.dev/',
id: '7d4c9046-c073-4d31-9bba-2da4be4499fc',
},
});

View File

@@ -1,5 +1,40 @@
<template>
<div>
Xeovalyte Portfolio
<div class="min-h-screen bg-dark-900 grid grid-cols-12">
<MobileNav class="xl:hidden col-span-12" />
<Sidebar class="col-span-2 hidden xl:flex" />
<Content id="content" class="col-span-10 col-start-2 xl:col-span-8 xl:col-start-4" />
</div>
</template>
<script setup>
const router = useRouter()
useSeoMeta({
title: 'Timo Boomers / Xeovalyte',
description: 'This is the portfolio of Timo Boomers, also known as Xeovalyte',
profileFirstName: 'Timo',
profileGender: 'male',
profileLastName: 'Boomers',
profileUsername: 'Xeovalyte',
author: 'Timo Boomers',
creator: 'Timo Boomers'
})
const callback = (entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
router.replace({ hash: '#' + entry.target.id})
}
})
}
onMounted(() => {
const content = document.getElementById('content')
const observer = new IntersectionObserver(callback, { root: document.querySelector('#observe'),threshold: 0.6 })
Object.values(content.children).forEach(child => {
observer.observe(child);
})
})
</script>

View File

@@ -0,0 +1,18 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
p > a[href^="https://"] {
@apply text-primary-100 hover:underline underline-offset-4
}
p > a[href^="https://"]::after {
filter: invert(62%) sepia(34%) saturate(1941%) hue-rotate(174deg) brightness(103%) contrast(102%);
content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDI1NiI+PHBhdGggZmlsbD0iY3VycmVudENvbG9yIiBkPSJNMjI0IDEwNGE4IDggMCAwIDEtMTYgMFY1OS4zMmwtNjYuMzMgNjYuMzRhOCA4IDAgMCAxLTExLjMyLTExLjMyTDE5Ni42OCA0OEgxNTJhOCA4IDAgMCAxIDAtMTZoNjRhOCA4IDAgMCAxIDggOFptLTQwIDI0YTggOCAwIDAgMC04IDh2NzJINDhWODBoNzJhOCA4IDAgMCAwIDAtMTZINDhhMTYgMTYgMCAwIDAtMTYgMTZ2MTI4YTE2IDE2IDAgMCAwIDE2IDE2aDEyOGExNiAxNiAwIDAgMCAxNi0xNnYtNzJhOCA4IDAgMCAwLTgtOFoiLz48L3N2Zz4=);
margin: 0 0 0 3px;
}
p {
position: relative;
z-index: 0
}

View File

@@ -0,0 +1,7 @@
<template>
<div>
<SectionsHeading id="about" class="min-h-screen" />
<SectionsSkills id="skills" class="min-h-screen" />
<SectionsProjects id="projects" class="min-h-screen" />
</div>
</template>

View File

@@ -0,0 +1,45 @@
<template>
<div class="w-full px-5 h-12 bg-dark-800/40 backdrop-blur-sm sticky z-40 top-0 left-0">
<div class="w-full h-full flex">
<img src="/logo.svg" alt="Xeovalyte logo" class="w-10 my-auto">
<Icon name="ph:list-bold" size="2.5em" class="ml-auto my-auto text-primary-500 hover:cursor-pointer" @click="menuOpen = true" />
</div>
<Transition>
<div v-if="menuOpen" class="fixed z-50 top-0 left-0 w-screen h-screen bg-dark-800/60 backdrop-blur-lg px-5 flex flex-col">
<div class="w-full h-12 flex">
<img src="/logo.svg" alt="Xeovalyte logo" class="w-10 my-auto">
<Icon name="ph:x-bold" size="2.5em" class="ml-auto my-auto text-primary-500 hover:cursor-pointer" @click="menuOpen = false" />
</div>
<div class="flex flex-col mx-auto mt-48 gap-y-8">
<a href="#about" class="font-bold text-4xl text-primary-500" :class="route.hash === '#about' ? 'opacity-100' : 'opacity-50'">
About
</a>
<a href="#skills" to="#skills" class="font-bold text-4xl text-primary-500" :class="route.hash === '#skills' ? 'opacity-100' : 'opacity-50'">
Skills
</a>
<a href="#projects" class="font-bold text-4xl text-primary-500" :class="route.hash === '#projects' ? 'opacity-100' : 'opacity-50'">
Projects
</a>
</div>
</div>
</Transition>
</div>
</template>
<script setup>
const menuOpen = ref(false);
const route = useRoute()
</script>
<style>
.v-enter-active,
.v-leave-active {
transition: transform 0.3s ease-out;
}
.v-enter-from,
.v-leave-to {
transform: translateY(-100%);
}
</style>

View File

@@ -0,0 +1,20 @@
<template>
<div class="bg-dark-800 h-screen w-full sticky top-0 flex flex-col justify-center">
<img src="/logo.svg" alt="Xeovalyte logo" class="mx-auto w-48">
<div class="flex flex-col gap-y-3 text-center mt-10">
<a href="#about" class="font-bold text-xl text-primary-500" :class="route.hash === '#about' ? 'opacity-100' : 'opacity-50'">
About
</a>
<a href="#skills" to="#skills" class="font-bold text-xl text-primary-500" :class="route.hash === '#skills' ? 'opacity-100' : 'opacity-50'">
Skills
</a>
<a href="#projects" class="font-bold text-xl text-primary-500" :class="route.hash === '#projects' ? 'opacity-100' : 'opacity-50'">
Projects
</a>
</div>
</div>
</template>
<script setup>
const route = useRoute()
</script>

View File

@@ -0,0 +1,20 @@
<template>
<div class="py-40">
<h1 class="text-primary-500 text-6xl font-bold">Timo Boomers</h1>
<h3 class="text-primary-700 font-bold text-xl">aka Xeovalyte</h3>
<p class="text-bright mt-10">
Hello everyone! My name is Timo Boomers also known as Xeovalyte. I live in the Netherlands and have always found electronics and computers interesting. Since I was about 12 years old I started to wander in the world of computers and programming. At this moment I program various things like websites, Discord bots, desktop applications and Arduino.
</p>
<div class="text-primary-500 flex gap-5 text-lg mt-16 font-bold">
<NuxtLink to="https://gitea.xeovalyte.dev/xeovalyte" :external="true" class="border-b pb-1 border-dotted hover:border-solid border-bright flex gap-1.5 hover:text-primary-100">
<Icon name="simple-icons:gitea" size="1.6em"/>
Gitea
</NuxtLink>
<NuxtLink to="mailto:contact@xeovalyte.dev" :external="true" class="border-b pb-1 border-dotted hover:border-solid border-bright flex gap-1.5 hover:text-primary-100">
<Icon name="simple-icons:maildotru" size="1.5em"/>
Email
</NuxtLink>
</div>
</div>
</template>

View File

@@ -0,0 +1,22 @@
<template>
<div class="py-40">
<h1 class="text-primary-500 font-bold text-6xl">Projects</h1>
<h2 class="text-primary-600 font-bold text-2xl mt-10">Homelab</h2>
<p class="text-bright mt-2">
In 2021 I bought a <a href="https://www.raspberrypi.com/">Raspberry Pi</a> to selfhost some applications with docker. I really loved to learn about networking and deploying applications, and so my homelab needed an upgrade. In 2022 I bough myself a dedicated computer to host a <a href="https://minecraft.net">Minecraft</a> server for me and my friends and some other applications. My homelab now consists of a <a href="https://www.zimaboard.com/">Zimaboard</a> running <a href="https://opnsense.org/">OPNsense</a>, a dedicated server running Linux with <a href="https://docker.io">Docker</a> applications and a <a href="raspberrypi.com">Raspberry Pi</a> as a backup server.
</p>
<h2 class="text-primary-600 font-bold text-2xl mt-10">LED hologram</h2>
<p class="text-bright mt-2">
Work in progress...
</p>
<!--
<h2 class="text-primary-600 font-bold text-2xl mt-10">WRB App</h2>
<p class="text-bright mt-2">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio commodi, atque dolorem beatae recusandae ipsum culpa vel accusantium. Autem at nostrum est libero excepturi numquam iste recusandae expedita ab laborum, fugit architecto soluta dolores non itaque aliquid reprehenderit alias eum cupiditate esse doloribus minus praesentium? Architecto totam sunt libero minus?
</p>
-->
</div>
</template>

View File

@@ -0,0 +1,22 @@
<template>
<div class="py-40">
<h1 class="text-6xl font-bold text-primary-500">Skills</h1>
<h2 class="text-primary-600 font-bold text-2xl mt-10">Linux</h2>
<p class="text-bright mt-2">
I have been using Linux as my daily driver since 2020. I started out with <a href="https://pop.system76.com/">Pop!_OS</a> and at that moment my love started with Linux. Early 2021 I switch to <a href="https://archlinux.org/">Archlinux</a> and was very happy with the customizability. Later in 2022 I started using a tiling window manager instead of a stacking window manager, because I wanted to be more productive and learn more about how a desktop works. Since late 2023 until now I use <a href="https://nixos.org/">NixOS</a> because I loved the idea of an declarative system.
</p>
<h2 class="text-primary-600 font-bold text-2xl mt-10">Programming</h2>
<p class="text-bright mt-2">
My programming journey started in 2018 with learning the basics of <a href="https://arduino.cc">Arduino</a>. Later I started learning html, css and javascript to learn about the web. I found the framework <a href="https://nuxt.com">Nuxt</a> and now use this to create websites and progressive web apps. Since late 2023 I started learning the <a href="https://rustlang.org">Rust</a> programming language, because I wanted to create native desktop applications without electron.
</p>
<h2 class="text-primary-600 font-bold text-2xl mt-10">Tools</h2>
<ul class="mt-2">
<li class="text-bright">
Docker, Git, Ionic
</li>
</ul>
</div>
</template>

View File

@@ -1,8 +1,20 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
extends: ['nuxt-umami'],
modules: [
'@nuxtjs/tailwindcss',
'@nuxtjs/i18n',
'nuxt-icon',
],
app: {
head: {
link: [
{
rel: "icon",
href: "/logo.svg",
type: "image/svg+xml",
},
],
}
}
})

View File

@@ -11,10 +11,13 @@
},
"devDependencies": {
"@nuxt/devtools": "latest",
"@nuxtjs/i18n": "^7.3.1",
"@nuxtjs/tailwindcss": "^6.9.5",
"nuxt": "^3.8.1",
"nuxt-icon": "^0.6.6",
"vue": "^3.3.8",
"vue-router": "^4.2.5"
},
"dependencies": {
"nuxt-umami": "^2.5.5"
}
}

1001
website/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

48
website/public/logo.svg Normal file
View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="40.1875"
height="30.464842"
viewBox="0 0 10.632943 8.0604894"
version="1.1"
id="svg5"
sodipodi:docname="inkscape.svg"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview46"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="9.8333334"
inkscape:cx="33.966101"
inkscape:cy="22.627119"
inkscape:window-width="1896"
inkscape:window-height="1022"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
id="layer1"
transform="translate(-1.0335286,-2.7486694)">
<path
id="rect753"
style="fill:#00aaff;fill-opacity:1;stroke-width:0.307565"
d="M 1.7197917,2.7486694 5.3211222,6.35 4.635376,7.036263 1.0335286,3.4344157 V 5.492688 L 3.6059814,8.0651408 1.7197917,9.9513306 H 3.7775472 L 4.6348592,9.0940186 5.3211222,9.7797648 6.35,10.809159 7.3788778,9.7797648 8.0651408,9.0940186 8.9224528,9.9513306 H 10.980208 L 9.0940186,8.0651408 11.666471,5.492688 V 3.4344157 L 8.064624,7.036263 7.3788778,6.35 10.980208,2.7486694 H 8.9224528 L 6.35,5.3211222 3.7775472,2.7486694 Z M 6.35,7.3788778 7.036263,8.064624 6.35,8.750887 5.663737,8.064624 Z"
inkscape:export-filename="rect753.svg"
inkscape:export-xdpi="114.66252"
inkscape:export-ydpi="114.66252" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

10
website/shell.nix Normal file
View File

@@ -0,0 +1,10 @@
let
pkgs = import <nixpkgs> { };
in
pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_18
nodePackages.pnpm
nodePackages.typescript-language-server
];
}

View File

@@ -0,0 +1,35 @@
export default {
theme: {
extend: {
colors: {
bright: '#f6fbfe',
dark: {
50: '#19688f',
100: '#175e82',
200: '#155575',
300: '#124b68',
400: '#10425b',
500: '#0e394e',
600: '#0b2f41',
700: '#092634',
800: '#071c27',
900: '#05131a',
950: '#02090d',
},
primary: {
50: '#4dc3ff',
100: '#3dbeff',
200: '#2eb9ff',
300: '#1fb4ff',
400: '#0fafff',
500: '#0af',
600: '#00a0f0',
700: '#0096e0',
800: '#008bd1',
900: '#0081c2',
950: '#0077b3',
},
},
}
}
}