aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2025-04-10 21:42:41 +0200
committerAriel Costas Guerrero <ariel@costas.dev>2025-04-10 21:42:41 +0200
commite3141794b95e534656427fadf0354435c62254d6 (patch)
tree95788249ac51475aea45ad17d7157dffd1564e47
parent3caee506c961ae0e78503164ed6a0f81db3c8c32 (diff)
Fix formatting
-rw-r--r--.github/workflows/production.yml2
-rw-r--r--.husky/pre-commit2
-rw-r--r--.prettierignore12
-rw-r--r--.prettierrc.cjs3
-rw-r--r--astro.config.mjs54
-rw-r--r--src/assets/Favicon.astro58
-rw-r--r--src/content.config.ts34
-rw-r--r--src/i18n/en.json176
-rw-r--r--src/i18n/es.json176
-rw-r--r--src/i18n/index.ts44
-rw-r--r--src/layouts/ContactPageLayout.astro139
-rw-r--r--src/layouts/HomePageLayout.astro81
-rw-r--r--src/layouts/Layout.astro262
-rw-r--r--src/layouts/PortfolioPageLayout.astro146
-rw-r--r--src/layouts/TrajectoryPageLayout.astro111
-rw-r--r--src/pages/blog.xml.ts29
-rw-r--r--src/pages/blog/[id].astro85
-rw-r--r--src/pages/blog/index.astro116
-rw-r--r--src/pages/contact.astro138
-rw-r--r--src/pages/en/contact.astro2
-rw-r--r--src/pages/en/index.astro2
-rw-r--r--src/pages/en/portfolio.astro2
-rw-r--r--src/pages/en/trajectory.astro2
-rw-r--r--src/pages/index.astro2
-rw-r--r--src/pages/portfolio/[id].astro73
-rw-r--r--src/pages/portfolio/index.astro2
-rw-r--r--src/partials/Footer.astro62
-rw-r--r--src/partials/Header.astro87
-rw-r--r--src/partials/TechnologyBadge.astro216
-rw-r--r--staticwebapp.config.json36
-rw-r--r--styles/shared.scss34
-rw-r--r--tsconfig.json2
32 files changed, 1138 insertions, 1052 deletions
diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml
index 7da097b..3263ce2 100644
--- a/.github/workflows/production.yml
+++ b/.github/workflows/production.yml
@@ -18,7 +18,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: lts/*
- cache: 'npm'
+ cache: "npm"
- name: Install Dependencies
run: npm ci
- name: Build
diff --git a/.husky/pre-commit b/.husky/pre-commit
index 0e40fa7..a5bb86d 100644
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,2 +1,2 @@
-npm run format
+npm run format:dry
npm run check
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..8df4d4b
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,12 @@
+**/*.md
+**/*.mdx
+
+**/.git
+**/node_modules
+**/package.json
+**/package-lock.json
+**/.github
+**/.husky
+**/dist
+**/.vscode
+**/public
diff --git a/.prettierrc.cjs b/.prettierrc.cjs
index 498404d..c3a95df 100644
--- a/.prettierrc.cjs
+++ b/.prettierrc.cjs
@@ -8,6 +8,5 @@ module.exports = {
parser: "astro",
},
},
- ],
- editorconfig: true,
+ ]
};
diff --git a/astro.config.mjs b/astro.config.mjs
index 06a3863..523b075 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -1,30 +1,34 @@
-import sitemap from '@astrojs/sitemap';
-import { defineConfig } from 'astro/config';
+import sitemap from "@astrojs/sitemap";
+import { defineConfig } from "astro/config";
-import mdx from '@astrojs/mdx';
-import { DEFAULT_LANGUAGE, LANGUAGE_CODES } from './src/i18n';
+import mdx from "@astrojs/mdx";
+import { DEFAULT_LANGUAGE, LANGUAGE_CODES } from "./src/i18n";
-import icon from 'astro-icon';
+import icon from "astro-icon";
export default defineConfig({
- compressHTML: true,
- site: "https://www.costas.dev",
- i18n: {
- defaultLocale: DEFAULT_LANGUAGE,
- locales: LANGUAGE_CODES,
- routing: {
- prefixDefaultLocale: false,
- fallbackType: 'redirect',
- redirectToDefaultLocale: true
- }
+ compressHTML: true,
+ site: "https://www.costas.dev",
+ i18n: {
+ defaultLocale: DEFAULT_LANGUAGE,
+ locales: LANGUAGE_CODES,
+ routing: {
+ prefixDefaultLocale: false,
+ fallbackType: "redirect",
+ redirectToDefaultLocale: true,
},
- integrations: [sitemap({
- priority: 0.5,
- changefreq: 'weekly'
- }), mdx(), icon()],
- build: {
- assets: 'assets',
- inlineStylesheets: 'never',
- },
- scopedStyleStrategy: 'where'
-}); \ No newline at end of file
+ },
+ integrations: [
+ sitemap({
+ priority: 0.5,
+ changefreq: "weekly",
+ }),
+ mdx(),
+ icon(),
+ ],
+ build: {
+ assets: "assets",
+ inlineStylesheets: "never",
+ },
+ scopedStyleStrategy: "where",
+});
diff --git a/src/assets/Favicon.astro b/src/assets/Favicon.astro
index 01b7291..3ba1f76 100644
--- a/src/assets/Favicon.astro
+++ b/src/assets/Favicon.astro
@@ -1,36 +1,36 @@
<svg viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg">
- <defs id="defs1">
- <marker
- style="overflow:visible"
- id="ArrowWideRounded"
- refX="0"
- refY="0"
- orient="auto-start-reverse"
- markerWidth="1"
- markerHeight="1"
- viewBox="0 0 1 1"
- preserveAspectRatio="xMidYMid"
- >
- <path
- style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:round"
- d="M 3,-3 0,0 3,3"
- transform="rotate(180,0.125,0)"
- id="path2"></path>
- </marker>
- </defs>
+ <defs id="defs1">
+ <marker
+ style="overflow:visible"
+ id="ArrowWideRounded"
+ refX="0"
+ refY="0"
+ orient="auto-start-reverse"
+ markerWidth="1"
+ markerHeight="1"
+ viewBox="0 0 1 1"
+ preserveAspectRatio="xMidYMid"
+ >
+ <path
+ style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:round"
+ d="M 3,-3 0,0 3,3"
+ transform="rotate(180,0.125,0)"
+ id="path2"></path>
+ </marker>
+ </defs>
- <title>Site icon</title>
+ <title>Site icon</title>
- <path
- style="stroke-width:1;stroke-dasharray:none;marker-end:url(#ArrowWideRounded);paint-order:stroke fill markers"
- d="m 331.6,348.2336 h -6.72 c -8.96,18.66667 -21.46667,32.48 -37.52,41.44 -15.67999,8.96 -32.29333,13.0464 -49.84,13.0464 -18.29333,0 -35.28,-2.98667 -50.96,-8.96 -15.68,-6.34667 -29.49333,-15.49333 -41.44,-27.44 -11.57333,-12.32 -20.72,-27.25333 -27.44,-44.8 -6.72001,-17.54667 -10.08001,-37.89333 -10.08001,-61.04 v -8.96 c 0,-22.77333 3.36,-42.93333 10.08001,-60.48 6.72,-17.54667 15.86667,-32.29333 27.44,-44.24 11.94667,-12.32 25.76,-21.65333 41.44001,-28 15.68,-6.34667 32.29333,-9.52 49.84,-9.52 19.04,0 36.21333,4.29333 51.52,12.88 15.68,8.21333 28,21.09333 36.96,38.64 h 6.72 v -43.68 h 43.68 v 220.64 c 0,11.2 5.04,16.8 15.12,16.8 h 14 v 40.32 h -29.68 c -12.69333,0 -23.14667,-3.71306 -31.36,-11.9264 -7.84,-8.21333 -11.75996,-18.66666 -11.76,-31.36 z M 242,361.28 c 13.06667,0 25.01334,-2.42667 35.84001,-7.28 C 289.04,349.14667 298.56,342.24 306.4,333.28 c 7.84,-8.96 14,-19.6 18.48,-31.92 4.48,-12.69333 6.72,-26.69333 6.72,-42 v -6.72 c 0,-14.93333 -2.24,-28.56 -6.72,-40.88 -4.48,-12.69333 -10.82666,-23.52 -19.03999,-32.48 -7.84,-8.96 -17.36,-15.86667 -28.56,-20.72 -10.82667,-5.22667 -22.58667,-7.84 -35.28,-7.84 -13.06667,0 -25.01333,2.42667 -35.84,7.28 -10.82667,4.85333 -20.34667,11.76 -28.56,20.72 -7.84,8.58667 -14,19.22667 -18.48,31.92 -4.48,12.32 -6.72,25.94667 -6.72,40.88 v 8.96 c 0,31.73333 8.21333,56.56 24.64,74.48 16.8,17.54667 38.45333,26.32 64.95999,26.32 z"
- id="text1"
- aria-label="a"></path>
+ <path
+ style="stroke-width:1;stroke-dasharray:none;marker-end:url(#ArrowWideRounded);paint-order:stroke fill markers"
+ d="m 331.6,348.2336 h -6.72 c -8.96,18.66667 -21.46667,32.48 -37.52,41.44 -15.67999,8.96 -32.29333,13.0464 -49.84,13.0464 -18.29333,0 -35.28,-2.98667 -50.96,-8.96 -15.68,-6.34667 -29.49333,-15.49333 -41.44,-27.44 -11.57333,-12.32 -20.72,-27.25333 -27.44,-44.8 -6.72001,-17.54667 -10.08001,-37.89333 -10.08001,-61.04 v -8.96 c 0,-22.77333 3.36,-42.93333 10.08001,-60.48 6.72,-17.54667 15.86667,-32.29333 27.44,-44.24 11.94667,-12.32 25.76,-21.65333 41.44001,-28 15.68,-6.34667 32.29333,-9.52 49.84,-9.52 19.04,0 36.21333,4.29333 51.52,12.88 15.68,8.21333 28,21.09333 36.96,38.64 h 6.72 v -43.68 h 43.68 v 220.64 c 0,11.2 5.04,16.8 15.12,16.8 h 14 v 40.32 h -29.68 c -12.69333,0 -23.14667,-3.71306 -31.36,-11.9264 -7.84,-8.21333 -11.75996,-18.66666 -11.76,-31.36 z M 242,361.28 c 13.06667,0 25.01334,-2.42667 35.84001,-7.28 C 289.04,349.14667 298.56,342.24 306.4,333.28 c 7.84,-8.96 14,-19.6 18.48,-31.92 4.48,-12.69333 6.72,-26.69333 6.72,-42 v -6.72 c 0,-14.93333 -2.24,-28.56 -6.72,-40.88 -4.48,-12.69333 -10.82666,-23.52 -19.03999,-32.48 -7.84,-8.96 -17.36,-15.86667 -28.56,-20.72 -10.82667,-5.22667 -22.58667,-7.84 -35.28,-7.84 -13.06667,0 -25.01333,2.42667 -35.84,7.28 -10.82667,4.85333 -20.34667,11.76 -28.56,20.72 -7.84,8.58667 -14,19.22667 -18.48,31.92 -4.48,12.32 -6.72,25.94667 -6.72,40.88 v 8.96 c 0,31.73333 8.21333,56.56 24.64,74.48 16.8,17.54667 38.45333,26.32 64.95999,26.32 z"
+ id="text1"
+ aria-label="a"></path>
</svg>
<style>
- svg {
- width: auto;
- height: 2rem;
- }
+ svg {
+ width: auto;
+ height: 2rem;
+ }
</style>
diff --git a/src/content.config.ts b/src/content.config.ts
index 1c24b41..999e4af 100644
--- a/src/content.config.ts
+++ b/src/content.config.ts
@@ -1,25 +1,25 @@
-import { glob } from 'astro/loaders';
-import { defineCollection, z } from 'astro:content';
+import { glob } from "astro/loaders";
+import { defineCollection, z } from "astro:content";
const blog = defineCollection({
- loader: glob({ pattern: '**/*.{md,mdx}', base: "src/data/blog" }),
- schema: z.object({
- title: z.string(),
- metaDescription: z.string(),
- publishedAt: z.coerce.date()
- })
+ loader: glob({ pattern: "**/*.{md,mdx}", base: "src/data/blog" }),
+ schema: z.object({
+ title: z.string(),
+ metaDescription: z.string(),
+ publishedAt: z.coerce.date(),
+ }),
});
const portfolio = defineCollection({
- loader: glob({ pattern: '**/*.{md,mdx}', base: "src/data/portfolio" }),
- schema: z.object({
- title: z.string(),
- description: z.string(),
- technologies: z.array(z.string())
- })
-})
+ loader: glob({ pattern: "**/*.{md,mdx}", base: "src/data/portfolio" }),
+ schema: z.object({
+ title: z.string(),
+ description: z.string(),
+ technologies: z.array(z.string()),
+ }),
+});
export const collections = {
- blog,
- portfolio
+ blog,
+ portfolio,
};
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 1c4c1b1..6cdebe1 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -1,89 +1,89 @@
{
- "header": {
- "home": "Home",
- "trajectory": "Trajectory",
- "portfolio": "Portfolio",
- "blog": "Blog",
- "contact": "Contact"
- },
- "footer": {
- "copyright": "All rights reserved.",
- "contentLicencedUnder": "Unless otherwise stated, the content of this site is licensed under",
- "sourceCodeAvailableOn": "Source code for this site is available on",
- "andIsLicencedUnder": "and is licenced under",
- "eupl": "European Union Public Licence"
- },
- "contactPage": {
- "title": "Contact",
- "description": "The ways to contact me, either by email, phone or social networks.",
- "headline": "Get in touch with me!",
- "enableJs": "JavaScript must be enabled to view the email address and phone number. This is done to prevent scrapers and spam.",
- "intro": "The easiest way to contact me is through my email address: <a href=\"#\" id=\"email-addr\">Enable JS</a>. You can also use <a href=\"https://wa.me/message/W7T7L4EZAELQI1\">WhatsApp</a> with the phone number <a href=\"#\" id=\"phone-number\">Enable JS</a>.",
- "socialMedia": "You can also find me on some social networks:"
- },
- "homePage": {
- "title": "Home",
- "description": "Homepage of my website",
- "welcome": "Welcome to my website. My name is Ariel, and here you will find information about me and my projects.",
- "whoAmI": "Who am I?",
- "whoAmIDesc": "I am a web developer who likes to learn new things and share knowledge. I enjoy programming, web design, and creativity. I love creating new things and learning from others.",
- "moreAboutMe": "More about me",
- "whatIDo": "What do I do?",
- "whatIDoDesc": "I currently work as a software developer and Cloud administrator at a technology company. I develop web applications in PHP and deploy them in the cloud securely and efficiently.",
- "myPortfolio": "My portfolio",
- "latestBlogPosts": "Latest blog posts",
- "viewAllPosts": "View all posts"
- },
- "trajectoryPage": {
- "title": "Trajectory",
- "description": "My trajectory as a software developer, with information about my education, work experience and projects I have worked on.",
- "headline": "My trajectory as a developer",
- "intro": "I am a software developer living in Vigo, Spain. I love technology and I enjoy learning new things. I am professionally dedicated to software development in all its aspects: from architecture design, implementation and production deployment, to other aspects such as user experience, accessibility and security.",
- "techTitle": "Technologies I master",
- "techDescription1": "I mainly master the Microsoft ecosystem: .NET (C#), ASP.NET Core, SQL Server, Azure and Azure DevOps. I also have experience with other languages and technologies, such as PHP, Python and Java. Additionally, I have frontend knowledge with HTML5, CSS3, JavaScript and TypeScript.",
- "techDescription2": "I also have experience with DevOps tools such as Docker, Kubernetes, Terraform and GitHub Actions; as well as the Azure Cloud ecosystem.",
- "educationTitle": "Education and credentials",
- "efsetCert1": "Official EF SET C2 Proficient Certificate",
- "efsetCert2": ": certifies my C2 English level, the highest according to the Common European Framework of Reference for Languages.",
- "viewCertificate": "View certificate",
- "azureDeveloperCert1": "Microsoft Certified: Azure Developer Associate",
- "azureDeveloperCert2": ": certifies my knowledge in Azure application development.",
- "viewCredential": "View credential",
- "azureDevOpsCert1": "Microsoft Certified: Azure DevOps Engineer Expert",
- "azureDevOpsCert2": ": certifies my knowledge in implementing DevOps methodologies in Azure with Azure DevOps and GitHub.",
- "higherTechCert1": "Higher Technical Certificate in Multiplatform Application Development",
- "higherTechCert2": ": higher vocational training degree, obtained at",
- "higherTechCert3": "IES de Teis",
- "higherTechCert4": "in Vigo.",
- "experienceTitle": "Work experience",
- "estelaria1": "Estelaria Solutions (Q3 2023 - present)",
- "estelaria2": "Full-stack application development, mainly in PHP with Symfony, MongoDB and Vanilla JavaScript. In addition, I implemented a considerable number of improvements in usability, accessibility and performance.",
- "estelaria3": "I am also responsible for managing the infrastructure on AWS, and implementing collaboration tools such as Jira and GitHub.",
- "polygon1": "Internship at Polygon-E (Q2 2023)",
- "polygon2": "I did my professional training internship at Polygon-E, where I developed several internal management applications with ASP.NET Core and Blazor, deploying on on-premise environments with Windows Server, IIS and SQL Server.",
- "projectsTitle": "Projects",
- "projectsDescription": "You can find the (public) projects I have worked on in <a href=\"/portfolio\">my portfolio</a> and on my <a href=\"https://github.com/arielcostas\">GitHub profile</a>."
- },
- "portfolioPage": {
- "title": "Portfolio",
- "description": "A list of projects I have worked on in recent years, with the technologies used.",
- "headline": "My portfolio",
- "intro": "In this section, you will find a list of the projects I have worked on, both for third parties and my own. If you would like more information about any of them, please do not hesitate to <a href=\"/contact\">contact me</a>.",
- "freelanceTitle": "Projects for third parties (freelance)",
- "freelanceDesc": "I have developed projects for third parties by commission, the most notable being the following:",
- "orderExtractorTitle": "Online Order Purchase Extractor",
- "orderExtractorDesc": "Desktop application that extracts data about online orders from various platforms (such as WooCommerce, Amazon, and eBay). <a href=\"/portfolio/order-extractor\">More information</a>.",
- "touristInfoTitle": "Tourist Information Point on Mobile Devices",
- "touristInfoDesc": "Web application for tourist information, with QR codes, 360° content, and YouTube embedding. <a href=\"/portfolio/dynamic-tourist-info\">More information</a>.",
- "wpConsultingTitle": "WordPress Consulting",
- "wpConsultingDesc": "Maintenance, optimisation, and migration work for WordPress websites and WooCommerce online shops. <a href=\"/portfolio/wp-consulting\">More information</a>. <a href=\"/contact\">Contact</a>.",
- "ownProjectsTitle": "My own projects",
- "ownProjectsDesc": "Additionally, I have several personal projects that I have developed in my own time, some of which are active and open source.",
- "personalWebTitle": "Personal Website",
- "personalWebDesc": "Developed with Astro, a static site generator that lets you write content in Markdown and publish to the web with excellent performance. Deployed on Azure Static Web Apps.",
- "mientrenoTitle": "MiEntreno (end-of-course project)",
- "mientrenoDesc": "Web application for managing sports training, with a simple and easy-to-use interface. Developed with ASP.NET Core, Razor Pages, and SQL Server. <a href=\"/portfolio/mientreno\">More information</a>. <a href=\"https://github.com/arielcostas/mientreno\">Source code</a>.",
- "vigo360Title": "Vigo 360",
- "vigo360Desc": "Blog about Vigo and its surroundings, mainly focused on mobility and toponymy. Developed in Go, with a MySQL database and deployed on a VPS managed by myself. <a href=\"/portfolio/vigo-360\">More information</a>. <a href=\"https://github.com/arielcostas/vigo360\">Source code</a>. <a href=\"https://vigo360.es\">Website</a>."
- }
-} \ No newline at end of file
+ "header": {
+ "home": "Home",
+ "trajectory": "Trajectory",
+ "portfolio": "Portfolio",
+ "blog": "Blog",
+ "contact": "Contact"
+ },
+ "footer": {
+ "copyright": "All rights reserved.",
+ "contentLicencedUnder": "Unless otherwise stated, the content of this site is licensed under",
+ "sourceCodeAvailableOn": "Source code for this site is available on",
+ "andIsLicencedUnder": "and is licenced under",
+ "eupl": "European Union Public Licence"
+ },
+ "contactPage": {
+ "title": "Contact",
+ "description": "The ways to contact me, either by email, phone or social networks.",
+ "headline": "Get in touch with me!",
+ "enableJs": "JavaScript must be enabled to view the email address and phone number. This is done to prevent scrapers and spam.",
+ "intro": "The easiest way to contact me is through my email address: <a href=\"#\" id=\"email-addr\">Enable JS</a>. You can also use <a href=\"https://wa.me/message/W7T7L4EZAELQI1\">WhatsApp</a> with the phone number <a href=\"#\" id=\"phone-number\">Enable JS</a>.",
+ "socialMedia": "You can also find me on some social networks:"
+ },
+ "homePage": {
+ "title": "Home",
+ "description": "Homepage of my website",
+ "welcome": "Welcome to my website. My name is Ariel, and here you will find information about me and my projects.",
+ "whoAmI": "Who am I?",
+ "whoAmIDesc": "I am a web developer who likes to learn new things and share knowledge. I enjoy programming, web design, and creativity. I love creating new things and learning from others.",
+ "moreAboutMe": "More about me",
+ "whatIDo": "What do I do?",
+ "whatIDoDesc": "I currently work as a software developer and Cloud administrator at a technology company. I develop web applications in PHP and deploy them in the cloud securely and efficiently.",
+ "myPortfolio": "My portfolio",
+ "latestBlogPosts": "Latest blog posts",
+ "viewAllPosts": "View all posts"
+ },
+ "trajectoryPage": {
+ "title": "Trajectory",
+ "description": "My trajectory as a software developer, with information about my education, work experience and projects I have worked on.",
+ "headline": "My trajectory as a developer",
+ "intro": "I am a software developer living in Vigo, Spain. I love technology and I enjoy learning new things. I am professionally dedicated to software development in all its aspects: from architecture design, implementation and production deployment, to other aspects such as user experience, accessibility and security.",
+ "techTitle": "Technologies I master",
+ "techDescription1": "I mainly master the Microsoft ecosystem: .NET (C#), ASP.NET Core, SQL Server, Azure and Azure DevOps. I also have experience with other languages and technologies, such as PHP, Python and Java. Additionally, I have frontend knowledge with HTML5, CSS3, JavaScript and TypeScript.",
+ "techDescription2": "I also have experience with DevOps tools such as Docker, Kubernetes, Terraform and GitHub Actions; as well as the Azure Cloud ecosystem.",
+ "educationTitle": "Education and credentials",
+ "efsetCert1": "Official EF SET C2 Proficient Certificate",
+ "efsetCert2": ": certifies my C2 English level, the highest according to the Common European Framework of Reference for Languages.",
+ "viewCertificate": "View certificate",
+ "azureDeveloperCert1": "Microsoft Certified: Azure Developer Associate",
+ "azureDeveloperCert2": ": certifies my knowledge in Azure application development.",
+ "viewCredential": "View credential",
+ "azureDevOpsCert1": "Microsoft Certified: Azure DevOps Engineer Expert",
+ "azureDevOpsCert2": ": certifies my knowledge in implementing DevOps methodologies in Azure with Azure DevOps and GitHub.",
+ "higherTechCert1": "Higher Technical Certificate in Multiplatform Application Development",
+ "higherTechCert2": ": higher vocational training degree, obtained at",
+ "higherTechCert3": "IES de Teis",
+ "higherTechCert4": "in Vigo.",
+ "experienceTitle": "Work experience",
+ "estelaria1": "Estelaria Solutions (Q3 2023 - present)",
+ "estelaria2": "Full-stack application development, mainly in PHP with Symfony, MongoDB and Vanilla JavaScript. In addition, I implemented a considerable number of improvements in usability, accessibility and performance.",
+ "estelaria3": "I am also responsible for managing the infrastructure on AWS, and implementing collaboration tools such as Jira and GitHub.",
+ "polygon1": "Internship at Polygon-E (Q2 2023)",
+ "polygon2": "I did my professional training internship at Polygon-E, where I developed several internal management applications with ASP.NET Core and Blazor, deploying on on-premise environments with Windows Server, IIS and SQL Server.",
+ "projectsTitle": "Projects",
+ "projectsDescription": "You can find the (public) projects I have worked on in <a href=\"/portfolio\">my portfolio</a> and on my <a href=\"https://github.com/arielcostas\">GitHub profile</a>."
+ },
+ "portfolioPage": {
+ "title": "Portfolio",
+ "description": "A list of projects I have worked on in recent years, with the technologies used.",
+ "headline": "My portfolio",
+ "intro": "In this section, you will find a list of the projects I have worked on, both for third parties and my own. If you would like more information about any of them, please do not hesitate to <a href=\"/contact\">contact me</a>.",
+ "freelanceTitle": "Projects for third parties (freelance)",
+ "freelanceDesc": "I have developed projects for third parties by commission, the most notable being the following:",
+ "orderExtractorTitle": "Online Order Purchase Extractor",
+ "orderExtractorDesc": "Desktop application that extracts data about online orders from various platforms (such as WooCommerce, Amazon, and eBay). <a href=\"/portfolio/order-extractor\">More information</a>.",
+ "touristInfoTitle": "Tourist Information Point on Mobile Devices",
+ "touristInfoDesc": "Web application for tourist information, with QR codes, 360° content, and YouTube embedding. <a href=\"/portfolio/dynamic-tourist-info\">More information</a>.",
+ "wpConsultingTitle": "WordPress Consulting",
+ "wpConsultingDesc": "Maintenance, optimisation, and migration work for WordPress websites and WooCommerce online shops. <a href=\"/portfolio/wp-consulting\">More information</a>. <a href=\"/contact\">Contact</a>.",
+ "ownProjectsTitle": "My own projects",
+ "ownProjectsDesc": "Additionally, I have several personal projects that I have developed in my own time, some of which are active and open source.",
+ "personalWebTitle": "Personal Website",
+ "personalWebDesc": "Developed with Astro, a static site generator that lets you write content in Markdown and publish to the web with excellent performance. Deployed on Azure Static Web Apps.",
+ "mientrenoTitle": "MiEntreno (end-of-course project)",
+ "mientrenoDesc": "Web application for managing sports training, with a simple and easy-to-use interface. Developed with ASP.NET Core, Razor Pages, and SQL Server. <a href=\"/portfolio/mientreno\">More information</a>. <a href=\"https://github.com/arielcostas/mientreno\">Source code</a>.",
+ "vigo360Title": "Vigo 360",
+ "vigo360Desc": "Blog about Vigo and its surroundings, mainly focused on mobility and toponymy. Developed in Go, with a MySQL database and deployed on a VPS managed by myself. <a href=\"/portfolio/vigo-360\">More information</a>. <a href=\"https://github.com/arielcostas/vigo360\">Source code</a>. <a href=\"https://vigo360.es\">Website</a>."
+ }
+}
diff --git a/src/i18n/es.json b/src/i18n/es.json
index 0e6e8bb..6ad3bc4 100644
--- a/src/i18n/es.json
+++ b/src/i18n/es.json
@@ -1,89 +1,89 @@
{
- "header": {
- "home": "Inicio",
- "trajectory": "Trayectoria",
- "portfolio": "Portafolio",
- "blog": "Blog",
- "contact": "Contacto"
- },
- "footer": {
- "copyright": "Todos los derechos reservados.",
- "contentLicencedUnder": "Salvo que se indique lo contrario, el contenido de este sitio está bajo licencia",
- "sourceCodeAvailableOn": "El código fuente de este sitio está disponible en",
- "andIsLicencedUnder": "y se ofrece bajo licencia",
- "eupl": "Licencia Pública de la Unión Europea"
- },
- "contactPage": {
- "title": "Contacto",
- "description": "Las formas de ponerte en contacto conmigo, ya sea por correo electrónico, teléfono o redes sociales.",
- "headline": "¡Ponte en contacto conmigo!",
- "enableJs": "Es necesario activar JavaScript para ver la dirección de correo electrónico y el número de teléfono. Esto se hace para evitar scrapers y spam.",
- "intro": "La forma más sencilla de contactar conmigo es a través de mi dirección de correo electrónico: <a href=\"#\" id=\"email-addr\">Activa JS</a>. También puedes usar <a href=\"https://wa.me/message/W7T7L4EZAELQI1\">WhatsApp</a> con el número de teléfono <a href=\"#\" id=\"phone-number\">Activa JS</a>.",
- "socialMedia": "También puedes encontrarme en algunas redes sociales:"
- },
- "homePage": {
- "title": "Inicio",
- "description": "Página de inicio de mi web",
- "welcome": "Te doy la bienvenida a mi web. Me llamo Ariel, y aquí encontrarás información sobre mí y mis proyectos.",
- "whoAmI": "¿Quién soy?",
- "whoAmIDesc": "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.",
- "moreAboutMe": "Más información sobre mí",
- "whatIDo": "¿Qué hago?",
- "whatIDoDesc": "Actualmente trabajo como desarrollador de software y administrador Cloud en una empresa de tecnología. Me encargo de desarrollar aplicaciones web en PHP y desplegarlas en la nube de forma segura y eficiente.",
- "myPortfolio": "Mi portfolio",
- "latestBlogPosts": "Últimas entradas del blog",
- "viewAllPosts": "Ver todas las entradas"
- },
- "trajectoryPage": {
- "title": "Trayectoria",
- "description": "Mi trayectoria como desarrollador de software, con información sobre mi educación, experiencia laboral y proyectos en los que he trabajado.",
- "headline": "Mi trayectoria como desarrollador",
- "intro": "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.",
- "techTitle": "Tecnologías que domino",
- "techDescription1": "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 HTML5, CSS3, JavaScript y TypeScript.",
- "techDescription2": "También tengo experiencia con herramientas de DevOps como Docker, Kubernetes, Terraform y GitHub Actions; así como el ecosistema Cloud de Azure.",
- "educationTitle": "Educación y credenciales",
- "efsetCert1": "Certificado oficial EF SET C2 Proficient",
- "efsetCert2": ": acredita mi nivel de inglés C2, el más alto según el Marco Común Europeo de Referencia para las Lenguas.",
- "viewCertificate": "Ver certificado",
- "azureDeveloperCert1": "Microsoft Certified: Azure Developer Associate",
- "azureDeveloperCert2": ": acredita mis conocimientos en el desarrollo de aplicaciones en Azure.",
- "viewCredential": "Ver credencial",
- "azureDevOpsCert1": "Microsoft Certified: Azure DevOps Engineer Expert",
- "azureDevOpsCert2": ": acredita mis conocimientos en la implementación de metodologías de DevOps en Azure con Azure DevOps y GitHub.",
- "higherTechCert1": "Técnico Superior en Desarrollo de Aplicaciones Multiplataforma",
- "higherTechCert2": ": título de formación profesional de grado superior, obtenido en el",
- "higherTechCert3": "IES de Teis",
- "higherTechCert4": "en Vigo.",
- "experienceTitle": "Experiencia laboral",
- "estelaria1": "Estelaria Solutions (Q3 2023 - actualidad)",
- "estelaria2": "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.",
- "estelaria3": "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.",
- "polygon1": "FCT en Polygon-E (Q2 2023)",
- "polygon2": "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 on-premise con Windows Server, IIS y SQL Server.",
- "projectsTitle": "Proyectos",
- "projectsDescription": "Puedes encontrar los proyectos (públicos) en los que he trabajado en <a href=\"/portfolio\">mi portfolio</a> y en mi <a href=\"https://github.com/arielcostas\">perfil de GitHub</a>."
- },
- "portfolioPage": {
- "title": "Portfolio",
- "description": "Un listado de los proyectos en los que he trabajado en los últimos años, con las tecnologías utilizadas.",
- "headline": "Mi portfolio",
- "intro": "En esta sección encontrarás una lista de los proyectos en los que he trabajado, tanto para terceros como propios. Si quieres más información sobre alguno de ellos, no dudes en <a href=\"/contact\">contactar conmigo</a>.",
- "freelanceTitle": "Proyectos para terceros (freelance)",
- "freelanceDesc": "He realizado desarrollos de proyectos para terceros por encargo, siendo los más destacados los siguientes:",
- "orderExtractorTitle": "Extractor de pedidos compra online",
- "orderExtractorDesc": "Aplicación de escritorio que extrae los datos sobre los pedidos on-line de diversas plataformas (como WooCommerce, Amazon y Ebay). <a href=\"/portfolio/order-extractor\">Más información</a>.",
- "touristInfoTitle": "Punto de información turística en móviles",
- "touristInfoDesc": "Aplicación web de información turística, con QR, contenido en 360º e incrustado de YouTube. <a href=\"/portfolio/dynamic-tourist-info\">Más información</a>.",
- "wpConsultingTitle": "Consultoría WordPress",
- "wpConsultingDesc": "Trabajos de mantenimiento, optimización y migración de sitios web WordPress y tiendas online WooCommerce. <a href=\"/portfolio/wp-consulting\">Más información</a>. <a href=\"/contact\">Contactar</a>.",
- "ownProjectsTitle": "Proyectos propios",
- "ownProjectsDesc": "Además, tengo varios proyectos propios que he desarrollado en mi tiempo, estando algunos de ellos en activo, y como código abierto.",
- "personalWebTitle": "Web personal",
- "personalWebDesc": "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.",
- "mientrenoTitle": "MiEntreno (proyecto fin de ciclo)",
- "mientrenoDesc": "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. <a href=\"/portfolio/mientreno\">Más información</a>. <a href=\"https://github.com/arielcostas/mientreno\">Código fuente</a>.",
- "vigo360Title": "Vigo 360",
- "vigo360Desc": "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. <a href=\"/portfolio/vigo-360\">Más información</a>. <a href=\"https://github.com/arielcostas/vigo360\">Código fuente</a>. <a href=\"https://vigo360.es\">Web</a>."
- }
-} \ No newline at end of file
+ "header": {
+ "home": "Inicio",
+ "trajectory": "Trayectoria",
+ "portfolio": "Portafolio",
+ "blog": "Blog",
+ "contact": "Contacto"
+ },
+ "footer": {
+ "copyright": "Todos los derechos reservados.",
+ "contentLicencedUnder": "Salvo que se indique lo contrario, el contenido de este sitio está bajo licencia",
+ "sourceCodeAvailableOn": "El código fuente de este sitio está disponible en",
+ "andIsLicencedUnder": "y se ofrece bajo licencia",
+ "eupl": "Licencia Pública de la Unión Europea"
+ },
+ "contactPage": {
+ "title": "Contacto",
+ "description": "Las formas de ponerte en contacto conmigo, ya sea por correo electrónico, teléfono o redes sociales.",
+ "headline": "¡Ponte en contacto conmigo!",
+ "enableJs": "Es necesario activar JavaScript para ver la dirección de correo electrónico y el número de teléfono. Esto se hace para evitar scrapers y spam.",
+ "intro": "La forma más sencilla de contactar conmigo es a través de mi dirección de correo electrónico: <a href=\"#\" id=\"email-addr\">Activa JS</a>. También puedes usar <a href=\"https://wa.me/message/W7T7L4EZAELQI1\">WhatsApp</a> con el número de teléfono <a href=\"#\" id=\"phone-number\">Activa JS</a>.",
+ "socialMedia": "También puedes encontrarme en algunas redes sociales:"
+ },
+ "homePage": {
+ "title": "Inicio",
+ "description": "Página de inicio de mi web",
+ "welcome": "Te doy la bienvenida a mi web. Me llamo Ariel, y aquí encontrarás información sobre mí y mis proyectos.",
+ "whoAmI": "¿Quién soy?",
+ "whoAmIDesc": "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.",
+ "moreAboutMe": "Más información sobre mí",
+ "whatIDo": "¿Qué hago?",
+ "whatIDoDesc": "Actualmente trabajo como desarrollador de software y administrador Cloud en una empresa de tecnología. Me encargo de desarrollar aplicaciones web en PHP y desplegarlas en la nube de forma segura y eficiente.",
+ "myPortfolio": "Mi portfolio",
+ "latestBlogPosts": "Últimas entradas del blog",
+ "viewAllPosts": "Ver todas las entradas"
+ },
+ "trajectoryPage": {
+ "title": "Trayectoria",
+ "description": "Mi trayectoria como desarrollador de software, con información sobre mi educación, experiencia laboral y proyectos en los que he trabajado.",
+ "headline": "Mi trayectoria como desarrollador",
+ "intro": "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.",
+ "techTitle": "Tecnologías que domino",
+ "techDescription1": "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 HTML5, CSS3, JavaScript y TypeScript.",
+ "techDescription2": "También tengo experiencia con herramientas de DevOps como Docker, Kubernetes, Terraform y GitHub Actions; así como el ecosistema Cloud de Azure.",
+ "educationTitle": "Educación y credenciales",
+ "efsetCert1": "Certificado oficial EF SET C2 Proficient",
+ "efsetCert2": ": acredita mi nivel de inglés C2, el más alto según el Marco Común Europeo de Referencia para las Lenguas.",
+ "viewCertificate": "Ver certificado",
+ "azureDeveloperCert1": "Microsoft Certified: Azure Developer Associate",
+ "azureDeveloperCert2": ": acredita mis conocimientos en el desarrollo de aplicaciones en Azure.",
+ "viewCredential": "Ver credencial",
+ "azureDevOpsCert1": "Microsoft Certified: Azure DevOps Engineer Expert",
+ "azureDevOpsCert2": ": acredita mis conocimientos en la implementación de metodologías de DevOps en Azure con Azure DevOps y GitHub.",
+ "higherTechCert1": "Técnico Superior en Desarrollo de Aplicaciones Multiplataforma",
+ "higherTechCert2": ": título de formación profesional de grado superior, obtenido en el",
+ "higherTechCert3": "IES de Teis",
+ "higherTechCert4": "en Vigo.",
+ "experienceTitle": "Experiencia laboral",
+ "estelaria1": "Estelaria Solutions (Q3 2023 - actualidad)",
+ "estelaria2": "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.",
+ "estelaria3": "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.",
+ "polygon1": "FCT en Polygon-E (Q2 2023)",
+ "polygon2": "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 on-premise con Windows Server, IIS y SQL Server.",
+ "projectsTitle": "Proyectos",
+ "projectsDescription": "Puedes encontrar los proyectos (públicos) en los que he trabajado en <a href=\"/portfolio\">mi portfolio</a> y en mi <a href=\"https://github.com/arielcostas\">perfil de GitHub</a>."
+ },
+ "portfolioPage": {
+ "title": "Portfolio",
+ "description": "Un listado de los proyectos en los que he trabajado en los últimos años, con las tecnologías utilizadas.",
+ "headline": "Mi portfolio",
+ "intro": "En esta sección encontrarás una lista de los proyectos en los que he trabajado, tanto para terceros como propios. Si quieres más información sobre alguno de ellos, no dudes en <a href=\"/contact\">contactar conmigo</a>.",
+ "freelanceTitle": "Proyectos para terceros (freelance)",
+ "freelanceDesc": "He realizado desarrollos de proyectos para terceros por encargo, siendo los más destacados los siguientes:",
+ "orderExtractorTitle": "Extractor de pedidos compra online",
+ "orderExtractorDesc": "Aplicación de escritorio que extrae los datos sobre los pedidos on-line de diversas plataformas (como WooCommerce, Amazon y Ebay). <a href=\"/portfolio/order-extractor\">Más información</a>.",
+ "touristInfoTitle": "Punto de información turística en móviles",
+ "touristInfoDesc": "Aplicación web de información turística, con QR, contenido en 360º e incrustado de YouTube. <a href=\"/portfolio/dynamic-tourist-info\">Más información</a>.",
+ "wpConsultingTitle": "Consultoría WordPress",
+ "wpConsultingDesc": "Trabajos de mantenimiento, optimización y migración de sitios web WordPress y tiendas online WooCommerce. <a href=\"/portfolio/wp-consulting\">Más información</a>. <a href=\"/contact\">Contactar</a>.",
+ "ownProjectsTitle": "Proyectos propios",
+ "ownProjectsDesc": "Además, tengo varios proyectos propios que he desarrollado en mi tiempo, estando algunos de ellos en activo, y como código abierto.",
+ "personalWebTitle": "Web personal",
+ "personalWebDesc": "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.",
+ "mientrenoTitle": "MiEntreno (proyecto fin de ciclo)",
+ "mientrenoDesc": "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. <a href=\"/portfolio/mientreno\">Más información</a>. <a href=\"https://github.com/arielcostas/mientreno\">Código fuente</a>.",
+ "vigo360Title": "Vigo 360",
+ "vigo360Desc": "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. <a href=\"/portfolio/vigo-360\">Más información</a>. <a href=\"https://github.com/arielcostas/vigo360\">Código fuente</a>. <a href=\"https://vigo360.es\">Web</a>."
+ }
+}
diff --git a/src/i18n/index.ts b/src/i18n/index.ts
index 4ed1a52..3e6083b 100644
--- a/src/i18n/index.ts
+++ b/src/i18n/index.ts
@@ -1,34 +1,34 @@
-import Spanish from './es.json';
-import English from './en.json';
+import Spanish from "./es.json";
+import English from "./en.json";
export const SHOW_DEFAULT_LANGUAGE = false;
export const DEFAULT_LANGUAGE = "es";
export type LanguageKeys = "es" | "en";
-export const languages: Record<LanguageKeys, { code: string, name: string }> = {
- es: {
- code: "es",
- name: "Español"
- },
- en: {
- code: "en",
- name: "English"
- }
-}
+export const languages: Record<LanguageKeys, { code: string; name: string }> = {
+ es: {
+ code: "es",
+ name: "Español",
+ },
+ en: {
+ code: "en",
+ name: "English",
+ },
+};
export const LANGUAGE_CODES = Object.keys(languages);
export const useTranslations = (lang: string | undefined) => {
- switch (lang) {
- case languages.en.code:
- return English;
- case languages.es.code:
- default:
- return Spanish;
- }
-}
+ switch (lang) {
+ case languages.en.code:
+ return English;
+ case languages.es.code:
+ default:
+ return Spanish;
+ }
+};
export function getUrlWithoutLocale(url: string) {
- return url.replace(/\/[a-z]{2}\//, "/");
-} \ No newline at end of file
+ return url.replace(/\/[a-z]{2}\//, "/");
+}
diff --git a/src/layouts/ContactPageLayout.astro b/src/layouts/ContactPageLayout.astro
index 3b3c278..c09969f 100644
--- a/src/layouts/ContactPageLayout.astro
+++ b/src/layouts/ContactPageLayout.astro
@@ -5,95 +5,94 @@ import Layout from "./Layout.astro";
const t = useTranslations(Astro.currentLocale);
const schema = {
- "@context": "https://schema.org",
- "@type": "ContactPage",
- url: "https://www.costas.dev/contact",
- headline: t.contactPage.headline,
+ "@context": "https://schema.org",
+ "@type": "ContactPage",
+ url: "https://www.costas.dev/contact",
+ headline: t.contactPage.headline,
};
---
<Layout title={t.contactPage.title} description={t.contactPage.description}>
- <script
- is:inline
- type="application/ld+json"
- slot="head-jsonld"
- set:html={JSON.stringify(schema)}
- />
+ <script
+ is:inline
+ type="application/ld+json"
+ slot="head-jsonld"
+ set:html={JSON.stringify(schema)}
+ />
- <h1>{t.contactPage.headline}</h1>
+ <h1>{t.contactPage.headline}</h1>
- <noscript>
- <div role="alert" class="warning">
- {t.contactPage.enableJs}
- </div>
- </noscript>
+ <noscript>
+ <div role="alert" class="warning">
+ {t.contactPage.enableJs}
+ </div>
+ </noscript>
- <p set:html={t.contactPage.intro} />
+ <p set:html={t.contactPage.intro} />
- <p>{t.contactPage.socialMedia}</p>
+ <p>{t.contactPage.socialMedia}</p>
- <dl>
- <dt>GitHub</dt>
- <dd><a href="https://github.com/arielcostas">@arielcostas</a></dd>
- <dt>LinkedIn</dt>
- <dd>
- <a href="https://www.linkedin.com/in/ariel-costas/"
- >/in/ariel-costas</a>
- </dd>
- <dt>BlueSky</dt>
- <dd><a href="https://bsky.app/profile/costas.dev">@costas.dev</a></dd>
- </dl>
+ <dl>
+ <dt>GitHub</dt>
+ <dd><a href="https://github.com/arielcostas">@arielcostas</a></dd>
+ <dt>LinkedIn</dt>
+ <dd>
+ <a href="https://www.linkedin.com/in/ariel-costas/">/in/ariel-costas</a>
+ </dd>
+ <dt>BlueSky</dt>
+ <dd><a href="https://bsky.app/profile/costas.dev">@costas.dev</a></dd>
+ </dl>
</Layout>
<script>
- const encryptedEmail = "LygNLiMmFRo/GlQZaFIWBA==";
- const encryptedPhoneNumber = "ZWlQfX1QT0Z+XgVd";
- const key = "NZdKOfvuLn5jF6sryF0Q";
+ const encryptedEmail = "LygNLiMmFRo/GlQZaFIWBA==";
+ const encryptedPhoneNumber = "ZWlQfX1QT0Z+XgVd";
+ const key = "NZdKOfvuLn5jF6sryF0Q";
- const emailAddrLink = document.getElementById(
- "email-addr",
- ) as HTMLAnchorElement;
- const phoneNumberLink = document.getElementById(
- "phone-number",
- ) as HTMLAnchorElement;
+ const emailAddrLink = document.getElementById(
+ "email-addr",
+ ) as HTMLAnchorElement;
+ const phoneNumberLink = document.getElementById(
+ "phone-number",
+ ) as HTMLAnchorElement;
- (() => {
- if (emailAddrLink == null || phoneNumberLink == null) {
- return;
- }
-
- const emailAddress = xorData(encryptedEmail, key);
- const phoneNumber = xorData(encryptedPhoneNumber, key);
+ (() => {
+ if (emailAddrLink == null || phoneNumberLink == null) {
+ return;
+ }
- emailAddrLink.href = `mailto:${emailAddress}`;
- emailAddrLink.textContent = emailAddress;
+ const emailAddress = xorData(encryptedEmail, key);
+ const phoneNumber = xorData(encryptedPhoneNumber, key);
- phoneNumberLink.href = `tel:${phoneNumber}`;
- phoneNumberLink.textContent = phoneNumber;
- })();
+ emailAddrLink.href = `mailto:${emailAddress}`;
+ emailAddrLink.textContent = emailAddress;
- function xorData(data: string, key: string): string {
- let actualData = atob(data);
- let actualKey = key;
- const keyLength = key.length;
- const dataLength = actualData.length;
- const result = new Array(dataLength);
+ phoneNumberLink.href = `tel:${phoneNumber}`;
+ phoneNumberLink.textContent = phoneNumber;
+ })();
- // If the key is 12 characters but the data is 30 characters, the key should be repeated 3 times and truncated to 30 characters
- if (keyLength < dataLength) {
- actualKey = key
- .repeat(Math.ceil(dataLength / keyLength))
- .substring(0, dataLength);
- } else if (keyLength > dataLength) {
- actualKey = key.substring(0, dataLength);
- }
+ function xorData(data: string, key: string): string {
+ let actualData = atob(data);
+ let actualKey = key;
+ const keyLength = key.length;
+ const dataLength = actualData.length;
+ const result = new Array(dataLength);
- for (let i = 0; i < dataLength; i++) {
- result[i] = String.fromCharCode(
- actualData.charCodeAt(i) ^ actualKey.charCodeAt(i),
- );
- }
+ // If the key is 12 characters but the data is 30 characters, the key should be repeated 3 times and truncated to 30 characters
+ if (keyLength < dataLength) {
+ actualKey = key
+ .repeat(Math.ceil(dataLength / keyLength))
+ .substring(0, dataLength);
+ } else if (keyLength > dataLength) {
+ actualKey = key.substring(0, dataLength);
+ }
- return result.join("");
+ for (let i = 0; i < dataLength; i++) {
+ result[i] = String.fromCharCode(
+ actualData.charCodeAt(i) ^ actualKey.charCodeAt(i),
+ );
}
+
+ return result.join("");
+ }
</script>
diff --git a/src/layouts/HomePageLayout.astro b/src/layouts/HomePageLayout.astro
index 146eaec..0906a11 100644
--- a/src/layouts/HomePageLayout.astro
+++ b/src/layouts/HomePageLayout.astro
@@ -4,59 +4,56 @@ import Layout from "./Layout.astro";
import { useTranslations } from "../i18n";
const blogCollection = (await getCollection("blog")).sort((a, b) => {
- return b.data.publishedAt.getTime() - a.data.publishedAt.getTime();
+ return b.data.publishedAt.getTime() - a.data.publishedAt.getTime();
});
const t = useTranslations(Astro.currentLocale);
const schema = {
- "@context": "http://schema.org",
- "@type": "WebSite",
- id: "https://www.costas.dev/",
- url: "https://www.costas.dev/",
- headline: t.homePage.title,
+ "@context": "http://schema.org",
+ "@type": "WebSite",
+ id: "https://www.costas.dev/",
+ url: "https://www.costas.dev/",
+ headline: t.homePage.title,
};
---
<Layout title={t.homePage.title} description={t.homePage.description}>
- <script
- is:inline
- type="application/ld+json"
- slot="head-jsonld"
- set:html={JSON.stringify(schema)}
- />
+ <script
+ is:inline
+ type="application/ld+json"
+ slot="head-jsonld"
+ set:html={JSON.stringify(schema)}
+ />
- <h1>{t.homePage.title}</h1>
- <p>{t.homePage.welcome}</p>
+ <h1>{t.homePage.title}</h1>
+ <p>{t.homePage.welcome}</p>
- <h2>{t.homePage.whoAmI}</h2>
- <p>{t.homePage.whoAmIDesc}</p>
- <a href="/trajectory">{t.homePage.moreAboutMe}</a>
+ <h2>{t.homePage.whoAmI}</h2>
+ <p>{t.homePage.whoAmIDesc}</p>
+ <a href="/trajectory">{t.homePage.moreAboutMe}</a>
- <h2>{t.homePage.whatIDo}</h2>
- <p>{t.homePage.whatIDoDesc}</p>
- <a href="/portfolio">{t.homePage.myPortfolio}</a>
-
- <h2>{t.homePage.latestBlogPosts}</h2>
- <ul>
- {
- blogCollection.slice(0, 5).map((p) => {
- const date = Intl.DateTimeFormat(Astro.currentLocale, {
- 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.id}`}>{p.data.title}</a>
- </li>
- );
- })
- }
- </ul>
- <a href="/blog">{t.homePage.viewAllPosts}</a>
+ <h2>{t.homePage.whatIDo}</h2>
+ <p>{t.homePage.whatIDoDesc}</p>
+ <a href="/portfolio">{t.homePage.myPortfolio}</a>
+ <h2>{t.homePage.latestBlogPosts}</h2>
+ <ul>
+ {
+ blogCollection.slice(0, 5).map((p) => {
+ const date = Intl.DateTimeFormat(Astro.currentLocale, {
+ 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.id}`}>{p.data.title}</a>
+ </li>
+ );
+ })
+ }
+ </ul>
+ <a href="/blog">{t.homePage.viewAllPosts}</a>
</Layout>
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index c8d3302..ff3a6cc 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -4,11 +4,11 @@ import "@fontsource-variable/sen";
import Header from "../partials/Header.astro";
import Footer from "../partials/Footer.astro";
import { getAbsoluteLocaleUrl } from "astro:i18n";
-import { getUrlWithoutLocale } from '../i18n';
+import { getUrlWithoutLocale } from "../i18n";
interface Props {
- title: string;
- description: string;
+ title: string;
+ description: string;
}
const { title, description } = Astro.props;
@@ -17,156 +17,170 @@ const urlWithoutLocale = getUrlWithoutLocale(Astro.url.pathname);
<!doctype html>
<html lang={Astro.currentLocale}>
- <head>
- <meta charset="UTF-8" />
- <meta name="description" content={description} />
- <meta name="viewport" content="width=device-width" />
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="description" content={description} />
+ <meta name="viewport" content="width=device-width" />
- <link rel="canonical" href={Astro.url.toString().replace(/\.html$/, '')} />
- <link rel="alternate" hreflang="es" href={getAbsoluteLocaleUrl("es", urlWithoutLocale)} />
- <link rel="alternate" hreflang="en" href={getAbsoluteLocaleUrl("en", urlWithoutLocale)} />
- <link rel="alternate" hreflang="x-default" href={getAbsoluteLocaleUrl("es", urlWithoutLocale)} />
+ <link rel="canonical" href={Astro.url.toString().replace(/\.html$/, "")} />
+ <link
+ rel="alternate"
+ hreflang="es"
+ href={getAbsoluteLocaleUrl("es", urlWithoutLocale)}
+ />
+ <link
+ rel="alternate"
+ hreflang="en"
+ href={getAbsoluteLocaleUrl("en", urlWithoutLocale)}
+ />
+ <link
+ rel="alternate"
+ hreflang="x-default"
+ href={getAbsoluteLocaleUrl("es", urlWithoutLocale)}
+ />
- <link rel="alternate" type="application/rss+xml" href="/blog.xml" />
- <link rel="sitemap" type="application/xml" href="/sitemap-index.xml" />
+ <link rel="alternate" type="application/rss+xml" href="/blog.xml" />
+ <link rel="sitemap" type="application/xml" href="/sitemap-index.xml" />
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
- <link rel="icon" type="image/png" href="/favicon.png" />
- <link rel="apple-touch-icon" href="/favicon.png" />
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+ <link rel="icon" type="image/png" href="/favicon.png" />
+ <link rel="apple-touch-icon" href="/favicon.png" />
- <meta property="og:title" content={title} />
- <meta property="og:description" content={description} />
- <meta property="og:type" content="website" />
- <meta property="og:url" content={Astro.url} />
- <meta property="og:image" content="/favicon.png" />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="og:type" content="website" />
+ <meta property="og:url" content={Astro.url} />
+ <meta property="og:image" content="/favicon.png" />
- <meta name="twitter:card" content="summary" />
- <meta name="twitter:title" content={title} />
- <meta name="twitter:description" content={description} />
- <meta name="twitter:image" content="/favicon.png" />
+ <meta name="twitter:card" content="summary" />
+ <meta name="twitter:title" content={title} />
+ <meta name="twitter:description" content={description} />
+ <meta name="twitter:image" content="/favicon.png" />
- <title>{title} - Ariel Costas</title>
+ <title>{title} - Ariel Costas</title>
- <slot name="head-jsonld" />
- </head>
- <body>
- <Header />
- <main>
- <slot />
- </main>
- <Footer />
- </body>
+ <slot name="head-jsonld" />
+ </head>
+ <body>
+ <Header />
+ <main>
+ <slot />
+ </main>
+ <Footer />
+ </body>
</html>
<style is:global lang="scss">
- @use "../../styles/shared.scss" as *;
- @use "sass:color";
+ @use "../../styles/shared.scss" as *;
+ @use "sass:color";
- html,
- body {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
+ html,
+ body {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
- body {
- min-height: 100vh;
- max-width: 100vw;
+ body {
+ min-height: 100vh;
+ max-width: 100vw;
- display: flex;
- flex-direction: column;
- gap: 1.5rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
- background: linear-gradient(to bottom,
- #FFFFFF 0%,
- $background 3rem,
- $background 100%
- );
- color: $dark;
- }
+ background: linear-gradient(
+ to bottom,
+ #ffffff 0%,
+ $background 3rem,
+ $background 100%
+ );
+ color: $dark;
+ }
- a {
- color: $accent;
- }
+ a {
+ color: $accent;
+ }
- *::selection {
- background-color: color.adjust($accent, $alpha: -0.85);
- }
+ *::selection {
+ background-color: color.adjust($accent, $alpha: -0.85);
+ }
- li > time {
- font-family: $monoFontStack;
- }
+ li > time {
+ font-family: $monoFontStack;
+ }
- div[role="alert"] {
- padding: 1rem;
- margin-block: 1rem;
- border-radius: 0.5rem;
-
- &.note {
- background-color: $noteBackground;
- color: $noteText;
- box-shadow: 0 0 0 1px $noteText;
- }
+ div[role="alert"] {
+ padding: 1rem;
+ margin-block: 1rem;
+ border-radius: 0.5rem;
- &.warning {
- background-color: $warningBackground;
- color: $warningText;
- box-shadow: 0 0 0 1px $warningText;
- }
- }
+ &.note {
+ background-color: $noteBackground;
+ color: $noteText;
+ box-shadow: 0 0 0 1px $noteText;
+ }
- main {
- box-sizing: border-box;
- margin-bottom: auto;
+ &.warning {
+ background-color: $warningBackground;
+ color: $warningText;
+ box-shadow: 0 0 0 1px $warningText;
+ }
+ }
- align-self: center;
+ main {
+ box-sizing: border-box;
+ margin-bottom: auto;
- max-width: 82ch;
- font-size: 1.2rem;
-
- padding-block-end: 3rem;
+ align-self: center;
- > p > code {
- word-break: break-word;
- font-family: $monoFontStack;
+ max-width: 82ch;
+ font-size: 1.2rem;
- color: $accentDark;
- background-color: #f6f6f6;
- }
+ padding-block-end: 3rem;
- p.meta {
- display: block;
- font-size: 0.85rem;
- margin-bottom: 1rem;
- }
+ > p > code {
+ word-break: break-word;
+ font-family: $monoFontStack;
- pre {
- overflow: scroll;
- }
- }
+ color: $accentDark;
+ background-color: #f6f6f6;
+ }
- main a {
- color: $accentDark;
- }
+ p.meta {
+ display: block;
+ font-size: 0.85rem;
+ margin-bottom: 1rem;
+ }
- footer a {
- color: $accentLight;
- }
+ pre {
+ overflow: scroll;
+ }
+ }
- main a, footer a {
- text-decoration: none;
- padding: 0.1rem;
- box-shadow: 0 1px $accent;
+ main a {
+ color: $accentDark;
+ }
- &:hover {
- box-shadow: 0 2px $accentDark;
- }
+ footer a {
+ color: $accentLight;
+ }
- &:focus {
- color: $accentDark;
- outline: none;
- background-color: $secondary;
- box-shadow: 0 4px #0b0c0c;
- }
- }
+ main a,
+ footer a {
+ text-decoration: none;
+ padding: 0.1rem;
+ box-shadow: 0 1px $accent;
+
+ &:hover {
+ box-shadow: 0 2px $accentDark;
+ }
+
+ &:focus {
+ color: $accentDark;
+ outline: none;
+ background-color: $secondary;
+ box-shadow: 0 4px #0b0c0c;
+ }
+ }
</style>
diff --git a/src/layouts/PortfolioPageLayout.astro b/src/layouts/PortfolioPageLayout.astro
index 0ade4ba..88f8614 100644
--- a/src/layouts/PortfolioPageLayout.astro
+++ b/src/layouts/PortfolioPageLayout.astro
@@ -6,108 +6,108 @@ import TechnologyBadge from "../partials/TechnologyBadge.astro";
const t = useTranslations(Astro.currentLocale);
const schema = {
- "@context": "https://schema.org",
- "@type": "WebPage",
- url: "https://www.costas.dev/portfolio",
- headline: t.portfolioPage.headline,
+ "@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)}
- ></script>
+ <script
+ is:inline
+ type="application/ld+json"
+ slot="head-jsonld"
+ set:html={JSON.stringify(schema)}
+ />
- <h1>{t.portfolioPage.headline}</h1>
+ <h1>{t.portfolioPage.headline}</h1>
- <p set:html={t.portfolioPage.intro} />
+ <p set:html={t.portfolioPage.intro} />
- <h2>{t.portfolioPage.freelanceTitle}</h2>
+ <h2>{t.portfolioPage.freelanceTitle}</h2>
- <p>{t.portfolioPage.freelanceDesc}</p>
+ <p>{t.portfolioPage.freelanceDesc}</p>
- <section>
- <article>
- <h3>{t.portfolioPage.orderExtractorTitle}</h3>
+ <section>
+ <article>
+ <h3>{t.portfolioPage.orderExtractorTitle}</h3>
- <p set:html={t.portfolioPage.orderExtractorDesc} />
+ <p set:html={t.portfolioPage.orderExtractorDesc} />
- <TechnologyBadge code="java" />
- <TechnologyBadge code="windows" />
- </article>
+ <TechnologyBadge code="java" />
+ <TechnologyBadge code="windows" />
+ </article>
- <article>
- <h3>{t.portfolioPage.touristInfoTitle}</h3>
+ <article>
+ <h3>{t.portfolioPage.touristInfoTitle}</h3>
- <p set:html={t.portfolioPage.touristInfoDesc} />
+ <p set:html={t.portfolioPage.touristInfoDesc} />
- <TechnologyBadge code="php" />
- <TechnologyBadge code="mysql" />
- </article>
+ <TechnologyBadge code="php" />
+ <TechnologyBadge code="mysql" />
+ </article>
- <article>
- <h3>{t.portfolioPage.wpConsultingTitle}</h3>
+ <article>
+ <h3>{t.portfolioPage.wpConsultingTitle}</h3>
- <p set:html={t.portfolioPage.wpConsultingDesc} />
+ <p set:html={t.portfolioPage.wpConsultingDesc} />
- <TechnologyBadge code="php" />
- </article>
- </section>
+ <TechnologyBadge code="php" />
+ </article>
+ </section>
- <h2>{t.portfolioPage.ownProjectsTitle}</h2>
+ <h2>{t.portfolioPage.ownProjectsTitle}</h2>
- <p>{t.portfolioPage.ownProjectsDesc}</p>
+ <p>{t.portfolioPage.ownProjectsDesc}</p>
- <section>
- <article>
- <h3>{t.portfolioPage.personalWebTitle}</h3>
+ <section>
+ <article>
+ <h3>{t.portfolioPage.personalWebTitle}</h3>
- <p>{t.portfolioPage.personalWebDesc}</p>
+ <p>{t.portfolioPage.personalWebDesc}</p>
- <TechnologyBadge code="astro" />
- <TechnologyBadge code="azure" />
- </article>
+ <TechnologyBadge code="astro" />
+ <TechnologyBadge code="azure" />
+ </article>
- <article>
- <h3>{t.portfolioPage.mientrenoTitle}</h3>
+ <article>
+ <h3>{t.portfolioPage.mientrenoTitle}</h3>
- <p set:html={t.portfolioPage.mientrenoDesc} />
+ <p set:html={t.portfolioPage.mientrenoDesc} />
- <TechnologyBadge code="dotnet" />
- <TechnologyBadge code="sqlserver" />
- <TechnologyBadge code="azure" />
- <TechnologyBadge code="rabbitmq" />
- </article>
+ <TechnologyBadge code="dotnet" />
+ <TechnologyBadge code="sqlserver" />
+ <TechnologyBadge code="azure" />
+ <TechnologyBadge code="rabbitmq" />
+ </article>
- <article>
- <h3>{t.portfolioPage.vigo360Title}</h3>
+ <article>
+ <h3>{t.portfolioPage.vigo360Title}</h3>
- <p set:html={t.portfolioPage.vigo360Desc} />
-
- <TechnologyBadge code="go" />
- <TechnologyBadge code="mysql" />
- <TechnologyBadge code="linux" />
- </article>
- </section>
+ <p set:html={t.portfolioPage.vigo360Desc} />
+
+ <TechnologyBadge code="go" />
+ <TechnologyBadge code="mysql" />
+ <TechnologyBadge code="linux" />
+ </article>
+ </section>
</Layout>
<style>
- section {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
- gap: 1rem;
- }
+ section {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
+ gap: 1rem;
+ }
- article {
- padding: 1rem;
- border: 1px solid var(--accent);
- border-radius: 0.5rem;
- }
+ article {
+ padding: 1rem;
+ border: 1px solid var(--accent);
+ border-radius: 0.5rem;
+ }
- article h3 {
- margin-top: 0;
- }
-</style> \ No newline at end of file
+ article h3 {
+ margin-top: 0;
+ }
+</style>
diff --git a/src/layouts/TrajectoryPageLayout.astro b/src/layouts/TrajectoryPageLayout.astro
index 1739a32..a5bfb46 100644
--- a/src/layouts/TrajectoryPageLayout.astro
+++ b/src/layouts/TrajectoryPageLayout.astro
@@ -5,77 +5,84 @@ import Layout from "./Layout.astro";
const t = useTranslations(Astro.currentLocale);
const schema = {
- "@context": "https://schema.org",
- "@type": "WebPage",
- url: "https://www.costas.dev/trajectory",
- headline: t.trajectoryPage.headline,
+ "@context": "https://schema.org",
+ "@type": "WebPage",
+ url: "https://www.costas.dev/trajectory",
+ headline: t.trajectoryPage.headline,
};
---
-<Layout title={t.trajectoryPage.title} description={t.trajectoryPage.description}>
- <script
- is:inline
- type="application/ld+json"
- slot="head-jsonld"
- set:html={JSON.stringify(schema)}
- />
+<Layout
+ title={t.trajectoryPage.title}
+ description={t.trajectoryPage.description}
+>
+ <script
+ is:inline
+ type="application/ld+json"
+ slot="head-jsonld"
+ set:html={JSON.stringify(schema)}
+ />
- <h1>{t.trajectoryPage.headline}</h1>
+ <h1>{t.trajectoryPage.headline}</h1>
- <p>{t.trajectoryPage.intro}</p>
+ <p>{t.trajectoryPage.intro}</p>
- <h2>{t.trajectoryPage.techTitle}</h2>
+ <h2>{t.trajectoryPage.techTitle}</h2>
- <p>{t.trajectoryPage.techDescription1}</p>
+ <p>{t.trajectoryPage.techDescription1}</p>
- <p>{t.trajectoryPage.techDescription2}</p>
+ <p>{t.trajectoryPage.techDescription2}</p>
- <h2>{t.trajectoryPage.educationTitle}</h2>
+ <h2>{t.trajectoryPage.educationTitle}</h2>
- <ul>
- <li>
- <strong>{t.trajectoryPage.efsetCert1}</strong>
- {t.trajectoryPage.efsetCert2} <a
- href="https://cert.efset.org/es/Yxzc9L"
- >{t.trajectoryPage.viewCertificate}</a
- >
- </li>
+ <ul>
+ <li>
+ <strong>{t.trajectoryPage.efsetCert1}</strong>
+ {t.trajectoryPage.efsetCert2}
+ <a href="https://cert.efset.org/es/Yxzc9L"
+ >{t.trajectoryPage.viewCertificate}</a
+ >
+ </li>
- <li>
- <strong>{t.trajectoryPage.azureDeveloperCert1}</strong>
- {t.trajectoryPage.azureDeveloperCert2} <a
- href="https://learn.microsoft.com/api/credentials/share/en-us/ariel-costas/E15072607CCF2DA9?sharingId=149A1CD9C13790F4"
- >{t.trajectoryPage.viewCredential}</a
- >.
- </li>
+ <li>
+ <strong>{t.trajectoryPage.azureDeveloperCert1}</strong>
+ {t.trajectoryPage.azureDeveloperCert2}
+ <a
+ href="https://learn.microsoft.com/api/credentials/share/en-us/ariel-costas/E15072607CCF2DA9?sharingId=149A1CD9C13790F4"
+ >{t.trajectoryPage.viewCredential}</a
+ >.
+ </li>
- <li>
- <strong>{t.trajectoryPage.azureDevOpsCert1}</strong>
- {t.trajectoryPage.azureDevOpsCert2} <a
- href="https://learn.microsoft.com/api/credentials/share/en-us/ariel-costas/5FB94876A1701595?sharingId=149A1CD9C13790F4"
- >{t.trajectoryPage.viewCredential}</a
- >
- </li>
+ <li>
+ <strong>{t.trajectoryPage.azureDevOpsCert1}</strong>
+ {t.trajectoryPage.azureDevOpsCert2}
+ <a
+ href="https://learn.microsoft.com/api/credentials/share/en-us/ariel-costas/5FB94876A1701595?sharingId=149A1CD9C13790F4"
+ >{t.trajectoryPage.viewCredential}</a
+ >
+ </li>
- <li>
- <strong>{t.trajectoryPage.higherTechCert1}</strong>
- {t.trajectoryPage.higherTechCert2} <a href="https://iesteis.es/">{t.trajectoryPage.higherTechCert3}</a> {t.trajectoryPage.higherTechCert4}
- </li>
- </ul>
+ <li>
+ <strong>{t.trajectoryPage.higherTechCert1}</strong>
+ {t.trajectoryPage.higherTechCert2}
+ <a href="https://iesteis.es/">{t.trajectoryPage.higherTechCert3}</a>
+ {t.trajectoryPage.higherTechCert4}
+ </li>
+ </ul>
- <h2>{t.trajectoryPage.experienceTitle}</h2>
+ <h2>{t.trajectoryPage.experienceTitle}</h2>
- <h3>{t.trajectoryPage.estelaria1}</h3>
+ <h3>{t.trajectoryPage.estelaria1}</h3>
- <p>{t.trajectoryPage.estelaria2}</p>
+ <p>{t.trajectoryPage.estelaria2}</p>
- <p>{t.trajectoryPage.estelaria3}</p>
+ <p>{t.trajectoryPage.estelaria3}</p>
- <h3>{t.trajectoryPage.polygon1}</h3>
+ <h3>{t.trajectoryPage.polygon1}</h3>
- <p>{t.trajectoryPage.polygon2}</p>
+ <p>{t.trajectoryPage.polygon2}</p>
- <h2>{t.trajectoryPage.projectsTitle}</h2>
+ <h2>{t.trajectoryPage.projectsTitle}</h2>
- <p set:html={t.trajectoryPage.projectsDescription} />
+ <p set:html={t.trajectoryPage.projectsDescription} />
</Layout>
diff --git a/src/pages/blog.xml.ts b/src/pages/blog.xml.ts
index f165475..44233b3 100644
--- a/src/pages/blog.xml.ts
+++ b/src/pages/blog.xml.ts
@@ -1,19 +1,18 @@
-import rss from '@astrojs/rss';
-import { getCollection } from 'astro:content';
-
+import rss from "@astrojs/rss";
+import { getCollection } from "astro:content";
export async function GET(context: any) {
- const collection = await getCollection('blog');
+ 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: any) => ({
- title: post.data.title,
- link: `${context.site}blog/${post.slug}`,
- description: post.data.metaDescription,
- pubDate: post.data.publishedAt
- }))
- })
+ return rss({
+ title: "Blog de Ariel Costas",
+ description: "Artículos del blog de Ariel Costas",
+ site: context.site,
+ items: collection.map((post: any) => ({
+ title: post.data.title,
+ link: `${context.site}blog/${post.slug}`,
+ description: post.data.metaDescription,
+ pubDate: post.data.publishedAt,
+ })),
+ });
}
diff --git a/src/pages/blog/[id].astro b/src/pages/blog/[id].astro
index e1b5250..65c8a25 100644
--- a/src/pages/blog/[id].astro
+++ b/src/pages/blog/[id].astro
@@ -4,59 +4,64 @@ import { getCollection, render } from "astro:content";
import { type GetStaticPaths } from "astro";
interface Props {
- entry: any;
+ entry: any;
}
-export const getStaticPaths: GetStaticPaths = (async () => {
- const entries = await getCollection("blog");
- return entries.map((entry: any) => ({
- params: { id: entry.id },
- props: { entry },
- }));
-});
+export const getStaticPaths: GetStaticPaths = async () => {
+ const entries = await getCollection("blog");
+ return entries.map((entry: any) => ({
+ params: { id: entry.id },
+ props: { entry },
+ }));
+};
const { entry } = Astro.props;
const { Content } = await render(entry);
const formattedDate = new Date(entry.data.publishedAt).toLocaleDateString(
- "es-ES",
- {
- year: "numeric",
- month: "long",
- day: "numeric",
- weekday: "long",
- },
+ "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",
- },
- },
+ "@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 is:inline type="application/ld+json" slot="head-jsonld" set:html={JSON.stringify(schema)}></script>
+ <script
+ is:inline
+ type="application/ld+json"
+ slot="head-jsonld"
+ set:html={JSON.stringify(schema)}
+ />
- <h1>{entry.data.title}</h1>
- <small>
- Publicado el
- <time datetime={entry.data.publishedAt.toISOString()}>
- {formattedDate}
- </time>
- </small>
+ <h1>{entry.data.title}</h1>
+ <small>
+ Publicado el
+ <time datetime={entry.data.publishedAt.toISOString()}>
+ {formattedDate}
+ </time>
+ </small>
- <Content />
+ <Content />
</Layout>
diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro
index e889706..68ad02e 100644
--- a/src/pages/blog/index.astro
+++ b/src/pages/blog/index.astro
@@ -1,69 +1,81 @@
---
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();
+ 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;
- },
- {},
+ (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 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",
- }
+ "@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. Disclaimer de siempre: las opiniones son mías, y no representan a ninguna empresa o institución.">
- <script is:inline type="application/ld+json" slot="head-jsonld" set:html={JSON.stringify(schema)}></script>
+<Layout
+ title="Blog"
+ description="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."
+>
+ <script
+ is:inline
+ type="application/ld+json"
+ slot="head-jsonld"
+ set:html={JSON.stringify(schema)}
+ />
- <h1>Blog de Ariel Costas</h1>
+ <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>
+ <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.id}`}>{post.data.title}</a>
- </li>
- ))}
- </ul>
- </section>
- ))
- }
+ {
+ Object.entries(groupedPosts).map(([key, posts]) => (
+ <section>
+ <h2>{humaniseDate(new Date(key))}</h2>
+ <ul>
+ {posts.map((post) => (
+ <li>
+ <a href={`/blog/${post.id}`}>{post.data.title}</a>
+ </li>
+ ))}
+ </ul>
+ </section>
+ ))
+ }
</Layout>
diff --git a/src/pages/contact.astro b/src/pages/contact.astro
index 3ca1b97..9cb58a6 100644
--- a/src/pages/contact.astro
+++ b/src/pages/contact.astro
@@ -2,84 +2,98 @@
import Layout from "../layouts/Layout.astro";
const schema = {
- "@context": "https://schema.org",
- "@type": "ContactPage",
- url: "https://www.costas.dev/contact",
- headline: "Ponte en contacto conmigo",
+ "@context": "https://schema.org",
+ "@type": "ContactPage",
+ url: "https://www.costas.dev/contact",
+ headline: "Ponte en contacto conmigo",
};
---
-<Layout title="Contacto" description="Las formas de ponerte en contacto conmigo, ya sea por correo electrónico, teléfono o redes sociales.">
- <script
- is:inline
- type="application/ld+json"
- slot="head-jsonld"
- set:html={JSON.stringify(schema)}
- />
+<Layout
+ title="Contacto"
+ description="Las formas de ponerte en contacto conmigo, ya sea por correo electrónico, teléfono o redes sociales."
+>
+ <script
+ is:inline
+ type="application/ld+json"
+ slot="head-jsonld"
+ set:html={JSON.stringify(schema)}
+ />
- <h1>Contacta conmigo</h1>
+ <h1>Contacta conmigo</h1>
- <p>
- La forma más sencilla de contactar conmigo es a través de mi dirección
- de correo electrónico:
- <a href="#" id="email-addr">ACTIVA JAVASCRIPT PARA VER ESTO</a>. También
- puedes usar <a href="https://wa.me/message/W7T7L4EZAELQI1">WhatsApp</a> con el número de teléfono
- <a href="#" id="phone-number">ACTIVA JAVASCRIPT PARA VER ESTO</a>.
- </p>
+ <p>
+ La forma más sencilla de contactar conmigo es a través de mi dirección de
+ correo electrónico:
+ <a href="#" id="email-addr">ACTIVA JAVASCRIPT PARA VER ESTO</a>. También
+ puedes usar <a href="https://wa.me/message/W7T7L4EZAELQI1">WhatsApp</a> con el
+ número de teléfono
+ <a href="#" id="phone-number">ACTIVA JAVASCRIPT PARA VER ESTO</a>.
+ </p>
- <p>También puedes encontrarme en algunas redes sociales:</p>
+ <p>También puedes encontrarme en algunas redes sociales:</p>
- <dl>
- <dt>GitHub</dt>
- <dd><a href="https://github.com/arielcostas">@arielcostas</a></dd>
- <dt>LinkedIn</dt>
- <dd><a href="https://www.linkedin.com/in/ariel-costas/">/in/ariel-costas</a></dd>
- <dt>BlueSky</dt>
- <dd><a href="https://bsky.app/profile/costas.dev">@costas.dev</a></dd>
- </dl>
+ <dl>
+ <dt>GitHub</dt>
+ <dd><a href="https://github.com/arielcostas">@arielcostas</a></dd>
+ <dt>LinkedIn</dt>
+ <dd>
+ <a href="https://www.linkedin.com/in/ariel-costas/">/in/ariel-costas</a>
+ </dd>
+ <dt>BlueSky</dt>
+ <dd><a href="https://bsky.app/profile/costas.dev">@costas.dev</a></dd>
+ </dl>
</Layout>
<script>
- const encryptedEmail = "LygNLiMmFRo/GlQZaFIWBA==";
- const encryptedPhoneNumber = "ZWlQfX1QT0Z+XgVd";
- const key = "NZdKOfvuLn5jF6sryF0Q";
+ const encryptedEmail = "LygNLiMmFRo/GlQZaFIWBA==";
+ const encryptedPhoneNumber = "ZWlQfX1QT0Z+XgVd";
+ const key = "NZdKOfvuLn5jF6sryF0Q";
- const emailAddrLink = document.getElementById("email-addr") as HTMLAnchorElement;
- const phoneNumberLink = document.getElementById("phone-number") as HTMLAnchorElement;
+ const emailAddrLink = document.getElementById(
+ "email-addr",
+ ) as HTMLAnchorElement;
+ const phoneNumberLink = document.getElementById(
+ "phone-number",
+ ) as HTMLAnchorElement;
- (() => {
- if (emailAddrLink == null || phoneNumberLink == null) {
- return;
- }
+ (() => {
+ if (emailAddrLink == null || phoneNumberLink == null) {
+ return;
+ }
- const emailAddress = xorData(encryptedEmail, key);
- const phoneNumber = xorData(encryptedPhoneNumber, key);
+ const emailAddress = xorData(encryptedEmail, key);
+ const phoneNumber = xorData(encryptedPhoneNumber, key);
- emailAddrLink.href = `mailto:${emailAddress}`;
- emailAddrLink.textContent = emailAddress;
+ emailAddrLink.href = `mailto:${emailAddress}`;
+ emailAddrLink.textContent = emailAddress;
- phoneNumberLink.href = `tel:${phoneNumber}`;
- phoneNumberLink.textContent = phoneNumber;
- })();
+ phoneNumberLink.href = `tel:${phoneNumber}`;
+ phoneNumberLink.textContent = phoneNumber;
+ })();
- function xorData(data: string, key: string): string {
- let actualData = atob(data);
- let actualKey = key;
- const keyLength = key.length;
- const dataLength = actualData.length;
- const result = new Array(dataLength);
-
- // If the key is 12 characters but the data is 30 characters, the key should be repeated 3 times and truncated to 30 characters
- if (keyLength < dataLength) {
- actualKey = key.repeat(Math.ceil(dataLength / keyLength)).substring(0, dataLength);
- } else if (keyLength > dataLength) {
- actualKey = key.substring(0, dataLength);
- }
+ function xorData(data: string, key: string): string {
+ let actualData = atob(data);
+ let actualKey = key;
+ const keyLength = key.length;
+ const dataLength = actualData.length;
+ const result = new Array(dataLength);
- for (let i = 0; i < dataLength; i++) {
- result[i] = String.fromCharCode(actualData.charCodeAt(i) ^ actualKey.charCodeAt(i));
- }
+ // If the key is 12 characters but the data is 30 characters, the key should be repeated 3 times and truncated to 30 characters
+ if (keyLength < dataLength) {
+ actualKey = key
+ .repeat(Math.ceil(dataLength / keyLength))
+ .substring(0, dataLength);
+ } else if (keyLength > dataLength) {
+ actualKey = key.substring(0, dataLength);
+ }
- return result.join("");
- }
+ for (let i = 0; i < dataLength; i++) {
+ result[i] = String.fromCharCode(
+ actualData.charCodeAt(i) ^ actualKey.charCodeAt(i),
+ );
+ }
+
+ return result.join("");
+ }
</script>
diff --git a/src/pages/en/contact.astro b/src/pages/en/contact.astro
index ef69d6e..6ccb15c 100644
--- a/src/pages/en/contact.astro
+++ b/src/pages/en/contact.astro
@@ -2,4 +2,4 @@
import ContactPageLayout from "../../layouts/ContactPageLayout.astro";
---
-<ContactPageLayout /> \ No newline at end of file
+<ContactPageLayout />
diff --git a/src/pages/en/index.astro b/src/pages/en/index.astro
index 8c5945a..a7c9dbf 100644
--- a/src/pages/en/index.astro
+++ b/src/pages/en/index.astro
@@ -2,4 +2,4 @@
import HomePageLayout from "../../layouts/HomePageLayout.astro";
---
-<HomePageLayout /> \ No newline at end of file
+<HomePageLayout />
diff --git a/src/pages/en/portfolio.astro b/src/pages/en/portfolio.astro
index 63840f5..17c4637 100644
--- a/src/pages/en/portfolio.astro
+++ b/src/pages/en/portfolio.astro
@@ -2,4 +2,4 @@
import PortfolioPageLayout from "../../layouts/PortfolioPageLayout.astro";
---
-<PortfolioPageLayout /> \ No newline at end of file
+<PortfolioPageLayout />
diff --git a/src/pages/en/trajectory.astro b/src/pages/en/trajectory.astro
index 3f5ff77..cb5b088 100644
--- a/src/pages/en/trajectory.astro
+++ b/src/pages/en/trajectory.astro
@@ -2,4 +2,4 @@
import TrajectoryPageLayout from "../../layouts/TrajectoryPageLayout.astro";
---
-<TrajectoryPageLayout /> \ No newline at end of file
+<TrajectoryPageLayout />
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 8ac64a6..2dd3973 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -2,4 +2,4 @@
import HomePageLayout from "../layouts/HomePageLayout.astro";
---
-<HomePageLayout /> \ No newline at end of file
+<HomePageLayout />
diff --git a/src/pages/portfolio/[id].astro b/src/pages/portfolio/[id].astro
index 55bac3f..b92ecbd 100644
--- a/src/pages/portfolio/[id].astro
+++ b/src/pages/portfolio/[id].astro
@@ -5,51 +5,62 @@ import { type GetStaticPaths } from "astro";
import TechnologyBadge from "../../partials/TechnologyBadge.astro";
interface Props {
- entry: any;
+ entry: any;
}
-export const getStaticPaths: GetStaticPaths = (async () => {
- const entries = await getCollection("portfolio");
- return entries.map((entry: any) => ({
- params: { id: entry.id },
- props: { entry },
- }));
-});
+export const getStaticPaths: GetStaticPaths = async () => {
+ const entries = await getCollection("portfolio");
+ return entries.map((entry: any) => ({
+ params: { id: entry.id },
+ props: { entry },
+ }));
+};
const { entry } = Astro.props;
const { Content } = await render(entry);
---
<Layout title={entry.data.title} description={entry.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>
+ <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>{entry.data.title}</h1>
+ <h1>{entry.data.title}</h1>
- <Content />
+ <Content />
- <h2>Tecnologías utilizadas</h2>
+ <h2>Tecnologías utilizadas</h2>
- {entry.data.technologies.map((technology: string) => (
- <TechnologyBadge size="small" code={technology} />
- ))}
+ {
+ entry.data.technologies.map((technology: string) => (
+ <TechnologyBadge size="small" code={technology} />
+ ))
+ }
</Layout>
<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 {
+ 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;
- }
+ a#link-back svg {
+ height: 1em;
+ }
</style>
diff --git a/src/pages/portfolio/index.astro b/src/pages/portfolio/index.astro
index 63840f5..17c4637 100644
--- a/src/pages/portfolio/index.astro
+++ b/src/pages/portfolio/index.astro
@@ -2,4 +2,4 @@
import PortfolioPageLayout from "../../layouts/PortfolioPageLayout.astro";
---
-<PortfolioPageLayout /> \ No newline at end of file
+<PortfolioPageLayout />
diff --git a/src/partials/Footer.astro b/src/partials/Footer.astro
index 0bb0570..2265576 100644
--- a/src/partials/Footer.astro
+++ b/src/partials/Footer.astro
@@ -1,43 +1,49 @@
---
-import { useTranslations } from "../i18n"
+import { useTranslations } from "../i18n";
const t = useTranslations(Astro.currentLocale);
---
<footer>
- <p>
- Copyright &copy; 2023-{new Date().getFullYear()} Ariel Costas Guerrero. {t.footer.copyright}
- </p>
+ <p>
+ Copyright &copy; 2023-{new Date().getFullYear()} Ariel Costas Guerrero. {
+ t.footer.copyright
+ }
+ </p>
- <p>
- {t.footer.contentLicencedUnder} <a
- href={`https://creativecommons.org/licenses/by-sa/4.0/deed.${Astro.currentLocale}`}
- >CC BY-SA 4.0</a>.
+ <p>
+ {t.footer.contentLicencedUnder}
+ <a
+ href={`https://creativecommons.org/licenses/by-sa/4.0/deed.${Astro.currentLocale}`}
+ >CC BY-SA 4.0</a
+ >.
- {t.footer.sourceCodeAvailableOn} <a href="https://github.com/arielcostas/costasdev">GitHub</a>
- {t.footer.andIsLicencedUnder} <a
- href="https://joinup.ec.europa.eu/collection/eupl/eupl-text-11-12"
- >{t.footer.eupl} 1.2</a>
- </p>
+ {t.footer.sourceCodeAvailableOn}
+ <a href="https://github.com/arielcostas/costasdev">GitHub</a>
+ {t.footer.andIsLicencedUnder}
+ <a href="https://joinup.ec.europa.eu/collection/eupl/eupl-text-11-12"
+ >{t.footer.eupl} 1.2</a
+ >
+ </p>
</footer>
<style lang="scss">
- @use "../../styles/shared.scss" as *;
+ @use "../../styles/shared.scss" as *;
- footer {
- background-color: $dark;
- color: $light;
- text-align: center;
+ footer {
+ background-color: $dark;
+ color: $light;
+ text-align: center;
- padding: 0.5rem 1rem;
-
- a {
- color: $accentLight;
- }
+ padding: 0.5rem 1rem;
- p {
- max-width: 82ch;
- margin-inline: auto;
- }
- }
+ a {
+ color: $accentLight;
+ }
+
+ p {
+ max-width: 82ch;
+ margin-inline: auto;
+ }
+ }
</style>
diff --git a/src/partials/Header.astro b/src/partials/Header.astro
index bd8c9d6..6df38e8 100644
--- a/src/partials/Header.astro
+++ b/src/partials/Header.astro
@@ -1,60 +1,67 @@
---
import { getRelativeLocaleUrl } from "astro:i18n";
-import { useTranslations } from "../i18n"
+import { useTranslations } from "../i18n";
const t = useTranslations(Astro.currentLocale);
---
<header>
- <a href={getRelativeLocaleUrl(Astro.currentLocale!, "")}>{t.header.home}</a>
- <a href={getRelativeLocaleUrl(Astro.currentLocale!, "trajectory")}>{t.header.trajectory}</a>
- <a href={getRelativeLocaleUrl(Astro.currentLocale!, "portfolio")}>{t.header.portfolio}</a>
- <a href={getRelativeLocaleUrl("es", "blog")}>{t.header.blog}</a>
- <a href={getRelativeLocaleUrl(Astro.currentLocale!, "contact")}>{t.header.contact}</a>
+ <a href={getRelativeLocaleUrl(Astro.currentLocale!, "")}>{t.header.home}</a>
+ <a href={getRelativeLocaleUrl(Astro.currentLocale!, "trajectory")}
+ >{t.header.trajectory}</a
+ >
+ <a href={getRelativeLocaleUrl(Astro.currentLocale!, "portfolio")}
+ >{t.header.portfolio}</a
+ >
+ <a href={getRelativeLocaleUrl("es", "blog")}>{t.header.blog}</a>
+ <a href={getRelativeLocaleUrl(Astro.currentLocale!, "contact")}
+ >{t.header.contact}</a
+ >
</header>
<style lang="scss">
- @use "../../styles/shared.scss" as *;
+ @use "../../styles/shared.scss" as *;
- header {
- color: $accent;
+ header {
+ color: $accent;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- gap: 2rem;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ gap: 2rem;
- padding: 2rem;
+ padding: 2rem;
- a {
- text-decoration: none;
- font-weight: 700;
- font-size: 1.2rem;
- text-transform: uppercase;
- transition: color 0.2s ease-in-out,
- border-bottom-color 0.2s ease-in-out;
- color: $accent;
- line-height: 1;
- border-bottom: 2px solid transparent;
+ a {
+ text-decoration: none;
+ font-weight: 700;
+ font-size: 1.2rem;
+ text-transform: uppercase;
+ transition:
+ color 0.2s ease-in-out,
+ border-bottom-color 0.2s ease-in-out;
+ color: $accent;
+ line-height: 1;
+ border-bottom: 2px solid transparent;
- &:hover {
- color: $accentDark;
- border-bottom-color: currentColor;
- }
+ &:hover {
+ color: $accentDark;
+ border-bottom-color: currentColor;
+ }
- &.active {
- color: $accentDark;
- }
- }
- }
+ &.active {
+ color: $accentDark;
+ }
+ }
+ }
- @media (max-width: $breakpointTablet) {
- }
+ @media (max-width: $breakpointTablet) {
+ }
- @media (min-width: $breakpointTablet) {
- }
+ @media (min-width: $breakpointTablet) {
+ }
- @media (min-width: $breakpointDesktop) {
- }
+ @media (min-width: $breakpointDesktop) {
+ }
</style>
diff --git a/src/partials/TechnologyBadge.astro b/src/partials/TechnologyBadge.astro
index 09cd377..c5e170e 100644
--- a/src/partials/TechnologyBadge.astro
+++ b/src/partials/TechnologyBadge.astro
@@ -1,95 +1,95 @@
---
interface Technology {
- name: string;
- colour: string;
- text?: "light" | "dark";
- icon: string;
+ name: string;
+ colour: string;
+ text?: "light" | "dark";
+ icon: string;
}
export const technologies: { [key: string]: Technology } = {
- java: {
- name: "Java",
- colour: "#e76f00",
- icon: "java",
- },
- dotnet: {
- name: ".NET",
- colour: "#512bd4",
- icon: "dotnet",
- },
- go: {
- name: "Go",
- colour: "#00add8",
- icon: "go",
- },
- mysql: {
- name: "MySQL",
- colour: "#3a75b0",
- icon: "mysql",
- },
- mongodb: {
- name: "MongoDB",
- colour: "#4db33d",
- icon: "mongodb",
- },
- sqlserver: {
- name: "SQL Server",
- colour: "#cc2927",
- icon: "sqlserver",
- },
- php: {
- name: "PHP",
- colour: "#8892be",
- icon: "php",
- },
- python: {
- name: "Python",
- colour: "#306998",
- icon: "python",
- },
- javascript: {
- name: "JavaScript",
- colour: "#ffe70b",
- text: "dark",
- icon: "javascript",
- },
- typescript: {
- name: "TypeScript",
- colour: "#007acc",
- icon: "typescript",
- },
- azure: {
- name: "Azure",
- colour: "#0089d6",
- icon: "azure",
- },
- linux: {
- name: "Linux",
- colour: "#010101",
- icon: "linux",
- },
- windows: {
- name: "Windows",
- colour: "#0078d6",
- icon: "windows",
- },
- astro: {
- name: "Astro",
- colour: "#3d50f5",
- icon: "astro",
- },
- rabbitmq: {
- name: "RabbitMQ",
- colour: "#ff6600",
- icon: "rabbitmq",
- },
+ java: {
+ name: "Java",
+ colour: "#e76f00",
+ icon: "java",
+ },
+ dotnet: {
+ name: ".NET",
+ colour: "#512bd4",
+ icon: "dotnet",
+ },
+ go: {
+ name: "Go",
+ colour: "#00add8",
+ icon: "go",
+ },
+ mysql: {
+ name: "MySQL",
+ colour: "#3a75b0",
+ icon: "mysql",
+ },
+ mongodb: {
+ name: "MongoDB",
+ colour: "#4db33d",
+ icon: "mongodb",
+ },
+ sqlserver: {
+ name: "SQL Server",
+ colour: "#cc2927",
+ icon: "sqlserver",
+ },
+ php: {
+ name: "PHP",
+ colour: "#8892be",
+ icon: "php",
+ },
+ python: {
+ name: "Python",
+ colour: "#306998",
+ icon: "python",
+ },
+ javascript: {
+ name: "JavaScript",
+ colour: "#ffe70b",
+ text: "dark",
+ icon: "javascript",
+ },
+ typescript: {
+ name: "TypeScript",
+ colour: "#007acc",
+ icon: "typescript",
+ },
+ azure: {
+ name: "Azure",
+ colour: "#0089d6",
+ icon: "azure",
+ },
+ linux: {
+ name: "Linux",
+ colour: "#010101",
+ icon: "linux",
+ },
+ windows: {
+ name: "Windows",
+ colour: "#0078d6",
+ icon: "windows",
+ },
+ astro: {
+ name: "Astro",
+ colour: "#3d50f5",
+ icon: "astro",
+ },
+ rabbitmq: {
+ name: "RabbitMQ",
+ colour: "#ff6600",
+ icon: "rabbitmq",
+ },
};
interface Props {
- // tech must be name of the key of one of the technologies
- code: string;
+ // tech must be name of the key of one of the technologies
+ code: string;
- size?: "small" | "large";
+ size?: "small" | "large";
}
const { code, size } = Astro.props;
@@ -97,38 +97,38 @@ const tech = technologies[code] as Technology;
---
<span class={`pill-${size ?? "small"} text-${tech.text ?? "light"}`}>
- {tech.name}
+ {tech.name}
</span>
<style define:vars={{ colour: tech.colour }}>
- span {
- display: inline-block;
- background-color: var(--colour);
- font-weight: bold;
- text-transform: uppercase;
- border-radius: 0.5em;
- padding: 0.5em 1em;
- }
+ span {
+ display: inline-block;
+ background-color: var(--colour);
+ font-weight: bold;
+ text-transform: uppercase;
+ border-radius: 0.5em;
+ padding: 0.5em 1em;
+ }
- .text-dark {
- color: #000;
- }
+ .text-dark {
+ color: #000;
+ }
- .text-light {
- color: #fff;
- }
+ .text-light {
+ color: #fff;
+ }
- .pill-small {
- padding: 0.35em 0.5em;
- border-radius: 0.25em;
+ .pill-small {
+ padding: 0.35em 0.5em;
+ border-radius: 0.25em;
- font-size: 0.75em;
- }
+ font-size: 0.75em;
+ }
- .pill-large {
- padding: 0.35 0.75em;
- border-radius: 0.5em;
+ .pill-large {
+ padding: 0.35 0.75em;
+ border-radius: 0.5em;
- font-size: 0.75em;
- }
+ font-size: 0.75em;
+ }
</style>
diff --git a/staticwebapp.config.json b/staticwebapp.config.json
index 587253a..ff706e3 100644
--- a/staticwebapp.config.json
+++ b/staticwebapp.config.json
@@ -1,19 +1,19 @@
{
- "trailingSlash": "never",
- "globalHeaders": {
- "X-Frame-Options": "DENY",
- "X-Content-Type-Options": "nosniff",
- "X-XSS-Protection": "1; mode=block",
- "Content-Security-Policy": "default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'"
- },
- "routes": [
- {
- "route": "/vcard",
- "rewrite": "/vcard.vcf",
- "statusCode": 301
- }
- ],
- "mimeTypes": {
- ".vcf": "text/vcard"
- }
-} \ No newline at end of file
+ "trailingSlash": "never",
+ "globalHeaders": {
+ "X-Frame-Options": "DENY",
+ "X-Content-Type-Options": "nosniff",
+ "X-XSS-Protection": "1; mode=block",
+ "Content-Security-Policy": "default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'"
+ },
+ "routes": [
+ {
+ "route": "/vcard",
+ "rewrite": "/vcard.vcf",
+ "statusCode": 301
+ }
+ ],
+ "mimeTypes": {
+ ".vcf": "text/vcard"
+ }
+}
diff --git a/styles/shared.scss b/styles/shared.scss
index 202651c..9bdf7d8 100644
--- a/styles/shared.scss
+++ b/styles/shared.scss
@@ -1,6 +1,6 @@
-$titleFontStack: 'Beiruti', 'Arial', system-ui, sans-serif;
-$mainFontStack: 'Sen Variable', 'Arial', system-ui, sans-serif;
-$monoFontStack: 'Fira Code', 'Consolas', monospace;
+$titleFontStack: "Beiruti", "Arial", system-ui, sans-serif;
+$mainFontStack: "Sen Variable", "Arial", system-ui, sans-serif;
+$monoFontStack: "Fira Code", "Consolas", monospace;
$accent: hsl(209, 94%, 42%);
$accentLight: hsl(215, 90%, 60%);
@@ -26,32 +26,32 @@ $breakpointTablet: 480px;
$breakpointDesktop: 1024px;
:root {
- font: 400 16px/1.65 $mainFontStack;
+ font: 400 16px/1.65 $mainFontStack;
}
%heading {
- font-family: $titleFontStack;
- line-height: 1.25;
- margin-block-start: 0.75em;
- margin-block-end: 0.25em;
+ font-family: $titleFontStack;
+ line-height: 1.25;
+ margin-block-start: 0.75em;
+ margin-block-end: 0.25em;
}
h1 {
- @extend %heading;
- font-size: 3.25rem;
+ @extend %heading;
+ font-size: 3.25rem;
}
h2 {
- @extend %heading;
- font-size: 2.5rem;
+ @extend %heading;
+ font-size: 2.5rem;
}
h3 {
- @extend %heading;
- font-size: 1.5rem;
+ @extend %heading;
+ font-size: 1.5rem;
}
h4 {
- @extend %heading;
- font-size: 1.25rem;
-} \ No newline at end of file
+ @extend %heading;
+ font-size: 1.25rem;
+}
diff --git a/tsconfig.json b/tsconfig.json
index 77da9dd..bcbf8b5 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,3 +1,3 @@
{
"extends": "astro/tsconfigs/strict"
-} \ No newline at end of file
+}