Index: frontend/src/pages/Dashboard/components/DashboardSidebar.jsx
===================================================================
--- frontend/src/pages/Dashboard/components/DashboardSidebar.jsx	(revision 8c01a1f14ebd23dc0aeffe2d391546a92ddde9f9)
+++ frontend/src/pages/Dashboard/components/DashboardSidebar.jsx	(revision b3d5fed65cdab945e6c84835e2e04bc1814d9699)
@@ -1,3 +1,3 @@
-import React from "react";
+import React, { useEffect, useMemo, useState } from "react";
 import { NavLink, useLocation } from "react-router-dom";
 
@@ -20,7 +20,19 @@
   MdChecklist,
   MdAdd,
+  MdBook,
+  MdFlag,
+  MdStar,
+  MdBolt,
+  MdNoteAlt,
+  MdAutoGraph,
 } from "react-icons/md";
 
 import logo from "../../../assets/logo.png";
+
+import AddCustomCategoryModal from "./AddCustomCategoryModal.jsx";
+import {
+  createCustomTrackingCategory,
+  getCustomTrackingCategories,
+} from "../../../api/discipline.js";
 
 const navItems = [
@@ -33,6 +45,45 @@
 ];
 
+const CUSTOM_ICONS = [MdBook, MdFlag, MdStar, MdBolt, MdNoteAlt, MdAutoGraph];
+
+function stableIconForId(id) {
+  const n = Number(id);
+  if (!Number.isFinite(n)) return CUSTOM_ICONS[0];
+  return CUSTOM_ICONS[Math.abs(n) % CUSTOM_ICONS.length];
+}
+
 const DashboardSidebar = () => {
   const location = useLocation();
+  const [customOpen, setCustomOpen] = useState(false);
+  const [customCategories, setCustomCategories] = useState([]);
+
+  useEffect(() => {
+    let mounted = true;
+    (async () => {
+      try {
+        const res = await getCustomTrackingCategories();
+        const items = res?.items ?? [];
+        if (mounted) setCustomCategories(items);
+      } catch {
+        // If the user isn't authenticated yet or the endpoint fails,
+        // keep the sidebar usable (no custom categories).
+        if (mounted) setCustomCategories([]);
+      }
+    })();
+    return () => {
+      mounted = false;
+    };
+  }, []);
+
+  const customNavItems = useMemo(() => {
+    return (customCategories ?? []).map((c) => {
+      const Icon = stableIconForId(c.customTrackingId);
+      return {
+        title: c.name,
+        to: `/dashboard/custom/${c.customTrackingId}`,
+        icon: Icon,
+      };
+    });
+  }, [customCategories]);
 
   return (
@@ -52,4 +103,46 @@
           {navItems.map((item) => (
             <SidebarMenuItem key={item.title}>
+              {(() => {
+                const isActive =
+                  location.pathname === item.to ||
+                  location.pathname.startsWith(`${item.to}/`);
+
+                return (
+                  <SidebarMenuButton
+                    asChild
+                    isActive={isActive}
+                    className={
+                      isActive
+                        ? "!bg-green-400 !text-black hover:!bg-green-400 active:!bg-green-400"
+                        : ""
+                    }
+                  >
+                    <NavLink
+                      to={item.to}
+                      className="flex w-full items-center gap-3"
+                    >
+                      <item.icon
+                        className={
+                          isActive
+                            ? "size-6 shrink-0 text-black"
+                            : "size-6 shrink-0"
+                        }
+                      />
+                      <span className={isActive ? "text-black" : ""}>
+                        {item.title}
+                      </span>
+                    </NavLink>
+                  </SidebarMenuButton>
+                );
+              })()}
+            </SidebarMenuItem>
+          ))}
+
+          {customNavItems.length > 0 ? (
+            <div className="my-4 border-t border-white/10" />
+          ) : null}
+
+          {customNavItems.map((item) => (
+            <SidebarMenuItem key={`custom-${item.to}`}>
               {(() => {
                 const isActive =
@@ -94,4 +187,5 @@
             className="w-full justify-start gap-2 !bg-green-400 !text-black hover:!bg-green-500"
             type="button"
+            onClick={() => setCustomOpen(true)}
           >
             <MdAdd className="size-5" />
@@ -99,4 +193,13 @@
           </Button>
         </div>
+
+        <AddCustomCategoryModal
+          open={customOpen}
+          onClose={() => setCustomOpen(false)}
+          onSubmit={async (payload) => {
+            const created = await createCustomTrackingCategory(payload);
+            setCustomCategories((prev) => [created, ...(prev ?? [])]);
+          }}
+        />
       </SidebarContent>
     </Sidebar>
