import { useMemo, useState } from "react"; import { useNavigate } from "react-router-dom"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import { useDashboardShortcuts, useDeleteDashboardShortcut, useSaveDashboardShortcut, } from "../hooks/useDashboard"; import { useWidgetInstances } from "../hooks/useWidgets"; import type { DashboardShortcut, DashboardShortcutInput } from "../types"; import { SectionCard } from "../components/SectionCard"; import { ConfirmDialog } from "../components/ConfirmDialog"; import { DialogFooter } from "../components/DialogFooter"; import { WidgetInstanceCard } from "../components/WidgetInstance"; import { WidgetConfigDialog } from "../components/WidgetConfigDialog"; function emptyShortcut(): DashboardShortcutInput { return { id: null, label: "", shortcut_type: "website", enabled: true, icon: "", url: "", task_id: "", machine_id: "", user_id: "", notes: "", }; } function normalizeWebsiteUrl(url: string): string { const trimmed = url.trim(); if (!trimmed) return ""; if (/^https?:\/\//i.test(trimmed)) return trimmed; return `https://${trimmed}`; } function shortcutHref(shortcut: DashboardShortcut): string { if (shortcut.shortcut_type === "website") { return normalizeWebsiteUrl(shortcut.url); } if (shortcut.shortcut_type === "action") { if (!shortcut.task_id) return ""; const params = new URLSearchParams({ task: shortcut.task_id }); if (shortcut.machine_id) params.set("machine_id", shortcut.machine_id); return `/actions?${params.toString()}`; } if (!shortcut.user_id) return ""; return `/users?user=${encodeURIComponent(shortcut.user_id)}`; } function Field({ label, htmlFor, helper, children, }: { label: string; htmlFor: string; helper?: string; children: React.ReactNode; }) { return (
{children} {helper ? (

{helper}

) : null}
); } function ShortcutDialog({ open, draft, onChange, onClose, onSave, }: { open: boolean; draft: DashboardShortcutInput; onChange: (shortcut: DashboardShortcutInput) => void; onClose: () => void; onSave: () => void; }) { return ( { if (!next) onClose(); }} > {draft.id ? "Edit shortcut" : "New shortcut"}
onChange({ ...draft, label: e.target.value }) } />
onChange({ ...draft, icon: e.target.value })} />
{draft.shortcut_type === "website" ? ( onChange({ ...draft, url: e.target.value })} /> ) : draft.shortcut_type === "action" ? (
onChange({ ...draft, task_id: e.target.value }) } /> onChange({ ...draft, machine_id: e.target.value }) } />
) : ( onChange({ ...draft, user_id: e.target.value }) } /> )} onChange({ ...draft, notes: e.target.value })} />
onChange({ ...draft, enabled: checked }) } />
); } function ShortcutCard({ shortcut, onOpen, onEdit, onDelete, }: { shortcut: DashboardShortcut; onOpen: () => void; onEdit: () => void; onDelete: () => void; }) { const href = shortcutHref(shortcut); const subtitle = shortcut.shortcut_type === "website" ? shortcut.url || "No URL configured" : shortcut.shortcut_type === "action" ? [ shortcut.task_id || "task pending", shortcut.machine_id ? `machine ${shortcut.machine_id}` : "any machine", ].join(" ยท ") : shortcut.user_id || "No user configured"; return (
{shortcut.label}
{subtitle}
{shortcut.icon ? (
{shortcut.icon}
) : null} {shortcut.shortcut_type}
{shortcut.notes ? (

{shortcut.notes}

) : null}
); } export function Dashboard() { const navigate = useNavigate(); const { data: shortcuts = [] } = useDashboardShortcuts(); const saveShortcut = useSaveDashboardShortcut(); const deleteShortcut = useDeleteDashboardShortcut(); const [shortcutDialogOpen, setShortcutDialogOpen] = useState(false); const [shortcutDraft, setShortcutDraft] = useState( emptyShortcut(), ); const [deleteShortcutId, setDeleteShortcutId] = useState(null); const [widgetDialogOpen, setWidgetDialogOpen] = useState(false); const { data: widgetInstances = [] } = useWidgetInstances(); const visibleWidgets = useMemo( () => widgetInstances .filter((w) => w.enabled) .sort((a, b) => a.sort_order - b.sort_order), [widgetInstances], ); const openCreateShortcut = () => { setShortcutDraft(emptyShortcut()); setShortcutDialogOpen(true); }; const openEditShortcut = (shortcut: DashboardShortcut) => { setShortcutDraft({ id: shortcut.id, label: shortcut.label, shortcut_type: shortcut.shortcut_type, enabled: shortcut.enabled, icon: shortcut.icon, url: shortcut.url, task_id: shortcut.task_id, machine_id: shortcut.machine_id, user_id: shortcut.user_id, notes: shortcut.notes, }); setShortcutDialogOpen(true); }; const saveShortcutDraft = async () => { await saveShortcut.mutateAsync(shortcutDraft); setShortcutDialogOpen(false); setShortcutDraft(emptyShortcut()); }; return (
} > {shortcuts.length ? (
{shortcuts.map((shortcut) => ( { const href = shortcutHref(shortcut); if (shortcut.shortcut_type === "website") { window.open(href, "_blank", "noopener,noreferrer"); } else if (href) { navigate(href); } }} onEdit={() => openEditShortcut(shortcut)} onDelete={() => setDeleteShortcutId(shortcut.id)} /> ))}
) : ( No shortcuts yet. Add a website now, then add action or user shortcuts later. )} {visibleWidgets.map((widget) => ( ))} setShortcutDialogOpen(false)} onSave={saveShortcutDraft} /> setDeleteShortcutId(null)} onConfirm={() => { if (deleteShortcutId) { deleteShortcut.mutate(deleteShortcutId); } setDeleteShortcutId(null); }} /> setWidgetDialogOpen(false)} /> ); }