Skip to content

Refactor code, tests and bug fixes - #13

Merged
twinik merged 12 commits into
mainfrom
feature/tests-and-bug-fixes
Aug 6, 2026
Merged

Refactor code, tests and bug fixes#13
twinik merged 12 commits into
mainfrom
feature/tests-and-bug-fixes

Conversation

@twinik

@twinik twinik commented Aug 2, 2026

Copy link
Copy Markdown
Member

📌 Resumen de Cambios

Este PR introduce mejoras significativas de UX/UI, optimizaciones de rendimiento y correcciones de errores en la interfaz de gestión de aplicaciones, ambientes y recursos compartidos de Caerus.


🎨 1. Rediseño y Mejora del Selector de Ambientes

  • Nueva Ubicación: Se movió el selector de ambientes a la barra de herramientas superior derecha como un botón outline elegante con indicador de color (dot) y menú desplegable.
  • Acceso directo a crear ambiente: La opción + Nuevo Ambiente abre el modal de creación de ambiente directamente en la página de configuración (action=create_env).
  • Insignias y Coherencia Visual: Se agregaron tags badges con el color personalizado del ambiente (envColors) en los contadores y estados vacíos de los encabezados de pestañas.

⚡ 2. Transiciones de Carga y Skeleton Loaders Ultra-Realistas

  • Skeleton Cards en Recursos, Locks y API Keys: Se implementaron componentes Skeleton con estructura realista (ícono, líneas de texto y botonera) para evitar saltos de contenido (flicker) al cambiar de ambiente.
  • Skeleton en la Grilla de Aplicaciones: Se reemplazó el spinner genérico por una grilla de 6 tarjetas Skeleton pulsantes.
  • Skeleton en la Barra Lateral (Sidebar): Estructura de carga realista con ícono, texto y puntos de ambiente.
  • Optimizaciones de Rendimiento:
    • Transición suave garantizada de 300ms al consultar la API para evitar destellos de 2ms.
    • Corrección del useEffect en la Sidebar ([] mount único) evitando re-consultar la API en cada navegación entre pantallas.

📋 3. Corrección y Rediseño de "Duplicar Recurso Compartido"

  • Alineación del Menú Desplegable: Se fijó el ancho (w-56) y alineación vertical de las opciones ("Configurar", "Duplicar...", "Eliminar").
  • Manejo de Errores Específico por Ambiente:
    • Traducción de errores técnicos de Spring Boot/Jackson a mensajes claros en español.
    • Especificación exacta de el/los ambiente/s en conflicto (p. ej. 'Ya existe una plantilla con el nombre "aaaa" en el ambiente "stage"').
  • Manejo de Operaciones Parciales y Toast Feedback:
    • Desmarcado automático de los ambientes en los que se creó exitosamente.
    • Notificación Toast flotante (Sonner) al completar la duplicación.
  • Ajustes Estéticos del Modal: Scrollbar fino oscuro personalizado (custom-scrollbar), tamaño del modal ampliado (sm:max-w-lg) y márgenes inferiores reducidos.

🛠️ 4. Correcciones Técnicas

  • React 19 ThemeProvider: Implementación nativa de ThemeProvider y useTheme para eliminar advertencias en la consola de desarrollo sobre <script> inline.
  • Montaje del Toaster de Notificaciones: Integración de <Toaster position="bottom-right" /> en el RootLayout (app/layout.tsx).
  • Color de Tarjetas de Recursos: Uso sincrónico de envColors respetando el presetId de cada ambiente (p. ej. violeta para local-test).

@twinik twinik self-assigned this Aug 2, 2026
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
caerus-fe Ignored Ignored Aug 6, 2026 1:18am

@twinik
twinik marked this pull request as ready for review August 6, 2026 01:20
Copilot AI lite review requested due to automatic review settings August 6, 2026 01:20
@twinik
twinik merged commit 66d6ff4 into main Aug 6, 2026
3 checks passed
@twinik
twinik deleted the feature/tests-and-bug-fixes branch August 6, 2026 01:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors and enhances the Caerus dashboard UX/UI around applications/environments/resources, introduces more consistent skeleton-loading states, improves shared resource duplication feedback, and adds a Vitest-based test setup with new type definitions.

Changes:

  • Reworked environment color/preset handling and expanded environment “kind” support across UI (badges/dots/cards).
  • Added skeleton loaders and refactored dashboard pages into reusable components/tabs for smoother loading transitions.
  • Introduced Vitest configuration + new unit tests, plus new types/* domain interfaces.

Reviewed changes

Copilot reviewed 39 out of 41 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
vitest.config.mts Adds Vitest configuration for running tests.
package.json Adds pnpm packageManager pin and test script via Vitest; adds Vitest dependency.
pnpm-lock.yaml Locks new Vitest/Vite/testing dependencies.
types/application.ts Adds application- and environment-related TypeScript interfaces.
types/resource.ts Adds Resource interface.
types/lock.ts Adds Lock interface.
types/api-key.ts Adds ApiKey interface.
types/billing.ts Adds billing-related interfaces (Plan/Invoice).
types/index.ts Exports all type modules from a single entrypoint.
lib/utils.ts Expands env color logic, presets, localStorage persistence, and environment dot aggregation helper.
lib/mocks/dashboard.ts Extracts dashboard mock stats/activity into shared mocks.
lib/mocks/applications.ts Adds mock environment data helpers and a TTL formatting helper.
components/ui/use-toast.ts Removes legacy toast hook implementation.
components/ui/use-mobile.tsx Removes legacy mobile breakpoint hook.
components/ui/sonner.tsx Switches Sonner toaster to use the new local ThemeProvider.
components/ui/skeleton.tsx Updates Skeleton styling for improved realism/contrast.
components/theme-provider.tsx Replaces next-themes provider with a custom ThemeProvider/useTheme implementation.
components/dashboard/sidebar.tsx Adds skeleton loading for app list, optimizes fetch behavior, updates env dots rendering.
components/dashboard/shared/stat-card.tsx Introduces reusable stat card component for dashboard stats.
components/dashboard/shared/env-badge.tsx Introduces reusable environment badge component.
components/dashboard/resource-form.tsx Preserves selected env query param when redirecting after save.
components/dashboard/header.tsx Switches theme hook import to the new ThemeProvider.
components/dashboard/applications/tabs/resources-tab.tsx Adds Resources tab component with skeletons and env-colored UI.
components/dashboard/applications/tabs/locks-tab.tsx Adds Locks tab component with skeletons and env-colored UI.
components/dashboard/applications/tabs/api-keys-tab.tsx Adds API Keys tab component with skeletons and env-colored UI.
components/dashboard/applications/duplicate-template-dialog.tsx Adds shared resource “duplicate to envs” dialog with translated error messaging and toast feedback.
components/dashboard/applications/application-detail-skeleton.tsx Adds detailed skeleton for application detail page.
components/dashboard/applications/application-card.tsx Adds reusable application card component.
app/layout.tsx Mounts Sonner <Toaster /> in RootLayout and uses new ThemeProvider.
app/globals.css Adds custom-scrollbar CSS utility.
app/dashboard/page.tsx Refactors dashboard page to use shared StatCard/EnvBadge and extracted mocks.
app/dashboard/applications/page.tsx Improves applications page loading UX with skeleton grid and refactors environment badges.
app/dashboard/applications/[id]/page.tsx Major refactor: new env selector, tabs extraction, skeleton loading, duplication dialog integration.
app/dashboard/applications/[id]/settings/page.tsx Adds environment color preset selection and “create env” deep-link behavior.
app/api/shared-resource-templates/route.ts Improves backend error parsing/normalization for POST failures.
.gitignore Ignores .claude/ directory.
tests/schemas/validation.test.ts Adds schema validation tests (Zod rules).
tests/proxy.test.ts Adds middleware/proxy behavior tests.
tests/lib/utils.test.ts Adds tests for cn and getEnvColors.
tests/lib/api.test.ts Adds tests for backend fetch helpers and auth token header behavior.
tests/api/routes.test.ts Adds tests for internal Next.js API route handlers.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/utils.ts
Comment on lines +110 to +126
let kind: EnvKind = envKind(envName)

let savedColor: string | null = customPresetId || null
if (!savedColor && typeof window !== "undefined") {
if (envId) {
savedColor = localStorage.getItem(`caerus_env_color_${envId}`)
}
if (!savedColor && envName) {
savedColor = localStorage.getItem(`caerus_env_color_name_${envName.toLowerCase()}`)
}
}

if (savedColor && savedColor in map) {
kind = savedColor as EnvKind
}

return map[kind] || map.slate
Comment on lines +102 to +118
<Card
key={lock.id}
className={cn(
'bg-card/50 border-border py-0 border-l-2',
getEnvColors(selectedEnv).borderStrong
)}
>
<CardContent className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 py-3 px-4">
<div className="flex items-center gap-3">
<div
className={cn(
'flex h-10 w-10 shrink-0 items-center justify-center rounded-lg',
getEnvColors(selectedEnv).bg
)}
>
<Lock className={cn('h-5 w-5', getEnvColors(selectedEnv).text)} />
</div>
Comment on lines +88 to +108
<Card
key={key.id}
className={cn(
'bg-card/50 border-border py-0 border-l-2',
getEnvColors(selectedEnv).borderStrong
)}
>
<CardContent className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 py-3 px-4">
<div className="flex items-center gap-3">
<div
className={cn(
'flex h-10 w-10 shrink-0 items-center justify-center rounded-lg border',
key.state === 'ACTIVE'
? cn(
getEnvColors(selectedEnv).bg,
getEnvColors(selectedEnv).border,
getEnvColors(selectedEnv).text
)
: 'bg-secondary text-muted-foreground border-border'
)}
>
Comment thread lib/utils.ts
Comment on lines +149 to +153
result.push({
kind,
colors: getEnvColors(kind),
})
}
Comment on lines +298 to +318
const { visibleDots, overflowCount, allNames } = getUniqueEnvDots(app.environments, 3);
const extraCount = app.environments.length - visibleDots.length;
return (
<span className="flex shrink-0 items-center gap-1">
{visibleDots.map(({ kind, colors }) => (
<span
key={kind}
className={cn("h-1.5 w-1.5 rounded-full", colors.dot)}
title={allNames.join(", ")}
/>
))}
{extraCount > 0 && (
<span
className="text-[10px] font-mono font-medium text-muted-foreground/80 leading-none"
title={allNames.join(", ")}
>
+{extraCount}
</span>
)}
</span>
);
Comment on lines +199 to +207
<Checkbox
id={`env-${env.id}`}
checked={isChecked}
onCheckedChange={() => handleToggleEnv(env.id.toString())}
/>
<Label htmlFor={`env-${env.id}`} className="cursor-pointer font-medium text-sm flex items-center gap-2">
<span className={cn("h-2.5 w-2.5 rounded-full shrink-0", colors.dot)} />
<span>{env.name}</span>
</Label>
Comment on lines +43 to +56
React.useEffect(() => {
const root = document.documentElement
root.classList.remove('light', 'dark')

let effectiveTheme: 'dark' | 'light' = 'dark'
if (theme === 'system') {
effectiveTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
} else {
effectiveTheme = theme
}

root.classList.add(effectiveTheme)
setResolvedTheme(effectiveTheme)
}, [theme])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants