Back to 0cron
0cron

De HTML estatico a dashboard SvelteKit en una noche

Como convertimos un sitio de marketing HTML estatico en un dashboard SvelteKit 2 completo con runes Svelte 5, autenticacion y un constructor cron wizard en una sesion.

Juste Thales Gnimavo & Claude | March 26, 2026 4 min 0cron
EN/ FR/ ES
0cronsveltesveltekitdashboardtailwindcssfrontendui

Cuando lanzamos la primera version de 0cron.dev, el "frontend" era un solo archivo HTML estatico. Una pagina de marketing con algunos gradientes bonitos, una tabla de precios, y un boton de llamada a la accion que apuntaba a una API que aun no tenia interfaz. El backend era solido -- 14 endpoints, 8 tablas de base de datos, 2,852 lineas de Rust -- pero los usuarios no tenian forma de interactuar con el mas alla de solicitudes HTTP crudas.

Eso cambio en una sola sesion. El 11 de marzo de 2026, convertimos 0cron-website de HTML estatico en una aplicacion SvelteKit 2 completa con 13 paginas de ruta, un store de auth reactivo, un cliente API, un layout de sidebar oscuro, y un wizard de creacion de tareas con un constructor de expresiones cron estilo cPanel.

Por que SvelteKit

Enrutamiento basado en archivos elimina boilerplate. Cada pagina es un archivo. Cada layout envuelve sus hijos automaticamente.

Las runes de Svelte 5 reemplazan el patron de stores. En lugar de importar writable stores, suscribirte y gestionar limpieza, escribes $state y el compilador maneja la reactividad.

TailwindCSS 4 viene de serie con SvelteKit. Sin configuracion de PostCSS, sin configuracion de purge, sin ajustes de pipeline de compilacion.

La estructura de rutas

src/routes/
  +page.svelte                          -- Landing (carga static/landing.html)
  (auth)/
    login/+page.svelte                  -- Google Sign-In + email/contrasena
  (app)/
    +layout.svelte                      -- Guardia de auth + layout sidebar
    dashboard/+page.svelte              -- Tarjetas de estadisticas, proximas tareas, ejecuciones recientes
    jobs/+page.svelte                   -- Lista de tareas con acciones (trigger/pausar/eliminar)
    jobs/new/+page.svelte               -- Wizard de creacion de tareas (CronBuilder)
    jobs/[id]/+page.svelte              -- Detalle de tarea + historial de ejecucion + estadisticas
    billing/+page.svelte                -- Visualizacion de plan, Stripe Checkout/Portal
    settings/+page.svelte               -- Gestion de claves API + secretos
    account/+page.svelte                -- Perfil

El store de auth: runes Svelte 5 en practica

typescriptclass AuthStore {
    token = $state<string | null>(null);
    user = $state<User | null>(null);

    get isAuthenticated() { return !!this.token; }
    get isAdmin() { return this.user?.is_admin ?? false; }

    login(token: string, user: User) {
        this.token = token;
        this.user = user;
        if (browser) {
            localStorage.setItem('auth_token', token);
            localStorage.setItem('auth_user', JSON.stringify(user));
        }
    }

    logout() {
        this.token = null;
        this.user = null;
        if (browser) {
            localStorage.removeItem('auth_token');
            localStorage.removeItem('auth_user');
        }
    }
}

$state hace que los campos de clase sean reactivos. Cuando this.token cambia, cualquier componente que lea authStore.token o authStore.isAuthenticated se re-renderiza automaticamente.

Los getters se convierten en estado derivado. isAuthenticated e isAdmin son getters JavaScript normales, pero como leen campos $state, Svelte los rastrea como dependencias.

El wizard de creacion de tareas

La pieza central es el CronBuilder -- un constructor de expresiones cron estilo cPanel con 18 presets que cubren la gran mayoria de necesidades de programacion del mundo real:

typescriptconst schedulePresets = [
    { label: 'Every minute', cron: '* * * * *' },
    { label: 'Every 5 minutes', cron: '*/5 * * * *' },
    { label: 'Every day at midnight', cron: '0 0 * * *' },
    { label: 'Every day at 9am', cron: '0 9 * * *' },
    { label: 'Every weekday at 9am', cron: '0 9 * * 1-5' },
    { label: 'First day of month', cron: '0 0 1 * *' },
    // ... 12 more presets
];

Usuarios que nunca han escrito una expresion cron pueden hacer clic en "Every weekday at 9am" y obtener 0 9 <em> </em> 1-5 sin entender el formato de cinco campos.

Lecciones aprendidas

Los grupos de rutas estan infrautilizados en SvelteKit. El patron (auth) / (app) resuelve el problema "algunas paginas necesitan sidebar, otras no" de forma limpia.

Las runes de Svelte 5 hacen que las clases sean viables para gestion de estado. El store de auth se lee como TypeScript normal, pero cada campo $state es rastreado.

Mantener lo que funciona. La pagina de marketing estatica estaba bien. No la reescribimos en Svelte.


Este es el articulo 7 de 10 en la serie "Como construimos 0cron".

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles

Thales & Claude deblo

El prompt decía que lo anunciara. El modelo no lo hizo. Así que lo hizo el worker: cerrar un silencio de 15 segundos en Déblo Voice

Déblo Voice se quedaba en silencio unos 15 segundos cada vez que una pregunta difícil activaba una búsqueda profunda. El prompt ya exigía un anuncio, pero el modelo de audio nativo emite la llamada a la función como su primer token. Además, el silencio tenía dos partes, la ejecución de la herramienta y la latencia de la respuesta, así que ningún prompt podía cerrarlo. Llevamos la garantía al worker de LiveKit: un anuncio pregrabado con la voz y el idioma de la sesión, y un suave sonido de tecleo mientras el agente piensa. Probado en producción el 16 de octubre de 2026: 14 y 17,5 segundos de silencio del lado del modelo, unos 0,4 segundos percibidos por el usuario.

13 min Oct 16, 2026
deblodeblo-voicevoice-aigemini-live +17
Thales & Claude zerosuite

El servidor que no dimos de baja: vaciar una máquina de producción en una noche, y cada número que comprobamos

Una noche, seis aplicaciones migradas fila por fila, tres copias de seguridad vacías, una sin destino y un servidor cuyo futuro cambió tres veces.

19 min Oct 2, 2026
caspclaude-codeclaude-opus-5.5infrastructure +10
Thales & Claude zerosuite

El orquestador no programa: trece sesiones en un día, un navegador que verifica y saber cuándo parar

Un día, una plataforma privada de un cliente, trece sesiones headless de Claude encadenadas por un orquestador que nunca escribe código. Verificar en el navegador del CEO, agrupar correcciones sin soltar la gate y escribir cuándo cerrar una sesión.

19 min Sep 30, 2026
caspclaude-codeclaude-opus-5.5multi-session +12