"use client";
import { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
import {
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/components/ui/command";
import {
Search,
LayoutDashboard,
Activity,
Calendar,
Kanban,
FolderKanban,
FileText,
Wrench,
Target,
ExternalLink,
CheckCircle2,
Clock,
AlertCircle,
} from "lucide-react";
import { supabaseClient } from "@/lib/supabase/client";
interface Task {
id: string;
title: string;
status: string;
priority: string;
project_id: string;
}
interface Project {
id: string;
name: string;
}
const navItems = [
{ name: "Dashboard", href: "/", icon: LayoutDashboard, shortcut: "D" },
{ name: "Activity", href: "/activity", icon: Activity, shortcut: "A" },
{ name: "Calendar", href: "/calendar", icon: Calendar, shortcut: "C" },
{ name: "Tasks", href: "/tasks", icon: Kanban, shortcut: "T" },
{ name: "Projects", href: "/projects", icon: FolderKanban, shortcut: "P" },
{ name: "Documents", href: "/documents", icon: FileText, shortcut: "D" },
{ name: "Tools", href: "/tools", icon: Wrench, shortcut: "O" },
{ name: "Mission", href: "/mission", icon: Target, shortcut: "M" },
];
const quickLinks = [
{ name: "Gantt Board", url: "https://gantt-board.vercel.app", icon: ExternalLink },
{ name: "Blog Backup", url: "https://blog-backup-two.vercel.app", icon: ExternalLink },
{ name: "Gitea", url: "http://192.168.1.128:3000", icon: ExternalLink },
];
function getStatusIcon(status: string) {
switch (status) {
case "done":
return ;
case "in-progress":
return ;
default:
return ;
}
}
function getPriorityColor(priority: string): string {
switch (priority) {
case "urgent":
return "text-red-500";
case "high":
return "text-orange-500";
case "medium":
return "text-yellow-500";
default:
return "text-blue-500";
}
}
export function QuickSearch() {
const [open, setOpen] = useState(false);
const [tasks, setTasks] = useState([]);
const [projects, setProjects] = useState([]);
const [loading, setLoading] = useState(false);
const router = useRouter();
// Fetch tasks when search opens
useEffect(() => {
if (!open) return;
setLoading(true);
const fetchData = async () => {
try {
// Fetch tasks
const { data: tasksData } = await supabaseClient
.from('tasks')
.select('id, title, status, priority, project_id')
.order('updated_at', { ascending: false })
.limit(50);
// Fetch projects for names
const { data: projectsData } = await supabaseClient
.from('projects')
.select('id, name');
setTasks(tasksData || []);
setProjects(projectsData || []);
} catch (err) {
console.error('Error fetching search data:', err);
} finally {
setLoading(false);
}
};
fetchData();
}, [open]);
useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
setOpen((open) => !open);
}
};
document.addEventListener("keydown", down);
return () => document.removeEventListener("keydown", down);
}, []);
const runCommand = useCallback((command: () => void) => {
setOpen(false);
command();
}, []);
const getProjectName = (projectId: string) => {
return projects.find(p => p.id === projectId)?.name || 'Unknown';
};
return (
<>
{/* Search Button Trigger */}
{/* Command Dialog */}
No results found.
{/* Navigation */}
{navItems.map((item) => {
const Icon = item.icon;
return (
runCommand(() => router.push(item.href))}
>
{item.name}
);
})}
{/* Quick Links */}
{quickLinks.map((link) => {
const Icon = link.icon;
return (
runCommand(() => window.open(link.url, "_blank"))}
>
{link.name}
);
})}
{/* Tasks */}
{tasks.length > 0 && (
<>
{tasks.slice(0, 10).map((task) => (
runCommand(() =>
window.open(
`https://gantt-board.vercel.app/tasks/${task.id}`,
"_blank"
)
)
}
>
{getStatusIcon(task.status)}
{task.title}
{task.priority}
{getProjectName(task.project_id)}
))}
>
)}
>
);
}