+
+
+ );
+}
diff --git a/app/[lang]/works/page.tsx b/app/[lang]/works/page.tsx
new file mode 100644
index 0000000..275c8b2
--- /dev/null
+++ b/app/[lang]/works/page.tsx
@@ -0,0 +1,69 @@
+import { getTranslation } from '@/get-translation';
+import { getWorkPosts } from '@/util/posts/work';
+import { Navigation } from '../components/navigation';
+import { Card } from '../components/card';
+import { Eye } from 'lucide-react';
+import Link from 'next/link';
+
+export function generateStaticParams() {
+ return [{ lang: 'en' }, { lang: 'es' }];
+}
+
+export default async function WorkPage(props: {
+ params: Promise<{ lang: 'es' | 'en' }>;
+}) {
+ const params = await props.params;
+
+ const { lang } = params;
+
+ const t = await getTranslation(lang);
+ const posts = await getWorkPosts(lang);
+
+ return (
+
+
+
+
+
+ {t.works.title}
+
+
{t.works.brief}
+
+
+
+
+
+ {posts.map(post => (
+
+
+
+
+
+ {' '}
+
+
+
+
+ {post.title}
+
+
+ {post.brief}
+
+
+
+ {t.projects.cta} →
+
+
+
+
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/bun.lockb b/bun.lockb
index ed40ffe..d35c70d 100644
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/constants/navigation.ts b/constants/navigation.ts
index 3dac17e..28d0d1f 100644
--- a/constants/navigation.ts
+++ b/constants/navigation.ts
@@ -2,11 +2,13 @@ export const navigation = {
es: [
{ name: 'Inicio', href: '/' },
{ name: 'Resumen', href: '/resume' },
+ { name: 'Trabajos', href: '/works' },
{ name: 'Proyectos', href: '/projects' },
],
en: [
{ name: 'Home', href: '/' },
{ name: 'Resume', href: '/resume' },
+ { name: 'Works', href: '/works' },
{ name: 'Projects', href: '/projects' },
],
};
diff --git a/content/work/en/comuny-t.md b/content/work/en/comuny-t.md
new file mode 100644
index 0000000..cd53db8
--- /dev/null
+++ b/content/work/en/comuny-t.md
@@ -0,0 +1,19 @@
+---
+title: “Comuny-T”
+brief: “Invest easily, quickly and securely with no minimum amounts in real state.”
+date: "06-01-2023"
+image: “https://res.cloudinary.com/digohrwkz/image/upload/v1731865012/comunyt-preview_wznyim.png”
+url: “https://comunyt.com/”
+stack : [“ReactJS”, “Chakra UI”]
+---
+
+Comuny-T is an investor community that allows you to invest in the real state market easily and with no minimum amounts through cryptoassets.
+
+## Functionalities
+
+- Website creation
+- Creation of several sections of the backoffice application.
+
+## Resume
+It was a layout work from a design. Consumption of internal APIs of the company to obtain some data to display both on the home page and in the backoffice.
+
diff --git a/content/work/en/mocka-software.md b/content/work/en/mocka-software.md
new file mode 100644
index 0000000..1bd8296
--- /dev/null
+++ b/content/work/en/mocka-software.md
@@ -0,0 +1,18 @@
+---
+title: “Mocka Software”
+brief: “We transform your ideas into what your customers need. Let's grow your business together.”
+date: “08-12-2024”
+image: “https://res.cloudinary.com/digohrwkz/image/upload/v1731865010/mocka-preview_okzc2i.png”
+url: “https://mockasoftware.com/”
+stack : [“ReactJS”, “NextJS”, “TailwindCSS”, “i18n”, “HonoJS”, “Bun”, “Brevo”]
+---
+
+Mocka is a software agency that offers different services related to building digital products such as websites, mobile applications or bots with A.I. They also offer other types of more technical services such as Web Hosting, SEO Optimization.
+
+## Features
+
+- Complete Landing page with several sections.
+- Multiple language support.
+- Serverless backend for sending emails.
+- Web and backend deployment.
+
diff --git a/content/work/es/comuny-t.md b/content/work/es/comuny-t.md
new file mode 100644
index 0000000..e78a7ee
--- /dev/null
+++ b/content/work/es/comuny-t.md
@@ -0,0 +1,18 @@
+---
+title: "Comuny-T"
+brief: "Invertí de forma fácil, rápida y segura sin montos mínimos en real state."
+date: "01-06-2023"
+image: "https://res.cloudinary.com/digohrwkz/image/upload/v1731865012/comunyt-preview_wznyim.png"
+url: "https://comunyt.com/"
+stack : ["ReactJS", "Chakra UI"]
+---
+
+Comuny-T es una comunidad de inversores que te permite invertir en el mercado de real state de forma fácil y sin montos mínimos a través de criptoactivos.
+
+## Funcionalidades
+
+- Creación del sitio web
+- Creación de varias secciones de la aplicación de backoffice.
+
+## Resumen
+Fue un trabajo de maquetado apartir de un diseño. Consumo de APIs internas de la empresa para la obtención de algunos datos a mostrar tanto en la página principal como en el backoffice.
\ No newline at end of file
diff --git a/content/work/es/mocka-software.md b/content/work/es/mocka-software.md
new file mode 100644
index 0000000..8c49a96
--- /dev/null
+++ b/content/work/es/mocka-software.md
@@ -0,0 +1,17 @@
+---
+title: "Mocka Software"
+brief: "Transformamos tus ideas en los que sus clientes necesitan. Hagamos crecer tu negocio juntos."
+date: 12-08-2024”
+image: "https://res.cloudinary.com/digohrwkz/image/upload/v1731865010/mocka-preview_okzc2i.png"
+url: "https://mockasoftware.com/"
+stack : ["ReactJS", "NextJS", "TailwindCSS", "i18n", "HonoJS", "Bun", "Brevo"]
+---
+
+Mocka es una agencia de software que ofrece distintos servicios relacionados con la construcción de productos digitales como sitios webs, aplicaciones móviles o bots con I.A. También ofrecen otros tipos de servicios más técnicos como Web Hosting, Optimización de SEO.
+
+## Funcionalidades
+
+- Landing page completa con varias secciones.
+- Soporte de múltiples idiomas.
+- Serverless backend para envío de emails.
+- Despliegue de web y backend.
diff --git a/next.config.js b/next.config.js
index 767719f..b24ecca 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,4 +1,10 @@
/** @type {import('next').NextConfig} */
-const nextConfig = {}
+const nextConfig = {
+ images: {
+ remotePatterns: [{
+ hostname: 'res.cloudinary.com'
+ }]
+ }
+}
module.exports = nextConfig
diff --git a/package.json b/package.json
index 1677cf8..2be1a63 100644
--- a/package.json
+++ b/package.json
@@ -18,10 +18,13 @@
"autoprefixer": "10.4.14",
"class-variance-authority": "^0.6.0",
"clsx": "^1.2.1",
+ "date-fns": "^4.1.0",
"eslint": "8.41.0",
"eslint-config-next": "13.4.3",
"framer-motion": "^10.12.16",
+ "gray-matter": "^4.0.3",
"lucide-react": "^0.221.0",
+ "markdown-to-jsx": "^7.6.2",
"negotiator": "^0.6.3",
"next": "^14.2.4",
"postcss": "8.4.23",
diff --git a/public/images/works/comunyt-preview.png b/public/images/works/comunyt-preview.png
new file mode 100644
index 0000000..f271513
Binary files /dev/null and b/public/images/works/comunyt-preview.png differ
diff --git a/public/images/works/mocka-preview.png b/public/images/works/mocka-preview.png
new file mode 100644
index 0000000..2ec2d67
Binary files /dev/null and b/public/images/works/mocka-preview.png differ
diff --git a/translations/en.json b/translations/en.json
index 8110aa1..b3fcbb0 100644
--- a/translations/en.json
+++ b/translations/en.json
@@ -5,6 +5,7 @@
"experience": "Experience",
"projects": "Projects",
"services": "Services",
+ "works": "Works",
"stack": "Stack",
"certifications": "Certifications"
},
@@ -29,5 +30,9 @@
"title": "Projects",
"brief": "Some of my most important or recent projects that I have been working on.",
"cta": "Read more"
+ },
+ "works": {
+ "title": "Works",
+ "brief": "Some of the most important works that I have been working on."
}
}
diff --git a/translations/es.json b/translations/es.json
index 7db1e39..d09bfa8 100644
--- a/translations/es.json
+++ b/translations/es.json
@@ -5,6 +5,7 @@
"experience": "Experiencia",
"projects": "Proyectos",
"services": "Servicios",
+ "works": "Trabajos",
"stack": "Stack",
"certifications": "Certificaciones"
},
@@ -29,5 +30,9 @@
"title": "Proyectos",
"brief": "Algunos de los proyectos más importantes que hice o en los que estuve trabajando.",
"cta": "Leer más"
+ },
+ "works": {
+ "title": "Trabajos",
+ "brief": "Algunos de los trabajos más importantes que hice o en los que estuve trabajando."
}
}
diff --git a/util/posts/work.ts b/util/posts/work.ts
new file mode 100644
index 0000000..80a148f
--- /dev/null
+++ b/util/posts/work.ts
@@ -0,0 +1,61 @@
+import fs from 'fs';
+import path from 'path';
+import matter from 'gray-matter';
+
+const WORK_DIR = path.join(process.cwd(), 'content/work');
+
+export interface WorkPost {
+ slug: string;
+ title: string;
+ brief: string
+ stack: string[]
+ url: string | undefined
+ date: string;
+ content: string;
+ image?: string;
+}
+
+export async function getWorkPosts(lang: string): Promise {
+ const postsDirectory = path.join(WORK_DIR, lang);
+ const files = fs.readdirSync(postsDirectory);
+
+ const posts = files
+ .filter((file) => file.endsWith('.md'))
+ .map((file) => {
+ const slug = file.replace(/\.md$/, '');
+ const fullPath = path.join(postsDirectory, file);
+ const fileContents = fs.readFileSync(fullPath, 'utf8');
+ const { data, content } = matter(fileContents);
+
+ return {
+ slug,
+ title: data.title,
+ date: data.date,
+ brief: data.brief,
+ stack: data.stack,
+ url: data.url,
+ content,
+ image: data.image,
+ };
+ })
+ .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
+
+ return posts;
+}
+
+export async function getWorkPost(lang: string, slug: string): Promise {
+ const fullPath = path.join(WORK_DIR, lang, `${slug}.md`);
+ const fileContents = fs.readFileSync(fullPath, 'utf8');
+ const { data, content } = matter(fileContents);
+
+ return {
+ slug,
+ title: data.title,
+ brief: data.brief,
+ url: data.url,
+ date: data.date,
+ stack: data.stack,
+ content,
+ image: data.image,
+ };
+}
\ No newline at end of file