Skip to content

Repository files navigation

ReadOn

Visitar ReadOn

ReadOn

Laravel PHP PostgreSQL SCSS Vite Docker Tests

Aplicación web para registrar, seguir y reseñar libros, inspirada en Letterboxd pero orientada a lecturas. Proyecto personal de portfolio, enfocado en una arquitectura clara, UX cuidada y un stack sencillo y mantenible.


Dark (Mocha) Light (Latte)
Homepage dark Homepage light
Búsqueda Detalle de libro
Búsqueda Detalle
Mis lecturas Perfil
Mis lecturas Perfil

🛠️ Stack

Capa Tecnología
Backend Laravel 11 + Blade
Base de datos PostgreSQL
Frontend SCSS + Vite (BEM, sin Tailwind)
Temas Catppuccin Mocha / Latte
Entorno DDEV · Docker · PHP 8.2 · nginx-fpm
Tests PHPUnit · SQLite in-memory

🚀 Puesta en marcha (local)

Requisitos: DDEV

git clone git@github.com:CristianSG2/ReadOn.git
cd ReadOn
ddev start
ddev composer install
ddev npm install
ddev artisan key:generate

Añadir en .env:

GOOGLE_BOOKS_API_KEY=tu_api_key
ddev artisan migrate
ddev npm run build
ddev launch

Datos de demo (opcional)

ddev artisan db:seed

Crea un usuario demo con libros de ejemplo. Requiere GOOGLE_BOOKS_API_KEY configurada en .env.

  • Email: demo@readon.app
  • Contraseña: password

🔐 Autenticación

Autenticación manual (sin Breeze):

  • Login, registro y logout propios
  • Middleware auth en rutas protegidas
  • CSRF, regeneración de sesión y throttle de login
  • Redirección post-login a /me

📚 Logs de lectura

  • Búsqueda vía Google Books API con resultados filtrados por idioma (español primero, inglés después) y sin portada
  • Guardado de libros en lista personal sin recarga de página
  • Estados: Wishlist, Leyendo, Leído, Abandonado
  • Rating de 0.5 a 5 estrellas (escala en medias estrellas) y reseñas
  • Edición y borrado de registros propios sin recarga de página

Autosave e inline saves

Todas las acciones sobre un registro se realizan sin recarga de página:

  • Rating y estado: se guardan automáticamente via fetch PATCH al interactuar
  • Reseña: guardado y eliminación via fetch, con actualización del DOM en tiempo real
  • Guardar libro: desde el detalle, via fetch sin redirección
  • Eliminar registro: con confirmación nativa y fade-out de la card en el DOM

El feedback de cada acción se muestra mediante toast notifications (esquina inferior derecha), consistentes en toda la app y adaptadas al tema activo.

Portadas y skeleton loader

Sistema de fallback en tres niveles:

  1. Thumbnail de Google Books (forzado a HTTPS para evitar mixed-content)
  2. Open Library por ISBN (/b/isbn/{ISBN}-L.jpg) si Google Books no devuelve portada
  3. Placeholder SVG local (/images/no-cover.svg) si ninguna fuente tiene imagen

Mientras cargan las portadas se muestra un skeleton loader con animación shimmer que respeta el tema activo (Mocha/Latte). El ISBN se extrae de industryIdentifiers en la respuesta de Google Books y se persiste en reading_logs.


👤 Perfil

Vista /me con:

  • Estadísticas de lectura (total, wishlist, leyendo, leído, abandonado)
  • Media de ratings
  • Últimos 5 registros, clicables — enlazan al detalle del libro
  • Acceso al listado completo

🎨 UX y temas

Sistema de temas

Paleta Catppuccin con roles de color diferenciados:

Token Mocha (dark) Latte (light) Rol
--accent Lavender #b4befe Rosewater #dc8a78 Links, nav activo
--primary Mauve #cba6f7 Rosewater #dc8a78 Botones CTA
--accent-2 Mauve #cba6f7 Flamingo #dd7878 Hover, estados secundarios

El switch dark/light persiste entre sesiones vía localStorage. El tema se aplica antes del primer render (script inline en <head>) para evitar flash. Ningún color está hardcodeado fuera del bloque de tokens.

Animaciones y transiciones

  • Transiciones de página: fade-out al salir, fade-in al entrar
  • Cards: animación fadeInUp escalonada al cargar la página
  • Skeleton loader: shimmer animado en portadas mientras cargan, respetando el tema
  • Toast notifications: sistema unificado de feedback para todas las acciones

Logo

Componente Blade reutilizable (<x-logo size="sm|md|lg" />): icono SVG bookmark + wordmark "ReadOn" en tres tamaños, todo via tokens CSS.

Homepage

Página standalone con:

  • Topbar con logo, toggle dark/light y CTA de acceso
  • Hero a dos columnas: tagline + CTAs / estantería SVG decorativa con colores de la paleta activa
  • Estado autenticado: muestra el nombre del usuario y enlaza a /books

Vistas de autenticación

Login y registro con el mismo layout de dos columnas que la homepage: formulario a la izquierda y estantería SVG decorativa a la derecha. Los botones comparten los mismos tokens de color que el resto de la app.


📌 Estado del proyecto

v1.1.1 — desplegado en producción: 🌐 readon.cristiansg.dev

  • Flujo de lectura operativo de extremo a extremo
  • Inline saves: todas las acciones sin recarga de página
  • Toast notifications unificadas en toda la app
  • Skeleton loader en búsqueda y Mis lecturas
  • Animaciones de entrada y transiciones de página
  • Sistema de portadas con fallback multinivel
  • Homepage rediseñada con visual SVG adaptativo
  • Tokens Catppuccin con roles diferenciados por función
  • Logo como componente reutilizable
  • SCSS limpio: sin duplicados, sin código muerto, sin utilidades inline
  • 16 Feature tests (auth, reading logs, perfil) — SQLite en memoria
  • Búsqueda filtrada por idioma (ES primero, EN después) y sin resultados sin portada

Tests

ddev php artisan test

Configurados con SQLite en memoria (phpunit.xml). Cubren auth, logs de lectura y perfil — 16 tests, 42 assertions.


🧰 Scripts útiles

ddev npm run dev
ddev npm run build
ddev artisan optimize:clear

Licencia MIT

About

Personal book-tracking app — Laravel 11 · Blade · PostgreSQL · Vite (SCSS) · DDEV/Docker

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages