Sitio web interactivo de alto rendimiento que despliega proyectos de forma dinámica, integrando animaciones fluidas y consumiendo información del ecosistema de desarrollo.
| Capa | Tecnología |
|---|---|
| Framework UI | React 19 con TypeScript 6 |
| Bundler | Vite 8 |
| Animaciones | Motion (Framer Motion) |
| Enrutamiento | React Router DOM v7 (HashRouter) |
| UI Framework | Bootstrap 5 + React Bootstrap |
| Iconos | Lucide React |
| Gestor de paquetes | pnpm 9 |
- Node.js >= 22
- pnpm >= 9 (instalar con:
npm install -g pnpm)
# 1. Clonar el repositorio
git clone https://github.com/KernelDVLPR/Portfolio.git
cd Portfolio/frontend
# 2. Configurar variables de entorno
cp .env.example .env
# Editar .env con tus datos
# 3. Instalar dependencias
pnpm install
# 4. Iniciar servidor de desarrollo
pnpm dev
# 5. Abrir en el navegador
# http://localhost:5173/Portfolio/| Script | Descripción |
|---|---|
pnpm dev |
Inicia servidor de desarrollo con hot-reload |
pnpm build |
Compila para producción (typecheck + bundle) |
pnpm lint |
Ejecuta ESLint en todo el proyecto |
pnpm preview |
Previsualiza el build de producción localmente |
pnpm optimize-images |
Convierte imágenes a WebP/AVIF optimizados |
| Variable | Requerida | Descripción |
|---|---|---|
VITE_GITHUB_USERNAME |
No | Usuario de GitHub para la sección de repositorios (default: kerneldvlpr) |
El proyecto se despliega automáticamente a GitHub Pages mediante GitHub Actions.
Flujo CI/CD:
- Push a
maincon cambios enfrontend/**o.github/workflows/deploy.yml pnpm install --frozen-lockfile(dependencias exactas)pnpm lint(análisis estático)pnpm build(typecheck + bundle)- Upload a GitHub Pages
Para habilitar:
- Ir a Settings → Pages del repositorio
- En "Source", seleccionar "GitHub Actions"
Portfolio/
├── .github/workflows/ # CI/CD: GitHub Actions
└── frontend/
├── public/ # Archivos estáticos (imágenes, _headers, robots.txt, sitemap.xml)
├── scripts/ # Scripts de utilidad (optimización de imágenes)
└── src/
├── components/ # Componentes globales reutilizables
│ ├── CarouselNavigation/ # Navegación de carrusel (compartido)
│ ├── ErrorBoundary/ # Captura de errores de renderizado
│ ├── GitHubIcon/ # Icono SVG de GitHub
│ ├── Link/ # Enlace unificado (interno/externo)
│ ├── ProjectCard/ # Tarjeta de proyecto
│ └── ThemeToggle/ # Botón de cambio de tema
├── features/ # Funcionalidades (Feature-Driven Design)
│ ├── home/ # Página de inicio
│ │ ├── api/ # Capa de datos (GitHub API, datos de proyectos)
│ │ └── components/ # Componentes de la página de inicio
│ └── projects/ # Página de detalle de proyecto
│ ├── api/ # Datos de proyectos
│ └── components/ # Componentes de detalle
├── hooks/ # Hooks globales (useTheme, useLocalStorage, useActiveSection, usePagination)
├── layouts/ # Layouts (Navbar, Footer, MainLayout)
├── styles/ # Estilos globales y variables CSS
├── types/ # Interfaces y tipos TypeScript
└── utils/ # Utilidades (constants, factories, helpers)
El sistema usa el patrón Factory para centralizar la creación de proyectos. Hay que registrar cada proyecto en dos lugares:
Editar frontend/src/features/home/api/projects.ts:
createProjectCard({
id: "mi-proyecto", // ID único (URL amigable)
title: "Mi Proyecto", // Título visible
description: "Descripción corta para la tarjeta.",
tags: ["React", "TypeScript"], // Tecnologías destacadas
accent: "blue", // Color de acento: "blue" | "green" | "violet"
imageId: "portfolioImage", // ID de imagen (ver projectFactory.ts)
github: "https://github.com/usuario/repo", // Opcional: URL de GitHub
demo: "https://mi-sitio.com", // Opcional: URL de demo
});Editar frontend/src/features/projects/api/projectsData.ts:
"mi-proyecto": createProjectDetail({
id: "mi-proyecto", // DEBE coincidir con el ID del paso 1
title: "Mi Proyecto",
subtitle: "Subtítulo del proyecto",
date: "Mes Año - Mes Año",
accent: "blue",
imageId: "portfolioImage",
overview: "Descripción general del proyecto...",
challenge: "Cuál fue el desafío técnico...",
solution: "Cómo se resolvió...",
results: ["Resultado clave 1", "Resultado clave 2"],
tech: [
tech("Frontend", ["React 19", "Bootstrap 5"]),
tech("Backend", ["Node.js", "Express"]),
],
github: "https://github.com/usuario/repo",
demo: "https://mi-sitio.com",
})| Configuración | Resultado |
|---|---|
Sin github |
Se autogenera https://github.com/KernelDVLPR/{id} |
github: "" |
Botón de GitHub oculto |
Sin demo |
Botón de demo oculto |
Con demo |
Botón visible con la URL proporcionada |
Los scripts en frontend/scripts/ se ejecutan bajo demanda:
| Script | Propósito | ¿Cuándo ejecutar? |
|---|---|---|
optimize-images.mjs |
Convierte imágenes a WebP/AVIF con compresión | Manual: pnpm optimize-images |
Este proyecto está bajo la licencia MIT. Ver LICENSE para más detalles.
Nota: Este proyecto no utiliza Sanity CMS como fuente de datos. Sanity se menciona únicamente como tecnología usada en algunos proyectos listados. Los datos del portafolio son estáticos y gestionados mediante factories.