diff --git a/src/App.tsx b/src/App.tsx index 8ec6113..44693ef 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -254,7 +254,7 @@ export default function App() { {/* ✅ AQUÍ VA LA MARCA DE AGUA */} -
+
{renderPage()}
diff --git a/src/components/layout/TopMenu.tsx b/src/components/layout/TopMenu.tsx index d47cfb9..ea766ce 100644 --- a/src/components/layout/TopMenu.tsx +++ b/src/components/layout/TopMenu.tsx @@ -180,14 +180,14 @@ const TopMenu: React.FC = ({ role="menu" className=" absolute right-0 mt-2 w-80 - rounded-2xl bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 + rounded-2xl bg-white dark:bg-zinc-900 border border-slate-200 dark:border-zinc-800 shadow-xl overflow-hidden z-50 " > {/* Header usuario */} -
+
-
+
{avatarUrl ? ( = ({ className="w-full h-full object-cover" /> ) : ( - + {initials} )} @@ -206,11 +206,11 @@ const TopMenu: React.FC = ({ {userName}
{userEmail ? ( -
+
{userEmail}
) : ( -
+
)}
@@ -225,7 +225,7 @@ const TopMenu: React.FC = ({ left={} /> -
+
- {left} + {left} {label} ); diff --git a/src/hooks/useNotifications.ts b/src/hooks/useNotifications.ts index 64ebfd8..34f3c03 100644 --- a/src/hooks/useNotifications.ts +++ b/src/hooks/useNotifications.ts @@ -32,7 +32,7 @@ export function useNotifications(autoRefreshInterval: number = 30000): UseNotifi const [hasMore, setHasMore] = useState(false); const [page, setPage] = useState(1); - const refreshIntervalRef = useRef(null); + const refreshIntervalRef = useRef | null>(null); const fetchNotifications = useCallback(async (filters?: NotificationFilters) => { try { diff --git a/src/index.css b/src/index.css index 690467e..66f22d3 100644 --- a/src/index.css +++ b/src/index.css @@ -14,10 +14,10 @@ /* Dark mode body */ body { - @apply bg-slate-50 text-gray-900; + @apply bg-slate-50 text-zinc-900; } .dark body, body:where(.dark *) { - @apply bg-gray-900 text-gray-100; + @apply bg-zinc-950 text-zinc-100; } \ No newline at end of file diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 8fea2f3..b2102e5 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -395,7 +395,7 @@ export default function Home({

Sistema de Tomas de Agua

-

+

Monitorea, administra y controla tus operaciones en un solo lugar.

@@ -412,42 +412,42 @@ export default function Home({ {/* Cards de Secciones */}
setPage("meters")} > - Tomas + Tomas
setPage("auditoria")} > - Alertas + Alertas
-
setPage("projects")} > - Proyectos + Proyectos
-
+
- Reportes + Reportes
{isAdmin && ( -
+
-

Organismos Operadores

-

+

Organismos Operadores

+

Seleccionado:{" "} - + {selectedOrganism === "Todos" ? "Todos" : organismsData.find(o => o.id === selectedOrganism)?.name || "Ninguno"} @@ -476,21 +476,21 @@ export default function Home({ /> {/* Panel */} -

+
{/* Header */} -
+

Organismos Operadores

-

+

Selecciona un organismo para filtrar la información del dashboard

{/* Search */} -
+
setOrganismQuery(e.target.value)} placeholder="Buscar organismo…" - className="w-full rounded-lg border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-500 dark:placeholder-gray-400" + className="w-full rounded-lg border border-gray-300 dark:border-zinc-700 dark:bg-zinc-800 dark:text-white px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-500 dark:placeholder-gray-400" />
@@ -523,7 +523,7 @@ export default function Home({ "rounded-xl border p-4 transition", selectedOrganism === "Todos" ? "border-blue-600 bg-blue-50/40 dark:bg-blue-900/20" - : "border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600", + : "border-gray-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 hover:bg-gray-50 dark:hover:bg-zinc-700", ].join(" ")} >
@@ -531,7 +531,7 @@ export default function Home({

Todos los Organismos

-

Ver todos los datos del sistema

+

Ver todos los datos del sistema

@@ -569,7 +569,7 @@ export default function Home({ "rounded-xl border p-4 transition", active ? "border-blue-600 bg-blue-50/40 dark:bg-blue-900/20" - : "border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600", + : "border-gray-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 hover:bg-gray-50 dark:hover:bg-zinc-700", ].join(" ")} >
@@ -577,7 +577,7 @@ export default function Home({

{o.name}

-

{o.region}

+

{o.region}

- Rol - + Rol + {o.contact}
- Email - + Email + {o.region}
- Proyectos - + Proyectos + {o.projects}
- Medidores - + Medidores + {o.meters}
- Último acceso - + Último acceso + {o.lastSync}
@@ -654,14 +654,14 @@ export default function Home({ )} {!loadingUsers && filteredOrganisms.length === 0 && ( -
+
No se encontraron organismos.
)}
{/* Footer */} -
+
Mostrando {filteredOrganisms.length} organismo{filteredOrganisms.length !== 1 ? 's' : ''} de {users.length} total{users.length !== 1 ? 'es' : ''}
@@ -672,7 +672,7 @@ export default function Home({
{/* Gráfica */} -
+

Numero de Medidores por Proyecto @@ -684,20 +684,20 @@ export default function Home({ {chartData.length === 0 && selectedOrganism !== "Todos" ? (
-

+

{selectedUserProjectName ? "Este organismo no tiene medidores registrados" : "Este organismo no tiene un proyecto asignado"}

{selectedUserProjectName && ( -

- Proyecto asignado: {selectedUserProjectName} +

+ Proyecto asignado: {selectedUserProjectName}

)}
) : chartData.length === 0 ? (
-

No hay datos disponibles

+

No hay datos disponibles

) : ( <> @@ -718,14 +718,14 @@ export default function Home({

{selectedOrganism !== "Todos" && selectedUserProjectName && ( -
+
- Proyecto del organismo: + Proyecto del organismo: {selectedUserProjectName}
- Total de medidores: + Total de medidores: {filteredMeters.length}
@@ -736,7 +736,7 @@ export default function Home({
{!isOperator && ( -
+

Historial Reciente de Auditoria

{loadingAuditLogs ? (
@@ -747,12 +747,12 @@ export default function Home({ No hay registros de auditoría disponibles

) : ( -
    +
      {history.map((h, i) => (
    • -

      +

      {h.user} {h.action}{" "} {h.target}

      @@ -766,7 +766,7 @@ export default function Home({ )} {!isOperator && ( -
      +

      Ultimas Alertas

      {loadingNotifications ? (
      @@ -777,11 +777,11 @@ export default function Home({ No hay alertas disponibles

      ) : ( -
        +
          {alerts.map((a, i) => (
        • - + {a.company} - {a.type}
          diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index f720ffc..9183b38 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -32,7 +32,6 @@ export default function LoginPage({ onSuccess }: LoginPageProps) { setLoading(true); try { await login({ email: form.email, password: form.password }); - // Tokens are stored by the auth module onSuccess(); } catch (err) { setServerError(err instanceof Error ? err.message : "Error de autenticación"); @@ -42,153 +41,155 @@ export default function LoginPage({ onSuccess }: LoginPageProps) { } return ( -
          -
          -
          +
          + {/* Imagen de fondo - agua */} +
          -
          - {/* IZQUIERDA */} -
          -
          + {/* Overlay oscuro */} +
          -
          - -
          -
          -

          - ¡Bienvenido! -

          -

          - Ingresa con tus credenciales para acceder al panel GRH. -

          -
          + {/* Layout dividido */} +
          + {/* Lado izquierdo - Branding */} +
          +
          +
          + GRH
          -
          + + GRH + +
          - {/* DERECHA */} -
          -
          -
          -
          - GRH -
          -

          - Iniciar sesión -

          -

          - Gestión de Recursos Hídricos -

          -
          +
          +

          + Gestión de +
          + Recursos Hídricos +

          +

          + Llevando agua potable a comunidades que más lo necesitan. + Monitoreo inteligente de infraestructura hídrica. +

          +
          + +

          + © 2026 GRH. Todos los derechos reservados. +

          +
          + + {/* Lado derecho - Formulario */} +
          +
          + {/* Logo móvil */} +
          + GRH + GRH +
          + +
          +

          + Iniciar sesión +

          +

          + Ingresa tus credenciales para acceder al sistema +

          +
          + +
          + {serverError && ( +
          + {serverError}
          + )} - - {serverError && ( -
          - {serverError} -
          - )} - - {/* Email */} -
          - -
          - - setForm((s) => ({ ...s, email: e.target.value })) - } - className="w-full border-b border-slate-300 py-2 pr-10 outline-none focus:border-slate-600" - /> - -
          - {errors.email && ( -

          - {errors.email} -

          - )} -
          - - {/* Contraseña */} -
          - -
          - - setForm((s) => ({ ...s, password: e.target.value })) - } - type={showPass ? "text" : "password"} - className="w-full border-b border-slate-300 py-2 pr-16 outline-none focus:border-slate-600" - /> - - -
          - {errors.password && ( -

          - {errors.password} -

          - )} -
          - - {/* Botón */} - -
          + {/* Email */} +
          + +
          + + setForm((s) => ({ ...s, email: e.target.value })) + } + placeholder="usuario@ejemplo.com" + className="w-full rounded-lg border border-slate-300 bg-white px-4 py-3 pr-11 text-slate-900 placeholder-slate-400 outline-none transition-all focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20" + /> + +
          + {errors.email && ( +

          {errors.email}

          + )}
          -
          -
          + + {/* Contraseña */} +
          + +
          + + setForm((s) => ({ ...s, password: e.target.value })) + } + type={showPass ? "text" : "password"} + placeholder="••••••••" + className="w-full rounded-lg border border-slate-300 bg-white px-4 py-3 pr-20 text-slate-900 placeholder-slate-400 outline-none transition-all focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20" + /> + + +
          + {errors.password && ( +

          {errors.password}

          + )} +
          + + {/* Botón */} + + +
          diff --git a/src/pages/conectores/SHMetersPage.tsx b/src/pages/conectores/SHMetersPage.tsx index fa300c5..ae91609 100644 --- a/src/pages/conectores/SHMetersPage.tsx +++ b/src/pages/conectores/SHMetersPage.tsx @@ -13,12 +13,12 @@ export default function SHMetersPage() {

          SH-METERS

          -

          Conector para medidores SH

          +

          Conector para medidores SH

      {/* Content */} -
      +
      {loading ? (
      @@ -26,10 +26,10 @@ export default function SHMetersPage() { ) : (
      -

      +

      Conector SH-METERS

      -

      +

      Configuracion e integracion con medidores SH. Esta seccion esta en desarrollo.

      diff --git a/src/pages/conectores/TTSPage.tsx b/src/pages/conectores/TTSPage.tsx index 9cd6937..6f98cd8 100644 --- a/src/pages/conectores/TTSPage.tsx +++ b/src/pages/conectores/TTSPage.tsx @@ -13,12 +13,12 @@ export default function TTSPage() {

      TTS

      -

      The Things Stack - Integracion LoRaWAN

      +

      The Things Stack - Integracion LoRaWAN

      {/* Content */} -
      +
      {loading ? (
      @@ -26,10 +26,10 @@ export default function TTSPage() { ) : (
      -

      +

      Conector TTS (The Things Stack)

      -

      +

      Configuracion e integracion con The Things Stack para dispositivos LoRaWAN. Esta seccion esta en desarrollo.

      diff --git a/src/pages/conectores/XMetersPage.tsx b/src/pages/conectores/XMetersPage.tsx index bab7e83..445f766 100644 --- a/src/pages/conectores/XMetersPage.tsx +++ b/src/pages/conectores/XMetersPage.tsx @@ -13,12 +13,12 @@ export default function XMetersPage() {

      XMETERS

      -

      Conector para medidores X

      +

      Conector para medidores X

      {/* Content */} -
      +
      {loading ? (
      @@ -26,10 +26,10 @@ export default function XMetersPage() { ) : (
      -

      +

      Conector XMETERS

      -

      +

      Configuracion e integracion con medidores X. Esta seccion esta en desarrollo.