aboutsummaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/blog.astro72
-rw-r--r--src/pages/blog.xml.js19
-rw-r--r--src/pages/blog/[slug].astro59
-rw-r--r--src/pages/index.astro64
-rw-r--r--src/pages/portfolio.astro175
5 files changed, 389 insertions, 0 deletions
diff --git a/src/pages/blog.astro b/src/pages/blog.astro
new file mode 100644
index 0000000..e533fb6
--- /dev/null
+++ b/src/pages/blog.astro
@@ -0,0 +1,72 @@
+---
+import { getCollection } from "astro:content";
+import Layout from "../layouts/Layout.astro";
+
+const blogCollection = (await getCollection("blog")).sort((a, b) => {
+ return b.data.publishedAt.getTime() - a.data.publishedAt.getTime();
+});
+
+const groupedPosts = blogCollection.reduce(
+ (acc: Record<string, any[]>, post) => {
+ const year = post.data.publishedAt.getFullYear();
+ const month = post.data.publishedAt.getMonth() + 1;
+ const key = `${year}-${month}`;
+ if (!acc[key]) {
+ acc[key] = [];
+ }
+ acc[key].push(post);
+ return acc;
+ },
+ {},
+);
+
+function humaniseDate(date: Date) {
+ const result = date.toLocaleDateString("es-ES", {
+ month: "long",
+ year: "numeric",
+ });
+ return result.charAt(0).toUpperCase() + result.slice(1);
+}
+
+const schema = {
+ "@context": "https://schema.org",
+ "@type": "Blog",
+ "headline": "Blog de Ariel Costas",
+ "description": "En este blog encontrarás artículos sobre desarrollo, tecnología y otras temáticas que pueda querer compartir. Disclaimer de siempre: las opiniones son mías, y no representan a ninguna empresa o institución.",
+ "publisher": {
+ "@type": "Person",
+ "name": "Ariel Costas",
+ },
+ "author": {
+ "@type": "Person",
+ "name": "Ariel Costas",
+ }
+};
+---
+
+<Layout title="Blog" description="Artículos sobre desarrollo, tecnología y otras temáticas que pueda querer compartir.">
+ <script type="application/ld+json" slot="head-jsonld" set:html={JSON.stringify(schema)}></script>
+
+ <h1>Blog de Ariel Costas</h1>
+
+ <p>
+ En este blog encontrarás artículos sobre desarrollo, tecnología y otras
+ temáticas que pueda querer compartir. Disclaimer de siempre: las
+ opiniones son mías, y no representan a ninguna empresa o institución.
+ </p>
+
+ {
+ Object.entries(groupedPosts).map(([key, posts]) => (
+ <section>
+ <h2>{humaniseDate(new Date(key))}</h2>
+ <ul>
+ {posts.map((post) => (
+ <li>
+ <a href={`/blog/${post.slug}`}>{post.data.title}</a>
+ </li>
+ ))}
+ </ul>
+ </section>
+ ))
+ }
+</Layout>
diff --git a/src/pages/blog.xml.js b/src/pages/blog.xml.js
new file mode 100644
index 0000000..ec8d424
--- /dev/null
+++ b/src/pages/blog.xml.js
@@ -0,0 +1,19 @@
+import rss from '@astrojs/rss';
+import { getCollection } from 'astro:content';
+
+
+export async function GET(context) {
+ const collection = await getCollection('blog');
+
+ return rss({
+ title: "Blog de Ariel Costas",
+ description: "Artículos del blog de Ariel Costas",
+ site: context.site,
+ items: collection.map((post) => ({
+ title: post.data.title,
+ link: `${context.site}blog/${post.slug}`,
+ description: post.data.metaDescription,
+ pubDate: post.data.publishedAt
+ }))
+ })
+} \ No newline at end of file
diff --git a/src/pages/blog/[slug].astro b/src/pages/blog/[slug].astro
new file mode 100644
index 0000000..f9ceec1
--- /dev/null
+++ b/src/pages/blog/[slug].astro
@@ -0,0 +1,59 @@
+---
+import type { GetStaticPaths } from "astro";
+import Layout from "../../layouts/Layout.astro";
+import { getCollection } from "astro:content";
+
+export const getStaticPaths = (async () => {
+ const entries = await getCollection("blog");
+ return entries.map((entry) => ({
+ params: { slug: entry.slug },
+ props: { entry },
+ }));
+}) satisfies GetStaticPaths;
+
+const { entry } = Astro.props;
+const { Content } = await entry.render();
+
+const formattedDate = new Date(entry.data.publishedAt).toLocaleDateString(
+ "es-ES",
+ {
+ year: "numeric",
+ month: "long",
+ day: "numeric",
+ weekday: "long",
+ },
+);
+
+const schema = {
+ "@context": "https://schema.org",
+ "@type": "BlogPosting",
+ headline: entry.data.title,
+ datePublished: entry.data.publishedAt.toISOString(),
+ author: {
+ "@type": "Person",
+ name: "Ariel Costas Guerrero",
+ },
+ publisher: {
+ "@type": "Person",
+ name: "Ariel Costas Guerrero",
+ logo: {
+ "@type": "ImageObject",
+ url: "https://www.costas.dev/favicon.png",
+ },
+ },
+};
+---
+
+<Layout title={entry.data.title} description={entry.data.metaDescription}>
+ <script type="application/ld+json" slot="head-jsonld" set:html={JSON.stringify(schema)}></script>
+
+ <h1>{entry.data.title}</h1>
+ <small>
+ Publicado el
+ <time datetime={entry.data.publishedAt.toISOString()}>
+ {formattedDate}
+ </time>
+ </small>
+
+ <Content />
+</Layout>
diff --git a/src/pages/index.astro b/src/pages/index.astro
new file mode 100644
index 0000000..abf3acd
--- /dev/null
+++ b/src/pages/index.astro
@@ -0,0 +1,64 @@
+---
+import { getCollection } from "astro:content";
+import Layout from "../layouts/Layout.astro";
+
+const blogCollection = (await getCollection("blog")).sort((a, b) => {
+ return b.data.publishedAt.getTime() - a.data.publishedAt.getTime();
+});
+
+const schema = {
+ "@context": "http://schema.org",
+ "@type": "WebSite",
+ id: "https://www.costas.dev/",
+ url: "https://www.costas.dev/",
+};
+---
+
+<Layout title="Inicio" description="Página de inicio de mi web">
+ <script type="application/ld+json" slot="head-jsonld" set:html={JSON.stringify(schema)}></script>
+
+ <h1>Inicio</h1>
+ <p>
+ Te doy la bienvenida a mi web. Aquí encontrarás información sobre mí,
+ mis proyectos y mis intereses. Esta web está creada con el generador
+ Hugo y un tema creado por mí desde cero.
+ </p>
+ <h2>¿Quién soy?</h2>
+ <p>
+ Soy un desarrollador web que le gusta aprender cosas nuevas y compartir
+ su conocimiento. Me gusta la programación, el diseño web y la
+ creatividad. Me encanta crear cosas nuevas y aprender de los demás.
+ </p>
+
+ <h2>¿Qué hago?</h2>
+ <p>
+ Actualmente trabajo como desarrollador de software y admistrador de
+ Cloud en una empresa de tecnología. Me encargo de desarrollar
+ aplicaciones web y desplegarlas en la nube de forma segura y eficiente.
+ </p>
+
+ <a href="/portfolio">Mi portafolio</a>
+
+ <h2>Últimas entradas del blog</h2>
+
+ <ul>
+ {
+ blogCollection.slice(0, 5).map((p) => {
+ const date = Intl.DateTimeFormat("es-ES", {
+ day: "2-digit",
+ month: "short",
+ year: "numeric",
+ }).format(p.data.publishedAt);
+ return (
+ <li>
+ <time datetime={p.data.publishedAt.toISOString()}>
+ {date}
+ </time>
+ <a href={`/blog/${p.slug}`}>{p.data.title}</a>
+ </li>
+ );
+ })
+ }
+ </ul>
+ <a href="/blog">Ver todas las entradas</a>
+</Layout>
diff --git a/src/pages/portfolio.astro b/src/pages/portfolio.astro
new file mode 100644
index 0000000..c0eb7bc
--- /dev/null
+++ b/src/pages/portfolio.astro
@@ -0,0 +1,175 @@
+---
+import Layout from "../layouts/Layout.astro";
+
+const schema = {
+ "@context": "https://schema.org",
+ "@type": "WebPage",
+ "url": "https://www.costas.dev/portfolio",
+ "headline": "Mi trayectoria como desarrollador"
+};
+---
+
+<Layout title="Portfolio" description="Mi trayectoria como desarrollador">
+ <script type="application/ld+json" slot="head-jsonld" set:html={JSON.stringify(schema)}></script>
+
+ <h1>Mi trayectoria como desarrollador</h1>
+
+ <p>
+ Soy un desarrollador de software que vive en Vigo, España. Me gusta
+ mucho la tecnología, y me gusta aprender cosas nuevas. Me dedico
+ profesionalmente al desarrollo de software en todos sus ámbitos: desde
+ el diseño de la arquitectura, la implementación y el despliegue en
+ producción, pasando por otros aspectos como la experiencia de usuario,
+ la accesibilidad y la seguridad.
+ </p>
+
+ <h2>Tecnologías que domino</h2>
+
+ <p>
+ Domino principalmente el ecosistema de Microsoft: .NET (C#), ASP.NET
+ Core, SQL Server, Azure y Azure DevOps. También tengo experiencia con
+ otros lenguajes y tecnologías, como PHP, Python y Java. Además, tengo
+ conocimientos de frontend con
+ <abbr title="Hypertext Markup Language">HTML5</abbr>,
+ <abbr title="Cascading Style Sheets">CSS3</abbr>, JavaScript y
+ TypeScript.
+ </p>
+
+ <p>
+ También tengo experiencia con herramientas de DevOps como Docker,
+ Kubernetes, Terraform y GitHub Actions; así como el ecosistema Cloud de
+ Azure.
+ </p>
+
+ <h2>Educación y credenciales</h2>
+
+ <ul>
+ <li>
+ <strong>Microsoft Certified: Azure Developer Associate</strong>:
+ acredita mis conocimientos en el desarrollo de aplicaciones en
+ Azure. <a
+ href="https://learn.microsoft.com/api/credentials/share/en-us/ariel-costas/E15072607CCF2DA9?sharingId=149A1CD9C13790F4"
+ >Ver credencial</a
+ >.
+ </li>
+
+ <li>
+ <strong>Microsoft Certified: Azure DevOps Engineer Expert</strong>:
+ acredita mis conocimientos en la implementación de metodologías de
+ DevOps en Azure con Azure DevOps y GitHub. <a
+ href="https://learn.microsoft.com/api/credentials/share/en-us/ariel-costas/5FB94876A1701595?sharingId=149A1CD9C13790F4"
+ >Ver credencial</a
+ >
+ </li>
+
+ <li>
+ <strong
+ >Técnico Superior en Desarrollo de Aplicaciones Multiplataforma</strong
+ >: título de formación profesional de grado superior, obtenido en el
+ <a href="https://iesteis.es/">IES de Teis</a> en Vigo.
+ </li>
+ </ul>
+
+ <h2>Experiencia laboral</h2>
+
+ <h3>Estelaria Solutions (Q3 2023 - actualidad)</h3>
+
+ <p>
+ Desarrollo de aplicaciones full-stack, principalmente en PHP con
+ Symfony, MongoDB y JavaScript Vanilla. Además, implementé una cantidad
+ considerable de mejoras en usabilidad, accesibilidad y rendimiento.
+ </p>
+
+ <p>
+ También me encargo de la gestión de la infraestructura en AWS, y de la
+ implementación de herramientas de colaboración como Jira y GitHub.
+ </p>
+
+ <h3>FCT en Polygon-E (Q2 2023)</h3>
+
+ <p>
+ Realicé mis prácticas de formación profesional en la empresa Polygon-E,
+ donde desarrollé varias aplicaciones de gestión interna con ASP.NET Core
+ y Blazor, desplegando sobre entornos <i>on-premise</i> con Windows Server,
+ IIS y SQL Server.
+ </p>
+
+ <h2>Proyectos para terceros (freelance)</h2>
+
+ <p>
+ En contadas ocasiones, he realizado proyectos para terceros por encargo:
+ </p>
+
+ <ul>
+ <li>
+ <p>
+ <strong>Extractor de pedidos compra online (2023)</strong>
+ Implementación de una aplicación de escritorio que extrae los datos
+ sobre los pedidos on-line de diversas plataformas (como WooCommerce,
+ Amazon y Ebay) para almacenar de forma local y centralizada. Además,
+ cruza estos datos con la base de datos de productos en almacén y
+ sus precios de coste, para generar informes de Excel sobre los ingresos
+ y costes por cada pedido, así como calcular la rentabilidad de estos.
+ </p>
+ </li>
+
+ <li>
+ <p>
+ <strong>
+ Punto de información turística en móviles (2020-2021)
+ </strong>
+ Creación de un sitio web dinámico con PHP adaptado a móviles y accesible
+ mediante QR en localizaciones físicas. Cada página muestra datos
+ de la ubicación correspondiente en tres idiomas (castellano, gallego
+ e inglés), una galería de imágenes en 360º con la biblioteca PanoLens
+ y vídeos incrustados de YouTube.
+ </p>
+ </li>
+ </ul>
+
+ <h2>Proyectos propios</h2>
+
+ <p>
+ Además, tengo varios proyectos propios que he desarrollado en mi tiempo
+ libre:
+ </p>
+
+ <ul>
+ <li>
+ <p>
+ <strong>Web personal (2023 - actualidad)</strong>
+ Desarrollado con Astro, un generador de sitios web estáticos que
+ permite escribir contenido en Markdown y publicar en la web con un
+ rendimiento excelente. Desplegado sobre Azure Static Web Apps.
+ </p>
+ </li>
+
+ <li>
+ <p>
+ <strong>MiEntreno (proyecto fin de ciclo)</strong>
+ Aplicación web para la gestión de entrenamientos deportivos, con
+ una interfaz sencilla y fácil de usar. Desarrollado con ASP.NET Core,
+ Razor Pages y SQL Server. Desplegado en Azure App Service, y usando
+ sistemas como RabbitMQ y Azure Communication Services.
+ </p>
+ </li>
+
+ <li>
+ <p>
+ <strong>Vigo 360 (2021 - actualidad)</strong>
+ Blog sobre Vigo y su entorno, orientado principalmente a hablar de
+ movilidad y toponimia. Desarrollado en Go, con base de datos MySQL
+ y desplegado sobre VPS administrado por mí mismo.
+ </p>
+ <p>
+ Además, dentro del ámbito de este proyecto, he desarrollado más
+ herramientas, como un bot de Telegram que informa sobre las
+ llegadas de autobuses en tiempo real, a partir de los datos
+ obtenidos mediante <i>web scraping</i> de la web de Vitrasa.
+ <a href="https://vigo360.es/post/publicamos-bot-infobus"
+ >Más información</a
+ >.
+ </p>
+ </li>
+ </ul>
+</Layout>