qrush 0.6.0

Lightweight Job Queue and Task Scheduler for Rust (Actix + Redis + Cron)
Documentation
<!DOCTYPE html>
<html lang="en" class="h-full antialiased">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>{% if title %}{{ title }} · QRush{% else %}QRush Metrics{% endif %}</title>

  <!-- Tailwind CDN (no build step needed) -->
  <script src="https://cdn.tailwindcss.com"></script>
  <script>
    tailwind.config = {
      darkMode: 'class',
      theme: { extend: {} }
    }
  </script>
  <style type="text/tailwindcss">
    @layer utilities {
      .container-px { @apply px-4 sm:px-6 lg:px-8; }
      .card { @apply rounded-2xl border border-slate-200/60 dark:border-slate-800/60 bg-white/70 dark:bg-slate-900/60 backdrop-blur-xl shadow; }
      .chip { @apply inline-flex items-center px-2 py-0.5 text-xs font-medium rounded-full; }
      .chip-green { @apply chip bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300; }
      .chip-red { @apply chip bg-rose-100 text-rose-700 dark:bg-rose-900/40 dark:text-rose-300; }
      .chip-amber { @apply chip bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300; }
      .chip-sky { @apply chip bg-sky-100 text-sky-700 dark:bg-sky-900/40 dark:text-sky-300; }
      .link { @apply text-slate-700 hover:text-slate-900 dark:text-slate-200 dark:hover:text-white transition; }
      .btn { @apply inline-flex items-center gap-2 rounded-xl px-3 py-1.5 border border-slate-300/60 dark:border-slate-700/60 bg-white/70 dark:bg-slate-900/60 hover:bg-slate-50 dark:hover:bg-slate-800; }
      .btn-danger { @apply btn border-rose-300/60 hover:bg-rose-50 dark:hover:bg-rose-900/20; }
      .btn-primary { @apply btn border-slate-300/60 ring-1 ring-slate-300/50; }
      .table { @apply min-w-full text-sm; }
      .th { @apply text-left font-semibold text-slate-600 dark:text-slate-300 px-3 py-2; }
      .td { @apply px-3 py-2 border-t border-slate-200/60 dark:border-slate-800/60; }
      .kpi { @apply card p-4; }
      .kpi-title { @apply text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400; }
      .kpi-value { @apply text-2xl font-semibold text-slate-900 dark:text-white; }
    }
  </style>
</head>
<body class="h-full bg-slate-50 dark:bg-slate-950 text-slate-900 dark:text-slate-100">
  <!-- Top gradient bar -->
  <div class="sticky top-0 z-50 w-full">
    <div class="absolute inset-0 h-16 bg-gradient-to-r from-indigo-500 via-violet-500 to-fuchsia-500 opacity-80 dark:from-indigo-700 dark:via-violet-700 dark:to-fuchsia-700"></div>
    <div class="relative z-50">
      <div class="container-px mx-auto max-w-7xl">
        <div class="h-16 flex items-center rounded-b-2xl border border-slate-200/60 dark:border-slate-800/60 bg-white/70 dark:bg-slate-900/60 backdrop-blur-xl shadow z-20">
          <a href="/qrush/metrics" class="flex items-center gap-2 pl-3">
            <span class="h-8 w-8 rounded-full bg-gradient-to-br from-indigo-500 to-fuchsia-500 ring-2 ring-white/70 dark:ring-slate-900/60 shadow">
              <!-- Logo image -->
              <img src="https://srotas-suite-space.s3.ap-south-1.amazonaws.com/sqrush.png" alt="AdminX Logo" class="h-8 w-8 rounded-full shadow ring-2 ring-indigo-500/70">
            </span>
          </a>
          <nav class="ml-auto flex items-center gap-4 pr-3">
            <a class="link text-sm" href="/qrush/metrics">Queues</a>
            <a class="link text-sm" href="/qrush/metrics/extras/summary">Summary</a>

            <!-- Extras dropdown -->
            <div class="relative">
              <button id="extrasToggle" class="link text-sm inline-flex items-center gap-1">
                Extras
                <span class="text-xs"></span>
              </button>
              <div
                id="extrasMenu"
                class="hidden absolute right-0 mt-2 w-40 card py-2 text-sm"
              >
                <a href="/qrush/metrics/extras/delayed"
                   class="block px-3 py-1.5 text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-800">
                  Delayed
                </a>
                <a href="/qrush/metrics/extras/dead"
                   class="block px-3 py-1.5 text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-800">
                  Dead
                </a>
                <a href="/qrush/metrics/extras/retry"
                   class="block px-3 py-1.5 text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-800">
                  Retry
                </a>
                <a href="/qrush/metrics/extras/failed"
                   class="block px-3 py-1.5 text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-800">
                  Failed
                </a>
              </div>
            </div>

            <a class="link text-sm" href="/qrush/metrics/extras/cron">Crons</a>
            <button id="themeToggle" class="btn" title="Toggle theme">🌓</button>
          </nav>
        </div>
      </div>
    </div>

    <main class="container-px mx-auto max-w-7xl py-6 z-10">
      {% block content %}{% endblock content %}
    </main>

    <footer class="relative mt-8 w-full">
      <div class="absolute inset-x-0 -top-4 h-1 bg-gradient-to-r from-indigo-500 via-violet-500 to-fuchsia-500 opacity-70"></div>
      <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-6">
        <div class="rounded-2xl border border-slate-200/60 dark:border-slate-700/60 bg-white/70 dark:bg-slate-900/60 backdrop-blur-xl shadow flex flex-col md:flex-row items-center justify-between gap-3 px-4 py-4">
          <p class="text-sm text-slate-600 dark:text-slate-400">
            © Srotas Space {{ now() | date(format="%Y") }} <span class="font-semibold text-slate-900 dark:text-white">Qrush</span>. All rights reserved.
          </p>
          <nav class="flex items-center gap-4 text-sm">
            <a href="https://srotas.space/open-source/qrush/privacy" class="text-slate-600 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white transition">Privacy</a>
            <span class="text-slate-300 dark:text-slate-600"></span>
            <a href="https://srotas.space/open-source/qrush/terms" class="text-slate-600 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white transition">Terms</a>
            <span class="text-slate-300 dark:text-slate-600"></span>
            <a href="https://srotas.space/open-source/qrush/support" class="text-slate-600 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white transition">Support</a>
            <span class="text-slate-300 dark:text-slate-600"></span>
            <a href="https://github.com/srotas-space/qrush" class="text-slate-600 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white transition">Github</a>
          </nav>
        </div>
      </div>
    </footer>

    <script>
      (function(){
        const key='qrush-theme';
        const saved = localStorage.getItem(key);
        if (saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
          document.documentElement.classList.add('dark');
        }

        const themeToggle = document.getElementById('themeToggle');
        if (themeToggle) {
          themeToggle.addEventListener('click', () => {
            document.documentElement.classList.toggle('dark');
            localStorage.setItem(
              key,
              document.documentElement.classList.contains('dark') ? 'dark':'light'
            );
          });
        }

        // Extras dropdown toggle
        const extrasToggle = document.getElementById('extrasToggle');
        const extrasMenu = document.getElementById('extrasMenu');

        if (extrasToggle && extrasMenu) {
          extrasToggle.addEventListener('click', (e) => {
            e.stopPropagation();
            extrasMenu.classList.toggle('hidden');
          });

          document.addEventListener('click', () => {
            extrasMenu.classList.add('hidden');
          });
        }
      })();
    </script>
  </body>
</html>