aboutsummaryrefslogtreecommitdiff
path: root/packages/ui/memory-graph/node-detail-panel.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/ui/memory-graph/node-detail-panel.tsx')
-rw-r--r--packages/ui/memory-graph/node-detail-panel.tsx268
1 files changed, 0 insertions, 268 deletions
diff --git a/packages/ui/memory-graph/node-detail-panel.tsx b/packages/ui/memory-graph/node-detail-panel.tsx
deleted file mode 100644
index 0fdc4801..00000000
--- a/packages/ui/memory-graph/node-detail-panel.tsx
+++ /dev/null
@@ -1,268 +0,0 @@
-"use client";
-
-import { cn } from "@repo/lib/utils";
-import { Badge } from "@repo/ui/components/badge";
-import { Button } from "@repo/ui/components/button";
-import { GlassMenuEffect } from "@repo/ui/other/glass-effect";
-import { Brain, Calendar, ExternalLink, FileText, Hash, X } from "lucide-react";
-import { motion } from "motion/react";
-import { memo } from "react";
-import {
- GoogleDocs,
- GoogleDrive,
- GoogleSheets,
- GoogleSlides,
- MicrosoftExcel,
- MicrosoftOneNote,
- MicrosoftPowerpoint,
- MicrosoftWord,
- NotionDoc,
- OneDrive,
- PDF,
-} from "../assets/icons";
-import { HeadingH3Bold } from "../text/heading/heading-h3-bold";
-import type {
- DocumentWithMemories,
- MemoryEntry,
- NodeDetailPanelProps,
-} from "./types";
-
-const formatDocumentType = (type: string) => {
- // Special case for PDF
- if (type.toLowerCase() === "pdf") return "PDF";
-
- // Replace underscores with spaces and capitalize each word
- return type
- .split("_")
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
- .join(" ");
-};
-
-const getDocumentIcon = (type: string) => {
- const iconProps = { className: "w-5 h-5 text-slate-300" };
-
- switch (type) {
- case "google_doc":
- return <GoogleDocs {...iconProps} />;
- case "google_sheet":
- return <GoogleSheets {...iconProps} />;
- case "google_slide":
- return <GoogleSlides {...iconProps} />;
- case "google_drive":
- return <GoogleDrive {...iconProps} />;
- case "notion":
- case "notion_doc":
- return <NotionDoc {...iconProps} />;
- case "word":
- case "microsoft_word":
- return <MicrosoftWord {...iconProps} />;
- case "excel":
- case "microsoft_excel":
- return <MicrosoftExcel {...iconProps} />;
- case "powerpoint":
- case "microsoft_powerpoint":
- return <MicrosoftPowerpoint {...iconProps} />;
- case "onenote":
- case "microsoft_onenote":
- return <MicrosoftOneNote {...iconProps} />;
- case "onedrive":
- return <OneDrive {...iconProps} />;
- case "pdf":
- return <PDF {...iconProps} />;
- default:
- return <FileText {...iconProps} />;
- }
-};
-
-export const NodeDetailPanel = memo<NodeDetailPanelProps>(
- ({ node, onClose, variant = "console" }) => {
- // Use explicit classes that Tailwind can detect
- const getPositioningClasses = () => {
- // Both variants use the same positioning for nodeDetail
- return "top-4 right-4";
- };
-
- if (!node) return null;
-
- const isDocument = node.type === "document";
- const data = node.data;
-
- return (
- <motion.div
- animate={{ opacity: 1 }}
- className={cn(
- "absolute w-80 rounded-xl overflow-hidden z-20 max-h-[80vh]",
- getPositioningClasses(),
- )}
- exit={{ opacity: 0 }}
- initial={{ opacity: 0 }}
- transition={{
- duration: 0.2,
- ease: "easeInOut",
- }}
- >
- {/* Glass effect background */}
- <GlassMenuEffect rounded="rounded-xl" />
-
- <motion.div
- animate={{ opacity: 1 }}
- className="relative z-10 p-4 overflow-y-auto max-h-[80vh]"
- initial={{ opacity: 0 }}
- transition={{ delay: 0.05, duration: 0.15 }}
- >
- <div className="flex items-center justify-between mb-3">
- <div className="flex items-center gap-2">
- {isDocument ? (
- getDocumentIcon((data as DocumentWithMemories).type)
- ) : (
- <Brain className="w-5 h-5 text-blue-400" />
- )}
- <HeadingH3Bold className="text-slate-100">
- {isDocument ? "Document" : "Memory"}
- </HeadingH3Bold>
- </div>
- <motion.div whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }}>
- <Button
- className="h-8 w-8 p-0 text-slate-300 hover:text-slate-100"
- onClick={onClose}
- size="sm"
- variant="ghost"
- >
- <X className="w-4 h-4" />
- </Button>
- </motion.div>
- </div>
-
- <div className="space-y-3">
- {isDocument ? (
- <>
- <div>
- <span className="text-xs text-slate-400 uppercase tracking-wide">
- Title
- </span>
- <p className="text-sm text-slate-200 mt-1">
- {(data as DocumentWithMemories).title ||
- "Untitled Document"}
- </p>
- </div>
-
- {(data as DocumentWithMemories).summary && (
- <div>
- <span className="text-xs text-slate-400 uppercase tracking-wide">
- Summary
- </span>
- <p className="text-sm text-slate-300 mt-1 line-clamp-3">
- {(data as DocumentWithMemories).summary}
- </p>
- </div>
- )}
-
- <div>
- <span className="text-xs text-slate-400 uppercase tracking-wide">
- Type
- </span>
- <p className="text-sm text-slate-200 mt-1">
- {formatDocumentType((data as DocumentWithMemories).type)}
- </p>
- </div>
-
- <div>
- <span className="text-xs text-slate-400 uppercase tracking-wide">
- Memory Count
- </span>
- <p className="text-sm text-slate-200 mt-1">
- {(data as DocumentWithMemories).memoryEntries.length}{" "}
- memories
- </p>
- </div>
-
- {((data as DocumentWithMemories).url ||
- (data as DocumentWithMemories).customId) && (
- <div>
- <span className="text-xs text-slate-400 uppercase tracking-wide">
- URL
- </span>
- <a
- className="text-sm text-indigo-400 hover:text-indigo-300 mt-1 flex items-center gap-1"
- href={(() => {
- const doc = data as DocumentWithMemories;
- if (doc.type === "google_doc" && doc.customId) {
- return `https://docs.google.com/document/d/${doc.customId}`;
- }
- if (doc.type === "google_sheet" && doc.customId) {
- return `https://docs.google.com/spreadsheets/d/${doc.customId}`;
- }
- if (doc.type === "google_slide" && doc.customId) {
- return `https://docs.google.com/presentation/d/${doc.customId}`;
- }
- return doc.url ?? undefined;
- })()}
- rel="noopener noreferrer"
- target="_blank"
- >
- <ExternalLink className="w-3 h-3" />
- View Document
- </a>
- </div>
- )}
- </>
- ) : (
- <>
- <div>
- <span className="text-xs text-slate-400 uppercase tracking-wide">
- Memory
- </span>
- <p className="text-sm text-slate-200 mt-1">
- {(data as MemoryEntry).memory}
- </p>
- {(data as MemoryEntry).isForgotten && (
- <Badge className="mt-2" variant="destructive">
- Forgotten
- </Badge>
- )}
- {(data as MemoryEntry).forgetAfter && (
- <p className="text-xs text-slate-400 mt-1">
- Expires:{" "}
- {(data as MemoryEntry).forgetAfter
- ? new Date(
- (data as MemoryEntry).forgetAfter!,
- ).toLocaleDateString()
- : ""}{" "}
- {"forgetReason" in data &&
- data.forgetReason &&
- `- ${data.forgetReason}`}
- </p>
- )}
- </div>
-
- <div>
- <span className="text-xs text-slate-400 uppercase tracking-wide">
- Space
- </span>
- <p className="text-sm text-slate-200 mt-1">
- {(data as MemoryEntry).spaceId || "Default"}
- </p>
- </div>
- </>
- )}
-
- <div className="pt-2 border-t border-slate-700/50">
- <div className="flex items-center gap-4 text-xs text-slate-400">
- <span className="flex items-center gap-1">
- <Calendar className="w-3 h-3" />
- {new Date(data.createdAt).toLocaleDateString()}
- </span>
- <span className="flex items-center gap-1">
- <Hash className="w-3 h-3" />
- {node.id}
- </span>
- </div>
- </div>
- </div>
- </motion.div>
- </motion.div>
- );
- },
-);
-
-NodeDetailPanel.displayName = "NodeDetailPanel";