"use client"; import type { ReactNode } from "react"; import { Upload, Globe, FolderSync, Cloud, Mic, CheckCircle2 } from "lucide-react"; type Status = "available" | "planned"; interface SourceTile { id: string; label: string; desc: string; icon: ReactNode; status: Status; } const TILES: SourceTile[] = [ { id: "upload", label: "Upload files", desc: "PDF · DOCX · HTML · MD · TXT · audio", icon: , status: "available" }, { id: "voice", label: "Voice note", desc: "WAV · MP3 · M4A — transcribed + diarized", icon: , status: "available" }, { id: "url", label: "Web URL", desc: "Scrape + index a page", icon: , status: "available" }, { id: "folder", label: "Watch folder", desc: "Auto-reindex a local directory", icon: , status: "available" }, { id: "cloud", label: "Cloud connectors", desc: "Drive · Slack · Notion", icon: , status: "available" }, ]; /** * Ingest source tile-grid (Onyx pattern, adapted honestly to a local-first RAG): * available sources are actionable; not-yet-built ones are shown as disabled * "Planned" tiles — the same available/planned discipline the RAG strategy * selector uses — rather than faking connectors that don't exist. */ export function IngestSources({ onUpload, onWebUrl }: { onUpload: () => void; onWebUrl?: () => void }) { return (

Add a source

5 available
{TILES.map((t) => { const available = t.status === "available"; const Tag = available ? "button" : "div"; // folder → jump to the Watch Folder manager; url → open the URL input; others → upload. const onClick = t.id === "folder" ? () => document .getElementById("watch-panel") ?.scrollIntoView({ behavior: "smooth", block: "start" }) : t.id === "url" ? onWebUrl ?? onUpload : t.id === "cloud" ? () => document .getElementById("connectors-panel") ?.scrollIntoView({ behavior: "smooth", block: "start" }) : onUpload; return ( {t.icon} {available ? ( Available ) : ( Planned )} {t.label} {t.desc} ); })}
); }