Skip to content

Repository files navigation

APROS · Lista de Tareas

Aplicación de una sola página (SPA) en React 19 + Vite. Gestiona una lista de tareas con persistencia local, métricas en vivo y la identidad visual de APROS.

React Vite Tests Deploy Build

Vista de escritorio

Progreso e interacción Vista móvil
Progreso recalculado al completar Responsive (390px)

Capturas generadas con Playwright (npx playwright test screenshots --project=chromium).

Autor: Juan Ordoñez.

1. Resumen de la aplicación

SPA cliente, sin backend. Las tareas se crean, completan y eliminan en el navegador y se persisten en localStorage, de modo que sobreviven a recargas. El estado base arranca con tres tareas provistas por el requerimiento. El build de producción sale sin warnings (≈196 kB JS / 62 kB gzip, ≈5 kB CSS).

Funcionalidad:

  • Alta de tareas con validación (no acepta texto vacío ni solo espacios).
  • Toggle de completado con estado visual (tachado + checkbox de marca).
  • Borrado por tarea.
  • Panel de métricas: completadas / total y barra de progreso.

2. Arquitectura de software

Separación estricta de responsabilidades. Toda la lógica de negocio y la persistencia viven en un Custom Hook, src/hooks/useTodos.js. Los componentes de src/components/ son funcionales y solo se ocupan de presentación: reciben datos y callbacks por props y no tocan localStorage ni mantienen estado de dominio.

useTodos()  ──> { todos, addTodo, toggleTodo, deleteTodo, totalTodos, completedTodos }
   │
   ├─ TodoApp        (contenedor; invoca el hook y reparte props)
   ├─ TodoForm       (input controlado + validación .trim())
   ├─ TodoStats      (métricas + barra de progreso)
   └─ TodoList ─ TodoItem  (render de la colección / tarjeta individual)

Mutaciones inmutables: addTodo usa spread, toggleTodo reemplaza solo el objeto afectado ({ ...t, completada: !t.completada }) y deleteTodo filtra a un arreglo nuevo. Nunca se muta el estado anterior.

Rendimiento:

  • Lazy initialization de useState(cargarEstadoInicial): la lectura de localStorage ocurre una sola vez, no en cada render.
  • useMemo para completedTodos, que solo se recalcula cuando cambia todos.
  • Persistencia vía un useEffect dependiente de todos; lectura y escritura envueltas en try/catch para tolerar modo privado o cuota agotada sin romper la app. Si el JSON guardado está corrupto, cae a los datos iniciales.

IDs derivados de Math.max(...ids) + 1 en lugar de length + 1, para no colisionar tras eliminar.

3. Ecosistema de testing (QA Automation)

Suite E2E con Playwright sobre Chromium y WebKit (10 ejecuciones: 5 specs × 2 motores). El ciclo de vida del servidor lo gestiona la propiedad webServer de playwright.config.js: levanta npm run dev antes de las pruebas y lo apaga al terminar, con reuseExistingServer: !process.env.CI. Cada test corre en un contexto aislado, así que localStorage arranca vacío y la carga inicial es determinista.

# Spec Qué certifica
1 Carga inicial Renderiza las 3 tareas iniciales y métricas 1 / 3 (33%)
2 Inserción Agrega tarea, limpia el input controlado e incrementa el total
3 Toggle Completar recalcula métricas en vivo (1 → 2, 67%) y aplica el tachado
4 Borrado Elimina el nodo del DOM y reduce el total
5 Persistencia Tras page.reload() la tarea agregada sigue presente (hook ↔ localStorage)
npm run test:e2e
# 10 passed

4. Instalación y desarrollo local

Requiere Node 18+.

git clone https://github.com/Dabji/apros-react-todo.git
cd apros-react-todo
npm install

npm run dev            # servidor de desarrollo (http://localhost:5173/apros-react-todo/)

Pruebas:

npx playwright install chromium webkit   # primera vez
npm run test:e2e                          # corre la suite completa
npx playwright show-report                # informe HTML del último run

5. Pipeline de CI/CD (GitHub Pages)

El despliegue se automatiza con gh-pages:

"predeploy": "npm run build",   // compila a /dist
"deploy": "gh-pages -d dist"    // publica /dist en la rama gh-pages
npm run deploy

predeploy corre automáticamente antes de deploy (convención de npm). El comando compila el proyecto y sube el contenido de dist/ a la rama remota gh-pages. Para que las rutas de los assets resuelvan en el subdirectorio del repo, vite.config.js fija base: '/apros-react-todo/'.

Tras el primer npm run deploy, activar GitHub Pages en Settings → Pages → Source: deploy from branch → gh-pages / root. URL resultante:

https://dabji.github.io/apros-react-todo/

6. Roadmap

  • TypeScript: tipar Todo y la firma del hook para detectar errores en compilación.
  • Sub-tareas y prioridades: extender el modelo con parentId y un campo prioridad, más filtros/orden en la UI.
  • GitHub Actions: workflow que corra npm run test:e2e en cada PR y publique a gh-pages al hacer merge en main.
  • Edición inline del texto de una tarea y deshacer borrado.
  • Migración del store a useReducer o Zustand si el estado crece.

7. Estructura

apros-react-todo/
├── public/favicon.svg
├── src/
│   ├── components/   TodoApp · TodoForm · TodoList · TodoItem · TodoStats
│   ├── hooks/        useTodos.js
│   ├── styles/       app.css
│   ├── App.jsx · main.jsx · index.css
├── tests/            todo.spec.js · screenshots.spec.js
├── docs/screenshots/
├── playwright.config.js
├── vite.config.js
└── package.json

About

App To-Do (React 19 + Vite). Diseño modular, lógica con Custom Hooks y persistencia en LocalStorage. Incluye suite E2E (Playwright) y despliegue CI/CD automático.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages