diff --git a/nuxt4/app/assets/css/main.css b/nuxt4/app/assets/css/main.css index 60cdb49..17f4a97 100644 --- a/nuxt4/app/assets/css/main.css +++ b/nuxt4/app/assets/css/main.css @@ -546,3 +546,52 @@ .dark .cata-toast-neutral .cata-toast-icon { color: rgb(156, 163, 175); } + +/* -------------------------------------------------------------------------- */ +/* SCROLLBARS PERSONALIZADAS */ +/* -------------------------------------------------------------------------- */ + +/* Scrollbar compacta para navegadores modernos (Firefox) */ +* { + scrollbar-width: thin; + scrollbar-color: color-mix(in srgb, var(--cata-primary) 40%, transparent) transparent; +} + +.dark * { + scrollbar-color: color-mix(in srgb, var(--cata-primary) 60%, transparent) transparent; +} + +/* Scrollbar compacta para navegadores WebKit (Chrome, Safari, Edge) */ +*::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +*::-webkit-scrollbar-track { + background-color: transparent; +} + +*::-webkit-scrollbar-thumb { + background-color: color-mix(in srgb, var(--cata-primary) 40%, transparent); + border-radius: 4px; + border: 2px solid transparent; + background-clip: padding-box; +} + +*::-webkit-scrollbar-thumb:hover { + background-color: color-mix(in srgb, var(--cata-primary) 60%, transparent); +} + +.dark *::-webkit-scrollbar-thumb { + background-color: color-mix(in srgb, var(--cata-primary) 60%, transparent); +} + +.dark *::-webkit-scrollbar-thumb:hover { + background-color: color-mix(in srgb, var(--cata-primary) 80%, transparent); + box-shadow: 0 0 6px color-mix(in srgb, var(--cata-primary) 40%, transparent); +} + +/* Scrollbar para esquinas cuando hay scroll horizontal y vertical */ +*::-webkit-scrollbar-corner { + background-color: transparent; +} diff --git a/nuxt4/app/composables/useIndexedDB.ts b/nuxt4/app/composables/useIndexedDB.ts index 4d75bfa..3533a0a 100644 --- a/nuxt4/app/composables/useIndexedDB.ts +++ b/nuxt4/app/composables/useIndexedDB.ts @@ -49,9 +49,11 @@ function openDatabase(): Promise { */ async function saveSession(sesion: SesionCatacion): Promise { try { - // Clonar la sesión para eliminar los proxies reactivos de Vue - // antes de guardar en IndexedDB - const sesionClonada = JSON.parse(JSON.stringify(sesion)) as SesionCatacion + // Usar toRaw para convertir proxies reactivos de Vue a objetos planos + // antes de guardar en IndexedDB, pero necesitamos clonar profundamente + // para evitar referencias a objetos reactivos + const { toRaw } = await import('vue') + const sesionPlana = JSON.parse(JSON.stringify(toRaw(sesion))) as SesionCatacion const db = await openDatabase() const transaction = db.transaction([STORE_NAME], 'readwrite') @@ -66,7 +68,7 @@ async function saveSession(sesion: SesionCatacion): Promise { // Guardar la nueva sesión await new Promise((resolve, reject) => { - const addRequest = objectStore.add(sesionClonada) + const addRequest = objectStore.add(sesionPlana) addRequest.onsuccess = () => resolve() addRequest.onerror = () => reject(new Error('Error al guardar la sesión')) }) @@ -216,19 +218,21 @@ async function deleteSession(): Promise { */ async function updateSession(sesion: SesionCatacion): Promise { try { - // Actualizar timestamp de modificación - sesion.modificadoEn = Date.now() + // Usar toRaw para convertir proxies reactivos de Vue a objetos planos + // antes de guardar en IndexedDB, pero necesitamos clonar profundamente + // para evitar referencias a objetos reactivos + const { toRaw } = await import('vue') + const sesionPlana = JSON.parse(JSON.stringify(toRaw(sesion))) as SesionCatacion - // Clonar la sesión para eliminar los proxies reactivos de Vue - // antes de guardar en IndexedDB - const sesionClonada = JSON.parse(JSON.stringify(sesion)) as SesionCatacion + // Actualizar timestamp solo en la copia, no en el objeto reactivo + sesionPlana.modificadoEn = Date.now() const db = await openDatabase() const transaction = db.transaction([STORE_NAME], 'readwrite') const objectStore = transaction.objectStore(STORE_NAME) await new Promise((resolve, reject) => { - const putRequest = objectStore.put(sesionClonada) + const putRequest = objectStore.put(sesionPlana) putRequest.onsuccess = () => resolve() putRequest.onerror = () => reject(new Error('Error al actualizar la sesión')) })