aboutsummaryrefslogtreecommitdiff
path: root/src/layouts
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2025-10-12 22:49:13 +0200
committerAriel Costas Guerrero <ariel@costas.dev>2025-10-12 22:49:13 +0200
commitcbdb2ee1547fcfbef8c874da60b17eee80b5fa18 (patch)
treef1adc98515c2ac7681dcd0902b9ebcc2997d6b73 /src/layouts
parentdcc806eff41da24ee6b5984d011f62bc9f4f00ee (diff)
Get rid of trajectory and portfolio
Diffstat (limited to 'src/layouts')
-rw-r--r--src/layouts/HomePageLayout.astro46
-rw-r--r--src/layouts/Layout.astro15
-rw-r--r--src/layouts/PortfolioListLayout.astro137
-rw-r--r--src/layouts/PortfolioSingleLayout.astro370
4 files changed, 13 insertions, 555 deletions
diff --git a/src/layouts/HomePageLayout.astro b/src/layouts/HomePageLayout.astro
index fb3cf34..ca009a5 100644
--- a/src/layouts/HomePageLayout.astro
+++ b/src/layouts/HomePageLayout.astro
@@ -24,56 +24,12 @@ const schema = {
/>
<h1>Inicio</h1>
+
<p>
Te doy la bienvenida a mi web. Me llamo Ariel, y aquí encontrarás
información sobre mí y mis proyectos.
</p>
- <h2>¿Quién soy?</h2>
-
- <p>
- Soy un desarrollador de software con varios años de experiencia en el
- sector, especializado en el desarrollo de aplicaciones web y la
- administración de sistemas Cloud. Me apasiona la tecnología y disfruto
- creando soluciones prácticas y eficientes para resolver problemas reales,
- simplificando la vida y el trabajo de las personas.
- </p>
-
- <p>
- En mi tiempo libre, fuera de mi trabajo, me interesan temas como la
- filosofía, la economía y las finanzas, así como el derecho y la política. Me
- gusta aprender sobre cómo funcionan las cosas y cómo se relacionan entre sí,
- y reflexionar sobre el impacto que tienen en nuestra sociedad y en nuestras
- vidas cotidianas.
- </p>
-
- <h2>¿Qué hago?</h2>
-
- <p>
- Actualmente trabajo como desarrollador de software y administrador Cloud en
- Estelaria Solutions, una empresa de tecnología en Vigo (España). Me encargo
- de desarrollar aplicaciones web en PHP y desplegarlas en la nube de forma
- segura y eficiente.
- </p>
-
- <a href="/trajectory/">Conoce más sobre mi trayectoria profesional</a>
-
- <p>
- También realizo ocasinalmente proyectos personales y freelance para clientes
- que necesitan soluciones a medida o apoyo técnico en sus proyectos. Me gusta
- trabajar con tecnologías modernas y aprender nuevas habilidades para mejorar
- mi trabajo y ofrecer un mejor servicio a mis clientes.
- </p>
-
- <p>
- Si necesitas ayuda con un proyecto o quieres colaborar conmigo, no dudes en
- ponerte en contacto conmigo a través de mi correo electrónico o mis redes
- sociales.
- </p>
-
- <a href="/portfolio/">Echa un vistazo a mi portfolio</a>
-
- <h2>Mis reflexiones</h2>
<p>
En mi blog comparto mis reflexiones, aprendizajes y experiencias sobre los
temas que me interesan, además de hablar ocasionalmente sobre tecnología y
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index 6e389e2..3aa2dd0 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -1,6 +1,4 @@
---
-import "@fontsource-variable/roboto";
-import "@fontsource-variable/roboto-mono";
import Header from "../partials/Header.astro";
import Footer from "../partials/Footer.astro";
@@ -137,8 +135,19 @@ const { title, description, empty } = Astro.props;
background-color: color.adjust($accent, $alpha: -0.85);
}
+ ul:has(li) {
+ padding-left: 1.25rem;
+ margin-top: 0;
+ margin-bottom: 1.5rem;
+
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ }
+
li > time {
- font-family: $monoFontStack;
+ font-size: 0.95rem;
+ user-select: none;
}
main {
diff --git a/src/layouts/PortfolioListLayout.astro b/src/layouts/PortfolioListLayout.astro
deleted file mode 100644
index b509bec..0000000
--- a/src/layouts/PortfolioListLayout.astro
+++ /dev/null
@@ -1,137 +0,0 @@
----
-import t from "../i18n/es.json";
-
-import Layout from "./Layout.astro";
-import PortfolioProject from "@/components/PortfolioProject.astro";
-
-const schema = {
- "@context": "https://schema.org",
- "@type": "WebPage",
- url: "https://www.costas.dev/portfolio",
- headline: t.portfolioPage.headline,
-};
----
-
-<Layout title={t.portfolioPage.title} description={t.portfolioPage.description}>
- <script
- is:inline
- type="application/ld+json"
- slot="head-jsonld"
- set:html={JSON.stringify(schema)}
- />
-
- <h1>{t.portfolioPage.headline}</h1>
-
- <p set:html={t.portfolioPage.intro} />
-
- <h2>{t.portfolioPage.freelanceTitle}</h2>
-
- <p>{t.portfolioPage.freelanceDesc}</p>
-
- <section>
- <PortfolioProject
- title="Mapa patrimonial de la Costa Ártabra"
- summary="Desarrollo de una aplicación completa para el patrimonio cultural y militar de la Costa Ártabra, con un sistema CMS para el personal de la administración y una aplicación web progresiva (PWA) para visualizar el mapa y planificar rutas."
- tags={["dotnet", "react", "mysql", "ubuntu"]}
- detailsLink="/portfolio/mapa-ferrol/"
- onlineLink="https://mapacostaartabramilitar.com"
- />
-
- <PortfolioProject
- title="Extractor de pedidos venta online"
- summary="Aplicación de escritorio que extrae los datos sobre los pedidos on-line de diversas plataformas (como WooCommerce, Amazon y Ebay)."
- tags={["java", "windows"]}
- detailsLink="/portfolio/order-extractor/"
- />
-
- <PortfolioProject
- title="Museo a ceo aberto de Ponteareas"
- summary="Desarrollo de visualización de contenido turístico para el Concello de Ponteareas. Incluye contenido en 360º e incrustación de vídeos de YouTube. Realizado en 2021."
- tags={["php", "web"]}
- detailsLink="/portfolio/qr-ponteareas/"
- />
-
- <PortfolioProject
- title="QR Touro turístico"
- summary="Desarrollo de un generador estático en TypeScript para información turística del Concello de Touro. Realizado en 2020."
- tags={["typescript", "web"]}
- detailsLink="/portfolio/qr-touro/"
- />
-
- <PortfolioProject
- title="Consultoría WordPress"
- summary="Trabajos de mantenimiento, optimización y migración de sitios web WordPress y tiendas online WooCommerce."
- tags={["php", "wordpress"]}
- detailsLink="/portfolio/wp-consulting/"
- />
- </section>
-
- <h2>{t.portfolioPage.ownProjectsTitle}</h2>
-
- <p>{t.portfolioPage.ownProjectsDesc}</p>
-
- <section>
- <PortfolioProject
- title="Web personal"
- summary="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 via GitHub Actions en mi servidor."
- tags={["astro", "github", "ubuntu"]}
- githubLink="https://github.com/arielcostas/costasdev"
- />
-
- <PortfolioProject
- title="MiEntreno (proyecto fin de ciclo)"
- summary="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."
- tags={["dotnet", "azure"]}
- githubLink="https://github.com/arielcostas/mientreno"
- detailsLink="/portfolio/mientreno/"
- />
-
- <PortfolioProject
- title="Vigo 360"
- summary="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."
- tags={["go", "mysql", "ubuntu"]}
- githubLink="https://github.com/arielcostas/vigo360"
- detailsLink="/portfolio/vigo-360/"
- onlineLink="https://vigo360.es"
- />
- </section>
-
- <div class="trajectory-summary">
- <h2>{t.portfolioPage.trajectoryTitle}</h2>
- <p>{t.portfolioPage.trajectorySummary}</p>
- <a href="/trajectory" class="cta-link">{t.portfolioPage.viewTrajectory} →</a>
- </div>
-</Layout>
-
-<style>
- section {
- display: grid;
- grid-template-columns: repeat(auto-fill,minmax(350px,1fr));
- gap: 1.5rem;
- }
-
- .trajectory-summary {
- margin-top: 3rem;
- background-color: #FFFFFF;
- border-radius: 8px;
- padding: 1.5rem;
- box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.08);
- border-left: 4px solid hsl(209, 94%, 42%);
- }
-
- .trajectory-summary h2 {
- margin-top: 0;
- }
-
- .cta-link {
- display: inline-block;
- margin-top: 0.5rem;
- font-weight: 600;
- text-decoration: none;
- color: hsl(215, 90%, 30%);
- }
-
- .cta-link:hover {
- text-decoration: underline;
- }
-</style>
diff --git a/src/layouts/PortfolioSingleLayout.astro b/src/layouts/PortfolioSingleLayout.astro
deleted file mode 100644
index 1922e16..0000000
--- a/src/layouts/PortfolioSingleLayout.astro
+++ /dev/null
@@ -1,370 +0,0 @@
----
-import Layout from "@/layouts/Layout.astro";
-import { render } from "astro:content";
-import TechnologyBadge from "@/components/TechnologyBadge.astro";
-import type { InferEntrySchema } from "astro:content";
-import { Icon } from "astro-icon/components";
-
-interface Props {
- entry: any;
-}
-
-const { entry } = Astro.props;
-const data = entry.data as InferEntrySchema<"portfolio">;
-const { Content } = await render(entry);
----
-
-<Layout title={data.title} description={data.description}>
- <a id="link-back" href="/portfolio/">
- <svg
- xmlns="http://www.w3.org/2000/svg"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
- class="w-6 h-6 inline-block mr-2"
- >
- <polyline points="15 18 9 12 15 6"></polyline>
- </svg>
- Volver al portfolio
- </a>
-
- <h1>{data.title}</h1>
-
- <small>Hecho con {data.technologies.map((technology: string) => (
- <TechnologyBadge size="small" code={technology} />
- ))}</small>
-
- <Content />
-
- <div class="project-links">
- {data.githubLink && <a href={data.githubLink} target="_blank" rel="noopener noreferrer" class="project-link">
- <Icon name="tabler:brand-github" class="link-icon"/>
- <span>Código en GitHub</span>
- </a>}
-
- {data.onlineLink && <a href={data.onlineLink} target="_blank" rel="noopener noreferrer" class="project-link">
- <Icon name="tabler:external-link" class="link-icon"/>
- <span>Ver en línea</span>
- </a>}
-
- {data.demoLink && <a href={data.demoLink} target="_blank" rel="noopener noreferrer" class="project-link">
- <Icon name="tabler:device-laptop" class="link-icon"/>
- <span>Ver demo</span>
- </a>}
- </div>
-
- {data.images.length > 0 && (
- <h2>Galería</h2>
- <section id="project-images">
- {data.images.map((image) => (
- <a href={`${image.src}.png`} target="_blank" rel="noopener noreferrer">
- <picture>
- <source
- srcset={`${image.src}.webp`}
- type="image/webp"
- />
- <img src={`${image.src}.png`} alt={image.alt} loading="lazy" />
- </picture>
- </a>
- ))}
- </section>
- )}
-
- <dialog id="largeimage-dialog">
- <div id="largeimage-dialogcontainer">
- <button class="largeimage__nav" aria-label="Previous image" id="largeimage__nav-left">
- <Icon name="tabler:chevron-left" />
- </button>
- <div id="largeimage-imagecontainer">
- <img id="largeimage-image" alt="Some alt" />
- </div>
- <div id="largeimage-caption">Some caption</div>
- <button class="largeimage__nav" aria-label="Next image" id="largeimage__nav-right">
- <Icon name="tabler:chevron-right" />
- </button>
- <button id="largeimage-close"><Icon name="tabler:x" /></button>
- </div>
- </dialog>
-
-</Layout>
-
-<script>
- document.addEventListener("DOMContentLoaded", () => {
- const dialog = document.getElementById("largeimage-dialog") as HTMLDialogElement;
- const closeButton = document.getElementById("largeimage-close") as HTMLButtonElement;
- const imageElement = document.getElementById("largeimage-image") as HTMLImageElement;
- const captionElement = document.getElementById("largeimage-caption") as HTMLDivElement;
- const navLeft = document.getElementById("largeimage__nav-left") as HTMLButtonElement;
- const navRight = document.getElementById("largeimage__nav-right") as HTMLButtonElement;
- const imageLinks = Array.from(document.querySelectorAll("#project-images a")) as HTMLAnchorElement[];
-
- const images = imageLinks.map(link => {
- const img = link.querySelector("img");
- return {
- src: img?.src,
- alt: img?.alt
- };
- });
- let currentIndex = 0;
-
- function showImage(index: number) {
- if (index < 0 || index >= images.length) return;
- currentIndex = index;
- const { src, alt } = images[currentIndex];
- if (!imageElement || !captionElement) {
- console.error("Image or caption element not found");
- return;
- }
- imageElement.src = src!;
- imageElement.alt = alt!;
- captionElement.textContent = alt || "Imagen del proyecto";
- }
-
- if (!dialog || !closeButton || !imageElement || !captionElement) {
- console.error("Dialog or elements not found");
- return;
- }
-
- imageLinks.forEach((link, idx) => {
- link.addEventListener("click", (e) => {
- e.preventDefault();
- showImage(idx);
- dialog.showModal();
- });
- });
-
- closeButton.addEventListener("click", () => {
- dialog.close();
- });
-
- if (navLeft) {
- navLeft.addEventListener("click", (e) => {
- e.preventDefault();
- showImage((currentIndex - 1 + images.length) % images.length);
- });
- }
- if (navRight) {
- navRight.addEventListener("click", (e) => {
- e.preventDefault();
- showImage((currentIndex + 1) % images.length);
- });
- }
-
- dialog.addEventListener("keydown", (e) => {
- if (e.key === "ArrowLeft") {
- showImage((currentIndex - 1 + images.length) % images.length);
- } else if (e.key === "ArrowRight") {
- showImage((currentIndex + 1) % images.length);
- } else if (e.key === "Escape") {
- dialog.close();
- }
- });
-
- dialog.addEventListener("shown", () => {
- dialog.focus();
- });
-
- dialog.addEventListener("open", () => {
- dialog.focus();
- });
-
- dialog.addEventListener("click", (e) => {
- if (e.target === dialog) {
- dialog.close();
- }
- });
- });
-</script>
-
-<style>
- a#link-back {
- display: inline-flex;
- align-items: center;
- gap: 0.5rem;
- text-decoration: none;
- text-transform: uppercase;
- transition: color 0.2s ease-in-out;
- }
-
- a#link-back svg {
- height: 1em;
- }
-
- #project-images {
- display: flex;
- flex-direction: row;
- gap: 1.5rem;
- margin: 1.5rem 0 2rem;
- overflow-x: auto;
- padding-bottom: 1rem;
- -webkit-overflow-scrolling: touch;
- scrollbar-width: thin;
- }
-
- #project-images a {
- display: block;
- flex: 0 0 auto;
- box-shadow: none;
- text-decoration: none;
- padding: 0;
- }
-
- #project-images picture {
- display: block;
- overflow: hidden;
- border-radius: 0.25rem;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
- height: max(20vh, 400px);
- }
-
- #project-images img {
- height: 100%;
- object-fit: cover;
- }
-
- #project-images a {
- position: relative;
- }
-
- .project-links {
- display: flex;
- gap: 1rem;
- flex-wrap: wrap;
- margin: 1.5rem 0 2.5rem;
- }
-
- .project-link {
- display: inline-flex;
- align-items: center;
- gap: 0.5rem;
- padding: 0.5rem 1.25rem;
- border-radius: 2rem;
- background-color: #f3f4f6;
- color: #333;
- font-weight: 600;
- text-decoration: none;
- box-shadow: none;
- transition: all 0.2s ease-in-out;
-
- &:hover {
- background-color: #e5e7eb;
- transform: translateY(-2px);
- box-shadow: none;
- }
-
- &:focus {
- outline: 2px solid $secondary;
- background-color: #e5e7eb;
- box-shadow: none;
- }
-
- .link-icon {
- font-size: 1.2rem;
- }
- }
-
- #largeimage-dialog {
- padding: 0;
- border: none;
- background: transparent;
- max-width: 100vw;
- max-height: 100vh;
- margin: auto;
- }
-
- #largeimage-dialog::backdrop {
- background: #000c;
- }
-
- #largeimage-dialogcontainer {
- position: relative;
- display: flex;
- flex-direction: column;
- gap: 1rem;
- height: 100%;
- padding: 1.5rem;
- }
-
- #largeimage-imagecontainer {
- max-width: 100%;
- max-height: calc(100vh - 2rem);
- overflow: hidden;
- position: relative;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
-
- #largeimage-image {
- object-fit: cover;
- max-width: 100%;
- max-height: calc(100vh - 9rem);
-
- border-radius: 0.5rem;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
- }
-
- #largeimage-caption {
- position: static;
- background: #FFFC;
- color: #000;
- font-size: 1rem;
- text-align: center;
- border-radius: 0.5rem;
- padding: 0.75rem 1rem;
- max-width: 100%;
- }
-
- #largeimage-close {
- position: absolute;
- top: 1rem;
- right: 1rem;
- width: 2rem;
- height: 2rem;
- border: none;
- background: #fffc;
- border-radius: 50%;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 1.5rem;
- color: #000;
- transition: background-color .2s;
- }
-
- .largeimage__nav {
- position: absolute;
- top: 50%;
- transform: translateY(-50%);
- width: 2.5rem;
- height: 2.5rem;
- border: none;
- background: #fffc;
- border-radius: 50%;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 2rem;
- z-index: 2;
- color: #000;
- transition: background-color .2s;
- }
-
- #largeimage__nav-left {
- left: 1rem;
- }
- #largeimage__nav-right {
- right: 1rem;
- }
-
- .largeimage__nav:hover,
- #largeimage-close:hover {
- background-color: #FFFFFF;
- }
-</style>