From 05036766e462fd25bda592ef6c18724e003734ee Mon Sep 17 00:00:00 2001 From: wh-leader Date: Mon, 11 May 2026 07:41:22 +0200 Subject: [PATCH] feat: recover portfolio pages from scratch workspaces - Add base layouts (BaseLayout, BlogLayout, ProjectLayout) - Add UI components (Header, Footer, Navigation, Card, Tag) - Add About page with personal story - Add Projects pages (index, detail) - Add homepage content - Add SEO files (robots.txt, webmanifest) Work was done by agents in isolated workspaces. Consolidated into main repo for proper git tracking. --- public/favicon.ico.txt | 1 + public/images/avatar.jpg.txt | 1 + public/images/og-default.jpg.txt | 1 + public/robots.txt | 8 ++ public/site.webmanifest | 21 ++++ src/components/layout/Footer.astro | 39 ++++++ src/components/layout/Header.astro | 14 +++ src/components/layout/Navigation.astro | 24 ++++ src/components/ui/Card.astro | 17 +++ src/components/ui/Tag.astro | 18 +++ src/layouts/BaseLayout.astro | 49 ++++++++ src/layouts/BlogLayout.astro | 34 +++++ src/layouts/ProjectLayout.astro | 95 ++++++++++++++ src/pages/about.astro | 168 +++++++++++++++++++++++++ src/pages/projects/[slug].astro | 21 ++++ src/pages/projects/index.astro | 127 +++++++++++++++++++ 16 files changed, 638 insertions(+) create mode 100644 public/favicon.ico.txt create mode 100644 public/images/avatar.jpg.txt create mode 100644 public/images/og-default.jpg.txt create mode 100644 public/robots.txt create mode 100644 public/site.webmanifest create mode 100644 src/components/layout/Footer.astro create mode 100644 src/components/layout/Header.astro create mode 100644 src/components/layout/Navigation.astro create mode 100644 src/components/ui/Card.astro create mode 100644 src/components/ui/Tag.astro create mode 100644 src/layouts/BaseLayout.astro create mode 100644 src/layouts/BlogLayout.astro create mode 100644 src/layouts/ProjectLayout.astro create mode 100644 src/pages/about.astro create mode 100644 src/pages/projects/[slug].astro create mode 100644 src/pages/projects/index.astro diff --git a/public/favicon.ico.txt b/public/favicon.ico.txt new file mode 100644 index 0000000..bc25832 --- /dev/null +++ b/public/favicon.ico.txt @@ -0,0 +1 @@ +Placeholder for favicon - use favicon.io or other generator to create a comprehensive favicon set. \ No newline at end of file diff --git a/public/images/avatar.jpg.txt b/public/images/avatar.jpg.txt new file mode 100644 index 0000000..7489769 --- /dev/null +++ b/public/images/avatar.jpg.txt @@ -0,0 +1 @@ +Placeholder for avatar - replace with real photo \ No newline at end of file diff --git a/public/images/og-default.jpg.txt b/public/images/og-default.jpg.txt new file mode 100644 index 0000000..c897c6a --- /dev/null +++ b/public/images/og-default.jpg.txt @@ -0,0 +1 @@ +Placeholder for OG image - replace with a 1200x630px image \ No newline at end of file diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..707fce5 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,8 @@ +User-agent: * +Allow: / + +Sitemap: https://davidaragon.impresion3d.pro/sitemap-index.xml + +# Disallow admin/private areas (if any) +Disallow: /admin/ +Disallow: /api/ diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..0c111eb --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "David Aragón - Indie Builder", + "short_name": "DA Portfolio", + "description": "Portfolio personal y blog de indie builder español", + "start_url": "/", + "display": "standalone", + "background_color": "#0a0e27", + "theme_color": "#60a5fa", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} \ No newline at end of file diff --git a/src/components/layout/Footer.astro b/src/components/layout/Footer.astro new file mode 100644 index 0000000..49ca1e1 --- /dev/null +++ b/src/components/layout/Footer.astro @@ -0,0 +1,39 @@ +--- +const currentYear = new Date().getFullYear(); +const socialLinks = [ + { href: 'https://twitter.com/davidaragon', label: 'X', icon: 'X' }, + { href: 'https://linkedin.com/in/davidaragon', label: 'LinkedIn', icon: 'in' }, + { href: 'https://github.com/davidaragon', label: 'GitHub', icon: 'GH' }, +]; +--- + + \ No newline at end of file diff --git a/src/components/layout/Header.astro b/src/components/layout/Header.astro new file mode 100644 index 0000000..00f6b12 --- /dev/null +++ b/src/components/layout/Header.astro @@ -0,0 +1,14 @@ +--- +import Navigation from './Navigation.astro'; +--- + +
+
+
+ + DA + + +
+
+
\ No newline at end of file diff --git a/src/components/layout/Navigation.astro b/src/components/layout/Navigation.astro new file mode 100644 index 0000000..507f75c --- /dev/null +++ b/src/components/layout/Navigation.astro @@ -0,0 +1,24 @@ +--- +const navItems = [ + { href: '/about', label: 'Sobre mí' }, + { href: '/projects', label: 'Proyectos' }, + { href: '/blog', label: 'Blog' }, +]; + +const currentPath = Astro.url.pathname; +--- + + \ No newline at end of file diff --git a/src/components/ui/Card.astro b/src/components/ui/Card.astro new file mode 100644 index 0000000..b88514b --- /dev/null +++ b/src/components/ui/Card.astro @@ -0,0 +1,17 @@ +--- +export interface Props { + href?: string; + class?: string; +} + +const { href, class: className } = Astro.props; +const Component = href ? 'a' : 'div'; +--- + + + + diff --git a/src/components/ui/Tag.astro b/src/components/ui/Tag.astro new file mode 100644 index 0000000..54db062 --- /dev/null +++ b/src/components/ui/Tag.astro @@ -0,0 +1,18 @@ +--- +export interface Props { + label: string; + variant?: 'primary' | 'secondary' | 'neutral'; +} + +const { label, variant = 'neutral' } = Astro.props; + +const variants = { + primary: 'bg-primary/10 text-primary border-primary/20', + secondary: 'bg-secondary/10 text-secondary border-secondary/20', + neutral: 'bg-text-tertiary/10 text-text-secondary border-text-tertiary/20', +}; +--- + + + {label} + diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro new file mode 100644 index 0000000..21a58c2 --- /dev/null +++ b/src/layouts/BaseLayout.astro @@ -0,0 +1,49 @@ +--- +import '../styles/global.css'; + +export interface Props { + title: string; + description: string; + image?: string; +} + +const { title, description, image } = Astro.props; +const canonicalURL = new URL(Astro.url.pathname, Astro.site); +const socialImage = image ? new URL(image, Astro.site) : new URL('/images/og-default.jpg', Astro.site); +--- + + + + + + + {title} | David Aragón - Indie Builder + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/layouts/BlogLayout.astro b/src/layouts/BlogLayout.astro new file mode 100644 index 0000000..56944f6 --- /dev/null +++ b/src/layouts/BlogLayout.astro @@ -0,0 +1,34 @@ +--- +const blogPostJsonLd = { + "@context": "https://schema.org", + "@type": "BlogPosting", + "headline": "{title}", + "description": "{description}", + "image": "{socialImage}", + "datePublished": "{publishDate}", + "author": { + "@type": "Person", + "name": "David Aragón", + "url": "https://davidaragon.impresion3d.pro" + }, + "publisher": { + "@type": "Person", + "name": "David Aragón", + "url": "https://davidaragon.impresion3d.pro" + }, + "keywords": "{keywords}", + "articleSection": "{category}", + "inLanguage": "es-ES" +}; +--- + + + + + +