Compare commits
10 Commits
f1a011e2ed
...
dev
Author | SHA1 | Date | |
---|---|---|---|
7b9c9e8971 | |||
2ff922cab5 | |||
dc23b5248b | |||
9ccb8a24f7 | |||
49eb33e83a
|
|||
2f86fc30c3
|
|||
92878dd50a
|
|||
1883dcb8bb
|
|||
25f68630c8
|
|||
8dd3994ed4 |
38
.gitea/workflows/ci.yml
Normal file
38
.gitea/workflows/ci.yml
Normal 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
9
Dockerfile
Normal 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
10
shell.nix
Normal 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
6
website/app.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export default defineAppConfig({
|
||||
umami: {
|
||||
host: 'https://umami.xeovalyte.dev/',
|
||||
id: '7d4c9046-c073-4d31-9bba-2da4be4499fc',
|
||||
},
|
||||
});
|
@@ -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>
|
||||
|
18
website/assets/css/tailwind.css
Normal file
18
website/assets/css/tailwind.css
Normal 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
|
||||
}
|
7
website/components/Content.vue
Normal file
7
website/components/Content.vue
Normal 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>
|
45
website/components/MobileNav.vue
Normal file
45
website/components/MobileNav.vue
Normal 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>
|
20
website/components/Sidebar.vue
Normal file
20
website/components/Sidebar.vue
Normal 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>
|
20
website/components/sections/Heading.vue
Normal file
20
website/components/sections/Heading.vue
Normal 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>
|
22
website/components/sections/Projects.vue
Normal file
22
website/components/sections/Projects.vue
Normal 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>
|
22
website/components/sections/Skills.vue
Normal file
22
website/components/sections/Skills.vue
Normal 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>
|
@@ -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",
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@@ -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
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
48
website/public/logo.svg
Normal 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
10
website/shell.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
let
|
||||
pkgs = import <nixpkgs> { };
|
||||
in
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
nodejs_18
|
||||
nodePackages.pnpm
|
||||
nodePackages.typescript-language-server
|
||||
];
|
||||
}
|
35
website/tailwind.config.js
Normal file
35
website/tailwind.config.js
Normal 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',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user