Fix: auth en NGINX, Tailwind local, soporte teclado y layout desktop
- 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1db200343d
commit
1244235820
@@ -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
|
||||
|
||||
+10
-2
@@ -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"]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 "$@"
|
||||
@@ -0,0 +1 @@
|
||||
root:$apr1$69HFcTHn$9hHiieirPfFe3M.lo87O21
|
||||
@@ -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/ {
|
||||
|
||||
+5
-7
@@ -4,10 +4,9 @@
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Nuevo Movimiento - Sanctuary</title>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@300;400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script src="js/tailwind.cdn.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@300;400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
@@ -98,6 +97,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background text-on-background min-h-screen flex flex-col">
|
||||
<div class="max-w-md mx-auto w-full flex flex-col flex-1 relative">
|
||||
<!-- Top AppBar - Transactional Context (Shell Suppressed per mandate) -->
|
||||
<header class="bg-[#f8faf9] dark:bg-[#191c1c] w-full top-0 px-6 py-4 flex justify-between items-center bg-transparent">
|
||||
<div class="flex items-center gap-4">
|
||||
@@ -174,9 +174,7 @@
|
||||
<span class="material-symbols-outlined" data-icon="check_circle">check_circle</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Background Decorative Image (Sanctuary Aesthetic) -->
|
||||
<div class="fixed top-0 right-0 -z-10 opacity-10">
|
||||
<img alt="Calm plant leaves" class="w-64 h-64 object-cover rounded-full blur-xl translate-x-20 -translate-y-20" data-alt="Close-up of minimalist green tropical leaves with soft natural light and subtle shadows on a neutral background" src="https://lh3.googleusercontent.com/aida-public/AB6AXuD2h_FlCe-zmCdWpoDHshmlKT5cXI45RMNZ5-AgxCqZYUPAm3glpQE_wwgbqJ2nxoYSqTenbalJ4bQQBYGIiBfP5wtSkQt6hOJ-Gtl_cifGTAktK43DvjfdfiHDniAMFOJUG0cJmjTrd3nISnFPn-xNsg3CSTGPMIIW_n5H7HSUQcYBeDxWje7Wu8zDxapTTpMfci3Y4IeXwn-Wq94lmbuXPYPbpNtL19_R_6JNyujOMerXEhtUQm5nUIjIEG27anBV5TGHfaZabw"/>
|
||||
</div>
|
||||
<script src="js/ui.js"></script>
|
||||
<script src="js/add.js"></script>
|
||||
</body></html>
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Historial - Quiet Wealth</title>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script src="js/tailwind.cdn.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script id="tailwind-config">
|
||||
@@ -82,6 +82,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background text-on-background min-h-screen pb-24">
|
||||
<div class="max-w-md mx-auto relative">
|
||||
|
||||
<!-- Header -->
|
||||
<header class="bg-[#f8faf9] sticky top-0 z-40 px-6 py-4 flex items-center gap-4">
|
||||
@@ -108,13 +109,14 @@
|
||||
</main>
|
||||
|
||||
<!-- FAB agregar -->
|
||||
<div class="fixed bottom-6 right-6 z-50">
|
||||
<div class="fixed bottom-6 right-6 z-50 md:right-[calc(50%-176px)]">
|
||||
<button onclick="window.location.href='add.html'"
|
||||
class="w-14 h-14 bg-primary text-white rounded-2xl shadow-lg shadow-primary/30 flex items-center justify-center active:scale-90 transition-transform">
|
||||
<span class="material-symbols-outlined">add</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="js/ui.js"></script>
|
||||
<script src="js/historial.js"></script>
|
||||
</body>
|
||||
|
||||
+10
-11
@@ -3,10 +3,9 @@
|
||||
<html lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script src="js/tailwind.cdn.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
@@ -89,6 +88,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background text-on-background min-h-screen pb-32">
|
||||
<div class="max-w-md mx-auto relative">
|
||||
<!-- TopAppBar -->
|
||||
<header class="bg-[#f8faf9] dark:bg-slate-950 docked full-width top-0 sticky z-40">
|
||||
<div class="flex justify-between items-center w-full px-6 py-4">
|
||||
@@ -218,19 +218,18 @@
|
||||
</section>
|
||||
</main>
|
||||
<!-- BottomNavBar -->
|
||||
<nav class="fixed bottom-0 left-0 w-full z-50 flex justify-around items-center px-8 pb-8 pt-4 bg-[#ffffff]/70 dark:bg-slate-900/70 backdrop-blur-xl shadow-[0px_-12px_32px_rgba(0,80,80,0.06)] rounded-t-[2rem]">
|
||||
<nav class="fixed bottom-0 left-0 right-0 max-w-md mx-auto z-50 flex justify-around items-center px-8 pb-8 pt-4 bg-[#ffffff]/70 backdrop-blur-xl shadow-[0px_-12px_32px_rgba(0,80,80,0.06)] rounded-t-[2rem]">
|
||||
<button class="flex items-center justify-center bg-[#006a6a] text-white rounded-2xl p-3 shadow-lg shadow-[#006a6a]/20 active:scale-90 transition-transform duration-300">
|
||||
<span class="material-symbols-outlined" style="font-variation-settings: 'FILL' 1;">home</span>
|
||||
</button>
|
||||
<button class="flex items-center justify-center text-[#3e4948] dark:text-slate-400 p-3 hover:text-[#006a6a] dark:hover:text-teal-300 active:scale-90 transition-transform duration-300" onclick="window.location.href='historial.html'">
|
||||
<button class="flex items-center justify-center text-[#3e4948] p-3 hover:text-[#006a6a] active:scale-90 transition-transform duration-300" onclick="window.location.href='historial.html'">
|
||||
<span class="material-symbols-outlined">history</span>
|
||||
</button>
|
||||
<button class="flex items-center justify-center text-[#3e4948] dark:text-slate-400 p-3 hover:text-[#006a6a] dark:hover:text-teal-300 active:scale-90 transition-transform duration-300">
|
||||
<span class="material-symbols-outlined">credit_card</span>
|
||||
</button>
|
||||
<button class="flex items-center justify-center text-[#3e4948] dark:text-slate-400 p-3 hover:text-[#006a6a] dark:hover:text-teal-300 active:scale-90 transition-transform duration-300">
|
||||
<span class="material-symbols-outlined">person</span>
|
||||
<button class="flex items-center justify-center text-[#3e4948] p-3 hover:text-[#006a6a] active:scale-90 transition-transform duration-300" onclick="window.location.href='add.html'">
|
||||
<span class="material-symbols-outlined">add_circle</span>
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
<script src="js/ui.js"></script>
|
||||
<script src="js/dashboard.js"></script>
|
||||
</body></html>
|
||||
+28
-14
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user