cd /Users/ctelloruiz/Desktop/Semestre\ 1/NewProject
npx create-next-app@latest fitness-app-frontend --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --yesConfiguración elegida:
- ✅ TypeScript
- ✅ Tailwind CSS
- ✅ ESLint
- ✅ App Router
- ✅ src/ directory
- ✅ Import alias "@/*"
fitness-app-frontend/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── layout.tsx # Layout principal
│ │ ├── page.tsx # Página de inicio (/)
│ │ ├── globals.css # Estilos globales
│ │ └── users/ # Módulo de usuarios
│ │ ├── layout.tsx # Layout para /users/*
│ │ ├── page.tsx # Lista de usuarios (/users)
│ │ └── [...profile]/ # Rutas dinámicas
│ │ ├── layout.tsx # Layout para perfiles
│ │ └── page.tsx # Página de perfil dinámico
│ │ ├── exercises/ # Módulo de ejercicios
│ │ │ ├── layout.tsx # Layout para /exercises/*
│ │ │ └── page.tsx # Catálogo de ejercicios (/exercises)
│ │ ├── routines/ # Módulo de rutinas
│ │ │ ├── layout.tsx # Layout para /routines/*
│ │ │ └── page.tsx # Rutinas semanales (/routines)
│ │ └── profiles/ # Módulo de perfiles
│ │ ├── layout.tsx # Layout para /profiles/*
│ │ └── page.tsx # Gestión de perfiles (/profiles)
│ ├── components/ # Componentes UI
│ │ ├── index.ts # Exportaciones centralizadas
│ │ ├── shared/ # Componentes reutilizables
│ │ │ ├── Header.tsx # Navegación principal
│ │ │ ├── Footer.tsx # Pie de página
│ │ │ └── index.ts # Barrel exports
│ │ ├── home/ # Componentes del home
│ │ │ ├── FeatureCard.tsx
│ │ │ ├── HeroSection.tsx
│ │ │ ├── StatsCard.tsx
│ │ │ ├── TeamPreview.tsx
│ │ │ ├── SectionContainer.tsx
│ │ │ └── index.ts
│ │ └── users/ # Componentes de usuarios
│ │ ├── UserCard.tsx
│ │ ├── UserForm.tsx
│ │ ├── UserProfile.tsx
│ │ └── index.ts
│ ├── exercises/ # Componentes de ejercicios
│ │ ├── ExerciseCard.tsx
│ │ ├── ExerciseForm.tsx
│ │ ├── ExerciseList.tsx
│ │ └── index.ts
│ ├── routines/ # Componentes de rutinas
│ │ ├── RoutineCard.tsx
│ │ ├── RoutineForm.tsx
│ │ ├── WeeklySchedule.tsx
│ │ └── index.ts
│ └── profiles/ # Componentes de perfiles
│ ├── ProfileCard.tsx
│ ├── ProfileForm.tsx
│ ├── HealthMetrics.tsx
│ └── index.ts
│ ├── modules/ # Lógica de negocio
│ │ ├── home/
│ │ │ ├── index.ts
│ │ │ └── types/
│ │ │ └── index.ts
│ │ ├── users/
│ │ │ ├── index.ts
│ │ │ ├── services/
│ │ │ │ ├── usersService.ts
│ │ │ │ └── index.ts
│ │ │ └── types/
│ │ │ └── index.ts
│ │ ├── exercises/
│ │ │ ├── index.ts
│ │ │ ├── services/
│ │ │ │ ├── exercisesService.ts
│ │ │ │ └── index.ts
│ │ │ └── types/
│ │ │ └── index.ts
│ │ ├── routines/
│ │ │ ├── index.ts
│ │ │ ├── services/
│ │ │ │ ├── routinesService.ts
│ │ │ │ └── index.ts
│ │ │ └── types/
│ │ │ └── index.ts
│ │ └── profiles/
│ │ ├── index.ts
│ │ ├── services/
│ │ │ ├── profilesService.ts
│ │ │ └── index.ts
│ │ └── types/
│ │ └── index.ts
│ ├── lib/ # Utilidades
│ │ └── utils.ts
│ └── types/ # Tipos globales
│ └── api.ts # Tipos del backend
├── public/
├── package.json
├── tailwind.config.ts
├── tsconfig.json
├── next.config.ts # ✅ Proxy configurado
└── README.md
- Framework: Next.js 15.5.4
- Styling: Tailwind CSS
- Language: TypeScript
- HTTP Client: Fetch nativo (sin axios)
- State Management: React hooks + Context API
- Proxy: Configurado para evitar CORS
- API Base URL:
http://localhost:3001 - Proxy Routes:
/api/*→http://localhost:3001/* - Documentación: Ver
../fitness-app-backend/API_DOCUMENTATION.md - Tipos: Disponibles en
src/types/api.ts
✅ Completado:
- Estructura completa de carpetas creada
- Tipos TypeScript del backend configurados
- Página principal básica implementada
- Configuración de Tailwind CSS lista
- Proxy configurado en next.config.ts
- Barrel exports configurados
- Servicio de usuarios implementado
- Rutas dinámicas configuradas
- Utilidades básicas creadas
🔄 Pendiente (para los estudiantes):
- Implementar funciones CRUD en los servicios (comentadas como guía)
- Implementar componentes UI específicos
- Crear páginas adicionales
- Integrar servicios con componentes
- Añadir manejo de estado global
app/
├── layout.tsx # Layout principal de la aplicación
├── page.tsx # Página de inicio (/)
├── globals.css # Estilos globales
└── users/ # Módulo de usuarios
├── layout.tsx # Layout para rutas /users/*
├── page.tsx # Lista de usuarios (/users)
└── [...profile]/ # Rutas dinámicas (/users/123, /users/123/edit)
├── layout.tsx # Layout para perfiles
└── page.tsx # Página de perfil dinámico
💡 Convención de rutas:
page.tsx= Página accesible públicamentelayout.tsx= Layout compartido para un grupo de rutas[...slug]= Rutas dinámicas catch-all
components/
├── index.ts # Exportaciones centralizadas
├── shared/ # Componentes reutilizables globalmente
│ ├── Header.tsx # Navegación principal
│ ├── Footer.tsx # Pie de página
│ └── index.ts # Barrel exports
├── home/ # Componentes específicos del home
│ ├── FeatureCard.tsx # Tarjeta de características
│ ├── HeroSection.tsx # Sección hero principal
│ ├── StatsCard.tsx # Tarjeta de estadísticas
│ ├── TeamPreview.tsx # Vista previa del equipo
│ ├── SectionContainer.tsx # Contenedor de secciones
│ └── index.ts # Exportaciones del módulo
└── users/ # Componentes específicos de usuarios
├── UserCard.tsx # Tarjeta de usuario
├── UserForm.tsx # Formulario de usuario
├── UserProfile.tsx # Perfil de usuario
└── index.ts # Exportaciones del módulo
🎯 Principios de Componentes:
- Reutilización: Los componentes
shared/son usables en cualquier parte - Especialización: Componentes por módulo (
home/,users/) - Barrel Exports: Cada directorio tiene un
index.tspara importaciones limpias
modules/
├── home/
│ ├── index.ts # Exportaciones del módulo home
│ └── types/
│ └── index.ts # Tipos específicos del home
└── users/
├── index.ts # Exportaciones del módulo users
├── services/
│ ├── usersService.ts # API calls y lógica de negocio
│ └── index.ts
└── types/
└── index.ts # Tipos del módulo users
📋 Estructura del Service (ejemplo usersService.ts):
// ✅ Funciones CRUD completas
- getAllUsers() // GET /api/users
- getUserById(id) // GET /api/users/:id
- createUser(data) // POST /api/users
- updateUser(data) // PUT /api/users/:id
- deleteUser(id) // DELETE /api/users/:id
- filterUsers() // Filtrado local
// ✅ Características avanzadas
- Manejo de errores con ApiError
- Transformación de datos Frontend ↔ Backend
- Proxy integrado para evitar CORS
- Logging de requests
- Tipado completo con TypeScriptlib/
└── utils.ts # Funciones helper y utilidades
types/
└── api.ts # Interfaces y tipos del backend
// ✅ Proxy para Backend (evita CORS)
rewrites: [
{
source: '/api/users/:path*',
destination: 'http://localhost:3001/users/:path*'
}
]
// ✅ Optimización de imágenes externas
images: {
remotePatterns: [
{ hostname: 'images.unsplash.com' },
{ hostname: 'ui-avatars.com' }
]
}{
"compilerOptions": {
"target": "ES2017",
"strict": true,
"paths": {
"app/*": ["./src/*"] // ✅ Path mapping
}
}
}1. Crear la estructura del módulo:
mkdir -p src/modules/nuevo-modulo/{services,types}
mkdir -p src/components/nuevo-modulo
mkdir -p src/app/nuevo-modulo2. Implementar el service:
// src/modules/nuevo-modulo/services/nuevoModuloService.ts
export async function getAllItems() { /* ... */ }
export async function createItem(data: CreateItemRequest) { /* ... */ }
// Seguir patrón de usersService.ts3. Definir tipos:
// src/modules/nuevo-modulo/types/index.ts
export interface Item {
id: number;
name: string;
// ... más propiedades
}
export interface CreateItemRequest { /* ... */ }4. Crear componentes:
// src/components/nuevo-modulo/ItemCard.tsx
// src/components/nuevo-modulo/ItemForm.tsx
// src/components/nuevo-modulo/index.ts (barrel exports)5. Agregar ruta en App Router:
// src/app/nuevo-modulo/page.tsx
// src/app/nuevo-modulo/layout.tsxLos tipos TypeScript del backend están disponibles en src/types/api.ts:
User,Profile,Exercise,WeeklyRoutine- Enums:
Goal,ActivityLevel,DayOfWeek - DTOs para requests:
CreateUserDto,UpdateUserDto, etc.
http://localhost:3001
// Usando el proxy configurado (recomendado)
const response = await fetch('/api/users/1/routines');
const routines = await response.json();
// O directamente al backend
const response = await fetch('http://localhost:3001/users/1/routines');
const routines = await response.json();- usersService.ts -
getAllUsers()implementado como guía - exercisesService.ts -
getAllExercises()implementado como guía - routinesService.ts -
getAllRoutines()implementado como guía - profilesService.ts -
getProfileByUserId()implementado como guía - Manejo de errores con
ApiErrorincluido - Funciones comentadas para implementar por los estudiantes
- Tipado completo con TypeScript
# Desarrollo
npm run dev
# Build
npm run build
# Lint
npm run lint- Backend:
../fitness-app-backend/ - API Docs:
../fitness-app-backend/API_DOCUMENTATION.md - Base de Datos: SQLite con datos de prueba incluidos
- usersService.ts -
getAllUsers()como ejemplo funcional completo
Cada servicio tiene las siguientes funciones comentadas para implementar:
Users Service:
- ✅
getAllUsers(): Promise<User[]>- IMPLEMENTADA COMO GUÍA getUserById(id: number): Promise<User>createUser(data: CreateUserDto): Promise<User>updateUser(id: number, data: UpdateUserDto): Promise<User>deleteUser(id: number): Promise<void>getUserRoutines(id: number): Promise<WeeklyRoutine[]>filterUsers(users: User[], filters: UserFilters): User[]transformUserForDisplay(user: User): UserWithStats
Exercises Service:
getAllExercises(): Promise<Exercise[]>getExerciseById(id: number): Promise<Exercise>createExercise(data: CreateExerciseDto): Promise<Exercise>updateExercise(id: number, data: UpdateExerciseDto): Promise<Exercise>deleteExercise(id: number): Promise<void>filterExercises(exercises: Exercise[], searchTerm: string): Exercise[]groupExercisesByCategory(exercises: Exercise[]): Record<string, Exercise[]>
Routines Service:
getAllRoutines(filters?: { dayOfWeek?: string; completed?: boolean; userId?: number }): Promise<WeeklyRoutine[]>getRoutineById(id: number): Promise<WeeklyRoutine>createRoutine(data: CreateRoutineDto): Promise<WeeklyRoutine>updateRoutine(id: number, data: UpdateRoutineDto): Promise<WeeklyRoutine>deleteRoutine(id: number): Promise<void>completeRoutine(id: number, completed: boolean): Promise<WeeklyRoutine>addExerciseToRoutine(routineId: number, exerciseId: number): Promise<WeeklyRoutine>removeExerciseFromRoutine(routineId: number, exerciseId: number): Promise<WeeklyRoutine>getRoutinesByDay(routines: WeeklyRoutine[], dayOfWeek: string): WeeklyRoutine[]getCompletedRoutines(routines: WeeklyRoutine[]): WeeklyRoutine[]getPendingRoutines(routines: WeeklyRoutine[]): WeeklyRoutine[]calculateRoutineProgress(routines: WeeklyRoutine[]): { completed: number; total: number; percentage: number }
Profiles Service:
getProfileByUserId(userId: number): Promise<Profile>updateProfile(userId: number, data: UpdateProfileDto): Promise<Profile>getGoalDescription(goal: string): stringgetActivityLevelDescription(activityLevel: string): stringcalculateCalorieNeeds(weight: number, height: number, age: number, activityLevel: string, goal: string): number
Cada función debe seguir el patrón de getAll:
export async function functionName(params): Promise<ReturnType> {
try {
const response = await fetch(`${API_BASE_URL}/endpoint`, {
method: 'METHOD',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data), // si aplica
});
if (!response.ok) {
throw new ApiError(response.status, 'Error message');
}
return response.json();
} catch (error) {
console.error('Error en functionName:', error);
throw error;
}
}- Implementar funciones CRUD en los servicios (siguiendo el patrón de
getAll) - Implementar componentes UI específicos (reemplazar placeholders)
- Crear páginas adicionales según necesidades
- Integrar servicios con componentes
- Añadir manejo de estado global si es necesario
- Total: 27 estudiantes
- Grupos: 6 grupos de 4 estudiantes + 1 grupo de 3 estudiantes
- Total grupos: 7 grupos
Total de endpoints: 21
División: 3 endpoints por grupo
- Endpoints: ✅ IMPLEMENTADOS
POST /users- Crear usuario ✅GET /users- Listar usuarios ✅GET /users/:id- Obtener usuario ✅
- Servicios Backend: ✅ IMPLEMENTADOS
createUser(data: CreateUserDto): Promise<User>✅getAllUsers(): Promise<User[]>✅getUserById(id: number): Promise<User>✅
- Componentes Visuales: ✅ IMPLEMENTADOS
UserCard.tsx- Tarjeta de usuario ✅UserForm.tsx- Formulario de usuario ✅UserList.tsx- Lista de usuarios ✅
- Páginas:
⚠️ PARCIALMENTE IMPLEMENTADAS/users- Lista de usuarios ✅/users/create- Crear usuario ✅/users/[id]- Detalle de usuario ✅
- Endpoints: ✅ IMPLEMENTADOS
PATCH /users/:id- Actualizar usuario ✅DELETE /users/:id- Eliminar usuario ✅GET /users/:id/routines- Rutinas del usuario ✅
- Servicios Backend: ✅ IMPLEMENTADOS
updateUser(id: number, data: UpdateUserDto): Promise<User>✅deleteUser(id: number): Promise<void>✅getUserRoutines(id: number): Promise<WeeklyRoutine[]>✅
- Componentes Visuales: ✅ IMPLEMENTADOS
UserEditForm.tsx- Formulario de edición ✅UserRoutinesList.tsx- Lista de rutinas del usuario ✅UserActions.tsx- Acciones de usuario ✅
- Páginas: ✅IMPLEMENTADAS
/users/[id]/edit- Editar usuario ✅/users/[id]/routines- Rutinas del usuario ✅
- Endpoints: ❌ NO IMPLEMENTADOS
GET /profiles/:userId- Obtener perfil ❌PATCH /profiles/:userId- Actualizar perfil ❌POST /exercises- Crear ejercicio (1 endpoint extra) ❌
- Servicios Backend: ❌ NO IMPLEMENTADOS
getProfileByUserId(userId: number): Promise<Profile>❌updateProfile(userId: number, data: UpdateProfileDto): Promise<Profile>❌createExercise(data: CreateExerciseDto): Promise<Exercise>❌
- Componentes Visuales: ❌ NO IMPLEMENTADOS
ProfileCard.tsx- Tarjeta de perfil ❌ProfileForm.tsx- Formulario de perfil ❌ExerciseForm.tsx- Formulario de ejercicio ❌
- Páginas: ❌ NO IMPLEMENTADAS
/profiles/[userId]- Detalle de perfil ❌/profiles/[userId]/edit- Editar perfil ❌/exercises/create- Crear ejercicio ❌
- Endpoints: ✅ IMPLEMENTADOS
GET /exercises- Listar ejercicios ✅GET /exercises/:id- Obtener ejercicio ✅PATCH /exercises/:id- Actualizar ejercicio ✅
- Servicios Backend: ✅ IMPLEMENTADOS
getAllExercises(): Promise<Exercise[]>✅getExerciseById(id: number): Promise<Exercise>✅updateExercise(id: number, data: UpdateExerciseDto): Promise<Exercise>✅
- Componentes Visuales: ✅ IMPLEMENTADOS
ExerciseList.tsx- Lista de ejercicios ✅ExerciseCard.tsx- Tarjeta de ejercicio ✅ExerciseEditForm.tsx- Formulario de edición ✅
- Páginas: ✅ IMPLEMENTADAS
/exercises- Lista de ejercicios ✅/exercises/[id]- Detalle de ejercicio ✅/exercises/[id]/edit- Editar ejercicio ✅
- Endpoints: ✅ IMPLEMENTADOS
DELETE /exercises/:id- Eliminar ejercicio ✅POST /routines- Crear rutina ✅GET /routines- Listar rutinas ✅
- Servicios Backend: ✅ IMPLEMENTADOS
deleteExercise(id: number): Promise<void>✅createRoutine(data: CreateRoutineDto): Promise<WeeklyRoutine>✅getAllRoutines(filters?: { dayOfWeek?: string; completed?: boolean; userId?: number }): Promise<WeeklyRoutine[]>✅
- Componentes Visuales: ✅ IMPLEMENTADOS
ExerciseActions.tsx- Acciones de ejercicio ✅RoutineForm.tsx- Formulario de rutina ✅RoutineList.tsx- Lista de rutinas ✅
- Páginas: ✅ IMPLEMENTADAS
/exercises/[id]/delete- Eliminar ejercicio ✅/routines- Lista de rutinas ✅/routines/create- Crear rutina ✅
- Endpoints: ✅ IMPLEMENTADOS
GET /routines/:id- Obtener rutina ✅PATCH /routines/:id- Actualizar rutina ✅DELETE /routines/:id- Eliminar rutina ✅
- Servicios Backend: ✅ IMPLEMENTADOS
getRoutineById(id: number): Promise<WeeklyRoutine>✅updateRoutine(id: number, data: UpdateRoutineDto): Promise<WeeklyRoutine>✅deleteRoutine(id: number): Promise<void>✅
- Componentes Visuales: ✅ IMPLEMENTADOS
RoutineForm.tsx- Formulario de rutina ✅RoutineList.tsx- Lista de rutinas ✅
- Páginas: ❌ NO IMPLEMENTADAS
/routines/[id]/edit- Editar rutina ❌ (NO IMPLEMENTADA)/routines/[id]- Detalle de rutina ❌ (NO IMPLEMENTADA)/routines/[id]/delete- Eliminar rutina ❌ (NO IMPLEMENTADA)
- Endpoints: ✅ IMPLEMENTADOS
PATCH /routines/:id/complete- Completar rutina ✅POST /routines/:id/exercises- Agregar ejercicio ✅DELETE /routines/:id/exercises/:exerciseId- Quitar ejercicio ✅
- Servicios Backend: ✅ IMPLEMENTADOS
completeRoutine(id: number, completed: boolean): Promise<WeeklyRoutine>✅addExerciseToRoutine(routineId: number, exerciseId: number): Promise<WeeklyRoutine>✅removeExerciseFromRoutine(routineId: number, exerciseId: number): Promise<WeeklyRoutine>✅
- Componentes Visuales: ✅ IMPLEMENTADOS
RoutineCompletion.tsx- Completar rutina ✅ExerciseSelector.tsx- Selector de ejercicios ✅RoutineExerciseManager.tsx- Gestor de ejercicios ✅
- Páginas: ✅ IMPLEMENTADAS
/routines/[id]/complete- Completar rutina ✅/routines/[id]/exercises- Gestionar ejercicios ✅
- ✅ Implementación completa de servicios backend
- ✅ Implementación completa de componentes visuales
- ✅ Páginas con navegación correcta
- ✅ Manejo de errores y estados de carga
- ✅ Validaciones de formularios
- ✅ Responsive design
- ✅ Integración correcta entre backend y frontend
- ✅ Tipado completo con TypeScript
- ✅ Uso correcto del proxy
/api
- Código funcional del módulo asignado
- Componentes con diseño atractivo
- Páginas con navegación correcta
- Documentación del módulo
- Presentación del trabajo realizado
- Todos los grupos pueden trabajar independientemente en sus módulos
- Cada grupo tiene responsabilidad completa de su módulo (Backend + Frontend)
- No hay dependencias críticas entre grupos
- Al final del proyecto, todos los grupos deben coordinar para:
- Integrar sus módulos en la aplicación principal
- Asegurar consistencia visual
- Verificar que todas las rutas funcionen correctamente
Semilla creada el 9 de octubre de 2025