feat: add validation for minimum length on various fields and update type definitions

This commit is contained in:
Abhimanyu Saharan
2026-02-06 16:12:04 +05:30
parent ca614328ac
commit d86fe0a7a6
157 changed files with 12340 additions and 2977 deletions

View File

@@ -1,51 +1,42 @@
"use client";
import Link from "next/link";
import { useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import { BarChart3, Bot, LayoutGrid, Network } from "lucide-react";
import { ApiError } from "@/api/mutator";
import {
type healthzHealthzGetResponse,
useHealthzHealthzGet,
} from "@/api/generated/default/default";
import { cn } from "@/lib/utils";
import { getApiBaseUrl } from "@/lib/api-base";
export function DashboardSidebar() {
const pathname = usePathname();
const [systemStatus, setSystemStatus] = useState<
"unknown" | "operational" | "degraded"
>("unknown");
const [statusLabel, setStatusLabel] = useState("System status unavailable");
const healthQuery = useHealthzHealthzGet<healthzHealthzGetResponse, ApiError>({
query: {
refetchInterval: 30_000,
refetchOnMount: "always",
retry: false,
},
request: { cache: "no-store" },
});
useEffect(() => {
let isMounted = true;
const apiBase = getApiBaseUrl();
const checkHealth = async () => {
try {
const response = await fetch(`${apiBase}/healthz`, { cache: "no-store" });
if (!response.ok) {
throw new Error("Health check failed");
}
const data = (await response.json()) as { ok?: boolean };
if (!isMounted) return;
if (data?.ok) {
setSystemStatus("operational");
setStatusLabel("All systems operational");
} else {
setSystemStatus("degraded");
setStatusLabel("System degraded");
}
} catch {
if (!isMounted) return;
setSystemStatus("degraded");
setStatusLabel("System degraded");
}
};
checkHealth();
const interval = setInterval(checkHealth, 30000);
return () => {
isMounted = false;
clearInterval(interval);
};
}, []);
const okValue = healthQuery.data?.data?.ok;
const systemStatus: "unknown" | "operational" | "degraded" =
okValue === true
? "operational"
: okValue === false
? "degraded"
: healthQuery.isError
? "degraded"
: "unknown";
const statusLabel =
systemStatus === "operational"
? "All systems operational"
: systemStatus === "unknown"
? "System status unavailable"
: "System degraded";
return (
<aside className="flex h-full w-64 flex-col border-r border-slate-200 bg-white">

View File

@@ -5,10 +5,12 @@ import { useMemo, useState } from "react";
import { TaskCard } from "@/components/molecules/TaskCard";
import { cn } from "@/lib/utils";
type TaskStatus = "inbox" | "in_progress" | "review" | "done";
type Task = {
id: string;
title: string;
status: string;
status: TaskStatus;
priority: string;
description?: string | null;
due_at?: string | null;
@@ -20,10 +22,17 @@ type Task = {
type TaskBoardProps = {
tasks: Task[];
onTaskSelect?: (task: Task) => void;
onTaskMove?: (taskId: string, status: string) => void;
onTaskMove?: (taskId: string, status: TaskStatus) => void | Promise<void>;
};
const columns = [
const columns: Array<{
title: string;
status: TaskStatus;
dot: string;
accent: string;
text: string;
badge: string;
}> = [
{
title: "Inbox",
status: "inbox",
@@ -74,10 +83,15 @@ export function TaskBoard({
onTaskMove,
}: TaskBoardProps) {
const [draggingId, setDraggingId] = useState<string | null>(null);
const [activeColumn, setActiveColumn] = useState<string | null>(null);
const [activeColumn, setActiveColumn] = useState<TaskStatus | null>(null);
const grouped = useMemo(() => {
const buckets: Record<string, Task[]> = {};
const buckets: Record<TaskStatus, Task[]> = {
inbox: [],
in_progress: [],
review: [],
done: [],
};
for (const column of columns) {
buckets[column.status] = [];
}
@@ -104,7 +118,7 @@ export function TaskBoard({
};
const handleDrop =
(status: string) => (event: React.DragEvent<HTMLDivElement>) => {
(status: TaskStatus) => (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
setActiveColumn(null);
const raw = event.dataTransfer.getData("text/plain");
@@ -120,14 +134,14 @@ export function TaskBoard({
};
const handleDragOver =
(status: string) => (event: React.DragEvent<HTMLDivElement>) => {
(status: TaskStatus) => (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
if (activeColumn !== status) {
setActiveColumn(status);
}
};
const handleDragLeave = (status: string) => () => {
const handleDragLeave = (status: TaskStatus) => () => {
if (activeColumn === status) {
setActiveColumn(null);
}