"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}
);
})}
);
}