From 12442358203475191ea990907b43a905856362c2 Mon Sep 17 00:00:00 2001 From: Ricardo Monla Date: Wed, 3 Jun 2026 16:19:37 -0300 Subject: [PATCH] Fix: auth en NGINX, Tailwind local, soporte teclado y layout desktop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Auth movida a NGINX (Basic Auth en htpasswd) para que fetch() del browser incluya credenciales automáticamente — resuelve categorías sin cargar y POST fallido - Tailwind CDN descargado al build del Docker y servido localmente — elimina dependencia externa en cada carga de página - Soporte de teclado físico en add.html (números, punto/coma, Backspace, Enter) - Layout centrado en desktop con max-w-md mx-auto en las tres páginas - Eliminada imagen decorativa externa y links de fonts duplicados Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 3 +++ Dockerfile | 12 ++++++++++-- docker-compose.yml | 1 + docker/entrypoint.sh | 6 ++++++ docker/htpasswd | 1 + docker/nginx.conf | 5 +++++ pagos/add.html | 12 +++++------- pagos/historial.html | 6 ++++-- pagos/index.html | 21 ++++++++++----------- pagos/js/add.js | 42 ++++++++++++++++++++++++++++-------------- 10 files changed, 73 insertions(+), 36 deletions(-) create mode 100644 docker/entrypoint.sh create mode 100644 docker/htpasswd diff --git a/.gitignore b/.gitignore index 8012272..2b5a589 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ # Credenciales locales — nunca commitear pagos/api/config.php + +# Assets generados (se descargan al hacer docker compose build) +pagos/js/tailwind.cdn.js diff --git a/Dockerfile b/Dockerfile index 56a87ea..3b28c2b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,14 @@ FROM php:8.2-fpm-alpine -RUN apk add --no-cache sqlite sqlite-dev \ - && docker-php-ext-install pdo pdo_sqlite +RUN apk add --no-cache sqlite sqlite-dev curl \ + && docker-php-ext-install pdo pdo_sqlite \ + && curl -sL "https://cdn.tailwindcss.com?plugins=forms,container-queries" \ + -o /tmp/tailwind.cdn.js WORKDIR /var/www/html + +COPY docker/entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["php-fpm"] diff --git a/docker-compose.yml b/docker-compose.yml index 5bb0267..87578d5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,7 @@ services: volumes: - ./pagos:/var/www/html - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf + - ./docker/htpasswd:/etc/nginx/.htpasswd:ro depends_on: - app networks: diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100644 index 0000000..da3c48d --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# Copiar tailwind.cdn.js al directorio servido si no existe +if [ ! -f /var/www/html/js/tailwind.cdn.js ]; then + cp /tmp/tailwind.cdn.js /var/www/html/js/tailwind.cdn.js +fi +exec "$@" diff --git a/docker/htpasswd b/docker/htpasswd new file mode 100644 index 0000000..f12f6cc --- /dev/null +++ b/docker/htpasswd @@ -0,0 +1 @@ +root:$apr1$69HFcTHn$9hHiieirPfFe3M.lo87O21 diff --git a/docker/nginx.conf b/docker/nginx.conf index 544634f..de7c45a 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -5,6 +5,9 @@ server { resolver 127.0.0.11 valid=10s; + auth_basic "Quiet Wealth"; + auth_basic_user_file /etc/nginx/.htpasswd; + location / { try_files $uri $uri/ =404; } @@ -15,6 +18,8 @@ server { fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PHP_AUTH_USER $remote_user; + fastcgi_param PHP_AUTH_PW $http_authorization; } location ~ /db/ { diff --git a/pagos/add.html b/pagos/add.html index 0ab1a60..5311090 100644 --- a/pagos/add.html +++ b/pagos/add.html @@ -4,10 +4,9 @@ Nuevo Movimiento - Sanctuary - - - - + + + \ No newline at end of file diff --git a/pagos/historial.html b/pagos/historial.html index dce6633..6c946e6 100644 --- a/pagos/historial.html +++ b/pagos/historial.html @@ -4,7 +4,7 @@ Historial - Quiet Wealth - + diff --git a/pagos/index.html b/pagos/index.html index c6ff7c5..209e75d 100644 --- a/pagos/index.html +++ b/pagos/index.html @@ -3,10 +3,9 @@ - - - - + + + \ No newline at end of file diff --git a/pagos/js/add.js b/pagos/js/add.js index aeefa6e..f609b34 100644 --- a/pagos/js/add.js +++ b/pagos/js/add.js @@ -43,25 +43,39 @@ document.addEventListener('DOMContentLoaded', () => { btnGasto.addEventListener('click', () => { selectedTipo = 'gasto'; updateTipoUI(); }); btnIngreso.addEventListener('click', () => { selectedTipo = 'ingreso'; updateTipoUI(); }); - // Numpad logic + function applyInput(val) { + if (val === 'backspace') { + currentMonto = currentMonto.slice(0, -1); + if (currentMonto === '') currentMonto = "0"; + } else if (/^[0-9]$/.test(val)) { + if (currentMonto === "0") { + currentMonto = val; + } else { + currentMonto += val; + } + } else if (val === '.') { + if (!currentMonto.includes('.')) currentMonto += '.'; + } + montoEl.textContent = currentMonto; + } + + // Numpad táctil numpad.addEventListener('click', (e) => { const btn = e.target.closest('button'); if (!btn) return; - - const val = btn.textContent.trim() || btn.innerText.trim(); - - if (val === 'backspace' || btn.querySelector('[data-icon="backspace"]')) { - currentMonto = currentMonto.slice(0, -1); - if (currentMonto === '') currentMonto = "0"; + if (btn.querySelector('[data-icon="backspace"]')) { + applyInput('backspace'); } else { - if (currentMonto === "0" && val !== ".") { - currentMonto = val; - } else { - if (val === "." && currentMonto.includes(".")) return; - currentMonto += val; - } + applyInput(btn.textContent.trim()); } - montoEl.textContent = currentMonto; + }); + + // Teclado físico (desktop) + document.addEventListener('keydown', (e) => { + if (e.key >= '0' && e.key <= '9') applyInput(e.key); + else if (e.key === '.' || e.key === ',') applyInput('.'); + else if (e.key === 'Backspace') applyInput('backspace'); + else if (e.key === 'Enter') btnSave.click(); }); // Guardar Movimiento