Skip to content

Frontend for basic-authy project. Built with React + Vite

Notifications You must be signed in to change notification settings

kubos777/basic-authy-front

Repository files navigation

Auth System Frontend

Aplicación web moderna de autenticación con MFA construida con React, TypeScript, Vite y Tailwind CSS.

Características

  • React 18: Framework UI moderno con hooks
  • TypeScript: Tipado estático para mayor seguridad
  • Tailwind CSS: Estilos utility-first responsive
  • Vite: Bundler ultra-rápido para desarrollo
  • React Router: Navegación SPA con rutas protegidas
  • React Hook Form: Manejo de formularios performante
  • Zod: Validación de esquemas TypeScript-first
  • Axios: Cliente HTTP con interceptores
  • MFA Support: Interfaz completa para autenticación de dos factores

Stack Tecnológico

  • React 18: Biblioteca UI con concurrent features
  • TypeScript: Superset de JavaScript con tipos
  • Vite: Build tool y dev server
  • Tailwind CSS: Framework CSS utility-first
  • React Router DOM: Enrutamiento client-side
  • React Hook Form: Librería de formularios
  • Zod: Validación y parsing de schemas
  • Axios: Cliente HTTP
  • ESLint + Prettier: Linting y formateo de código

Estructura del Proyecto

frontend/
├── public/
│   └── vite.svg              # Assets estáticos
├── src/
│   ├── components/           # Componentes reutilizables
│   ├── context/
│   │   └── AuthContext.tsx   # Context para autenticación global
│   ├── hooks/               # Custom hooks
│   ├── pages/
│   │   ├── LoginPage.tsx    # Página de login
│   │   ├── RegisterPage.tsx # Página de registro
│   │   ├── DashboardPage.tsx# Dashboard principal
│   │   └── MfaSetupPage.tsx # Configuración de MFA
│   ├── services/
│   │   └── api.ts           # Cliente API y servicios
│   ├── types/
│   │   └── auth.ts          # Tipos TypeScript
│   ├── utils/               # Utilidades
│   ├── App.tsx              # Componente principal
│   ├── main.tsx            # Punto de entrada
│   └── index.css           # Estilos globales
├── package.json
├── tsconfig.json
├── vite.config.ts
├── tailwind.config.js
└── eslint.config.js

Instalación

Requisitos

  • Node.js 18+
  • npm o yarn

Configuración

  1. Clonar el repositorio
git clone <tu-repo>
cd frontend
  1. Instalar dependencias
npm install
  1. Configurar variables de entorno
# Crear .env.local
VITE_API_URL=http://localhost:8000
  1. Ejecutar en desarrollo
npm run dev
  1. Abrir en navegador
http://localhost:5173

Scripts Disponibles

# Desarrollo
npm run dev

# Build de producción
npm run build

# Preview del build
npm run preview

# Linting
npm run lint
npm run lint:fix

# Formateo
npm run format
npm run format:check

Configuración de Desarrollo

Vite

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
  ],
  server: {
    port: 5173,
    host: true
  }
})

Tailwind CSS

// tailwind.config.js
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

TypeScript

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

Funcionalidades

Autenticación

  • Registro: Formulario con validación completa
  • Login: Soporte para login con y sin MFA
  • Logout: Limpieza de estado y tokens
  • Rutas Protegidas: Redirección automática según estado de auth

Multi-Factor Authentication (MFA)

  • Setup Wizard: Proceso guiado de configuración
  • QR Code: Generación y display para apps de autenticación
  • Verificación: Validación de códigos TOTP
  • Códigos de Respaldo: Display y descarga de códigos de emergencia

Manejo de Estado

// AuthContext.tsx
interface AuthContextType {
  user: User | null;
  token: string | null;
  isLoading: boolean;
  isAuthenticated: boolean;
  login: (token: string) => Promise<void>;
  logout: () => void;
  updateUser: (user: User) => void;
}

Validación de Formularios

// Ejemplo con Zod y React Hook Form
const loginSchema = z.object({
  email: z.string().email('Email inválido'),
  password: z.string().min(6, 'Mínimo 6 caracteres'),
  mfa_code: z.string().optional(),
});

const { register, handleSubmit, formState: { errors } } = useForm<LoginFormData>({
  resolver: zodResolver(loginSchema),
});

Rutas

  • / - Redirección al dashboard o login
  • /login - Página de inicio de sesión
  • /register - Página de registro
  • /dashboard - Dashboard principal (protegida)
  • /mfa/setup - Configuración de MFA (protegida)

Componentes Principales

AuthProvider

Proveedor de contexto global para el estado de autenticación:

<AuthProvider>
  <App />
</AuthProvider>

ProtectedRoute

Componente para proteger rutas que requieren autenticación:

<ProtectedRoute>
  <DashboardPage />
</ProtectedRoute>

Formularios

Todos los formularios utilizan:

  • React Hook Form para manejo de estado
  • Zod para validación
  • Tailwind para estilos
  • Manejo de errores consistente

Estilos y UI

Tailwind CSS

Utility classes para desarrollo rápido:

<button className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md transition-colors">
  Botón
</button>

Componentes Responsive

Diseño mobile-first con breakpoints:

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">

Estados de Carga

Indicadores visuales para mejor UX:

{isLoading ? (
  <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600"></div>
) : (
  'Continuar'
)}

API Integration

Cliente HTTP

const api = axios.create({
  baseURL: 'http://localhost:8000',
  headers: {
    'Content-Type': 'application/json',
  },
});

// Interceptor para tokens automáticos
api.interceptors.request.use((config) => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

Servicios

export const authService = {
  register: async (data: RegisterData): Promise<User> => {
    const response = await api.post('/auth/register', data);
    return response.data;
  },
  
  login: async (credentials: LoginCredentials): Promise<AuthResponse> => {
    const response = await api.post('/auth/login', credentials);
    return response.data;
  }
};

Build y Deploy

Build de Producción

npm run build

Genera archivos optimizados en /dist

Deploy

Netlify

# netlify.toml
[build]
  publish = "dist"
  command = "npm run build"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Vercel

{
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}

Docker

FROM node:18-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Testing

Jest + Testing Library

npm install -D @testing-library/react @testing-library/jest-dom jest
// Ejemplo de test
import { render, screen } from '@testing-library/react';
import LoginPage from './LoginPage';

test('renders login form', () => {
  render(<LoginPage />);
  expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
});

Mejores Prácticas

Estructura de Componentes

interface Props {
  title: string;
  children: React.ReactNode;
}

const Component: React.FC<Props> = ({ title, children }) => {
  return (
    <div>
      <h1>{title}</h1>
      {children}
    </div>
  );
};

export default Component;

Custom Hooks

const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within AuthProvider');
  }
  return context;
};

Error Handling

try {
  await authService.login(credentials);
} catch (error) {
  if (error.response?.status === 401) {
    setError('Credenciales inválidas');
  } else {
    setError('Error de conexión');
  }
}

Contribución

  1. Fork el proyecto
  2. Crear branch para feature (git checkout -b feature/nueva-feature)
  3. Commit cambios (git commit -am 'Agregar nueva feature')
  4. Push al branch (git push origin feature/nueva-feature)
  5. Crear Pull Request

Licencia

Este proyecto está bajo la licencia MIT. Ver LICENSE para más detalles.

Autor

Jorge Chávez - kubos777

About

Frontend for basic-authy project. Built with React + Vite

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published