Big update
All checks were successful
Build and Deploy Nuxt / build (push) Successful in 35s

This commit is contained in:
2026-03-20 23:10:38 +01:00
parent 63cb32779f
commit c105669065
25 changed files with 268 additions and 135 deletions

View File

@@ -1,6 +1,6 @@
<template>
<div class="footer">
<span>(C) 2026 Aran Roig. All rights whatever.</span>
<span>{{ $t('footer') }}</span>
</div>
</template>

View File

@@ -1,8 +1,13 @@
<script setup lang="ts">
const localePath = useLocalePath()
</script>
<template>
<div class="menus">
<NuxtLink href="/">About</NuxtLink>
<NuxtLink href="/blog">Blog</NuxtLink>
<NuxtLink class="disabled">Drawings</NuxtLink>
<NuxtLink :to="localePath('index')">/</NuxtLink>
<NuxtLink :to="localePath('blog')">/{{ $t('header.links.blog') }}</NuxtLink>
<NuxtLink :to="localePath('contact')">/{{ $t('header.links.contact') }}</NuxtLink>
<!-- <NuxtLink class="disabled">Drawings</NuxtLink> -->
</div>
</template>

View File

@@ -35,7 +35,7 @@ import SiteOptions from './site_options/SiteOptions.vue';
position: relative;
left: 45px;
margin-top: 300px;
margin-left: -500px;
margin-left: -360px;
margin-bottom: 25px;
user-select: none;
}

View File

@@ -1,6 +1,5 @@
<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
const dropdownVisible = ref(false);
@@ -26,29 +25,24 @@ onUnmounted(() => {
// i18n
const { locale } = useI18n()
const { locales, setLocale, locale } = useI18n()
const setLocale = (lang) => {
locale.value = lang
const changeLocale = (lang) => {
setLocale(lang.code);
dropdownVisible.value = false
}
</script>
<template>
<div class="menu-container" ref="menuContainer">
<button class="menu-button" @click="toggleDropdown">Language </button>
<button class="menu-button" @click="toggleDropdown">{{ $t("site_options.language_selector.dropdown") }} </button>
<div class="dropdown" v-show="dropdownVisible">
<div class="section">
<div class="menu-item" @click="setLocale('en')">
🇬🇧 English
</div>
<div class="menu-item" @click="setLocale('es')">
🇪🇸 Spanish
</div>
<div class="menu-item" @click="setLocale('ca')">
🇦🇩 Catalan
</div>
<div :class="{'menu-item': true, 'active': locale === loc.code}"
v-for="loc in locales" @click="changeLocale(loc)">
{{ $t('locales.' + loc.code) }}
</div>
</div>
</div>
</div>
@@ -64,6 +58,10 @@ const setLocale = (lang) => {
border-radius: 6px;
cursor: pointer;
margin-right: 15px;
&.active {
background-color: #30363d;
}
}
.dropdown {
z-index: 10;

View File

@@ -13,5 +13,7 @@ import ThemeSelector from './ThemeSelector.vue';
<style lang="scss" scoped>
.site-options {
display: flex;
justify-content: right;
width: 400px;
}
</style>

View File

@@ -30,36 +30,39 @@ onUnmounted(() => {
<template>
<div class="menu-container" ref="menuContainer">
<button class="menu-button" @click="toggleDropdown">Theme </button>
<button class="menu-button" @click="toggleDropdown">{{ $t('site_options.theme_selector.dropdown') }} </button>
<div class="dropdown" v-show="dropdownVisible">
<div class="two-columns">
<div class="section">
<div class="menu-section">
<div class="menu-header">
Theme
{{ $t('site_options.theme_selector.dropdown') }}
</div>
</div>
<div class="divider"></div>
<div class="menu-section">
<div :class="{'menu-item': true, 'active': theme === 'dark' }" @click="setTheme('dark')">
<div class="circle dark"></div>Dark
<div class="circle dark"></div>
{{ $t('themes.dark') }}
</div>
<div :class="{'menu-item': true, 'active': theme === 'light' }" @click="setTheme('light')">
<div class="circle light"></div>Light
<div class="circle light"></div>
{{ $t('themes.light') }}
</div>
</div>
</div>
<div class="section">
<div class="menu-section">
<div class="menu-header">
Dragon
{{ $t('site_options.theme_selector.dragon') }}
</div>
</div>
<div class="divider"></div>
<div class="menu-section">
<div :class="{'menu-item': true, 'active': accent === 'katlum' }" @click="setAccent('katlum')">
<div class="circle katlum"></div>Katlum
<div class="circle katlum"></div>
{{ $t('themes.accents.katlum') }}
</div>
<!--
<div :class="{'menu-item': true, 'active': accent === 'solus' }" @click="setAccent('solus')">

View File

@@ -0,0 +1,6 @@
// i18n.config.ts
export default defineI18nConfig(() => ({
fallbackLocale: 'en',
missingWarn: true,
fallbackWarn: true
}))

View File

@@ -5,7 +5,8 @@ const slug = useRoute().params.slug;
const { locale } = useI18n();
const { data: post } = await useAsyncData(`blog-${slug}`, () => {
return queryCollection(`blog_${locale.value}`).path(`/blog/${locale.value}/${slug}`).first()
console.log(queryCollection(`blog`).path(`/blog/${locale.value}/${slug}`).first())
return queryCollection(`blog`).path(`/blog/${locale.value}/${slug}`).first()
})
</script>

View File

@@ -4,11 +4,8 @@ import { useAsyncData } from '#app';
const { locale } = useI18n();
const {data: posts} = useAsyncData('posts', async () =>
await queryCollection(`blog_${locale.value}`).order('date', 'DESC').all()
);
console.log(await queryCollection(`blog_${locale.value}`).order('date', 'DESC').all());
await queryCollection(`blog`).where('path', 'LIKE', `/blog/${locale.value}/%`).order('date', 'DESC').all()
, {watch: [locale]});
</script>
<template>

View File

@@ -0,0 +1,36 @@
<script setup lang="ts">
import TableHeader from '~/components/parts/TableHeader.vue';
const { get, post } = api();
const { locale } = useI18n();
// Move useAsyncData to top level — NOT inside onMounted
const { data: markdown } = await useAsyncData(`fixed`, async () =>
await queryCollection(`fixed`).path(`/fixed/${locale.value}/contact`).first()
, {watch: [locale]})
</script>
<template>
<TableHeader></TableHeader>
<Container>
<ContentRenderer v-if="markdown" :value="markdown"></ContentRenderer>
</Container>
<Footer></Footer>
</template>
<style lang="scss" scoped>
h2 {
margin-left: 20px;
}
p {
margin-left: 30px;
}
.two-columns {
display: flex;
width: 100%;
}
</style>

View File

@@ -1,7 +1,14 @@
<script setup lang="ts">
import TableHeader from '~/components/parts/TableHeader.vue';
import api from '~/composables/api'
const { get, post } = api();
const { locale } = useI18n();
// Move useAsyncData to top level — NOT inside onMounted
const { data: markdown } = await useAsyncData(`fixed-root`, async () =>
await queryCollection(`fixed`).path(`/fixed/${locale.value}/root`).first()
, {watch: [locale]})
onMounted(async () => {
try {
@@ -15,80 +22,9 @@ onMounted(async () => {
</script>
<template>
<TableHeader></TableHeader>
<Container>
<h2>About</h2>
<p>
I'm Aran. Welcome to my website! It will always remain under development.
</p>
<p>
I am a Mathematician and Software Engineer from Barcelona. I'm currently working as a full-stack dev at <a href="https://codelearn.cat">Codelearn</a> while
also studying on the master's degree in <i>Machine Learning and Cybersecurity for Internet-Connected Systems</i> at <a href="https://upc.edu">UPC</a>
</p>
<p>
Besides all of that, I also like drawing, board games and self-hosting
</p>
<p>You can download my resume <a href="https://cv.aranroig.com">here</a></p>
<h2>Contact</h2>
<ul>
<li>Mail: <a href="mailto:aranseraroig@gmail.com">aranseraroig@gmail.com</a> (Still pending to host my email)</li>
<li>Gitea: <a href="https://git.aranroig.com/Syndria98">git.aranroig.com</a> (My self-hosted git server)</li>
<li>GitHub: <a href="https://github.com/BinarySandia04">BinarySandia04</a></li>
<li>LinkedIn: <a href="https://www.linkedin.com/in/aran-roig/">aran-roig</a></li>
<li>Instagram: <a href="https://www.instagram.com/aran.roig/">aran.roig</a> (Some of my drawings are there)</li>
</ul>
</Container>
<Footer></Footer>
<!--
<div class="two-columns">
<Container style="flex-basis: 70%">
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
</Container>
<Container style="flex-basis: 30%">
Test Lorem ipsum
</Container>
</div>
<div class="two-columns">
<Container style="flex-basis: 70%">
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
</Container>
<Container style="flex-basis: 30%">
Test Lorem ipsum
</Container>
</div>
<div class="two-columns">
<Container style="flex-basis: 70%">
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
Test Lorem ipsum dolor sit amet idk doctor professor idk djdaksjdkasj dmsakjdkj blablabla
</Container>
<Container style="flex-basis: 30%">
Test Lorem ipsum
</Container>
</div>
-->
</template>
<style lang="scss" scoped>
h2 {
margin-left: 20px;
}
p {
margin-left: 30px;
}
.two-columns {
display: flex;
width: 100%;
}
</style>
<TableHeader></TableHeader>
<Container>
<ContentRenderer v-if="markdown" :value="markdown"></ContentRenderer>
</Container>
<Footer></Footer>
</template>

View File

@@ -3,9 +3,9 @@ import { z } from 'zod'
export default defineContentConfig({
collections: {
blog_en: defineCollection({
blog: defineCollection({
type: 'page',
source: 'blog/en/*.md',
source: 'blog/**/**.md',
schema: z.object({
title: z.string(),
slug: z.string(),
@@ -14,26 +14,9 @@ export default defineContentConfig({
})
}),
blog_es: defineCollection({
fixed: defineCollection({
type: 'page',
source: 'blog/en/*.md',
schema: z.object({
title: z.string(),
slug: z.string(),
date: z.string(),
description: z.string()
})
source: 'fixed/**/**.md'
}),
blog_ca: defineCollection({
type: 'page',
source: 'blog/en/*.md',
schema: z.object({
title: z.string(),
slug: z.string(),
date: z.string(),
description: z.string()
})
})
}
})

View File

@@ -0,0 +1,13 @@
---
title: Traductor
description: Problemes del tercer món
date: 2026-03-20
slug: translator
---
Tenir una pàgina web en tres idiomes diferents NO és una bona idea. Hauré de contractar a algú perque em tradueixi els
posts.
Ara mateix tinc fet que només surtin els del teu idioma. No és gens òptim. Li podria demanar a una IA que els tradueixi?
No tinc ni idea.

View File

@@ -0,0 +1,12 @@
---
title: Translator
description: Third world problems
date: 2026-03-20
slug: translator
---
Having a webpage with three different languages is definetly NOT a good idea. I will have to hire someone that translates all my posts for me.
Right now the website only displays blogs of your current locale. Maybe I could ask an AI to translate the posts instead?
Maybe, I don't know.

View File

@@ -0,0 +1,12 @@
---
title: Traductor
description: Problemas del tercer mundo
date: 2026-03-20
slug: translator
---
Tener una pàgina web con tres lenguajes distintos NO es una buena idea. Tendria que contratar a alguien para que traduzca los posts que hago.
Ahora mismo la web solo muestra los blogs que he escrito en el idioma que está seleccionado. A lo mejor seria buena idea decirle a una IA que los tradujera?
Ni idea.

View File

@@ -0,0 +1,7 @@
Contacta'm!
- Correu: [aranseraroig@gmail.com](mailto:aranseraroig@gmail.com) (Aviat tindré el meu propi)
- Gitea: [git.aranroig.com](https://git.aranroig.com/Syndria98) (El meu servidor de git)
- GitHub: [BinarySandia04](https://github.com/BinarySandia04)
- LinkedIn: [aran-roig](https://www.linkedin.com/in/aran-roig/)
- Instagram: [aran.roig](https://www.instagram.com/aran.roig/) (Uns quants dibuixos els tinc allà)

View File

@@ -0,0 +1,8 @@
Hola! Sóc l'Aran. Benvingut a la meva pàgina web! Malauradament, sempre estarà en desenvolupament.
Sóc un matemàtic i enginyer de software de Barcelona. Actualment treballo com a desenvolupador full-stack a [Codelearn](https://codelearn.cat) mentres curso
el màster en *Aprenentatge Automàtic i Ciberseguretat per a Sistemes IoT* de la [UPC](https://upc.edu).
D'altra banda, magrada dibuixar, jugar a jocs de taula i allotjar software localment.
Pots descarregar el meu currículum [aquí](https://cv.aranroig.com)

View File

@@ -0,0 +1,7 @@
Contact me!
- Mail: [aranseraroig@gmail.com](mailto:aranseraroig@gmail.com) (Still pending to host my email)
- Gitea: [git.aranroig.com](https://git.aranroig.com/Syndria98) (My self-hosted git server)
- GitHub: [BinarySandia04](https://github.com/BinarySandia04)
- LinkedIn: [aran-roig](https://www.linkedin.com/in/aran-roig/)
- Instagram: [aran.roig](https://www.instagram.com/aran.roig/) (Some of my drawings are there)

View File

@@ -0,0 +1,8 @@
Hi! I'm Aran. Welcome to my website! Unfortunately, it will always remain under development.
I am a Mathematician and Software Engineer from Barcelona. I'm currently working as a full-stack dev at [Codelearn](https://codelearn.cat) while
also studying on the master's degree in *Machine Learning and Cybersecurity for Internet-Connected Systems* at [UPC](https://upc.edu).
Besides all of that, I also like drawing, board games and self-hosting
You can download my resume [here](https://cv.aranroig.com)

View File

@@ -0,0 +1,7 @@
Contactame!
- Correo: [aranseraroig@gmail.com](mailto:aranseraroig@gmail.com) (Pronto tendre mi propio correo)
- Gitea: [git.aranroig.com](https://git.aranroig.com/Syndria98) (Mi server de git)
- GitHub: [BinarySandia04](https://github.com/BinarySandia04)
- LinkedIn: [aran-roig](https://www.linkedin.com/in/aran-roig/)
- Instagram: [aran.roig](https://www.instagram.com/aran.roig/) (Algunos dibujos mios están allí)

View File

@@ -0,0 +1,7 @@
Hola! Soy Aran. Bienvenido a mi página web! Por desgracia estará siempre en desarrollo.
Soy un matemático e ingeniero de software de Barcelona. Actualmente estoy trabajando como desarrollador full-stack en [Codelearn](https://codelearn.cat) mientras curso el master de *Aprendizaje automático y Ciberseguridad para Sistemas IoT* de la [UPC](https://upc.edu).
A parte de todo esto, me gusta dibujar, los juegos de mesa y alojar software.
Puedes descargar mi currículum [aquí](https://cv.aranroig.com)

View File

@@ -1,3 +1,30 @@
{
"locales": {
"en": "🇺🇸 Anglès",
"es": "🇪🇸 Espanyol",
"ca": "🇦🇩 Català"
},
"themes": {
"light": "Clar",
"dark": "Fosc",
"accents": {
"katlum": "Katlum"
}
},
"site_options": {
"language_selector": {
"dropdown": "Idioma"
},
"theme_selector": {
"dropdown": "Aparença",
"dragon": "Drac"
}
},
"header": {
"links": {
"blog": "blog",
"contact": "contacte"
}
},
"footer": "(C) 2026 Aran Roig. Tots els drets no sé que."
}

View File

@@ -1,3 +1,33 @@
{
"locales": {
"en": "🇺🇸 English",
"es": "🇪🇸 Spanish",
"ca": "🇦🇩 Catalan"
},
"themes": {
"light": "Light",
"dark": "Dark",
"accents": {
"katlum": "Katlum"
}
},
"site_options": {
"language_selector": {
"dropdown": "Language"
},
"theme_selector": {
"dropdown": "Theme",
"dragon": "Dragon"
}
},
"header": {
"links": {
"blog": "blog",
"contact": "contact"
}
},
"pages": {
"root": ""
},
"footer": "(C) 2026 Aran Roig. All rights whatever."
}

View File

@@ -1,3 +1,30 @@
{
"locales": {
"en": "🇺🇸 Ingles",
"es": "🇪🇸 Español",
"ca": "🇦🇩 Catalán"
},
"themes": {
"light": "Claro",
"dark": "Oscuro",
"accents": {
"katlum": "Katlum"
}
},
"site_options": {
"language_selector": {
"dropdown": "Idioma"
},
"theme_selector": {
"dropdown": "Tema",
"dragon": "Dragón"
}
},
"header": {
"links": {
"blog": "blog",
"contact": "contacto"
}
},
"footer": "(C) 2026 Aran Roig. Todos los derechos no se que."
}

View File

@@ -19,11 +19,12 @@ export default defineNuxtConfig({
i18n: {
locales: [
{ code: 'en', iso: 'en-US', name: 'English', file: 'en.json' },
{ code: 'es', iso: 'es-ES', name: 'Spanish', file: 'es.json' },
{ code: 'ca', iso: 'ca-ES', name: 'Catalan', file: 'ca.json' }
{ code: 'en', iso: 'en-US', name: '🇺🇸 English', file: 'en.json' },
{ code: 'es', iso: 'es-ES', name: '🇪🇸 Spanish', file: 'es.json' },
{ code: 'ca', iso: 'ca-ES', name: '🇦🇩 Catalan', file: 'ca.json' }
],
defaultLocale: 'en',
vueI18n: './i18n.config.ts',
langDir: 'locales/'
},
modules: ['@nuxtjs/i18n', '@nuxt/content']