HomeContactBlogPlayground

Published September 10, 2026

Building MaintInsight

How I built a maintenance intelligence dashboard with Next.js.

ZB
Ziane BadreddineAuthor

Hello World 👋

Welcome to my blog.

This is where I'll share things I'm learning while building software.

What I'll write about

  • Next.js
  • React
  • Full-stack development
  • Software architecture
  • My projects
  • Things I learn along the way

Stay tuned 🚀

Inline: c=±a2+b2c = \pm\sqrt{a^2 + b^2}c=±a2+b2​

c=±a2+b2c = \pm\sqrt{a^2 + b^2} c=±a2+b2​
.g
  • group
  • groupCollapsed
  • groupEnd
;
const player: = { : "Hello World" };
const player: Player
("test");
@import "tailwindcss";

@custom-variant dark (&:is(.dark *));

:root {
  --background: #fcfcfc;
  --foreground: #000000;
  --card: #ffffff;
  --card-foreground: #000000;
  --popover: #fcfcfc;
  --popover-foreground: #000000;
  --primary: #bb2def;
  --primary-foreground: #ffffff;
  --secondary: #ebebeb;
  --secondary-foreground: #000000;
  --muted: #f5f5f5;
  --muted-foreground: #525252;
  --accent: #55ff05;
  --accent-foreground: #000000;
  --destructive: #e5e14b;
  --destructive-foreground: #ffffff;
  --border: #e4e4e4;
  --input: #ebebeb;
  --ring: #000000;
  --chart-1: #55ff05;
  --chart-2: #bb2def;
  --chart-3: #a4a4a4;
  --chart-4: #e4e4e4;
  --chart-5: #747474;
  --sidebar: #fcfcfc;
  --sidebar-foreground: #000000;
  --sidebar-primary: #bb2def;
  --sidebar-primary-foreground: #ffffff;
  --sidebar-accent: #55ff05;
  --sidebar-accent-foreground: #000000;
  --sidebar-border: #e4e4e4;
  --sidebar-ring: #000000;
  --font-sans: Geist, sans-serif;
  --font-serif: Georgia, serif;
  --font-mono: Fira Code, ui-monospace, monospace;
  --radius: 0rem;
  --shadow-x: 0px;
  --shadow-y: 1px;
  --shadow-blur: 2px;
  --shadow-spread: 0px;
  --shadow-opacity: 0.18;
  --shadow-color: #1a1a1a;
  --shadow-2xs: 0px 1px 2px 0px hsl(0 0% 10.1961% / 0.09);
  --shadow-xs: 0px 1px 2px 0px hsl(0 0% 10.1961% / 0.09);
  --shadow-sm:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 1px 2px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 1px 2px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow-md:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 2px 4px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow-lg:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 4px 6px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow-xl:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 8px 10px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow-2xl: 0px 1px 2px 0px hsl(0 0% 10.1961% / 0.45);
  --tracking-normal: 0em;
  --spacing: 0.25rem;
}

.dark {
  --background: #000000;
  --foreground: #ffffff;
  --card: #1a191a;
  --card-foreground: #ffffff;
  --popover: #1a191a;
  --popover-foreground: #ffffff;
  --primary: #a926f4;
  --primary-foreground: #000000;
  --secondary: #222222;
  --secondary-foreground: #ffffff;
  --muted: #1d1d1d;
  --muted-foreground: #a4a4a4;
  --accent: #333333;
  --accent-foreground: #ffffff;
  --destructive: #ffff5b;
  --destructive-foreground: #000000;
  --border: #242424;
  --input: #333333;
  --ring: #a4a4a4;
  --chart-1: #55ff05;
  --chart-2: #a926f4;
  --chart-3: #747474;
  --chart-4: #525252;
  --chart-5: #e4e4e4;
  --sidebar: #000000;
  --sidebar-foreground: #ffffff;
  --sidebar-primary: #a926f4;
  --sidebar-primary-foreground: #000000;
  --sidebar-accent: #333333;
  --sidebar-accent-foreground: #ffffff;
  --sidebar-border: #242424;
  --sidebar-ring: #a4a4a4;
  --font-sans: Geist, sans-serif;
  --font-serif: Georgia, serif;
  --font-mono: Fira Code, ui-monospace, monospace;
  --radius: 0rem;
  --shadow-x: 0px;
  --shadow-y: 1px;
  --shadow-blur: 2px;
  --shadow-spread: 0px;
  --shadow-opacity: 0.18;
  --shadow-color: #1a1a1a;
  --shadow-2xs: 0px 1px 2px 0px hsl(0 0% 10.1961% / 0.09);
  --shadow-xs: 0px 1px 2px 0px hsl(0 0% 10.1961% / 0.09);
  --shadow-sm:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 1px 2px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 1px 2px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow-md:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 2px 4px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow-lg:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 4px 6px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow-xl:
    0px 1px 2px 0px hsl(0 0% 10.1961% / 0.18),
    0px 8px 10px -1px hsl(0 0% 10.1961% / 0.18);
  --shadow-2xl: 0px 1px 2px 0px hsl(0 0% 10.1961% / 0.45);
}

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-card: var(--card);
  --color-card-foreground: var(--card-foreground);
  --color-popover: var(--popover);
  --color-popover-foreground: var(--popover-foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-secondary: var(--primary);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  --color-accent: var(--accent);
  --color-accent-foreground: var(--accent-foreground);
  --color-destructive: var(--destructive);
  --color-destructive-foreground: var(--destructive-foreground);
  --color-border: var(--border);
  --color-input: var(--input);
  --color-ring: var(--ring);
  --color-chart-1: var(--chart-1);
  --color-chart-2: var(--chart-2);
  --color-chart-3: var(--chart-3);
  --color-chart-4: var(--chart-4);
  --color-chart-5: var(--chart-5);
  --color-sidebar: var(--sidebar);
  --color-sidebar-foreground: var(--sidebar-foreground);
  --color-sidebar-primary: var(--sidebar-primary);
  --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
  --color-sidebar-accent: var(--sidebar-accent);
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
  --color-sidebar-border: var(--sidebar-border);
  --color-sidebar-ring: var(--sidebar-ring);

  --font-sans: var(--font-sans);
  --font-mono: var(--font-mono);
  --font-serif: var(--font-serif);

  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);

  --shadow-2xs: var(--shadow-2xs);
  --shadow-xs: var(--shadow-xs);
  --shadow-sm: var(--shadow-sm);
  --shadow: var(--shadow);
  --shadow-md: var(--shadow-md);
  --shadow-lg: var(--shadow-lg);
  --shadow-xl: var(--shadow-xl);
  --shadow-2xl: var(--shadow-2xl);
}

@layer base {
  * {
    @apply border-border outline-ring/50;
  }
  body {
    @apply bg-background text-foreground;
  }
}

On this page

Hello World 👋What I'll write about

Related Blogs

Oct 10,2026

17,600 Actions: Agent Security Is a Systems Problem

The OpenAI/Hugging Face incident exposed a new challenge for AI agent security. 17,600 attacker actions show why AI agent security can’t rely on human review. Explore the controls needed to constrain, observe, and govern agents at speed.

Next.js

TypeScript

PostgreSQL

Navigation

  • Home
  • About
  • Projects
  • Contact

Explore

  • Experience
  • Education
  • Activities

Blog

  • 17,600 Actions: Agent Security Is a Systems Problem
  • Building MaintInsight
  • Component Library
  • Problem C — Moroccan Carpet Patterns
  • Game of Codes — CP Contest
  • All posts

Language

Connect

GitHub
LinkedIn
Email

Ziane Badr Eddine.