Customization

Last updated on 2026-09-07

The kit is designed to be customized for your own project management product. This guide covers the most common customization scenarios.

Adding a New Task Status

Task statuses are defined in three places: the database enum, the TypeScript types, and the Kanban board column order.

1. Add the Database Enum Value

In your Supabase SQL Editor, run:

ALTER TYPE task_status ADD VALUE 'QA' AFTER 'In Review';

2. Update the TypeScript Type

In types/index.ts, add the new status:

export type TaskStatusType =
  | "Backlog"
  | "Todo"
  | "In Progress"
  | "In Review"
  | "QA"         // new
  | "Done"
  | "Cancelled"

3. Update the Kanban Board Columns

In components/kanban/kanban-board.tsx, add the new column:

const COLUMN_ORDER: { status: TaskStatusType; color: string; wipLimit?: number }[] = [
  { status: "Backlog", color: "#6b7280" },
  { status: "Todo", color: "#8b5cf6", wipLimit: 8 },
  { status: "In Progress", color: "#f59e0b", wipLimit: 5 },
  { status: "In Review", color: "#3b82f6", wipLimit: 3 },
  { status: "QA", color: "#14b8a6", wipLimit: 3 },  // new
  { status: "Done", color: "#22c55e" },
  { status: "Cancelled", color: "#ef4444" },
]

4. Update the Status Grouping

In the same file, add the new status to groupTasksByStatus:

const grouped: Record<TaskStatusType, Task[]> = {
  Backlog: [],
  Todo: [],
  "In Progress": [],
  "In Review": [],
  QA: [],          // new
  Done: [],
  Cancelled: [],
}

5. Update Analytics Colors

In app/(dashboard)/analytics/page-client.tsx, add the status color:

const statusColors: Record<TaskStatusType, string> = {
  Backlog: "#94a3b8",
  Todo: "#8b5cf6",
  "In Progress": "#f59e0b",
  "In Review": "#3b82f6",
  QA: "#14b8a6",      // new
  Done: "#22c55e",
  Cancelled: "#ef4444",
}

6. Update Cumulative Flow

In the cumulative flow chart and cumulative_flow_points table, add a qa column.

Changing Priority Levels

Priority levels are also a database enum plus TypeScript types.

1. Database

ALTER TYPE task_priority ADD VALUE 'Critical' BEFORE 'Urgent';

2. TypeScript

export type TaskPriorityLevel =
  | "Critical"   // new
  | "Urgent"
  | "High"
  | "Medium"
  | "Low"
  | "None"

3. Priority Colors

Update the priority color mapping in analytics/page-client.tsx and workload/workload-client.tsx:

const priorityColors: Record<TaskPriorityLevel, string> = {
  Critical: "#dc2626",  // new
  Urgent: "#ef4444",
  High: "#f97316",
  Medium: "#eab308",
  Low: "#3b82f6",
  None: "#6b7280",
}

Modifying Labels

Labels are stored in the labels table and managed via lib/actions/labels.ts.

Label Groups

Labels belong to one of three groups: Type, Area, or Status. To add a new group:

  1. Add a new value to the label_group enum:
    ALTER TYPE label_group ADD VALUE 'Component';
    
  2. Update the TaskLabel interface in types/index.ts:
    export interface TaskLabel {
      id: string
      name: string
      color: string
      group: "Type" | "Area" | "Status" | "Component"
      description?: string
      usageCount: number
    }
    

Creating Labels Programmatically

Use the createLabel Server Action:

import { createLabel } from "@/lib/actions/labels"

await createLabel({
  name: "Performance",
  color: "#f59e0b",
  group: "Area",
  description: "Performance-related tasks",
})

Bulk Seeding Labels

Insert directly via SQL for bulk operations:

INSERT INTO labels (name, color, label_group, description) VALUES
  ('Bug', '#ef4444', 'Type', 'Something is broken'),
  ('Feature', '#22c55e', 'Type', 'New feature request'),
  ('Improvement', '#3b82f6', 'Type', 'Enhancement to existing feature'),
  ('Frontend', '#8b5cf6', 'Area', 'Frontend related'),
  ('Backend', '#f97316', 'Area', 'Backend related'),
  ('API', '#14b8a6', 'Area', 'API related');

Adding a New Project View

Project views are the different layouts for viewing tasks (board, list, calendar, timeline). To add a new view:

1. Add the View Layout Type

ALTER TYPE view_layout ADD VALUE 'table';
// types/index.ts
export type ViewLayout = "board" | "list" | "timeline" | "calendar" | "table"

2. Create the Route

Create a new route at app/(dashboard)/projects/[id]/table/:

app/(dashboard)/projects/[id]/table/
├── page.tsx        (server component)
└── page-client.tsx (client component)

The server component fetches data and passes it to the client component:

// page.tsx
import { getTasksByProject } from "@/lib/actions/tasks"
import { getProject } from "@/lib/actions/projects"
import TablePageClient from "./page-client"

export default async function TablePage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params
  const [{ data: project }, { data: tasks }] = await Promise.all([
    getProject(id),
    getTasksByProject(id),
  ])
  if (!project) return notFound()
  return <TablePageClient tasks={tasks ?? []} />
}

3. Add Navigation Tab

In the project layout navigation, add a link to the new view alongside the existing board, list, calendar, and timeline tabs.

Rebranding

Change the Brand Color

Edit app/globals.css and change the primary hue from 255 (blue-indigo) to your brand hue:

:root {
  --primary: oklch(0.45 0.2 YOUR_HUE);
  --primary-foreground: oklch(0.98 0.005 YOUR_HUE);
}
.dark {
  --primary: oklch(0.7 0.18 YOUR_HUE);
  --primary-foreground: oklch(0.15 0.02 YOUR_HUE);
}

Change the App Name

  1. In app/layout.tsx, update the metadata.title:
    export const metadata: Metadata = {
      title: {
        default: "Your App Name",
        template: "%s | Your App Name",
      },
    }
    
  2. Update the sidebar header component with your logo and app name

Change Fonts

In app/layout.tsx, replace the font imports:

import { YourFont } from "next/font/google"

const yourFont = YourFont({
  variable: "--font-inter",
  subsets: ["latin"],
})

Then update CSS variable references as needed.

Customizing the Kanban Board

WIP Limits

Adjust WIP (work-in-progress) limits in kanban-board.tsx:

const COLUMN_ORDER = [
  { status: "Backlog", color: "#6b7280" },
  { status: "Todo", color: "#8b5cf6", wipLimit: 10 },        // changed from 8
  { status: "In Progress", color: "#f59e0b", wipLimit: 3 },  // changed from 5
  { status: "In Review", color: "#3b82f6", wipLimit: 2 },    // changed from 3
  { status: "Done", color: "#22c55e" },
  { status: "Cancelled", color: "#ef4444" },
]

Column Colors

Change any column's color indicator by modifying the color hex value in COLUMN_ORDER.

Card Content

Modify KanbanCard to show or hide task properties:

  • Remove the assignee avatar to simplify cards
  • Add the estimate (story points) to each card
  • Show the due date more prominently

Adding Project Templates

Project templates define pre-configured projects. Add new templates via SQL:

INSERT INTO project_templates (name, description, category, icon, statuses, labels, sample_tasks) VALUES
  ('Bug Tracker',
   'A streamlined workflow for tracking and resolving bugs.',
   'Bug Tracking',
   'bug',
   '{"Triage", "Confirmed", "In Progress", "Fixed", "Closed"}',
   '{"Bug", "Regression", "P0", "P1", "P2"}',
   '{"Fix login timeout", "Resolve 500 error on dashboard", "Update error handling"}');

Custom Automation Rules

Automation rules are stored in automation_rules and can be created via the UI or Server Actions:

import { createAutomationRule } from "@/lib/actions/automations"

await createAutomationRule({
  projectId: "...",
  name: "Auto-close stale tasks",
  trigger: "task_idle_30_days",
  condition: "status = 'Backlog'",
  action: "set_status_cancelled",
})

Feature Toggles

Each project has feature flags in the database:

Column Controls
feat_cycles Show/hide Cycles tab
feat_modules Show/hide Modules tab
feat_pages Show/hide Pages (wiki) tab
feat_automations Show/hide Automations tab
feat_estimates Show/hide story point estimates

Toggle these via the project settings page or directly:

UPDATE projects SET feat_cycles = true, feat_modules = true WHERE id = '...';