13 KiB
13 KiB
🛠️ Guía de Desarrollo - Karibeo
Configuración del Entorno
Requisitos del Sistema
- Node.js: >= 18.0.0 (recomendado 20.x LTS)
- npm: >= 9.0.0 o yarn: >= 1.22.0
- Git: >= 2.30.0
- Editor: VSCode (recomendado) con extensiones
Extensiones VSCode Recomendadas
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"bradlc.vscode-tailwindcss",
"formulahendry.auto-rename-tag",
"christian-kohler.path-intellisense",
"dsznajder.es7-react-js-snippets",
"mikestead.dotenv"
]
}
Setup Inicial
1. Clonar el Repositorio
git clone https://github.com/tu-usuario/karibeo.git
cd karibeo
2. Instalar Dependencias
npm install
# o
yarn install
3. Configurar Variables de Entorno
Crear archivo .env en la raíz:
# API Backend
VITE_API_BASE_URL=https://karibeo.lesoluciones.net:8443/api/v1
# Google Maps
VITE_GOOGLE_MAPS_API_KEY=your_google_maps_api_key
# Stripe (Pagos)
VITE_STRIPE_PUBLIC_KEY=pk_test_...
# Analytics (Opcional)
VITE_GA_ID=G-XXXXXXXXXX
# Sentry (Error Tracking - Opcional)
VITE_SENTRY_DSN=https://...@sentry.io/...
# Feature Flags (Opcional)
VITE_ENABLE_ANALYTICS=true
VITE_ENABLE_PWA=false
4. Iniciar Servidor de Desarrollo
npm run dev
La aplicación estará disponible en: http://localhost:5173
Estructura de Carpetas Detallada
karibeo/
├── .vscode/ # Configuración de VSCode
│ ├── settings.json # Configuraciones del workspace
│ └── extensions.json # Extensiones recomendadas
│
├── docs/ # Documentación
│ ├── API.md # Documentación de API
│ ├── ARCHITECTURE.md # Arquitectura del sistema
│ └── DEVELOPMENT.md # Esta guía
│
├── public/ # Assets estáticos
│ ├── favicon.ico
│ ├── manifest.json # PWA manifest
│ └── robots.txt
│
├── src/
│ ├── assets/ # Recursos (imágenes, fonts)
│ │ ├── images/
│ │ └── fonts/
│ │
│ ├── components/ # Componentes React
│ │ ├── ui/ # Componentes base (shadcn)
│ │ │ ├── button.tsx
│ │ │ ├── input.tsx
│ │ │ └── ...
│ │ │
│ │ ├── admin/ # Componentes de admin
│ │ │ ├── ConfigTab.tsx
│ │ │ ├── UsersTab.tsx
│ │ │ └── ...
│ │ │
│ │ ├── hotel/ # Componentes hoteleros
│ │ ├── restaurant/ # Componentes de restaurante
│ │ ├── roles/ # Sistema de roles
│ │ ├── security/ # Componentes de seguridad
│ │ └── shared/ # Componentes compartidos
│ │
│ ├── contexts/ # React Contexts
│ │ ├── AuthContext.tsx
│ │ ├── CartContext.tsx
│ │ ├── CurrencyContext.tsx
│ │ └── LanguageContext.tsx
│ │
│ ├── hooks/ # Custom Hooks
│ │ ├── useAdminData.ts
│ │ ├── useBooking.ts
│ │ ├── useChannelManager.ts
│ │ └── ...
│ │
│ ├── lib/ # Utilidades y helpers
│ │ ├── utils.ts # Funciones utilitarias
│ │ └── validation.ts # Schemas de validación
│ │
│ ├── pages/ # Páginas/Rutas
│ │ ├── dashboard/ # Panel de control
│ │ │ ├── AdminDashboard.tsx
│ │ │ ├── Dashboard.tsx
│ │ │ └── ...
│ │ │
│ │ ├── Index.tsx # Landing page
│ │ ├── SignIn.tsx # Login
│ │ └── SignUp.tsx # Registro
│ │
│ ├── services/ # Servicios API
│ │ ├── adminApi.ts
│ │ ├── emergencyApi.ts
│ │ └── ...
│ │
│ ├── types/ # TypeScript types
│ │ ├── index.ts
│ │ └── roles.ts
│ │
│ ├── i18n/ # Internacionalización
│ │ ├── en.ts
│ │ └── es.ts
│ │
│ ├── App.tsx # Componente principal
│ ├── main.tsx # Entry point
│ └── index.css # Estilos globales
│
├── .eslintrc.js # Configuración ESLint
├── .prettierrc # Configuración Prettier
├── tailwind.config.ts # Configuración Tailwind
├── tsconfig.json # Configuración TypeScript
├── vite.config.ts # Configuración Vite
└── package.json # Dependencias y scripts
Convenciones de Código
Nomenclatura
Archivos
// PascalCase para componentes
UserProfile.tsx
AdminDashboard.tsx
// camelCase para utilidades y hooks
useAuth.ts
formatCurrency.ts
// kebab-case para estilos
user-profile.css
Variables y Funciones
// camelCase para variables y funciones
const userName = "John";
function getUserData() {}
// PascalCase para componentes y clases
const UserCard = () => {};
class ApiClient {}
// UPPER_SNAKE_CASE para constantes
const MAX_RETRY_ATTEMPTS = 3;
const API_BASE_URL = "https://...";
Interfaces y Types
// PascalCase con prefijo "I" opcional
interface UserProfile {}
interface IUserProfile {} // alternativa
type UserRole = 'admin' | 'user';
Formato de Código
Imports
// 1. Imports de librerías externas
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
// 2. Imports de componentes UI
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
// 3. Imports de componentes propios
import { UserCard } from '@/components/UserCard';
// 4. Imports de hooks y contexts
import { useAuth } from '@/contexts/AuthContext';
import { useAdminData } from '@/hooks/useAdminData';
// 5. Imports de utilidades y tipos
import { cn } from '@/lib/utils';
import type { User } from '@/types';
// 6. Imports de assets
import logo from '@/assets/logo.png';
// 7. Imports de estilos
import './styles.css';
Componentes Funcionales
// Buena práctica
interface UserCardProps {
user: User;
onEdit?: (id: string) => void;
className?: string;
}
export const UserCard: React.FC<UserCardProps> = ({
user,
onEdit,
className
}) => {
const [isExpanded, setIsExpanded] = useState(false);
useEffect(() => {
// Effect logic
}, []);
const handleClick = () => {
setIsExpanded(!isExpanded);
};
return (
<div className={cn("card", className)}>
{/* JSX */}
</div>
);
};
TypeScript
Tipado Estricto
// ✅ Bueno
interface User {
id: string;
name: string;
email: string;
}
const getUser = (id: string): Promise<User> => {
return api.get<User>(`/users/${id}`);
};
// ❌ Evitar
const getUser = (id: any): any => {
return api.get(`/users/${id}`);
};
Usar Interfaces sobre Types
// ✅ Preferido para objetos
interface UserProfile {
name: string;
age: number;
}
// ✅ Usar type para unions, intersections
type UserRole = 'admin' | 'user' | 'guest';
type ExtendedUser = UserProfile & { role: UserRole };
React Patterns
Hooks
// Custom hook
export const useUser = (userId: string) => {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetchUser(userId)
.then(setUser)
.catch(setError)
.finally(() => setLoading(false));
}, [userId]);
return { user, loading, error };
};
Memoization
// useMemo para cálculos costosos
const expensiveValue = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);
// useCallback para funciones
const handleSubmit = useCallback((data: FormData) => {
submitForm(data);
}, []);
// memo para componentes
export const UserCard = memo(({ user }: Props) => {
return <div>{user.name}</div>;
});
Tailwind CSS
Ordenamiento de Clases
// Orden recomendado:
// 1. Layout (display, position)
// 2. Box model (width, height, margin, padding)
// 3. Typography
// 4. Visual (background, border, shadow)
// 5. Misc (cursor, transform, transition)
<div className="
flex items-center justify-between
w-full h-20 p-4
text-lg font-semibold
bg-white border border-gray-200 rounded-lg shadow-md
hover:shadow-lg transition-shadow
">
Content
</div>
Usar cn() para Clases Condicionales
import { cn } from '@/lib/utils';
<Button
className={cn(
"base-class",
isActive && "active-class",
isDisabled && "disabled-class",
customClass
)}
/>
Testing
Jest + React Testing Library
Setup
npm install --save-dev @testing-library/react @testing-library/jest-dom jest
Escribir Tests
// UserCard.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { UserCard } from './UserCard';
describe('UserCard', () => {
const mockUser = {
id: '1',
name: 'John Doe',
email: 'john@example.com'
};
it('renders user information', () => {
render(<UserCard user={mockUser} />);
expect(screen.getByText('John Doe')).toBeInTheDocument();
});
it('calls onEdit when edit button is clicked', () => {
const onEdit = jest.fn();
render(<UserCard user={mockUser} onEdit={onEdit} />);
fireEvent.click(screen.getByRole('button', { name: /edit/i }));
expect(onEdit).toHaveBeenCalledWith('1');
});
});
Ejecutar Tests
npm run test # Ejecutar todos los tests
npm run test:watch # Watch mode
npm run test:coverage # Con coverage
Debugging
React Developer Tools
Instalar extensión de navegador: React Developer Tools
VSCode Debugging
Crear .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/src"
}
]
}
Console Logs Útiles
// Debug con contexto
console.log('🔍 User data:', user);
console.error('❌ Error:', error);
console.warn('⚠️ Warning:', warning);
// Grupos
console.group('API Request');
console.log('URL:', url);
console.log('Method:', method);
console.groupEnd();
// Tiempo de ejecución
console.time('fetchData');
await fetchData();
console.timeEnd('fetchData');
Performance
Optimizaciones
Code Splitting
// Lazy loading de componentes
const AdminDashboard = lazy(() => import('./pages/AdminDashboard'));
<Suspense fallback={<LoadingSpinner />}>
<AdminDashboard />
</Suspense>
Bundle Analysis
npm run build
npm run analyze
Lighthouse CI
npm install -g @lhci/cli
lhci autorun
Git Workflow
Branches
main # Producción
develop # Desarrollo
feature/xxx # Nuevas características
bugfix/xxx # Corrección de bugs
hotfix/xxx # Hotfixes urgentes
Commits
Usar convención de commits semánticos:
feat: add user authentication
fix: resolve booking calculation bug
docs: update API documentation
style: format code with prettier
refactor: reorganize admin components
test: add tests for UserCard component
chore: update dependencies
Pull Requests
- Crear branch desde
develop - Hacer cambios y commits
- Push al repositorio remoto
- Crear PR hacia
develop - Code review
- Merge después de aprobación
Build y Deploy
Build Local
npm run build
Archivos generados en /dist
Preview Build
npm run preview
Deploy a Lovable
- Commit y push cambios
- Ir a proyecto en Lovable
- Cambios se sincronizarán automáticamente
Deploy Manual
# Vercel
vercel deploy
# Netlify
netlify deploy --prod
# AWS S3
aws s3 sync dist/ s3://your-bucket/
Troubleshooting
Problemas Comunes
Puerto 5173 en uso
# Cambiar puerto en vite.config.ts
export default defineConfig({
server: {
port: 3000
}
});
Problemas con node_modules
rm -rf node_modules package-lock.json
npm install
Errores de TypeScript
# Limpiar cache
rm -rf node_modules/.vite
npm run dev
Build falla
# Verificar errores
npm run build 2>&1 | tee build.log
# Limpiar y rebuild
rm -rf dist
npm run build
Resources
Documentación Oficial
Comunidad
Última actualización: 2025-01-12